@uiw/react-codemirror 4.19.7 → 4.19.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/useCodeMirror.js +9 -2
- package/cjs/useCodeMirror.js.map +11 -3
- package/dist/mdeditor.js +84 -26
- package/dist/mdeditor.min.js +1 -1
- package/esm/useCodeMirror.js +8 -3
- package/esm/useCodeMirror.js.map +11 -3
- package/package.json +2 -2
- package/src/__tests__/index.test.tsx +7 -0
- package/src/useCodeMirror.ts +11 -2
package/esm/useCodeMirror.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
|
-
import { EditorState, StateEffect } from '@codemirror/state';
|
|
2
|
+
import { Annotation, EditorState, StateEffect } from '@codemirror/state';
|
|
3
3
|
import { indentWithTab } from '@codemirror/commands';
|
|
4
4
|
import { EditorView, keymap, placeholder } from '@codemirror/view';
|
|
5
5
|
import { basicSetup } from '@uiw/codemirror-extensions-basic-setup';
|
|
6
6
|
import { oneDark } from '@codemirror/theme-one-dark';
|
|
7
7
|
import { getStatistics } from './utils';
|
|
8
|
+
var External = Annotation.define();
|
|
8
9
|
export function useCodeMirror(props) {
|
|
9
10
|
var {
|
|
10
11
|
value,
|
|
@@ -51,7 +52,10 @@ export function useCodeMirror(props) {
|
|
|
51
52
|
}
|
|
52
53
|
});
|
|
53
54
|
var updateListener = EditorView.updateListener.of(vu => {
|
|
54
|
-
if (vu.docChanged && typeof onChange === 'function'
|
|
55
|
+
if (vu.docChanged && typeof onChange === 'function' &&
|
|
56
|
+
// Fix echoing of the remote changes:
|
|
57
|
+
// If transaction is market as remote we don't have to call `onChange` handler again
|
|
58
|
+
!vu.transactions.some(tr => tr.annotation(External))) {
|
|
55
59
|
var doc = vu.state.doc;
|
|
56
60
|
var _value = doc.toString();
|
|
57
61
|
onChange(_value, vu);
|
|
@@ -152,7 +156,8 @@ export function useCodeMirror(props) {
|
|
|
152
156
|
from: 0,
|
|
153
157
|
to: currentValue.length,
|
|
154
158
|
insert: value || ''
|
|
155
|
-
}
|
|
159
|
+
},
|
|
160
|
+
annotations: [External.of(true)]
|
|
156
161
|
});
|
|
157
162
|
}
|
|
158
163
|
}, [value, view]);
|
package/esm/useCodeMirror.js.map
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
"names": [
|
|
4
4
|
"useEffect",
|
|
5
5
|
"useState",
|
|
6
|
+
"Annotation",
|
|
6
7
|
"EditorState",
|
|
7
8
|
"StateEffect",
|
|
8
9
|
"indentWithTab",
|
|
@@ -12,6 +13,8 @@
|
|
|
12
13
|
"basicSetup",
|
|
13
14
|
"oneDark",
|
|
14
15
|
"getStatistics",
|
|
16
|
+
"External",
|
|
17
|
+
"define",
|
|
15
18
|
"useCodeMirror",
|
|
16
19
|
"props",
|
|
17
20
|
"value",
|
|
@@ -50,6 +53,10 @@
|
|
|
50
53
|
"of",
|
|
51
54
|
"vu",
|
|
52
55
|
"docChanged",
|
|
56
|
+
"transactions",
|
|
57
|
+
"some",
|
|
58
|
+
"tr",
|
|
59
|
+
"annotation",
|
|
53
60
|
"doc",
|
|
54
61
|
"toString",
|
|
55
62
|
"getExtensions",
|
|
@@ -75,13 +82,14 @@
|
|
|
75
82
|
"from",
|
|
76
83
|
"to",
|
|
77
84
|
"length",
|
|
78
|
-
"insert"
|
|
85
|
+
"insert",
|
|
86
|
+
"annotations"
|
|
79
87
|
],
|
|
80
88
|
"sources": [
|
|
81
89
|
"../src/useCodeMirror.ts"
|
|
82
90
|
],
|
|
83
91
|
"sourcesContent": [
|
|
84
|
-
"import { useEffect, useState } from 'react';\nimport { EditorState, StateEffect } from '@codemirror/state';\nimport { indentWithTab } from '@codemirror/commands';\nimport { EditorView, keymap, ViewUpdate, placeholder } from '@codemirror/view';\nimport { basicSetup } from '@uiw/codemirror-extensions-basic-setup';\nimport { oneDark } from '@codemirror/theme-one-dark';\nimport { getStatistics } from './utils';\nimport { ReactCodeMirrorProps } from '.';\n\nexport interface UseCodeMirror extends ReactCodeMirrorProps {\n container?: HTMLDivElement | null;\n}\n\nexport function useCodeMirror(props: UseCodeMirror) {\n const {\n value,\n selection,\n onChange,\n onStatistics,\n onCreateEditor,\n onUpdate,\n extensions = [],\n autoFocus,\n theme = 'light',\n height = '',\n minHeight = '',\n maxHeight = '',\n placeholder: placeholderStr = '',\n width = '',\n minWidth = '',\n maxWidth = '',\n editable = true,\n readOnly = false,\n indentWithTab: defaultIndentWithTab = true,\n basicSetup: defaultBasicSetup = true,\n root,\n initialState,\n } = props;\n const [container, setContainer] = useState<HTMLDivElement>();\n const [view, setView] = useState<EditorView>();\n const [state, setState] = useState<EditorState>();\n const defaultLightThemeOption = EditorView.theme(\n {\n '&': {\n backgroundColor: '#fff',\n },\n },\n {\n dark: false,\n },\n );\n const defaultThemeOption = EditorView.theme({\n '&': {\n height,\n minHeight,\n maxHeight,\n width,\n minWidth,\n maxWidth,\n },\n });\n const updateListener = EditorView.updateListener.of((vu: ViewUpdate) => {\n if (vu.docChanged
|
|
92
|
+
"import { useEffect, useState } from 'react';\nimport { Annotation, EditorState, StateEffect } from '@codemirror/state';\nimport { indentWithTab } from '@codemirror/commands';\nimport { EditorView, keymap, ViewUpdate, placeholder } from '@codemirror/view';\nimport { basicSetup } from '@uiw/codemirror-extensions-basic-setup';\nimport { oneDark } from '@codemirror/theme-one-dark';\nimport { getStatistics } from './utils';\nimport { ReactCodeMirrorProps } from '.';\n\nconst External = Annotation.define<boolean>();\n\nexport interface UseCodeMirror extends ReactCodeMirrorProps {\n container?: HTMLDivElement | null;\n}\n\nexport function useCodeMirror(props: UseCodeMirror) {\n const {\n value,\n selection,\n onChange,\n onStatistics,\n onCreateEditor,\n onUpdate,\n extensions = [],\n autoFocus,\n theme = 'light',\n height = '',\n minHeight = '',\n maxHeight = '',\n placeholder: placeholderStr = '',\n width = '',\n minWidth = '',\n maxWidth = '',\n editable = true,\n readOnly = false,\n indentWithTab: defaultIndentWithTab = true,\n basicSetup: defaultBasicSetup = true,\n root,\n initialState,\n } = props;\n const [container, setContainer] = useState<HTMLDivElement>();\n const [view, setView] = useState<EditorView>();\n const [state, setState] = useState<EditorState>();\n const defaultLightThemeOption = EditorView.theme(\n {\n '&': {\n backgroundColor: '#fff',\n },\n },\n {\n dark: false,\n },\n );\n const defaultThemeOption = EditorView.theme({\n '&': {\n height,\n minHeight,\n maxHeight,\n width,\n minWidth,\n maxWidth,\n },\n });\n const updateListener = EditorView.updateListener.of((vu: ViewUpdate) => {\n if (\n vu.docChanged &&\n typeof onChange === 'function' &&\n // Fix echoing of the remote changes:\n // If transaction is market as remote we don't have to call `onChange` handler again\n !vu.transactions.some((tr) => tr.annotation(External))\n ) {\n const doc = vu.state.doc;\n const value = doc.toString();\n onChange(value, vu);\n }\n onStatistics && onStatistics(getStatistics(vu));\n });\n\n let getExtensions = [updateListener, defaultThemeOption];\n if (defaultIndentWithTab) {\n getExtensions.unshift(keymap.of([indentWithTab]));\n }\n if (defaultBasicSetup) {\n if (typeof defaultBasicSetup === 'boolean') {\n getExtensions.unshift(basicSetup());\n } else {\n getExtensions.unshift(basicSetup(defaultBasicSetup));\n }\n }\n\n if (placeholderStr) {\n getExtensions.unshift(placeholder(placeholderStr));\n }\n\n switch (theme) {\n case 'light':\n getExtensions.push(defaultLightThemeOption);\n break;\n case 'dark':\n getExtensions.push(oneDark);\n break;\n case 'none':\n break;\n default:\n getExtensions.push(theme);\n break;\n }\n\n if (editable === false) {\n getExtensions.push(EditorView.editable.of(false));\n }\n if (readOnly) {\n getExtensions.push(EditorState.readOnly.of(true));\n }\n\n if (onUpdate && typeof onUpdate === 'function') {\n getExtensions.push(EditorView.updateListener.of(onUpdate));\n }\n getExtensions = getExtensions.concat(extensions);\n\n useEffect(() => {\n if (container && !state) {\n const config = {\n doc: value,\n selection,\n extensions: getExtensions,\n };\n const stateCurrent = initialState\n ? EditorState.fromJSON(initialState.json, config, initialState.fields)\n : EditorState.create(config);\n setState(stateCurrent);\n if (!view) {\n const viewCurrent = new EditorView({\n state: stateCurrent,\n parent: container,\n root,\n });\n setView(viewCurrent);\n onCreateEditor && onCreateEditor(viewCurrent, stateCurrent);\n }\n }\n return () => {\n if (view) {\n setState(undefined);\n setView(undefined);\n }\n };\n }, [container, state]);\n\n useEffect(() => setContainer(props.container!), [props.container]);\n\n useEffect(\n () => () => {\n if (view) {\n view.destroy();\n setView(undefined);\n }\n },\n [view],\n );\n\n useEffect(() => {\n if (autoFocus && view) {\n view.focus();\n }\n }, [autoFocus, view]);\n\n useEffect(() => {\n if (view) {\n view.dispatch({ effects: StateEffect.reconfigure.of(getExtensions) });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n theme,\n extensions,\n height,\n minHeight,\n maxHeight,\n width,\n minWidth,\n maxWidth,\n placeholderStr,\n editable,\n readOnly,\n defaultIndentWithTab,\n defaultBasicSetup,\n onChange,\n onUpdate,\n ]);\n\n useEffect(() => {\n if (value === undefined) {\n return;\n }\n const currentValue = view ? view.state.doc.toString() : '';\n if (view && value !== currentValue) {\n view.dispatch({\n changes: { from: 0, to: currentValue.length, insert: value || '' },\n annotations: [External.of(true)],\n });\n }\n }, [value, view]);\n\n return { state, setState, view, setView, container, setContainer };\n}\n"
|
|
85
93
|
],
|
|
86
|
-
"mappings": "AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC3C,SAASC,WAAW,EAAEC,WAAW,QAAQ,mBAAmB;
|
|
94
|
+
"mappings": "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"
|
|
87
95
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uiw/react-codemirror",
|
|
3
|
-
"version": "4.19.
|
|
3
|
+
"version": "4.19.8",
|
|
4
4
|
"description": "CodeMirror component for React.",
|
|
5
5
|
"homepage": "https://uiwjs.github.io/react-codemirror",
|
|
6
6
|
"author": "kenny wong <wowohoo@qq.com>",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@codemirror/commands": "^6.1.0",
|
|
41
41
|
"@codemirror/state": "^6.1.1",
|
|
42
42
|
"@codemirror/theme-one-dark": "^6.0.0",
|
|
43
|
-
"@uiw/codemirror-extensions-basic-setup": "4.19.
|
|
43
|
+
"@uiw/codemirror-extensions-basic-setup": "4.19.8",
|
|
44
44
|
"codemirror": "^6.0.0"
|
|
45
45
|
},
|
|
46
46
|
"keywords": [
|
|
@@ -85,3 +85,10 @@ it('CodeMirror editable', async () => {
|
|
|
85
85
|
expect(text.className).toEqual('cm-content');
|
|
86
86
|
expect(text.tagName).toEqual('DIV');
|
|
87
87
|
});
|
|
88
|
+
|
|
89
|
+
it("CodeMirror doesn't echo changes", async () => {
|
|
90
|
+
const handleChange = jest.fn();
|
|
91
|
+
const { rerender } = render(<CodeMirror value="value a" onChange={handleChange} />);
|
|
92
|
+
rerender(<CodeMirror value="value b" onChange={handleChange} />);
|
|
93
|
+
expect(handleChange).not.toHaveBeenCalled();
|
|
94
|
+
});
|
package/src/useCodeMirror.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
|
-
import { EditorState, StateEffect } from '@codemirror/state';
|
|
2
|
+
import { Annotation, EditorState, StateEffect } from '@codemirror/state';
|
|
3
3
|
import { indentWithTab } from '@codemirror/commands';
|
|
4
4
|
import { EditorView, keymap, ViewUpdate, placeholder } from '@codemirror/view';
|
|
5
5
|
import { basicSetup } from '@uiw/codemirror-extensions-basic-setup';
|
|
@@ -7,6 +7,8 @@ import { oneDark } from '@codemirror/theme-one-dark';
|
|
|
7
7
|
import { getStatistics } from './utils';
|
|
8
8
|
import { ReactCodeMirrorProps } from '.';
|
|
9
9
|
|
|
10
|
+
const External = Annotation.define<boolean>();
|
|
11
|
+
|
|
10
12
|
export interface UseCodeMirror extends ReactCodeMirrorProps {
|
|
11
13
|
container?: HTMLDivElement | null;
|
|
12
14
|
}
|
|
@@ -60,7 +62,13 @@ export function useCodeMirror(props: UseCodeMirror) {
|
|
|
60
62
|
},
|
|
61
63
|
});
|
|
62
64
|
const updateListener = EditorView.updateListener.of((vu: ViewUpdate) => {
|
|
63
|
-
if (
|
|
65
|
+
if (
|
|
66
|
+
vu.docChanged &&
|
|
67
|
+
typeof onChange === 'function' &&
|
|
68
|
+
// Fix echoing of the remote changes:
|
|
69
|
+
// If transaction is market as remote we don't have to call `onChange` handler again
|
|
70
|
+
!vu.transactions.some((tr) => tr.annotation(External))
|
|
71
|
+
) {
|
|
64
72
|
const doc = vu.state.doc;
|
|
65
73
|
const value = doc.toString();
|
|
66
74
|
onChange(value, vu);
|
|
@@ -188,6 +196,7 @@ export function useCodeMirror(props: UseCodeMirror) {
|
|
|
188
196
|
if (view && value !== currentValue) {
|
|
189
197
|
view.dispatch({
|
|
190
198
|
changes: { from: 0, to: currentValue.length, insert: value || '' },
|
|
199
|
+
annotations: [External.of(true)],
|
|
191
200
|
});
|
|
192
201
|
}
|
|
193
202
|
}, [value, view]);
|