Skip to content

Commit

Permalink
fix(merge): fix onChange props issue. #681
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Sep 5, 2024
1 parent a7137dc commit 48a754b
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 48 deletions.
26 changes: 22 additions & 4 deletions merge/src/Internal.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useEffect, useImperativeHandle, useRef } from 'react';
import { EditorStateConfig, StateEffect } from '@codemirror/state';
import { EditorStateConfig } from '@codemirror/state';
import { getDefaultExtensions } from '@uiw/react-codemirror';
import { MergeView, MergeConfig, DirectMergeConfig } from '@codemirror/merge';
import { useStore } from './store';
import { CodeMirrorMergeProps } from './';

import { EditorView, ViewUpdate } from '@codemirror/view';
export interface InternalRef {
container?: HTMLDivElement | null;
view?: MergeView;
Expand Down Expand Up @@ -48,28 +48,46 @@ export const Internal = React.forwardRef<InternalRef, CodeMirrorMergeProps>((pro
[editor, view, modified, original, opts],
);

const originalUpdateListener = EditorView.updateListener.of((vu: ViewUpdate) => {
if (vu.docChanged && typeof originalExtension?.onChange === 'function') {
const doc = vu.state.doc;
const val = doc.toString();
originalExtension?.onChange(val, vu);
}
});

const modifiedUpdateListener = EditorView.updateListener.of((vu: ViewUpdate) => {
if (vu.docChanged && typeof modifiedExtension?.onChange === 'function') {
const doc = vu.state.doc;
const val = doc.toString();
modifiedExtension?.onChange(val, vu);
}
});

useEffect(() => {
if (!view.current && editor.current) {
if (!view.current && editor.current && originalExtension && modifiedExtension) {
view.current = new MergeView({
a: {
...original,
extensions: [
...(originalExtension?.extension || []),
...getDefaultExtensions({ ...originalExtension?.option, theme }),
originalUpdateListener,
],
},
b: {
...modified,
extensions: [
...(modifiedExtension?.extension || []),
...getDefaultExtensions({ ...modifiedExtension?.option, theme }),
modifiedUpdateListener,
],
},
parent: editor.current,
...opts,
});
}
}, [view, editor]);
}, [view, editor, originalExtension, modifiedExtension]);

useEffect(() => {
if (original && original.doc && view.current) {
Expand Down
40 changes: 15 additions & 25 deletions merge/src/Modified.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect } from 'react';
import { getDefaultExtensions, DefaultExtensionsOptions } from '@uiw/react-codemirror';
import { EditorStateConfig, Extension } from '@codemirror/state';
import { EditorView, ViewUpdate } from '@codemirror/view';
import { ViewUpdate } from '@codemirror/view';
import { useStore } from './store';

export interface ModifiedProps extends Omit<DefaultExtensionsOptions, 'theme'>, Omit<EditorStateConfig, 'doc'> {
Expand All @@ -15,30 +15,20 @@ export const Modified = (props: ModifiedProps): JSX.Element | null => {
const { extensions = [], value, selection, onChange, ...otherOption } = props;
const { theme, dispatch } = useStore();
const defaultExtensions = getDefaultExtensions({ ...otherOption, theme });
const updateListener = EditorView.updateListener.of((vu: ViewUpdate) => {
if (vu.docChanged && typeof onChange === 'function') {
const doc = vu.state.doc;
const val = doc.toString();
onChange(val, vu);
}
});

useEffect(
() =>
dispatch!({
modified: {
doc: value,
selection: selection,
extensions: [updateListener, ...defaultExtensions, ...extensions],
},
modifiedExtension: {
onChange,
option: otherOption,
extension: [updateListener, extensions],
},
}),
[props],
);
useEffect(() => {
dispatch!({
modified: {
doc: value,
selection: selection,
extensions: [...defaultExtensions, ...extensions],
},
modifiedExtension: {
onChange,
option: otherOption,
extension: [extensions],
},
});
}, [props]);
return null;
};

Expand Down
13 changes: 3 additions & 10 deletions merge/src/Original.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect } from 'react';
import { getDefaultExtensions, DefaultExtensionsOptions } from '@uiw/react-codemirror';
import { EditorStateConfig, Extension } from '@codemirror/state';
import { EditorView, ViewUpdate } from '@codemirror/view';
import { ViewUpdate } from '@codemirror/view';
import { useStore } from './store';

export interface OriginalProps extends Omit<DefaultExtensionsOptions, 'theme'>, Omit<EditorStateConfig, 'doc'> {
Expand All @@ -15,26 +15,19 @@ export const Original = (props: OriginalProps): JSX.Element | null => {
const { extensions = [], value, selection, onChange, ...otherOption } = props;
const { theme, dispatch } = useStore();
const defaultExtensions = getDefaultExtensions({ ...otherOption, theme });
const updateListener = EditorView.updateListener.of((vu: ViewUpdate) => {
if (vu.docChanged && typeof onChange === 'function') {
const doc = vu.state.doc;
const val = doc.toString();
onChange(val, vu);
}
});

useEffect(
() =>
dispatch!({
original: {
doc: value,
selection: selection,
extensions: [updateListener, ...defaultExtensions, ...extensions],
extensions: [...defaultExtensions, ...extensions],
},
originalExtension: {
onChange,
option: otherOption,
extension: [extensions, updateListener],
extension: [extensions],
},
}),
[props],
Expand Down
20 changes: 11 additions & 9 deletions www/src/pages/merge/examples/Example.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,24 @@ four
five`;

export default function App() {
const [value, setValue] = useState('');
const [valueModified, setValueModified] = useState('');
const [value, setValue] = useState(doc);
const [valueModified, setValueModified] = useState(doc);
return (
<div>
<CodeMirrorMerge>
<CodeMirrorMerge destroyRerender={false}>
<Original
onChange={(value) => {
setValue(value);
onChange={(val) => {
console.log('~~:1', val);
setValue(val);
}}
value={doc}
value={value}
/>
<Modified
onChange={(value) => {
setValueModified(value);
onChange={(val) => {
console.log('~~:2', val);
setValueModified(val);
}}
value={doc.replace(/t/g, 'T') + 'Six'}
value={valueModified}
/>
</CodeMirrorMerge>
<div style={{ display: 'flex', marginTop: 10 }}>
Expand Down

0 comments on commit 48a754b

Please sign in to comment.