@uiw/react-codemirror 4.3.0 → 4.4.0
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/README.md +30 -1
- package/cjs/index.js +13 -4
- package/cjs/index.js.map +4 -2
- package/cjs/useCodeMirror.js +1 -1
- package/cjs/useCodeMirror.js.map +3 -3
- package/dist/codemirror.js +35094 -0
- package/dist/codemirror.min.js +2 -0
- package/dist/codemirror.min.js.LICENSE.txt +14 -0
- package/esm/index.js +10 -4
- package/esm/index.js.map +4 -2
- package/esm/useCodeMirror.js +2 -2
- package/esm/useCodeMirror.js.map +3 -3
- package/package.json +18 -20
- package/src/__tests__/index.test.tsx +87 -0
- package/src/index.tsx +9 -3
- package/src/useCodeMirror.ts +2 -2
- package/src/react-app-env.d.ts +0 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
object-assign
|
|
3
|
+
(c) Sindre Sorhus
|
|
4
|
+
@license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** @license React v17.0.2
|
|
8
|
+
* react-jsx-runtime.production.min.js
|
|
9
|
+
*
|
|
10
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
11
|
+
*
|
|
12
|
+
* This source code is licensed under the MIT license found in the
|
|
13
|
+
* LICENSE file in the root directory of this source tree.
|
|
14
|
+
*/
|
package/esm/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export * from './useCodeMirror';
|
|
|
11
11
|
var ReactCodeMirror = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
12
12
|
var {
|
|
13
13
|
className,
|
|
14
|
-
value,
|
|
14
|
+
value = '',
|
|
15
15
|
selection,
|
|
16
16
|
extensions = [],
|
|
17
17
|
onChange,
|
|
@@ -63,7 +63,7 @@ var ReactCodeMirror = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
63
63
|
editor: container,
|
|
64
64
|
state,
|
|
65
65
|
view
|
|
66
|
-
}));
|
|
66
|
+
}), [container, state, view]);
|
|
67
67
|
useEffect(() => {
|
|
68
68
|
setContainer(editor.current);
|
|
69
69
|
return () => {
|
|
@@ -71,10 +71,16 @@ var ReactCodeMirror = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
71
71
|
view.destroy();
|
|
72
72
|
}
|
|
73
73
|
}; // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
74
|
-
}, []);
|
|
74
|
+
}, []); // check type of value
|
|
75
|
+
|
|
76
|
+
if (typeof value !== 'string') {
|
|
77
|
+
throw new Error("value must be typeof string but got " + typeof value);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
var defaultClassNames = typeof theme === 'string' ? "cm-theme-" + theme : 'cm-theme';
|
|
75
81
|
return /*#__PURE__*/_jsx("div", _extends({
|
|
76
82
|
ref: editor,
|
|
77
|
-
className: "
|
|
83
|
+
className: "" + defaultClassNames + (className ? " " + className : '')
|
|
78
84
|
}, other));
|
|
79
85
|
});
|
|
80
86
|
ReactCodeMirror.displayName = 'CodeMirror';
|
package/esm/index.js.map
CHANGED
|
@@ -40,10 +40,12 @@
|
|
|
40
40
|
"setContainer",
|
|
41
41
|
"current",
|
|
42
42
|
"destroy",
|
|
43
|
+
"Error",
|
|
44
|
+
"defaultClassNames",
|
|
43
45
|
"displayName"
|
|
44
46
|
],
|
|
45
|
-
"mappings": ";;;AAAA,OAAOA,KAAP,IAAgBC,SAAhB,EAA2BC,MAA3B,EAAmCC,mBAAnC,QAA8D,OAA9D;AAGA,SAASC,aAAT,QAA8B,iBAA9B;;AAEA,cAAc,kBAAd;AACA,cAAc,yBAAd;AACA,cAAc,mBAAd;AACA,cAAc,iBAAd;AA6DA,IAAMC,eAAe,gBAAGL,KAAK,CAACM,UAAN,CAA2D,CAACC,KAAD,EAAQC,GAAR,KAAgB;AACjG,MAAM;AACJC,IAAAA,SADI;AAEJC,IAAAA,
|
|
47
|
+
"mappings": ";;;AAAA,OAAOA,KAAP,IAAgBC,SAAhB,EAA2BC,MAA3B,EAAmCC,mBAAnC,QAA8D,OAA9D;AAGA,SAASC,aAAT,QAA8B,iBAA9B;;AAEA,cAAc,kBAAd;AACA,cAAc,yBAAd;AACA,cAAc,mBAAd;AACA,cAAc,iBAAd;AA6DA,IAAMC,eAAe,gBAAGL,KAAK,CAACM,UAAN,CAA2D,CAACC,KAAD,EAAQC,GAAR,KAAgB;AACjG,MAAM;AACJC,IAAAA,SADI;AAEJC,IAAAA,KAAK,GAAG,EAFJ;AAGJC,IAAAA,SAHI;AAIJC,IAAAA,UAAU,GAAG,EAJT;AAKJC,IAAAA,QALI;AAMJC,IAAAA,QANI;AAOJC,IAAAA,SAPI;AAQJC,IAAAA,KAAK,GAAG,OARJ;AASJC,IAAAA,MATI;AAUJC,IAAAA,SAVI;AAWJC,IAAAA,SAXI;AAYJC,IAAAA,KAZI;AAaJC,IAAAA,QAbI;AAcJC,IAAAA,QAdI;AAeJC,IAAAA,UAfI;AAgBJC,IAAAA,WAhBI;AAiBJC,IAAAA,aAjBI;AAkBJC,IAAAA,QAlBI;AAmBJC,IAAAA;AAnBI,MAqBFpB,KArBJ;AAAA,MAoBKqB,KApBL,iCAqBIrB,KArBJ;;AAsBA,MAAMsB,MAAM,GAAG3B,MAAM,CAAiB,IAAjB,CAArB;AACA,MAAM;AAAE4B,IAAAA,KAAF;AAASC,IAAAA,IAAT;AAAeC,IAAAA,SAAf;AAA0BC,IAAAA;AAA1B,MAA2C7B,aAAa,CAAC;AAC7D4B,IAAAA,SAAS,EAAEH,MAAM,CAACK,OAD2C;AAE7DP,IAAAA,IAF6D;AAG7DjB,IAAAA,KAH6D;AAI7DK,IAAAA,SAJ6D;AAK7DC,IAAAA,KAL6D;AAM7DC,IAAAA,MAN6D;AAO7DC,IAAAA,SAP6D;AAQ7DC,IAAAA,SAR6D;AAS7DC,IAAAA,KAT6D;AAU7DC,IAAAA,QAV6D;AAW7DC,IAAAA,QAX6D;AAY7DC,IAAAA,UAZ6D;AAa7DC,IAAAA,WAb6D;AAc7DC,IAAAA,aAd6D;AAe7DC,IAAAA,QAf6D;AAgB7Df,IAAAA,SAhB6D;AAiB7DE,IAAAA,QAjB6D;AAkB7DC,IAAAA,QAlB6D;AAmB7DF,IAAAA;AAnB6D,GAAD,CAA9D;AAqBAT,EAAAA,mBAAmB,CAACK,GAAD,EAAM,OAAO;AAAEqB,IAAAA,MAAM,EAAEG,SAAV;AAAqBF,IAAAA,KAArB;AAA4BC,IAAAA;AAA5B,GAAP,CAAN,EAAkD,CAACC,SAAD,EAAYF,KAAZ,EAAmBC,IAAnB,CAAlD,CAAnB;AACA9B,EAAAA,SAAS,CAAC,MAAM;AACdgC,IAAAA,YAAY,CAACJ,MAAM,CAACK,OAAR,CAAZ;AACA,WAAO,MAAM;AACX,UAAIH,IAAJ,EAAU;AACRA,QAAAA,IAAI,CAACI,OAAL;AACD;AACF,KAJD,CAFc,CAOd;AACD,GARQ,EAQN,EARM,CAAT,CA9CiG,CAwDjG;;AACA,MAAI,OAAOzB,KAAP,KAAiB,QAArB,EAA+B;AAC7B,UAAM,IAAI0B,KAAJ,0CAAiD,OAAO1B,KAAxD,CAAN;AACD;;AAED,MAAM2B,iBAAiB,GAAG,OAAOrB,KAAP,KAAiB,QAAjB,iBAAwCA,KAAxC,GAAkD,UAA5E;AACA,sBAAO;AAAK,IAAA,GAAG,EAAEa,MAAV;AAAkB,IAAA,SAAS,OAAKQ,iBAAL,IAAyB5B,SAAS,SAAOA,SAAP,GAAqB,EAAvD;AAA3B,KAA4FmB,KAA5F,EAAP;AACD,CA/DuB,CAAxB;AAiEAvB,eAAe,CAACiC,WAAhB,GAA8B,YAA9B;AAEA,eAAejC,eAAf",
|
|
46
48
|
"sourcesContent": [
|
|
47
|
-
"import React, { useEffect, useRef, useImperativeHandle } from 'react';\nimport { EditorState, EditorStateConfig, Extension } from '@codemirror/state';\nimport { EditorView, ViewUpdate } from '@codemirror/view';\nimport { useCodeMirror } from './useCodeMirror';\n\nexport * from '@codemirror/view';\nexport * from '@codemirror/basic-setup';\nexport * from '@codemirror/state';\nexport * from './useCodeMirror';\n\nexport interface ReactCodeMirrorProps\n extends Omit<EditorStateConfig, 'doc' | 'extensions'>,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'placeholder'> {\n /** value of the auto created model in the editor. */\n value?: string;\n height?: string;\n minHeight?: string;\n maxHeight?: string;\n width?: string;\n minWidth?: string;\n maxWidth?: string;\n /** focus on the editor. */\n autoFocus?: boolean;\n /** Enables a placeholder—a piece of example content to show when the editor is empty. */\n placeholder?: string | HTMLElement;\n /**\n * `light` / `dark` / `Extension` Defaults to `light`.\n * @default light\n */\n theme?: 'light' | 'dark' | Extension;\n /**\n * Whether to optional basicSetup by default\n * @default true\n */\n basicSetup?: boolean;\n /**\n * This disables editing of the editor content by the user.\n * @default true\n */\n editable?: boolean;\n /**\n * Whether to optional basicSetup by default\n * @default true\n */\n indentWithTab?: boolean;\n /** Fired whenever a change occurs to the document. */\n onChange?(value: string, viewUpdate: ViewUpdate): void;\n /** Fired whenever a change occurs to the document. There is a certain difference with `onChange`. */\n onUpdate?(viewUpdate: ViewUpdate): void;\n /**\n * Extension values can be [provided](https://codemirror.net/6/docs/ref/#state.EditorStateConfig.extensions) when creating a state to attach various kinds of configuration and behavior information.\n * They can either be built-in extension-providing objects,\n * such as [state fields](https://codemirror.net/6/docs/ref/#state.StateField) or [facet providers](https://codemirror.net/6/docs/ref/#state.Facet.of),\n * or objects with an extension in its `extension` property. Extensions can be nested in arrays arbitrarily deep—they will be flattened when processed.\n */\n extensions?: Extension[];\n /**\n * If the view is going to be mounted in a shadow root or document other than the one held by the global variable document (the default), you should pass it here.\n * Originally from the [config of EditorView](https://codemirror.net/6/docs/ref/#view.EditorView.constructor%5Econfig.root)\n */\n root?: ShadowRoot | Document;\n}\n\nexport interface ReactCodeMirrorRef {\n editor?: HTMLDivElement | null;\n state?: EditorState;\n view?: EditorView;\n}\n\nconst ReactCodeMirror = React.forwardRef<ReactCodeMirrorRef, ReactCodeMirrorProps>((props, ref) => {\n const {\n className,\n value,\n selection,\n extensions = [],\n onChange,\n onUpdate,\n autoFocus,\n theme = 'light',\n height,\n minHeight,\n maxHeight,\n width,\n minWidth,\n maxWidth,\n basicSetup,\n placeholder,\n indentWithTab,\n editable,\n root,\n ...other\n } = props;\n const editor = useRef<HTMLDivElement>(null);\n const { state, view, container, setContainer } = useCodeMirror({\n container: editor.current,\n root,\n value,\n autoFocus,\n theme,\n height,\n minHeight,\n maxHeight,\n width,\n minWidth,\n maxWidth,\n basicSetup,\n placeholder,\n indentWithTab,\n editable,\n selection,\n onChange,\n onUpdate,\n extensions,\n });\n useImperativeHandle(ref, () => ({ editor: container, state, view }));\n useEffect(() => {\n setContainer(editor.current);\n return () => {\n if (view) {\n view.destroy();\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return <div ref={editor} className={
|
|
49
|
+
"import React, { useEffect, useRef, useImperativeHandle } from 'react';\nimport { EditorState, EditorStateConfig, Extension } from '@codemirror/state';\nimport { EditorView, ViewUpdate } from '@codemirror/view';\nimport { useCodeMirror } from './useCodeMirror';\n\nexport * from '@codemirror/view';\nexport * from '@codemirror/basic-setup';\nexport * from '@codemirror/state';\nexport * from './useCodeMirror';\n\nexport interface ReactCodeMirrorProps\n extends Omit<EditorStateConfig, 'doc' | 'extensions'>,\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'placeholder'> {\n /** value of the auto created model in the editor. */\n value?: string;\n height?: string;\n minHeight?: string;\n maxHeight?: string;\n width?: string;\n minWidth?: string;\n maxWidth?: string;\n /** focus on the editor. */\n autoFocus?: boolean;\n /** Enables a placeholder—a piece of example content to show when the editor is empty. */\n placeholder?: string | HTMLElement;\n /**\n * `light` / `dark` / `Extension` Defaults to `light`.\n * @default light\n */\n theme?: 'light' | 'dark' | Extension;\n /**\n * Whether to optional basicSetup by default\n * @default true\n */\n basicSetup?: boolean;\n /**\n * This disables editing of the editor content by the user.\n * @default true\n */\n editable?: boolean;\n /**\n * Whether to optional basicSetup by default\n * @default true\n */\n indentWithTab?: boolean;\n /** Fired whenever a change occurs to the document. */\n onChange?(value: string, viewUpdate: ViewUpdate): void;\n /** Fired whenever a change occurs to the document. There is a certain difference with `onChange`. */\n onUpdate?(viewUpdate: ViewUpdate): void;\n /**\n * Extension values can be [provided](https://codemirror.net/6/docs/ref/#state.EditorStateConfig.extensions) when creating a state to attach various kinds of configuration and behavior information.\n * They can either be built-in extension-providing objects,\n * such as [state fields](https://codemirror.net/6/docs/ref/#state.StateField) or [facet providers](https://codemirror.net/6/docs/ref/#state.Facet.of),\n * or objects with an extension in its `extension` property. Extensions can be nested in arrays arbitrarily deep—they will be flattened when processed.\n */\n extensions?: Extension[];\n /**\n * If the view is going to be mounted in a shadow root or document other than the one held by the global variable document (the default), you should pass it here.\n * Originally from the [config of EditorView](https://codemirror.net/6/docs/ref/#view.EditorView.constructor%5Econfig.root)\n */\n root?: ShadowRoot | Document;\n}\n\nexport interface ReactCodeMirrorRef {\n editor?: HTMLDivElement | null;\n state?: EditorState;\n view?: EditorView;\n}\n\nconst ReactCodeMirror = React.forwardRef<ReactCodeMirrorRef, ReactCodeMirrorProps>((props, ref) => {\n const {\n className,\n value = '',\n selection,\n extensions = [],\n onChange,\n onUpdate,\n autoFocus,\n theme = 'light',\n height,\n minHeight,\n maxHeight,\n width,\n minWidth,\n maxWidth,\n basicSetup,\n placeholder,\n indentWithTab,\n editable,\n root,\n ...other\n } = props;\n const editor = useRef<HTMLDivElement>(null);\n const { state, view, container, setContainer } = useCodeMirror({\n container: editor.current,\n root,\n value,\n autoFocus,\n theme,\n height,\n minHeight,\n maxHeight,\n width,\n minWidth,\n maxWidth,\n basicSetup,\n placeholder,\n indentWithTab,\n editable,\n selection,\n onChange,\n onUpdate,\n extensions,\n });\n useImperativeHandle(ref, () => ({ editor: container, state, view }), [container, state, view]);\n useEffect(() => {\n setContainer(editor.current);\n return () => {\n if (view) {\n view.destroy();\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // check type of value\n if (typeof value !== 'string') {\n throw new Error(`value must be typeof string but got ${typeof value}`);\n }\n\n const defaultClassNames = typeof theme === 'string' ? `cm-theme-${theme}` : 'cm-theme';\n return <div ref={editor} className={`${defaultClassNames}${className ? ` ${className}` : ''}`} {...other}></div>;\n});\n\nReactCodeMirror.displayName = 'CodeMirror';\n\nexport default ReactCodeMirror;\n"
|
|
48
50
|
]
|
|
49
51
|
}
|
package/esm/useCodeMirror.js
CHANGED
|
@@ -3,7 +3,7 @@ import { basicSetup as defaultBasicSetup } from '@codemirror/basic-setup';
|
|
|
3
3
|
import { EditorState, StateEffect } from '@codemirror/state';
|
|
4
4
|
import { indentWithTab as defaultIndentWithTab } from '@codemirror/commands';
|
|
5
5
|
import { EditorView, keymap, placeholder as extendPlaceholder } from '@codemirror/view';
|
|
6
|
-
import {
|
|
6
|
+
import { oneDark } from '@codemirror/theme-one-dark';
|
|
7
7
|
import { defaultLightThemeOption } from './theme/light';
|
|
8
8
|
export function useCodeMirror(props) {
|
|
9
9
|
var {
|
|
@@ -68,7 +68,7 @@ export function useCodeMirror(props) {
|
|
|
68
68
|
break;
|
|
69
69
|
|
|
70
70
|
case 'dark':
|
|
71
|
-
getExtensions.push(
|
|
71
|
+
getExtensions.push(oneDark);
|
|
72
72
|
break;
|
|
73
73
|
|
|
74
74
|
default:
|
package/esm/useCodeMirror.js.map
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"keymap",
|
|
17
17
|
"placeholder",
|
|
18
18
|
"extendPlaceholder",
|
|
19
|
-
"
|
|
19
|
+
"oneDark",
|
|
20
20
|
"defaultLightThemeOption",
|
|
21
21
|
"useCodeMirror",
|
|
22
22
|
"props",
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"reconfigure",
|
|
69
69
|
"focus"
|
|
70
70
|
],
|
|
71
|
-
"mappings": "AAAA,SAASA,SAAT,EAAoBC,QAApB,QAAoC,OAApC;AACA,SAASC,UAAU,IAAIC,iBAAvB,QAAgD,yBAAhD;AACA,SAASC,WAAT,EAAsBC,WAAtB,QAAyC,mBAAzC;AACA,SAASC,aAAa,IAAIC,oBAA1B,QAAsD,sBAAtD;AACA,SAASC,UAAT,EAAqBC,MAArB,EAAyCC,WAAW,IAAIC,iBAAxD,QAAiF,kBAAjF;AACA,SAASC,
|
|
71
|
+
"mappings": "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",
|
|
72
72
|
"sourcesContent": [
|
|
73
|
-
"import { useEffect, useState } from 'react';\nimport { basicSetup as defaultBasicSetup } from '@codemirror/basic-setup';\nimport { EditorState, StateEffect } from '@codemirror/state';\nimport { indentWithTab as defaultIndentWithTab } from '@codemirror/commands';\nimport { EditorView, keymap, ViewUpdate, placeholder as extendPlaceholder } from '@codemirror/view';\nimport {
|
|
73
|
+
"import { useEffect, useState } from 'react';\nimport { basicSetup as defaultBasicSetup } from '@codemirror/basic-setup';\nimport { EditorState, StateEffect } from '@codemirror/state';\nimport { indentWithTab as defaultIndentWithTab } from '@codemirror/commands';\nimport { EditorView, keymap, ViewUpdate, placeholder as extendPlaceholder } from '@codemirror/view';\nimport { oneDark } from '@codemirror/theme-one-dark';\nimport { ReactCodeMirrorProps } from './';\nimport { defaultLightThemeOption } from './theme/light';\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 onUpdate,\n extensions = [],\n autoFocus,\n theme = 'light',\n height = '',\n minHeight = '',\n maxHeight = '',\n placeholder = '',\n width = '',\n minWidth = '',\n maxWidth = '',\n editable = true,\n indentWithTab = true,\n basicSetup = true,\n root,\n } = props;\n const [container, setContainer] = useState(props.container);\n const [view, setView] = useState<EditorView>();\n const [state, setState] = useState<EditorState>();\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 && typeof onChange === 'function') {\n const doc = vu.state.doc;\n const value = doc.toString();\n onChange(value, vu);\n }\n });\n let getExtensions = [updateListener, defaultThemeOption];\n if (indentWithTab) {\n getExtensions.unshift(keymap.of([defaultIndentWithTab]));\n }\n if (basicSetup) {\n getExtensions.unshift(defaultBasicSetup);\n }\n\n if (placeholder) {\n getExtensions.unshift(extendPlaceholder(placeholder));\n }\n\n switch (theme) {\n case 'light':\n getExtensions.push(defaultLightThemeOption);\n break;\n case 'dark':\n getExtensions.push(oneDark);\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\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 stateCurrent = EditorState.create({\n doc: value,\n selection,\n extensions: getExtensions,\n });\n setState(stateCurrent);\n if (!view) {\n const viewCurrent = new EditorView({\n state: stateCurrent,\n parent: container as any,\n root,\n });\n setView(viewCurrent);\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [container, state]);\n\n useEffect(() => {\n return () => {\n if (view) {\n view.destroy();\n }\n };\n }, [view]);\n\n useEffect(() => {\n if (view) {\n const currentValue = view.state.doc.toString();\n if (value !== currentValue) {\n view.dispatch({\n changes: { from: 0, to: currentValue.length, insert: value || '' },\n });\n }\n }\n }, [value, 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 placeholder,\n height,\n minHeight,\n maxHeight,\n width,\n minWidth,\n maxWidth,\n editable,\n indentWithTab,\n basicSetup,\n ]);\n\n useEffect(() => {\n if (autoFocus && view) {\n view.focus();\n }\n }, [autoFocus, view]);\n\n return { state, setState, view, setView, container, setContainer };\n}\n"
|
|
74
74
|
]
|
|
75
75
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uiw/react-codemirror",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"description": "CodeMirror component for React.",
|
|
5
5
|
"homepage": "https://uiwjs.github.io/react-codemirror",
|
|
6
6
|
"main": "cjs/index.js",
|
|
@@ -13,8 +13,10 @@
|
|
|
13
13
|
"prepare": "husky install && npm run build",
|
|
14
14
|
"watch": "tsbb watch",
|
|
15
15
|
"build": "tsbb build",
|
|
16
|
+
"bundle": "kkt build --bundle",
|
|
17
|
+
"bundle:min": "kkt build --bundle --mini --no-emptyDir",
|
|
16
18
|
"test": "tsbb test --env=jsdom",
|
|
17
|
-
"coverage": "tsbb test --coverage",
|
|
19
|
+
"coverage": "tsbb test --coverage --bail",
|
|
18
20
|
"doc": "kkt build --app-src ./website",
|
|
19
21
|
"start": "kkt start --app-src ./website",
|
|
20
22
|
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,html,less,md,json}'"
|
|
@@ -34,6 +36,7 @@
|
|
|
34
36
|
"code"
|
|
35
37
|
],
|
|
36
38
|
"files": [
|
|
39
|
+
"dist",
|
|
37
40
|
"src",
|
|
38
41
|
"esm",
|
|
39
42
|
"cjs"
|
|
@@ -52,11 +55,6 @@
|
|
|
52
55
|
"react-app/jest"
|
|
53
56
|
]
|
|
54
57
|
},
|
|
55
|
-
"lint-staged": {
|
|
56
|
-
"*.{js,jsx,ts,tsx,html,less,md,json}": [
|
|
57
|
-
"prettier --write"
|
|
58
|
-
]
|
|
59
|
-
},
|
|
60
58
|
"peerDependencies": {
|
|
61
59
|
"@babel/runtime": ">=7.11.0",
|
|
62
60
|
"react": ">=16.8.0",
|
|
@@ -73,37 +71,37 @@
|
|
|
73
71
|
"@codemirror/lang-cpp": "0.19.1",
|
|
74
72
|
"@codemirror/lang-html": "0.19.4",
|
|
75
73
|
"@codemirror/lang-java": "0.19.1",
|
|
76
|
-
"@codemirror/lang-javascript": "0.19.
|
|
74
|
+
"@codemirror/lang-javascript": "0.19.7",
|
|
77
75
|
"@codemirror/lang-json": "0.19.1",
|
|
78
76
|
"@codemirror/lang-lezer": "0.19.1",
|
|
79
|
-
"@codemirror/lang-markdown": "0.19.
|
|
77
|
+
"@codemirror/lang-markdown": "0.19.6",
|
|
80
78
|
"@codemirror/lang-php": "0.19.1",
|
|
81
|
-
"@codemirror/lang-python": "0.19.
|
|
79
|
+
"@codemirror/lang-python": "0.19.4",
|
|
82
80
|
"@codemirror/lang-rust": "0.19.1",
|
|
83
81
|
"@codemirror/lang-sql": "0.19.4",
|
|
84
82
|
"@codemirror/lang-xml": "0.19.2",
|
|
85
83
|
"@codemirror/legacy-modes": "0.19.0",
|
|
86
|
-
"@codemirror/stream-parser": "0.19.
|
|
87
|
-
"@kkt/less-modules": "
|
|
88
|
-
"@kkt/raw-modules": "
|
|
89
|
-
"@kkt/
|
|
90
|
-
"@
|
|
84
|
+
"@codemirror/stream-parser": "0.19.5",
|
|
85
|
+
"@kkt/less-modules": "7.1.0",
|
|
86
|
+
"@kkt/raw-modules": "7.1.0",
|
|
87
|
+
"@kkt/react-library": "7.1.0",
|
|
88
|
+
"@kkt/scope-plugin-options": "7.1.0",
|
|
89
|
+
"@types/react": "17.0.38",
|
|
91
90
|
"@types/react-dom": "17.0.11",
|
|
92
91
|
"@types/react-test-renderer": "17.0.1",
|
|
93
92
|
"@uiw/react-github-corners": "1.5.3",
|
|
94
|
-
"@uiw/react-markdown-preview": "3.4.
|
|
93
|
+
"@uiw/react-markdown-preview": "3.4.7",
|
|
95
94
|
"@uiw/react-shields": "1.1.2",
|
|
96
95
|
"@uiw/reset.css": "1.0.5",
|
|
97
96
|
"code-example": "3.3.1",
|
|
98
97
|
"husky": "7.0.4",
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
"lint-staged": "11.2.6",
|
|
98
|
+
"kkt": "7.1.0",
|
|
99
|
+
"lint-staged": "12.3.4",
|
|
102
100
|
"prettier": "2.5.1",
|
|
103
101
|
"react": "17.0.2",
|
|
104
102
|
"react-dom": "17.0.2",
|
|
105
103
|
"react-test-renderer": "17.0.2",
|
|
106
|
-
"tsbb": "3.5.
|
|
104
|
+
"tsbb": "3.5.6"
|
|
107
105
|
},
|
|
108
106
|
"browserslist": {
|
|
109
107
|
"production": [
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
/* eslint-disable jest/no-conditional-expect */
|
|
5
|
+
import React, { useEffect, useRef } from 'react';
|
|
6
|
+
import renderer from 'react-test-renderer';
|
|
7
|
+
import { render, fireEvent, screen } from '@testing-library/react';
|
|
8
|
+
// import userEvent from '@testing-library/user-event';
|
|
9
|
+
// import '@testing-library/jest-dom';
|
|
10
|
+
import CodeMirror, { ReactCodeMirrorRef } from '..';
|
|
11
|
+
|
|
12
|
+
it('CodeMirror', async () => {
|
|
13
|
+
const component = renderer.create(<CodeMirror />);
|
|
14
|
+
let tree = component.toJSON();
|
|
15
|
+
if (tree && !Array.isArray(tree)) {
|
|
16
|
+
expect(tree.type).toEqual('div');
|
|
17
|
+
expect(tree.props.className).toEqual('cm-theme-light');
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('CodeMirror onChange', async () => {
|
|
22
|
+
const handleChange = jest.fn((value) => {
|
|
23
|
+
expect(value).toEqual('# title');
|
|
24
|
+
return Array.isArray(value) ? value.join() : value;
|
|
25
|
+
});
|
|
26
|
+
render(<CodeMirror autoFocus value="console.log('Hello world!')" onChange={handleChange} />);
|
|
27
|
+
const input = await screen.findByRole<HTMLInputElement>('textbox'); // findByRole('textbox');
|
|
28
|
+
fireEvent.change(input, { target: { textContent: '# title' } });
|
|
29
|
+
const elm = screen.queryByText('# title');
|
|
30
|
+
expect((elm as any).cmView.dom.innerHTML).toEqual('# title');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('CodeMirror onUpdate', async () => {
|
|
34
|
+
render(
|
|
35
|
+
<CodeMirror
|
|
36
|
+
value="console.log('Hello world!')"
|
|
37
|
+
autoFocus
|
|
38
|
+
onUpdate={(viewUpdate) => {
|
|
39
|
+
expect(viewUpdate.state.doc.length).toEqual(27);
|
|
40
|
+
}}
|
|
41
|
+
/>,
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('CodeMirror ref', async () => {
|
|
46
|
+
function Demo() {
|
|
47
|
+
const ref = useRef<ReactCodeMirrorRef>(null);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
expect(Object.keys(ref.current!)).toEqual(['editor', 'state', 'view']);
|
|
50
|
+
}, [ref]);
|
|
51
|
+
|
|
52
|
+
return <CodeMirror ref={ref} value="console.log('Hello world!')" />;
|
|
53
|
+
}
|
|
54
|
+
render(<Demo />);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('CodeMirror theme', async () => {
|
|
58
|
+
const component = renderer.create(<CodeMirror theme="dark" />);
|
|
59
|
+
let tree = component.toJSON();
|
|
60
|
+
if (tree && !Array.isArray(tree)) {
|
|
61
|
+
expect(tree.type).toEqual('div');
|
|
62
|
+
expect(tree.props.className).toEqual('cm-theme-dark');
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('CodeMirror className', async () => {
|
|
67
|
+
const component = renderer.create(<CodeMirror className="test" />);
|
|
68
|
+
let tree = component.toJSON();
|
|
69
|
+
if (tree && !Array.isArray(tree)) {
|
|
70
|
+
expect(tree.type).toEqual('div');
|
|
71
|
+
expect(tree.props.className).toEqual('cm-theme-light test');
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('CodeMirror placeholder', async () => {
|
|
76
|
+
render(<CodeMirror placeholder="Hello World" className="test" />);
|
|
77
|
+
const elm = screen.queryByText('Hello World');
|
|
78
|
+
expect(elm!.style['pointerEvents']).toEqual('none');
|
|
79
|
+
expect(elm!.className).toEqual('cm-placeholder');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('CodeMirror editable', async () => {
|
|
83
|
+
render(<CodeMirror editable={false} className="test" />);
|
|
84
|
+
const text = screen.getByRole('textbox');
|
|
85
|
+
expect(text.className).toEqual('cm-content');
|
|
86
|
+
expect(text.tagName).toEqual('DIV');
|
|
87
|
+
});
|
package/src/index.tsx
CHANGED
|
@@ -70,7 +70,7 @@ export interface ReactCodeMirrorRef {
|
|
|
70
70
|
const ReactCodeMirror = React.forwardRef<ReactCodeMirrorRef, ReactCodeMirrorProps>((props, ref) => {
|
|
71
71
|
const {
|
|
72
72
|
className,
|
|
73
|
-
value,
|
|
73
|
+
value = '',
|
|
74
74
|
selection,
|
|
75
75
|
extensions = [],
|
|
76
76
|
onChange,
|
|
@@ -112,7 +112,7 @@ const ReactCodeMirror = React.forwardRef<ReactCodeMirrorRef, ReactCodeMirrorProp
|
|
|
112
112
|
onUpdate,
|
|
113
113
|
extensions,
|
|
114
114
|
});
|
|
115
|
-
useImperativeHandle(ref, () => ({ editor: container, state, view }));
|
|
115
|
+
useImperativeHandle(ref, () => ({ editor: container, state, view }), [container, state, view]);
|
|
116
116
|
useEffect(() => {
|
|
117
117
|
setContainer(editor.current);
|
|
118
118
|
return () => {
|
|
@@ -123,7 +123,13 @@ const ReactCodeMirror = React.forwardRef<ReactCodeMirrorRef, ReactCodeMirrorProp
|
|
|
123
123
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
124
124
|
}, []);
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
// check type of value
|
|
127
|
+
if (typeof value !== 'string') {
|
|
128
|
+
throw new Error(`value must be typeof string but got ${typeof value}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const defaultClassNames = typeof theme === 'string' ? `cm-theme-${theme}` : 'cm-theme';
|
|
132
|
+
return <div ref={editor} className={`${defaultClassNames}${className ? ` ${className}` : ''}`} {...other}></div>;
|
|
127
133
|
});
|
|
128
134
|
|
|
129
135
|
ReactCodeMirror.displayName = 'CodeMirror';
|
package/src/useCodeMirror.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { basicSetup as defaultBasicSetup } from '@codemirror/basic-setup';
|
|
|
3
3
|
import { EditorState, StateEffect } from '@codemirror/state';
|
|
4
4
|
import { indentWithTab as defaultIndentWithTab } from '@codemirror/commands';
|
|
5
5
|
import { EditorView, keymap, ViewUpdate, placeholder as extendPlaceholder } from '@codemirror/view';
|
|
6
|
-
import {
|
|
6
|
+
import { oneDark } from '@codemirror/theme-one-dark';
|
|
7
7
|
import { ReactCodeMirrorProps } from './';
|
|
8
8
|
import { defaultLightThemeOption } from './theme/light';
|
|
9
9
|
|
|
@@ -69,7 +69,7 @@ export function useCodeMirror(props: UseCodeMirror) {
|
|
|
69
69
|
getExtensions.push(defaultLightThemeOption);
|
|
70
70
|
break;
|
|
71
71
|
case 'dark':
|
|
72
|
-
getExtensions.push(
|
|
72
|
+
getExtensions.push(oneDark);
|
|
73
73
|
break;
|
|
74
74
|
default:
|
|
75
75
|
getExtensions.push(theme);
|
package/src/react-app-env.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/// <reference types="react-scripts" />
|