/
Internal.tsx
95 lines (89 loc) · 2.71 KB
/
Internal.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import React, { useEffect, useImperativeHandle, useMemo, useRef, memo } from 'react';
import { MergeView, MergeConfig } from '@codemirror/merge';
import { useStore } from './store';
import { CodeMirrorMergeProps } from './';
export interface InternalRef {
container?: HTMLDivElement | null;
view?: MergeView;
}
export const Internal = React.forwardRef((props: CodeMirrorMergeProps, ref?: React.ForwardedRef<InternalRef>) => {
const {
className,
children,
orientation,
revertControls,
highlightChanges,
gutter,
collapseUnchanged,
renderRevertControl,
...elmProps
} = props;
const { modified, original, view, dispatch, ...otherStore } = useStore();
const editor = useRef<HTMLDivElement>(null);
useImperativeHandle(ref, () => ({ container: editor.current, view }), [editor, view]);
useEffect(() => {
if (!view && editor.current && original && modified) {
const opts = { orientation, revertControls, highlightChanges, gutter, collapseUnchanged, renderRevertControl };
const viewDefault = new MergeView({
a: original,
b: modified,
parent: editor.current,
...opts,
});
dispatch && dispatch({ view: viewDefault, ...opts });
}
}, [editor.current, original, modified, view]);
useEffect(() => {
return () => {
view && view.destroy();
};
}, []);
useEffect(() => {
if (view) {
const opts: MergeConfig = {};
if (otherStore.orientation !== orientation) {
opts.orientation = orientation;
}
if (otherStore.revertControls !== revertControls) {
opts.revertControls = revertControls;
}
if (otherStore.highlightChanges !== highlightChanges) {
opts.highlightChanges = highlightChanges;
}
if (otherStore.gutter !== gutter) {
opts.gutter = gutter;
}
if (otherStore.collapseUnchanged !== collapseUnchanged) {
opts.collapseUnchanged = collapseUnchanged;
}
if (Object.keys(opts).length && dispatch && original && modified && editor.current) {
view.destroy();
const viewDefault = new MergeView({
a: original,
b: modified,
parent: editor.current,
...opts,
});
dispatch({ ...opts, renderRevertControl, view: viewDefault });
}
}
}, [
view,
original,
modified,
editor,
orientation,
revertControls,
highlightChanges,
gutter,
collapseUnchanged,
renderRevertControl,
]);
const defaultClassNames = 'cm-merge-theme';
return (
<div ref={editor} className={`${defaultClassNames}${className ? ` ${className}` : ''}`} {...elmProps}>
{children}
</div>
);
});
Internal.displayName = 'CodeMirrorMerge.Internal';