@uiw/react-md-editor 3.14.5 → 3.17.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 +71 -4
- package/dist/mdeditor.css +1 -0
- package/dist/mdeditor.js +686 -83
- package/dist/mdeditor.min.css +1 -1
- package/dist/mdeditor.min.js +1 -1
- package/esm/Context.d.ts +17 -2
- package/esm/Context.js.map +2 -2
- package/esm/Editor.d.ts +20 -4
- package/esm/Editor.js +6 -4
- package/esm/Editor.js.map +4 -3
- package/esm/commands/index.d.ts +2 -0
- package/esm/commands/index.js.map +2 -2
- package/esm/components/Toolbar/index.js +4 -1
- package/esm/components/Toolbar/index.js.map +7 -2
- package/esm/index.css +1 -0
- package/esm/index.less +1 -0
- package/lib/Context.d.ts +17 -2
- package/lib/Context.js.map +2 -2
- package/lib/Editor.d.ts +20 -4
- package/lib/Editor.js +6 -4
- package/lib/Editor.js.map +4 -3
- package/lib/commands/index.d.ts +2 -0
- package/lib/commands/index.js.map +2 -2
- package/lib/components/Toolbar/index.js +4 -1
- package/lib/components/Toolbar/index.js.map +8 -3
- package/lib/index.less +1 -0
- package/markdown-editor.css +1 -0
- package/package.json +1 -1
- package/src/Context.tsx +3 -1
- package/src/Editor.tsx +25 -8
- package/src/commands/index.ts +7 -0
- package/src/components/Toolbar/index.tsx +9 -3
- package/src/index.less +1 -0
package/lib/Editor.js
CHANGED
|
@@ -31,7 +31,7 @@ var _Context = require("./Context");
|
|
|
31
31
|
|
|
32
32
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
33
33
|
|
|
34
|
-
var _excluded = ["prefixCls", "className", "value", "commands", "commandsFilter", "extraCommands", "height", "toolbarHeight", "enableScroll", "visibleDragbar", "highlightEnable", "preview", "fullscreen", "overflow", "previewOptions", "textareaProps", "maxHeight", "minHeight", "autoFocus", "tabSize", "defaultTabEnable", "onChange", "onHeightChange", "hideToolbar", "toolbarBottom", "renderTextarea"];
|
|
34
|
+
var _excluded = ["prefixCls", "className", "value", "commands", "commandsFilter", "extraCommands", "height", "toolbarHeight", "enableScroll", "visibleDragbar", "highlightEnable", "preview", "fullscreen", "overflow", "previewOptions", "textareaProps", "maxHeight", "minHeight", "autoFocus", "tabSize", "defaultTabEnable", "onChange", "onHeightChange", "hideToolbar", "toolbarBottom", "components", "renderTextarea"];
|
|
35
35
|
|
|
36
36
|
function setGroupPopFalse() {
|
|
37
37
|
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
@@ -85,6 +85,7 @@ var InternalMDEditor = function InternalMDEditor(props, ref) {
|
|
|
85
85
|
hideToolbar = _ref.hideToolbar,
|
|
86
86
|
_ref$toolbarBottom = _ref.toolbarBottom,
|
|
87
87
|
toolbarBottom = _ref$toolbarBottom === void 0 ? false : _ref$toolbarBottom,
|
|
88
|
+
components = _ref.components,
|
|
88
89
|
renderTextarea = _ref.renderTextarea,
|
|
89
90
|
other = (0, _objectWithoutProperties2["default"])(_ref, _excluded);
|
|
90
91
|
|
|
@@ -98,6 +99,7 @@ var InternalMDEditor = function InternalMDEditor(props, ref) {
|
|
|
98
99
|
var _useReducer = (0, _react.useReducer)(_Context.reducer, {
|
|
99
100
|
markdown: propsValue,
|
|
100
101
|
preview: previewType,
|
|
102
|
+
components: components,
|
|
101
103
|
height: height,
|
|
102
104
|
highlightEnable: highlightEnable,
|
|
103
105
|
tabSize: tabSize,
|
|
@@ -257,7 +259,7 @@ var InternalMDEditor = function InternalMDEditor(props, ref) {
|
|
|
257
259
|
});
|
|
258
260
|
},
|
|
259
261
|
style: (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, other.style), {}, {
|
|
260
|
-
height: state.
|
|
262
|
+
height: state.height || '100%'
|
|
261
263
|
}),
|
|
262
264
|
children: [!hideToolbar && !toolbarBottom && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbar["default"], {
|
|
263
265
|
prefixCls: prefixCls,
|
|
@@ -267,7 +269,7 @@ var InternalMDEditor = function InternalMDEditor(props, ref) {
|
|
|
267
269
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
268
270
|
className: "".concat(prefixCls, "-content"),
|
|
269
271
|
style: {
|
|
270
|
-
height:
|
|
272
|
+
height: "calc(100% - ".concat(toolbarHeight, "px)")
|
|
271
273
|
},
|
|
272
274
|
children: [/(edit|live)/.test(state.preview || '') && /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextArea["default"], (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
|
|
273
275
|
className: "".concat(prefixCls, "-input"),
|
|
@@ -281,7 +283,7 @@ var InternalMDEditor = function InternalMDEditor(props, ref) {
|
|
|
281
283
|
textareaProps.onChange(evn);
|
|
282
284
|
}
|
|
283
285
|
},
|
|
284
|
-
renderTextarea: renderTextarea,
|
|
286
|
+
renderTextarea: (components === null || components === void 0 ? void 0 : components.textarea) || renderTextarea,
|
|
285
287
|
onScroll: function onScroll(e) {
|
|
286
288
|
return handleScroll(e, 'text');
|
|
287
289
|
}
|
package/lib/Editor.js.map
CHANGED
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"onHeightChange",
|
|
41
41
|
"hideToolbar",
|
|
42
42
|
"toolbarBottom",
|
|
43
|
+
"components",
|
|
43
44
|
"renderTextarea",
|
|
44
45
|
"other",
|
|
45
46
|
"cmds",
|
|
@@ -86,9 +87,9 @@
|
|
|
86
87
|
"target",
|
|
87
88
|
"mdPreview",
|
|
88
89
|
"style",
|
|
89
|
-
"Number",
|
|
90
90
|
"test",
|
|
91
91
|
"evn",
|
|
92
|
+
"textarea",
|
|
92
93
|
"newHeight",
|
|
93
94
|
"mdEditor",
|
|
94
95
|
"React",
|
|
@@ -100,7 +101,7 @@
|
|
|
100
101
|
"../src/Editor.tsx"
|
|
101
102
|
],
|
|
102
103
|
"sourcesContent": [
|
|
103
|
-
"import React, { useEffect, useReducer, useMemo, useRef, useImperativeHandle } from 'react';\nimport MarkdownPreview, { MarkdownPreviewProps, MarkdownPreviewRef } from '@uiw/react-markdown-preview';\nimport TextArea, { ITextAreaProps } from './components/TextArea';\nimport Toolbar from './components/Toolbar';\nimport DragBar from './components/DragBar';\nimport { getCommands, getExtraCommands, ICommand } from './commands';\nimport { reducer, EditorContext, ContextStore, PreviewType } from './Context';\nimport './index.less';\n\nexport interface IProps {\n prefixCls?: string;\n className?: string;\n}\n\nexport interface MDEditorProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'>, IProps {\n /**\n * The Markdown value.\n */\n value?: string;\n /**\n * Event handler for the `onChange` event.\n */\n onChange?: (value?: string, event?: React.ChangeEvent<HTMLTextAreaElement>, state?: ContextStore) => void;\n /**\n * editor height change listener\n */\n onHeightChange?: (value?: number, oldValue?: number, state?: ContextStore) => void;\n /**\n * Can be used to make `Markdown Editor` focus itself on initialization. Defaults to on.\n * it will be set to true when either the source `textarea` is focused,\n * or it has an `autofocus` attribute and no other element is focused.\n */\n autoFocus?: ITextAreaProps['autoFocus'];\n /**\n * The height of the editor.\n */\n height?: number;\n /**\n * Custom toolbar heigth\n * @default 29px\n */\n toolbarHeight?: number;\n /**\n * Show drag and drop tool. Set the height of the editor.\n */\n visibleDragbar?: boolean;\n /**\n * @deprecated use `visibleDragbar`\n */\n visiableDragbar?: boolean;\n /**\n * Show markdown preview.\n */\n preview?: PreviewType;\n /**\n * Full screen display editor.\n */\n fullscreen?: boolean;\n /**\n * Disable `fullscreen` setting body styles\n */\n overflow?: boolean;\n /**\n * Maximum drag height. `visibleDragbar=true`\n */\n maxHeight?: number;\n /**\n * Minimum drag height. `visibleDragbar=true`\n */\n minHeight?: number;\n /**\n * This is reset [react-markdown](https://github.com/rexxars/react-markdown) settings.\n */\n previewOptions?: Omit<MarkdownPreviewProps, 'source'>;\n /**\n * Set the `textarea` related props.\n */\n textareaProps?: ITextAreaProps;\n /** Use div to replace TextArea or re-render TextArea */\n renderTextarea?: ITextAreaProps['renderTextarea'];\n /**\n * Disable editing area code highlighting. The value is `false`, which increases the editing speed.\n * @default true\n */\n highlightEnable?: boolean;\n /**\n * The number of characters to insert when pressing tab key.\n * Default `2` spaces.\n */\n tabSize?: number;\n /**\n * If `false`, the `tab` key inserts a tab character into the textarea. If `true`, the `tab` key executes default behavior e.g. focus shifts to next element.\n */\n defaultTabEnable?: boolean;\n /**\n * You can create your own commands or reuse existing commands.\n */\n commands?: ICommand[];\n /**\n * Filter or modify your commands.\n * https://github.com/uiwjs/react-md-editor/issues/296\n */\n commandsFilter?: (command: ICommand, isExtra: boolean) => false | ICommand;\n /**\n * You can create your own commands or reuse existing commands.\n */\n extraCommands?: ICommand[];\n /**\n * Hide the tool bar\n */\n hideToolbar?: boolean;\n /** Whether to enable scrolling */\n enableScroll?: boolean;\n /** Toolbar on bottom */\n toolbarBottom?: boolean;\n}\n\nfunction setGroupPopFalse(data: Record<string, boolean> = {}) {\n Object.keys(data).forEach((keyname) => {\n data[keyname] = false;\n });\n return data;\n}\n\nconst InternalMDEditor = (\n props: MDEditorProps,\n ref?: ((instance: ContextStore) => void) | React.RefObject<ContextStore> | null,\n) => {\n const {\n prefixCls = 'w-md-editor',\n className,\n value: propsValue,\n commands = getCommands(),\n commandsFilter,\n extraCommands = getExtraCommands(),\n height = 200,\n toolbarHeight = 29,\n enableScroll = true,\n visibleDragbar = typeof props.visiableDragbar === 'boolean' ? props.visiableDragbar : true,\n highlightEnable = true,\n preview: previewType = 'live',\n fullscreen = false,\n overflow = true,\n previewOptions = {},\n textareaProps,\n maxHeight = 1200,\n minHeight = 100,\n autoFocus,\n tabSize = 2,\n defaultTabEnable = false,\n onChange,\n onHeightChange,\n hideToolbar,\n toolbarBottom = false,\n renderTextarea,\n ...other\n } = props || {};\n const cmds = commands\n .map((item) => (commandsFilter ? commandsFilter(item, false) : item))\n .filter(Boolean) as ICommand[];\n const extraCmds = extraCommands\n .map((item) => (commandsFilter ? commandsFilter(item, true) : item))\n .filter(Boolean) as ICommand[];\n let [state, dispatch] = useReducer(reducer, {\n markdown: propsValue,\n preview: previewType,\n height,\n highlightEnable,\n tabSize,\n defaultTabEnable,\n scrollTop: 0,\n scrollTopPreview: 0,\n commands: cmds,\n extraCommands: extraCmds,\n fullscreen,\n barPopup: {},\n });\n const container = useRef<HTMLDivElement>(null);\n const previewRef = useRef<MarkdownPreviewRef>(null);\n const enableScrollRef = useRef(enableScroll);\n\n useImperativeHandle(ref, () => ({ ...state }));\n useMemo(() => (enableScrollRef.current = enableScroll), [enableScroll]);\n useEffect(() => {\n const stateInit: ContextStore = {};\n if (container.current) {\n stateInit.container = container.current || undefined;\n }\n stateInit.markdown = propsValue || '';\n stateInit.barPopup = {};\n if (dispatch) {\n dispatch({ ...state, ...stateInit });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const cls = [\n className,\n 'wmde-markdown-var',\n prefixCls,\n state.preview ? `${prefixCls}-show-${state.preview}` : null,\n state.fullscreen ? `${prefixCls}-fullscreen` : null,\n ]\n .filter(Boolean)\n .join(' ')\n .trim();\n\n useMemo(\n () => propsValue !== state.markdown && dispatch({ markdown: propsValue || '' }),\n [propsValue, state.markdown],\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useMemo(() => previewType !== state.preview && dispatch({ preview: previewType }), [previewType]);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useMemo(() => tabSize !== state.tabSize && dispatch({ tabSize }), [tabSize]);\n useMemo(\n () => highlightEnable !== state.highlightEnable && dispatch({ highlightEnable }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [highlightEnable],\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useMemo(() => autoFocus !== state.autoFocus && dispatch({ autoFocus: autoFocus }), [autoFocus]);\n useMemo(\n () => fullscreen !== state.fullscreen && dispatch({ fullscreen: fullscreen }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [fullscreen],\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useMemo(() => height !== state.height && dispatch({ height: height }), [height]);\n useMemo(\n () => height !== state.height && onHeightChange && onHeightChange(state.height, height, state),\n [height, onHeightChange, state],\n );\n\n const textareaDomRef = useRef<HTMLDivElement>();\n const active = useRef<'text' | 'preview'>('preview');\n const initScroll = useRef(false);\n\n useMemo(() => {\n textareaDomRef.current = state.textareaWarp;\n if (state.textareaWarp) {\n state.textareaWarp.addEventListener('mouseover', () => {\n active.current = 'text';\n });\n state.textareaWarp.addEventListener('mouseleave', () => {\n active.current = 'preview';\n });\n }\n }, [state.textareaWarp]);\n\n const handleScroll = (e: React.UIEvent<HTMLDivElement>, type: 'text' | 'preview') => {\n if (!enableScrollRef.current) return;\n const textareaDom = textareaDomRef.current;\n const previewDom = previewRef.current ? previewRef.current.mdp.current : undefined;\n if (!initScroll.current) {\n active.current = type;\n initScroll.current = true;\n }\n if (textareaDom && previewDom) {\n const scale =\n (textareaDom.scrollHeight - textareaDom.offsetHeight) / (previewDom.scrollHeight - previewDom.offsetHeight);\n if (e.target === textareaDom && active.current === 'text') {\n previewDom.scrollTop = textareaDom.scrollTop / scale;\n }\n if (e.target === previewDom && active.current === 'preview') {\n textareaDom.scrollTop = previewDom.scrollTop * scale;\n }\n let scrollTop = 0;\n if (active.current === 'text') {\n scrollTop = textareaDom.scrollTop || 0;\n } else if (active.current === 'preview') {\n scrollTop = previewDom.scrollTop || 0;\n }\n dispatch({ scrollTop });\n }\n };\n\n const mdPreview = useMemo(\n () => (\n <MarkdownPreview\n {...previewOptions}\n onScroll={(e) => handleScroll(e, 'preview')}\n ref={previewRef}\n source={state.markdown || ''}\n className={`${prefixCls}-preview ${previewOptions.className || ''}`}\n />\n ),\n [prefixCls, previewOptions, state.markdown],\n );\n\n return (\n <EditorContext.Provider value={{ ...state, dispatch }}>\n <div\n ref={container}\n className={cls}\n {...other}\n onClick={() => {\n dispatch({ barPopup: { ...setGroupPopFalse(state.barPopup) } });\n }}\n style={{\n ...other.style,\n height: state.fullscreen ? '100%' : hideToolbar ? Number(state.height) - toolbarHeight : state.height,\n }}\n >\n {!hideToolbar && !toolbarBottom && (\n <Toolbar prefixCls={prefixCls} height={toolbarHeight} overflow={overflow} toolbarBottom={toolbarBottom} />\n )}\n <div\n className={`${prefixCls}-content`}\n style={{\n height: state.fullscreen ? `calc(100% - ${toolbarHeight}px)` : Number(state.height) - toolbarHeight,\n }}\n >\n {/(edit|live)/.test(state.preview || '') && (\n <TextArea\n className={`${prefixCls}-input`}\n prefixCls={prefixCls}\n autoFocus={autoFocus}\n {...textareaProps}\n onChange={(evn) => {\n onChange && onChange(evn.target.value, evn, state);\n if (textareaProps && textareaProps.onChange) {\n textareaProps.onChange(evn);\n }\n }}\n renderTextarea={renderTextarea}\n onScroll={(e) => handleScroll(e, 'text')}\n />\n )}\n {/(live|preview)/.test(state.preview || '') && mdPreview}\n </div>\n {visibleDragbar && !state.fullscreen && (\n <DragBar\n prefixCls={prefixCls}\n height={state.height as number}\n maxHeight={maxHeight!}\n minHeight={minHeight!}\n onChange={(newHeight) => {\n dispatch({ height: newHeight });\n }}\n />\n )}\n {!hideToolbar && toolbarBottom && (\n <Toolbar prefixCls={prefixCls} height={toolbarHeight} overflow={overflow} toolbarBottom={toolbarBottom} />\n )}\n </div>\n </EditorContext.Provider>\n );\n};\n\nconst mdEditor = React.forwardRef<ContextStore, MDEditorProps>(InternalMDEditor);\n\ntype MDEditor = typeof mdEditor & {\n Markdown: typeof MarkdownPreview;\n};\n\n(mdEditor as MDEditor).Markdown = MarkdownPreview;\n\nexport default mdEditor as MDEditor;\n"
|
|
104
|
+
"import React, { useEffect, useReducer, useMemo, useRef, useImperativeHandle, CSSProperties } from 'react';\nimport MarkdownPreview, { MarkdownPreviewProps, MarkdownPreviewRef } from '@uiw/react-markdown-preview';\nimport TextArea, { ITextAreaProps } from './components/TextArea';\nimport Toolbar from './components/Toolbar';\nimport DragBar from './components/DragBar';\nimport { getCommands, getExtraCommands, ICommand } from './commands';\nimport { reducer, EditorContext, ContextStore, PreviewType } from './Context';\nimport './index.less';\n\nexport interface IProps {\n prefixCls?: string;\n className?: string;\n}\n\nexport interface MDEditorProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'>, IProps {\n /**\n * The Markdown value.\n */\n value?: string;\n /**\n * Event handler for the `onChange` event.\n */\n onChange?: (value?: string, event?: React.ChangeEvent<HTMLTextAreaElement>, state?: ContextStore) => void;\n /**\n * editor height change listener\n */\n onHeightChange?: (value?: CSSProperties['height'], oldValue?: CSSProperties['height'], state?: ContextStore) => void;\n /**\n * Can be used to make `Markdown Editor` focus itself on initialization. Defaults to on.\n * it will be set to true when either the source `textarea` is focused,\n * or it has an `autofocus` attribute and no other element is focused.\n */\n autoFocus?: ITextAreaProps['autoFocus'];\n /**\n * The height of the editor.\n * ⚠️ `Dragbar` is invalid when **`height`** parameter percentage.\n */\n height?: CSSProperties['height'];\n /**\n * Custom toolbar heigth\n * @default 29px\n */\n toolbarHeight?: number;\n /**\n * Show drag and drop tool. Set the height of the editor.\n */\n visibleDragbar?: boolean;\n /**\n * @deprecated use `visibleDragbar`\n */\n visiableDragbar?: boolean;\n /**\n * Show markdown preview.\n */\n preview?: PreviewType;\n /**\n * Full screen display editor.\n */\n fullscreen?: boolean;\n /**\n * Disable `fullscreen` setting body styles\n */\n overflow?: boolean;\n /**\n * Maximum drag height. `visibleDragbar=true`\n */\n maxHeight?: number;\n /**\n * Minimum drag height. `visibleDragbar=true`\n */\n minHeight?: number;\n /**\n * This is reset [react-markdown](https://github.com/rexxars/react-markdown) settings.\n */\n previewOptions?: Omit<MarkdownPreviewProps, 'source'>;\n /**\n * Set the `textarea` related props.\n */\n textareaProps?: ITextAreaProps;\n /**\n * Use div to replace TextArea or re-render TextArea\n * @deprecated Please use ~~`renderTextarea`~~ -> `components`\n */\n renderTextarea?: ITextAreaProps['renderTextarea'];\n /**\n * re-render element\n */\n components?: {\n /** Use div to replace TextArea or re-render TextArea */\n textarea?: ITextAreaProps['renderTextarea'];\n /**\n * Override the default command element\n * _`toolbar`_ < _`command[].render`_\n */\n toolbar?: ICommand['render'];\n };\n /**\n * Disable editing area code highlighting. The value is `false`, which increases the editing speed.\n * @default true\n */\n highlightEnable?: boolean;\n /**\n * The number of characters to insert when pressing tab key.\n * Default `2` spaces.\n */\n tabSize?: number;\n /**\n * If `false`, the `tab` key inserts a tab character into the textarea. If `true`, the `tab` key executes default behavior e.g. focus shifts to next element.\n */\n defaultTabEnable?: boolean;\n /**\n * You can create your own commands or reuse existing commands.\n */\n commands?: ICommand[];\n /**\n * Filter or modify your commands.\n * https://github.com/uiwjs/react-md-editor/issues/296\n */\n commandsFilter?: (command: ICommand, isExtra: boolean) => false | ICommand;\n /**\n * You can create your own commands or reuse existing commands.\n */\n extraCommands?: ICommand[];\n /**\n * Hide the tool bar\n */\n hideToolbar?: boolean;\n /** Whether to enable scrolling */\n enableScroll?: boolean;\n /** Toolbar on bottom */\n toolbarBottom?: boolean;\n}\n\nfunction setGroupPopFalse(data: Record<string, boolean> = {}) {\n Object.keys(data).forEach((keyname) => {\n data[keyname] = false;\n });\n return data;\n}\n\nconst InternalMDEditor = (\n props: MDEditorProps,\n ref?: ((instance: ContextStore) => void) | React.RefObject<ContextStore> | null,\n) => {\n const {\n prefixCls = 'w-md-editor',\n className,\n value: propsValue,\n commands = getCommands(),\n commandsFilter,\n extraCommands = getExtraCommands(),\n height = 200,\n toolbarHeight = 29,\n enableScroll = true,\n visibleDragbar = typeof props.visiableDragbar === 'boolean' ? props.visiableDragbar : true,\n highlightEnable = true,\n preview: previewType = 'live',\n fullscreen = false,\n overflow = true,\n previewOptions = {},\n textareaProps,\n maxHeight = 1200,\n minHeight = 100,\n autoFocus,\n tabSize = 2,\n defaultTabEnable = false,\n onChange,\n onHeightChange,\n hideToolbar,\n toolbarBottom = false,\n components,\n renderTextarea,\n ...other\n } = props || {};\n const cmds = commands\n .map((item) => (commandsFilter ? commandsFilter(item, false) : item))\n .filter(Boolean) as ICommand[];\n const extraCmds = extraCommands\n .map((item) => (commandsFilter ? commandsFilter(item, true) : item))\n .filter(Boolean) as ICommand[];\n let [state, dispatch] = useReducer(reducer, {\n markdown: propsValue,\n preview: previewType,\n components,\n height,\n highlightEnable,\n tabSize,\n defaultTabEnable,\n scrollTop: 0,\n scrollTopPreview: 0,\n commands: cmds,\n extraCommands: extraCmds,\n fullscreen,\n barPopup: {},\n });\n const container = useRef<HTMLDivElement>(null);\n const previewRef = useRef<MarkdownPreviewRef>(null);\n const enableScrollRef = useRef(enableScroll);\n\n useImperativeHandle(ref, () => ({ ...state }));\n useMemo(() => (enableScrollRef.current = enableScroll), [enableScroll]);\n useEffect(() => {\n const stateInit: ContextStore = {};\n if (container.current) {\n stateInit.container = container.current || undefined;\n }\n stateInit.markdown = propsValue || '';\n stateInit.barPopup = {};\n if (dispatch) {\n dispatch({ ...state, ...stateInit });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const cls = [\n className,\n 'wmde-markdown-var',\n prefixCls,\n state.preview ? `${prefixCls}-show-${state.preview}` : null,\n state.fullscreen ? `${prefixCls}-fullscreen` : null,\n ]\n .filter(Boolean)\n .join(' ')\n .trim();\n\n useMemo(\n () => propsValue !== state.markdown && dispatch({ markdown: propsValue || '' }),\n [propsValue, state.markdown],\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useMemo(() => previewType !== state.preview && dispatch({ preview: previewType }), [previewType]);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useMemo(() => tabSize !== state.tabSize && dispatch({ tabSize }), [tabSize]);\n useMemo(\n () => highlightEnable !== state.highlightEnable && dispatch({ highlightEnable }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [highlightEnable],\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useMemo(() => autoFocus !== state.autoFocus && dispatch({ autoFocus: autoFocus }), [autoFocus]);\n useMemo(\n () => fullscreen !== state.fullscreen && dispatch({ fullscreen: fullscreen }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [fullscreen],\n );\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useMemo(() => height !== state.height && dispatch({ height: height }), [height]);\n useMemo(\n () => height !== state.height && onHeightChange && onHeightChange(state.height, height, state),\n [height, onHeightChange, state],\n );\n\n const textareaDomRef = useRef<HTMLDivElement>();\n const active = useRef<'text' | 'preview'>('preview');\n const initScroll = useRef(false);\n\n useMemo(() => {\n textareaDomRef.current = state.textareaWarp;\n if (state.textareaWarp) {\n state.textareaWarp.addEventListener('mouseover', () => {\n active.current = 'text';\n });\n state.textareaWarp.addEventListener('mouseleave', () => {\n active.current = 'preview';\n });\n }\n }, [state.textareaWarp]);\n\n const handleScroll = (e: React.UIEvent<HTMLDivElement>, type: 'text' | 'preview') => {\n if (!enableScrollRef.current) return;\n const textareaDom = textareaDomRef.current;\n const previewDom = previewRef.current ? previewRef.current.mdp.current : undefined;\n if (!initScroll.current) {\n active.current = type;\n initScroll.current = true;\n }\n if (textareaDom && previewDom) {\n const scale =\n (textareaDom.scrollHeight - textareaDom.offsetHeight) / (previewDom.scrollHeight - previewDom.offsetHeight);\n if (e.target === textareaDom && active.current === 'text') {\n previewDom.scrollTop = textareaDom.scrollTop / scale;\n }\n if (e.target === previewDom && active.current === 'preview') {\n textareaDom.scrollTop = previewDom.scrollTop * scale;\n }\n let scrollTop = 0;\n if (active.current === 'text') {\n scrollTop = textareaDom.scrollTop || 0;\n } else if (active.current === 'preview') {\n scrollTop = previewDom.scrollTop || 0;\n }\n dispatch({ scrollTop });\n }\n };\n\n const mdPreview = useMemo(\n () => (\n <MarkdownPreview\n {...previewOptions}\n onScroll={(e) => handleScroll(e, 'preview')}\n ref={previewRef}\n source={state.markdown || ''}\n className={`${prefixCls}-preview ${previewOptions.className || ''}`}\n />\n ),\n [prefixCls, previewOptions, state.markdown],\n );\n return (\n <EditorContext.Provider value={{ ...state, dispatch }}>\n <div\n ref={container}\n className={cls}\n {...other}\n onClick={() => {\n dispatch({ barPopup: { ...setGroupPopFalse(state.barPopup) } });\n }}\n style={{\n ...other.style,\n height: state.height || '100%',\n }}\n >\n {!hideToolbar && !toolbarBottom && (\n <Toolbar prefixCls={prefixCls} height={toolbarHeight} overflow={overflow} toolbarBottom={toolbarBottom} />\n )}\n <div\n className={`${prefixCls}-content`}\n style={{\n height: `calc(100% - ${toolbarHeight}px)`,\n }}\n >\n {/(edit|live)/.test(state.preview || '') && (\n <TextArea\n className={`${prefixCls}-input`}\n prefixCls={prefixCls}\n autoFocus={autoFocus}\n {...textareaProps}\n onChange={(evn) => {\n onChange && onChange(evn.target.value, evn, state);\n if (textareaProps && textareaProps.onChange) {\n textareaProps.onChange(evn);\n }\n }}\n renderTextarea={components?.textarea || renderTextarea}\n onScroll={(e) => handleScroll(e, 'text')}\n />\n )}\n {/(live|preview)/.test(state.preview || '') && mdPreview}\n </div>\n {visibleDragbar && !state.fullscreen && (\n <DragBar\n prefixCls={prefixCls}\n height={state.height as number}\n maxHeight={maxHeight!}\n minHeight={minHeight!}\n onChange={(newHeight) => {\n dispatch({ height: newHeight });\n }}\n />\n )}\n {!hideToolbar && toolbarBottom && (\n <Toolbar prefixCls={prefixCls} height={toolbarHeight} overflow={overflow} toolbarBottom={toolbarBottom} />\n )}\n </div>\n </EditorContext.Provider>\n );\n};\n\nconst mdEditor = React.forwardRef<ContextStore, MDEditorProps>(InternalMDEditor);\n\ntype MDEditor = typeof mdEditor & {\n Markdown: typeof MarkdownPreview;\n};\n\n(mdEditor as MDEditor).Markdown = MarkdownPreview;\n\nexport default mdEditor as MDEditor;\n"
|
|
104
105
|
],
|
|
105
|
-
"mappings": ";;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;;;;;AA+
|
|
106
|
+
"mappings": "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"
|
|
106
107
|
}
|
package/lib/commands/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { bold } from './bold';
|
|
2
3
|
import { code, codeBlock } from './code';
|
|
3
4
|
import { italic } from './italic';
|
|
@@ -44,6 +45,7 @@ export interface ICommandBase<T> {
|
|
|
44
45
|
position?: 'right';
|
|
45
46
|
liProps?: React.LiHTMLAttributes<HTMLLIElement>;
|
|
46
47
|
buttonProps?: React.ButtonHTMLAttributes<HTMLButtonElement> | null;
|
|
48
|
+
render?: (command: ICommand<T>, disabled: boolean, executeCommand: (command: ICommand<T>, name?: string) => void, index: number) => void | undefined | null | React.ReactElement;
|
|
47
49
|
execute?: (state: TextState, api: TextAreaTextApi, dispatch?: React.Dispatch<ContextStore>, executeCommandState?: ExecuteCommandState) => void;
|
|
48
50
|
}
|
|
49
51
|
export declare type ICommand<T = string> = ICommandChildCommands<T> | ICommandChildHandle<T>;
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"../../src/commands/index.ts"
|
|
48
48
|
],
|
|
49
49
|
"sourcesContent": [
|
|
50
|
-
"import { bold } from './bold';\nimport { code, codeBlock } from './code';\nimport { italic } from './italic';\nimport { link } from './link';\nimport { unorderedListCommand, orderedListCommand, checkedListCommand } from './list';\nimport { quote } from './quote';\nimport { hr } from './hr';\nimport { title } from './title';\nimport { title1 } from './title1';\nimport { title2 } from './title2';\nimport { title3 } from './title3';\nimport { title4 } from './title4';\nimport { title5 } from './title5';\nimport { title6 } from './title6';\nimport { comment } from './comment';\nimport { group } from './group';\nimport { divider } from './divider';\nimport { codePreview, codeEdit, codeLive } from './preview';\nimport { fullscreen } from './fullscreen';\nimport { image } from './image';\nimport { strikethrough } from './strikeThrough';\nimport { insertTextAtPosition } from '../utils/InsertTextAtPosition';\nimport { ContextStore, ExecuteCommandState } from '../Context';\n\nexport interface CommandOrchestrator {\n executeCommand(command: ICommand): void;\n}\n\nexport interface ICommandChildHandle<T = string> extends ICommandBase<T> {\n children?: (handle: {\n close: () => void;\n execute: () => void;\n getState?: TextAreaCommandOrchestrator['getState'];\n textApi?: TextAreaTextApi;\n }) => React.ReactElement;\n}\n\nexport interface ICommandChildCommands<T = string> extends ICommandBase<T> {\n children?: Array<ICommand<T>>;\n}\n\nexport interface ICommandBase<T> {\n parent?: ICommand<any>;\n keyCommand?: string;\n name?: string;\n shortcuts?: string;\n groupName?: string;\n icon?: React.ReactElement;\n value?: T;\n position?: 'right';\n liProps?: React.LiHTMLAttributes<HTMLLIElement>;\n buttonProps?: React.ButtonHTMLAttributes<HTMLButtonElement> | null;\n execute?: (\n state: TextState,\n api: TextAreaTextApi,\n dispatch?: React.Dispatch<ContextStore>,\n executeCommandState?: ExecuteCommandState,\n ) => void;\n}\n\nexport type ICommand<T = string> = ICommandChildCommands<T> | ICommandChildHandle<T>;\n\nexport interface TextRange {\n start: number;\n end: number;\n}\n\nexport interface TextState {\n text: string;\n selectedText: string;\n selection: TextRange;\n}\n\nconst getCommands: () => ICommand[] = () => [\n comment,\n bold,\n italic,\n strikethrough,\n hr,\n title,\n divider,\n link,\n quote,\n code,\n codeBlock,\n image,\n divider,\n unorderedListCommand,\n orderedListCommand,\n checkedListCommand,\n];\n\nconst getExtraCommands: () => ICommand[] = () => [codeEdit, codeLive, codePreview, divider, fullscreen];\n\nfunction getStateFromTextArea(textArea: HTMLTextAreaElement): TextState {\n return {\n selection: {\n start: textArea.selectionStart,\n end: textArea.selectionEnd,\n },\n text: textArea.value,\n selectedText: textArea.value.slice(textArea.selectionStart, textArea.selectionEnd),\n };\n}\n\nclass TextAreaTextApi {\n textArea: HTMLTextAreaElement;\n\n constructor(textArea: HTMLTextAreaElement) {\n this.textArea = textArea;\n }\n\n /**\n * Replaces the current selection with the new text. This will make the new selectedText to be empty, the\n * selection start and selection end will be the same and will both point to the end\n * @param text Text that should replace the current selection\n */\n replaceSelection(text: string): TextState {\n insertTextAtPosition(this.textArea, text);\n return getStateFromTextArea(this.textArea);\n }\n\n /**\n * Selects the specified text range\n * @param selection\n */\n setSelectionRange(selection: TextRange): TextState {\n this.textArea.focus();\n this.textArea.selectionStart = selection.start;\n this.textArea.selectionEnd = selection.end;\n return getStateFromTextArea(this.textArea);\n }\n}\n\nclass TextAreaCommandOrchestrator implements CommandOrchestrator {\n textArea: HTMLTextAreaElement;\n textApi: TextAreaTextApi;\n\n constructor(textArea: HTMLTextAreaElement) {\n this.textArea = textArea;\n this.textApi = new TextAreaTextApi(textArea);\n }\n\n getState() {\n if (!this.textArea) return false;\n return getStateFromTextArea(this.textArea);\n }\n\n executeCommand(\n command: ICommand<string>,\n dispatch?: React.Dispatch<ContextStore>,\n state?: ExecuteCommandState,\n ): void {\n command.execute && command.execute(getStateFromTextArea(this.textArea), this.textApi, dispatch, state);\n }\n}\n\nexport {\n // Toolbars.\n title,\n title1,\n title2,\n title3,\n title4,\n title5,\n title6,\n bold,\n codeBlock,\n italic,\n strikethrough,\n hr,\n group,\n divider,\n link,\n quote,\n code,\n image,\n unorderedListCommand,\n orderedListCommand,\n checkedListCommand,\n codeEdit,\n codeLive,\n codePreview,\n fullscreen,\n // Tool method.\n getCommands,\n getExtraCommands,\n getStateFromTextArea,\n TextAreaCommandOrchestrator,\n TextAreaTextApi,\n};\n"
|
|
50
|
+
"import React from 'react';\nimport { bold } from './bold';\nimport { code, codeBlock } from './code';\nimport { italic } from './italic';\nimport { link } from './link';\nimport { unorderedListCommand, orderedListCommand, checkedListCommand } from './list';\nimport { quote } from './quote';\nimport { hr } from './hr';\nimport { title } from './title';\nimport { title1 } from './title1';\nimport { title2 } from './title2';\nimport { title3 } from './title3';\nimport { title4 } from './title4';\nimport { title5 } from './title5';\nimport { title6 } from './title6';\nimport { comment } from './comment';\nimport { group } from './group';\nimport { divider } from './divider';\nimport { codePreview, codeEdit, codeLive } from './preview';\nimport { fullscreen } from './fullscreen';\nimport { image } from './image';\nimport { strikethrough } from './strikeThrough';\nimport { insertTextAtPosition } from '../utils/InsertTextAtPosition';\nimport { ContextStore, ExecuteCommandState } from '../Context';\n\nexport interface CommandOrchestrator {\n executeCommand(command: ICommand): void;\n}\n\nexport interface ICommandChildHandle<T = string> extends ICommandBase<T> {\n children?: (handle: {\n close: () => void;\n execute: () => void;\n getState?: TextAreaCommandOrchestrator['getState'];\n textApi?: TextAreaTextApi;\n }) => React.ReactElement;\n}\n\nexport interface ICommandChildCommands<T = string> extends ICommandBase<T> {\n children?: Array<ICommand<T>>;\n}\n\nexport interface ICommandBase<T> {\n parent?: ICommand<any>;\n keyCommand?: string;\n name?: string;\n shortcuts?: string;\n groupName?: string;\n icon?: React.ReactElement;\n value?: T;\n position?: 'right';\n liProps?: React.LiHTMLAttributes<HTMLLIElement>;\n buttonProps?: React.ButtonHTMLAttributes<HTMLButtonElement> | null;\n render?: (\n command: ICommand<T>,\n disabled: boolean,\n executeCommand: (command: ICommand<T>, name?: string) => void,\n index: number,\n ) => void | undefined | null | React.ReactElement;\n execute?: (\n state: TextState,\n api: TextAreaTextApi,\n dispatch?: React.Dispatch<ContextStore>,\n executeCommandState?: ExecuteCommandState,\n ) => void;\n}\n\nexport type ICommand<T = string> = ICommandChildCommands<T> | ICommandChildHandle<T>;\n\nexport interface TextRange {\n start: number;\n end: number;\n}\n\nexport interface TextState {\n text: string;\n selectedText: string;\n selection: TextRange;\n}\n\nconst getCommands: () => ICommand[] = () => [\n comment,\n bold,\n italic,\n strikethrough,\n hr,\n title,\n divider,\n link,\n quote,\n code,\n codeBlock,\n image,\n divider,\n unorderedListCommand,\n orderedListCommand,\n checkedListCommand,\n];\n\nconst getExtraCommands: () => ICommand[] = () => [codeEdit, codeLive, codePreview, divider, fullscreen];\n\nfunction getStateFromTextArea(textArea: HTMLTextAreaElement): TextState {\n return {\n selection: {\n start: textArea.selectionStart,\n end: textArea.selectionEnd,\n },\n text: textArea.value,\n selectedText: textArea.value.slice(textArea.selectionStart, textArea.selectionEnd),\n };\n}\n\nclass TextAreaTextApi {\n textArea: HTMLTextAreaElement;\n\n constructor(textArea: HTMLTextAreaElement) {\n this.textArea = textArea;\n }\n\n /**\n * Replaces the current selection with the new text. This will make the new selectedText to be empty, the\n * selection start and selection end will be the same and will both point to the end\n * @param text Text that should replace the current selection\n */\n replaceSelection(text: string): TextState {\n insertTextAtPosition(this.textArea, text);\n return getStateFromTextArea(this.textArea);\n }\n\n /**\n * Selects the specified text range\n * @param selection\n */\n setSelectionRange(selection: TextRange): TextState {\n this.textArea.focus();\n this.textArea.selectionStart = selection.start;\n this.textArea.selectionEnd = selection.end;\n return getStateFromTextArea(this.textArea);\n }\n}\n\nclass TextAreaCommandOrchestrator implements CommandOrchestrator {\n textArea: HTMLTextAreaElement;\n textApi: TextAreaTextApi;\n\n constructor(textArea: HTMLTextAreaElement) {\n this.textArea = textArea;\n this.textApi = new TextAreaTextApi(textArea);\n }\n\n getState() {\n if (!this.textArea) return false;\n return getStateFromTextArea(this.textArea);\n }\n\n executeCommand(\n command: ICommand<string>,\n dispatch?: React.Dispatch<ContextStore>,\n state?: ExecuteCommandState,\n ): void {\n command.execute && command.execute(getStateFromTextArea(this.textArea), this.textApi, dispatch, state);\n }\n}\n\nexport {\n // Toolbars.\n title,\n title1,\n title2,\n title3,\n title4,\n title5,\n title6,\n bold,\n codeBlock,\n italic,\n strikethrough,\n hr,\n group,\n divider,\n link,\n quote,\n code,\n image,\n unorderedListCommand,\n orderedListCommand,\n checkedListCommand,\n codeEdit,\n codeLive,\n codePreview,\n fullscreen,\n // Tool method.\n getCommands,\n getExtraCommands,\n getStateFromTextArea,\n TextAreaCommandOrchestrator,\n TextAreaTextApi,\n};\n"
|
|
51
51
|
],
|
|
52
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
52
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AA0DA,IAAMA,WAA6B,GAAG,SAAhCA,WAAgC;EAAA,OAAM,CAC1CC,gBAD0C,EAE1CC,UAF0C,EAG1CC,cAH0C,EAI1CC,4BAJ0C,EAK1CC,MAL0C,EAM1CC,YAN0C,EAO1CC,gBAP0C,EAQ1CC,UAR0C,EAS1CC,YAT0C,EAU1CC,UAV0C,EAW1CC,eAX0C,EAY1CC,YAZ0C,EAa1CL,gBAb0C,EAc1CM,0BAd0C,EAe1CC,wBAf0C,EAgB1CC,wBAhB0C,CAAN;AAAA,CAAtC;;;;AAmBA,IAAMC,gBAAkC,GAAG,SAArCA,gBAAqC;EAAA,OAAM,CAACC,iBAAD,EAAWC,iBAAX,EAAqBC,oBAArB,EAAkCZ,gBAAlC,EAA2Ca,sBAA3C,CAAN;AAAA,CAA3C;;;;AAEA,SAASC,oBAAT,CAA8BC,QAA9B,EAAwE;EACtE,OAAO;IACLC,SAAS,EAAE;MACTC,KAAK,EAAEF,QAAQ,CAACG,cADP;MAETC,GAAG,EAAEJ,QAAQ,CAACK;IAFL,CADN;IAKLC,IAAI,EAAEN,QAAQ,CAACO,KALV;IAMLC,YAAY,EAAER,QAAQ,CAACO,KAAT,CAAeE,KAAf,CAAqBT,QAAQ,CAACG,cAA9B,EAA8CH,QAAQ,CAACK,YAAvD;EANT,CAAP;AAQD;;IAEKK,e;EAGJ,yBAAYV,QAAZ,EAA2C;IAAA;IAAA;IACzC,KAAKA,QAAL,GAAgBA,QAAhB;EACD;EAED;AACF;AACA;AACA;AACA;;;;;WACE,0BAAiBM,IAAjB,EAA0C;MACxC,IAAAK,0CAAA,EAAqB,KAAKX,QAA1B,EAAoCM,IAApC;MACA,OAAOP,oBAAoB,CAAC,KAAKC,QAAN,CAA3B;IACD;IAED;AACF;AACA;AACA;;;;WACE,2BAAkBC,SAAlB,EAAmD;MACjD,KAAKD,QAAL,CAAcY,KAAd;MACA,KAAKZ,QAAL,CAAcG,cAAd,GAA+BF,SAAS,CAACC,KAAzC;MACA,KAAKF,QAAL,CAAcK,YAAd,GAA6BJ,SAAS,CAACG,GAAvC;MACA,OAAOL,oBAAoB,CAAC,KAAKC,QAAN,CAA3B;IACD;;;;;;;IAGGa,2B;EAIJ,qCAAYb,QAAZ,EAA2C;IAAA;IAAA;IAAA;IACzC,KAAKA,QAAL,GAAgBA,QAAhB;IACA,KAAKc,OAAL,GAAe,IAAIJ,eAAJ,CAAoBV,QAApB,CAAf;EACD;;;;WAED,oBAAW;MACT,IAAI,CAAC,KAAKA,QAAV,EAAoB,OAAO,KAAP;MACpB,OAAOD,oBAAoB,CAAC,KAAKC,QAAN,CAA3B;IACD;;;WAED,wBACEe,OADF,EAEEC,QAFF,EAGEC,KAHF,EAIQ;MACNF,OAAO,CAACG,OAAR,IAAmBH,OAAO,CAACG,OAAR,CAAgBnB,oBAAoB,CAAC,KAAKC,QAAN,CAApC,EAAqD,KAAKc,OAA1D,EAAmEE,QAAnE,EAA6EC,KAA7E,CAAnB;IACD"
|
|
53
53
|
}
|
|
@@ -29,6 +29,7 @@ function ToolbarItems(props) {
|
|
|
29
29
|
preview = _useContext.preview,
|
|
30
30
|
_useContext$barPopup = _useContext.barPopup,
|
|
31
31
|
barPopup = _useContext$barPopup === void 0 ? {} : _useContext$barPopup,
|
|
32
|
+
components = _useContext.components,
|
|
32
33
|
commandOrchestrator = _useContext.commandOrchestrator,
|
|
33
34
|
dispatch = _useContext.dispatch;
|
|
34
35
|
|
|
@@ -110,9 +111,11 @@ function ToolbarItems(props) {
|
|
|
110
111
|
}
|
|
111
112
|
}) : undefined;
|
|
112
113
|
var disabled = barPopup && preview && preview === 'preview' && !/(preview|fullscreen)/.test(item.keyCommand);
|
|
114
|
+
var render = (components === null || components === void 0 ? void 0 : components.toolbar) || item.render;
|
|
115
|
+
var com = render && typeof render === 'function' ? render(item, !!disabled, handleClick, idx) : null;
|
|
113
116
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("li", (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, item.liProps), {}, {
|
|
114
117
|
className: activeBtn ? "active" : '',
|
|
115
|
-
children: [!item.buttonProps && item.icon, item.buttonProps && /*#__PURE__*/_react["default"].createElement('button', (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
|
|
118
|
+
children: [com && /*#__PURE__*/_react["default"].isValidElement(com) && com, !com && !item.buttonProps && item.icon, !com && item.buttonProps && /*#__PURE__*/_react["default"].createElement('button', (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
|
|
116
119
|
type: 'button',
|
|
117
120
|
key: idx,
|
|
118
121
|
disabled: disabled,
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"fullscreen",
|
|
11
11
|
"preview",
|
|
12
12
|
"barPopup",
|
|
13
|
+
"components",
|
|
13
14
|
"commandOrchestrator",
|
|
14
15
|
"dispatch",
|
|
15
16
|
"originalOverflow",
|
|
@@ -50,9 +51,13 @@
|
|
|
50
51
|
"execute",
|
|
51
52
|
"disabled",
|
|
52
53
|
"test",
|
|
54
|
+
"render",
|
|
55
|
+
"toolbar",
|
|
56
|
+
"com",
|
|
57
|
+
"React",
|
|
58
|
+
"isValidElement",
|
|
53
59
|
"buttonProps",
|
|
54
60
|
"icon",
|
|
55
|
-
"React",
|
|
56
61
|
"createElement",
|
|
57
62
|
"type",
|
|
58
63
|
"key",
|
|
@@ -72,7 +77,7 @@
|
|
|
72
77
|
"../../../src/components/Toolbar/index.tsx"
|
|
73
78
|
],
|
|
74
79
|
"sourcesContent": [
|
|
75
|
-
"import React, { Fragment, useContext, useEffect, useRef } from 'react';\nimport { IProps } from '../../Editor';\nimport { EditorContext, PreviewType, ContextStore } from '../../Context';\nimport { ICommand } from '../../commands';\nimport Child from './Child';\nimport './index.less';\n\nexport interface IToolbarProps extends IProps {\n overflow?: boolean;\n height?: React.CSSProperties['height'];\n toolbarBottom?: boolean;\n onCommand?: (command: ICommand<string>, groupName?: string) => void;\n commands?: ICommand<string>[];\n isChild?: boolean;\n}\n\nexport function ToolbarItems(props: IToolbarProps) {\n const { prefixCls, overflow } = props;\n const { fullscreen, preview, barPopup = {}, commandOrchestrator, dispatch } = useContext(EditorContext);\n const originalOverflow = useRef('');\n\n function handleClick(command: ICommand<string>, name?: string) {\n if (!dispatch) return;\n const state: ContextStore = { barPopup: { ...barPopup } };\n if (command.keyCommand === 'preview') {\n state.preview = command.value as PreviewType;\n }\n if (command.keyCommand === 'fullscreen') {\n state.fullscreen = !fullscreen;\n }\n if (props.commands && command.keyCommand === 'group') {\n props.commands.forEach((item) => {\n if (name === item.groupName) {\n state.barPopup![name!] = true;\n } else if (item.keyCommand) {\n state.barPopup![item.groupName!] = false;\n }\n });\n } else if (name || command.parent) {\n Object.keys(state.barPopup || {}).forEach((keyName) => {\n state.barPopup![keyName] = false;\n });\n }\n\n if (Object.keys(state).length) {\n dispatch({ ...state });\n }\n commandOrchestrator && commandOrchestrator.executeCommand(command);\n }\n\n useEffect(() => {\n if (document && overflow) {\n if (fullscreen) {\n // prevent scroll on fullscreen\n document.body.style.overflow = 'hidden';\n } else {\n // get the original overflow only the first time\n if (!originalOverflow.current) {\n originalOverflow.current = window.getComputedStyle(document.body, null).overflow;\n }\n // reset to the original overflow\n document.body.style.overflow = originalOverflow.current;\n }\n }\n }, [fullscreen, originalOverflow, overflow]);\n\n return (\n <ul>\n {(props.commands || []).map((item, idx) => {\n if (item.keyCommand === 'divider') {\n return <li key={idx} {...item.liProps} className={`${prefixCls}-toolbar-divider`} />;\n }\n if (!item.keyCommand) return <Fragment key={idx} />;\n const activeBtn =\n (fullscreen && item.keyCommand === 'fullscreen') || (item.keyCommand === 'preview' && preview === item.value);\n const childNode =\n item.children && typeof item.children === 'function'\n ? item.children({\n getState: () => commandOrchestrator!.getState(),\n textApi: commandOrchestrator ? commandOrchestrator!.textApi : undefined,\n close: () => handleClick({}, item.groupName),\n execute: () => handleClick({ execute: item.execute }),\n })\n : undefined;\n const disabled = barPopup && preview && preview === 'preview' && !/(preview|fullscreen)/.test(item.keyCommand);\n return (\n <li key={idx} {...item.liProps} className={activeBtn ? `active` : ''}>\n {!item.buttonProps && item.icon}\n {item.buttonProps &&\n React.createElement(\n 'button',\n {\n type: 'button',\n key: idx,\n disabled,\n 'data-name': item.name,\n ...item.buttonProps,\n onClick: (evn: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n evn.stopPropagation();\n handleClick(item, item.groupName);\n },\n },\n item.icon,\n )}\n {item.children && (\n <Child\n overflow={overflow}\n groupName={item.groupName}\n prefixCls={prefixCls}\n children={childNode}\n commands={Array.isArray(item.children) ? item.children : undefined}\n />\n )}\n </li>\n );\n })}\n </ul>\n );\n}\n\nexport default function Toolbar(props: IToolbarProps = {}) {\n const { prefixCls, height = 29, toolbarBottom, isChild } = props;\n const { commands, extraCommands } = useContext(EditorContext);\n const bottomClassName = toolbarBottom ? 'bottom' : '';\n return (\n <div className={`${prefixCls}-toolbar ${bottomClassName}`} style={{ height }}>\n <ToolbarItems {...props} commands={props.commands || commands || []} />\n {!isChild && <ToolbarItems {...props} commands={extraCommands || []} />}\n </div>\n );\n}\n"
|
|
80
|
+
"import React, { Fragment, useContext, useEffect, useRef } from 'react';\nimport { IProps } from '../../Editor';\nimport { EditorContext, PreviewType, ContextStore } from '../../Context';\nimport { ICommand } from '../../commands';\nimport Child from './Child';\nimport './index.less';\n\nexport interface IToolbarProps extends IProps {\n overflow?: boolean;\n height?: React.CSSProperties['height'];\n toolbarBottom?: boolean;\n onCommand?: (command: ICommand<string>, groupName?: string) => void;\n commands?: ICommand<string>[];\n isChild?: boolean;\n}\n\nexport function ToolbarItems(props: IToolbarProps) {\n const { prefixCls, overflow } = props;\n const { fullscreen, preview, barPopup = {}, components, commandOrchestrator, dispatch } = useContext(EditorContext);\n const originalOverflow = useRef('');\n\n function handleClick(command: ICommand<string>, name?: string) {\n if (!dispatch) return;\n const state: ContextStore = { barPopup: { ...barPopup } };\n if (command.keyCommand === 'preview') {\n state.preview = command.value as PreviewType;\n }\n if (command.keyCommand === 'fullscreen') {\n state.fullscreen = !fullscreen;\n }\n if (props.commands && command.keyCommand === 'group') {\n props.commands.forEach((item) => {\n if (name === item.groupName) {\n state.barPopup![name!] = true;\n } else if (item.keyCommand) {\n state.barPopup![item.groupName!] = false;\n }\n });\n } else if (name || command.parent) {\n Object.keys(state.barPopup || {}).forEach((keyName) => {\n state.barPopup![keyName] = false;\n });\n }\n\n if (Object.keys(state).length) {\n dispatch({ ...state });\n }\n commandOrchestrator && commandOrchestrator.executeCommand(command);\n }\n\n useEffect(() => {\n if (document && overflow) {\n if (fullscreen) {\n // prevent scroll on fullscreen\n document.body.style.overflow = 'hidden';\n } else {\n // get the original overflow only the first time\n if (!originalOverflow.current) {\n originalOverflow.current = window.getComputedStyle(document.body, null).overflow;\n }\n // reset to the original overflow\n document.body.style.overflow = originalOverflow.current;\n }\n }\n }, [fullscreen, originalOverflow, overflow]);\n\n return (\n <ul>\n {(props.commands || []).map((item, idx) => {\n if (item.keyCommand === 'divider') {\n return <li key={idx} {...item.liProps} className={`${prefixCls}-toolbar-divider`} />;\n }\n if (!item.keyCommand) return <Fragment key={idx} />;\n const activeBtn =\n (fullscreen && item.keyCommand === 'fullscreen') || (item.keyCommand === 'preview' && preview === item.value);\n const childNode =\n item.children && typeof item.children === 'function'\n ? item.children({\n getState: () => commandOrchestrator!.getState(),\n textApi: commandOrchestrator ? commandOrchestrator!.textApi : undefined,\n close: () => handleClick({}, item.groupName),\n execute: () => handleClick({ execute: item.execute }),\n })\n : undefined;\n const disabled = barPopup && preview && preview === 'preview' && !/(preview|fullscreen)/.test(item.keyCommand);\n const render = components?.toolbar || item.render;\n const com = (\n render && typeof render === 'function' ? render(item, !!disabled, handleClick, idx) : null\n ) as React.ReactElement;\n return (\n <li key={idx} {...item.liProps} className={activeBtn ? `active` : ''}>\n {com && React.isValidElement(com) && com}\n {!com && !item.buttonProps && item.icon}\n {!com &&\n item.buttonProps &&\n React.createElement(\n 'button',\n {\n type: 'button',\n key: idx,\n disabled,\n 'data-name': item.name,\n ...item.buttonProps,\n onClick: (evn: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n evn.stopPropagation();\n handleClick(item, item.groupName);\n },\n },\n item.icon,\n )}\n {item.children && (\n <Child\n overflow={overflow}\n groupName={item.groupName}\n prefixCls={prefixCls}\n children={childNode}\n commands={Array.isArray(item.children) ? item.children : undefined}\n />\n )}\n </li>\n );\n })}\n </ul>\n );\n}\n\nexport default function Toolbar(props: IToolbarProps = {}) {\n const { prefixCls, height = 29, toolbarBottom, isChild } = props;\n const { commands, extraCommands } = useContext(EditorContext);\n const bottomClassName = toolbarBottom ? 'bottom' : '';\n return (\n <div className={`${prefixCls}-toolbar ${bottomClassName}`} style={{ height }}>\n <ToolbarItems {...props} commands={props.commands || commands || []} />\n {!isChild && <ToolbarItems {...props} commands={extraCommands || []} />}\n </div>\n );\n}\n"
|
|
76
81
|
],
|
|
77
|
-
"mappings": ";;;;;;;;;;;;;;AAAA;;AAEA;;AAEA;;;;AAYO,SAASA,YAAT,CAAsBC,KAAtB,EAA4C;EACjD,IAAQC,SAAR,GAAgCD,KAAhC,CAAQC,SAAR;EAAA,IAAmBC,QAAnB,GAAgCF,KAAhC,CAAmBE,QAAnB;;EACA,
|
|
82
|
+
"mappings": ";;;;;;;;;;;;;;AAAA;;AAEA;;AAEA;;;;AAYO,SAASA,YAAT,CAAsBC,KAAtB,EAA4C;EACjD,IAAQC,SAAR,GAAgCD,KAAhC,CAAQC,SAAR;EAAA,IAAmBC,QAAnB,GAAgCF,KAAhC,CAAmBE,QAAnB;;EACA,kBAA0F,IAAAC,iBAAA,EAAWC,sBAAX,CAA1F;EAAA,IAAQC,UAAR,eAAQA,UAAR;EAAA,IAAoBC,OAApB,eAAoBA,OAApB;EAAA,uCAA6BC,QAA7B;EAAA,IAA6BA,QAA7B,qCAAwC,EAAxC;EAAA,IAA4CC,UAA5C,eAA4CA,UAA5C;EAAA,IAAwDC,mBAAxD,eAAwDA,mBAAxD;EAAA,IAA6EC,QAA7E,eAA6EA,QAA7E;;EACA,IAAMC,gBAAgB,GAAG,IAAAC,aAAA,EAAO,EAAP,CAAzB;;EAEA,SAASC,WAAT,CAAqBC,OAArB,EAAgDC,IAAhD,EAA+D;IAC7D,IAAI,CAACL,QAAL,EAAe;IACf,IAAMM,KAAmB,GAAG;MAAET,QAAQ,qCAAOA,QAAP;IAAV,CAA5B;;IACA,IAAIO,OAAO,CAACG,UAAR,KAAuB,SAA3B,EAAsC;MACpCD,KAAK,CAACV,OAAN,GAAgBQ,OAAO,CAACI,KAAxB;IACD;;IACD,IAAIJ,OAAO,CAACG,UAAR,KAAuB,YAA3B,EAAyC;MACvCD,KAAK,CAACX,UAAN,GAAmB,CAACA,UAApB;IACD;;IACD,IAAIL,KAAK,CAACmB,QAAN,IAAkBL,OAAO,CAACG,UAAR,KAAuB,OAA7C,EAAsD;MACpDjB,KAAK,CAACmB,QAAN,CAAeC,OAAf,CAAuB,UAACC,IAAD,EAAU;QAC/B,IAAIN,IAAI,KAAKM,IAAI,CAACC,SAAlB,EAA6B;UAC3BN,KAAK,CAACT,QAAN,CAAgBQ,IAAhB,IAAyB,IAAzB;QACD,CAFD,MAEO,IAAIM,IAAI,CAACJ,UAAT,EAAqB;UAC1BD,KAAK,CAACT,QAAN,CAAgBc,IAAI,CAACC,SAArB,IAAmC,KAAnC;QACD;MACF,CAND;IAOD,CARD,MAQO,IAAIP,IAAI,IAAID,OAAO,CAACS,MAApB,EAA4B;MACjCC,MAAM,CAACC,IAAP,CAAYT,KAAK,CAACT,QAAN,IAAkB,EAA9B,EAAkCa,OAAlC,CAA0C,UAACM,OAAD,EAAa;QACrDV,KAAK,CAACT,QAAN,CAAgBmB,OAAhB,IAA2B,KAA3B;MACD,CAFD;IAGD;;IAED,IAAIF,MAAM,CAACC,IAAP,CAAYT,KAAZ,EAAmBW,MAAvB,EAA+B;MAC7BjB,QAAQ,oCAAMM,KAAN,EAAR;IACD;;IACDP,mBAAmB,IAAIA,mBAAmB,CAACmB,cAApB,CAAmCd,OAAnC,CAAvB;EACD;;EAED,IAAAe,gBAAA,EAAU,YAAM;IACd,IAAIC,QAAQ,IAAI5B,QAAhB,EAA0B;MACxB,IAAIG,UAAJ,EAAgB;QACd;QACAyB,QAAQ,CAACC,IAAT,CAAcC,KAAd,CAAoB9B,QAApB,GAA+B,QAA/B;MACD,CAHD,MAGO;QACL;QACA,IAAI,CAACS,gBAAgB,CAACsB,OAAtB,EAA+B;UAC7BtB,gBAAgB,CAACsB,OAAjB,GAA2BC,MAAM,CAACC,gBAAP,CAAwBL,QAAQ,CAACC,IAAjC,EAAuC,IAAvC,EAA6C7B,QAAxE;QACD,CAJI,CAKL;;;QACA4B,QAAQ,CAACC,IAAT,CAAcC,KAAd,CAAoB9B,QAApB,GAA+BS,gBAAgB,CAACsB,OAAhD;MACD;IACF;EACF,CAdD,EAcG,CAAC5B,UAAD,EAAaM,gBAAb,EAA+BT,QAA/B,CAdH;EAgBA,oBACE;IAAA,UACG,CAACF,KAAK,CAACmB,QAAN,IAAkB,EAAnB,EAAuBiB,GAAvB,CAA2B,UAACf,IAAD,EAAOgB,GAAP,EAAe;MACzC,IAAIhB,IAAI,CAACJ,UAAL,KAAoB,SAAxB,EAAmC;QACjC,oBAAO,6FAAkBI,IAAI,CAACiB,OAAvB;UAAgC,SAAS,YAAKrC,SAAL;QAAzC,IAASoC,GAAT,CAAP;MACD;;MACD,IAAI,CAAChB,IAAI,CAACJ,UAAV,EAAsB,oBAAO,qBAAC,eAAD,MAAeoB,GAAf,CAAP;MACtB,IAAME,SAAS,GACZlC,UAAU,IAAIgB,IAAI,CAACJ,UAAL,KAAoB,YAAnC,IAAqDI,IAAI,CAACJ,UAAL,KAAoB,SAApB,IAAiCX,OAAO,KAAKe,IAAI,CAACH,KADzG;MAEA,IAAMsB,SAAS,GACbnB,IAAI,CAACoB,QAAL,IAAiB,OAAOpB,IAAI,CAACoB,QAAZ,KAAyB,UAA1C,GACIpB,IAAI,CAACoB,QAAL,CAAc;QACZC,QAAQ,EAAE;UAAA,OAAMjC,mBAAmB,CAAEiC,QAArB,EAAN;QAAA,CADE;QAEZC,OAAO,EAAElC,mBAAmB,GAAGA,mBAAmB,CAAEkC,OAAxB,GAAkCC,SAFlD;QAGZC,KAAK,EAAE;UAAA,OAAMhC,WAAW,CAAC,EAAD,EAAKQ,IAAI,CAACC,SAAV,CAAjB;QAAA,CAHK;QAIZwB,OAAO,EAAE;UAAA,OAAMjC,WAAW,CAAC;YAAEiC,OAAO,EAAEzB,IAAI,CAACyB;UAAhB,CAAD,CAAjB;QAAA;MAJG,CAAd,CADJ,GAOIF,SARN;MASA,IAAMG,QAAQ,GAAGxC,QAAQ,IAAID,OAAZ,IAAuBA,OAAO,KAAK,SAAnC,IAAgD,CAAC,uBAAuB0C,IAAvB,CAA4B3B,IAAI,CAACJ,UAAjC,CAAlE;MACA,IAAMgC,MAAM,GAAG,CAAAzC,UAAU,SAAV,IAAAA,UAAU,WAAV,YAAAA,UAAU,CAAE0C,OAAZ,KAAuB7B,IAAI,CAAC4B,MAA3C;MACA,IAAME,GAAG,GACPF,MAAM,IAAI,OAAOA,MAAP,KAAkB,UAA5B,GAAyCA,MAAM,CAAC5B,IAAD,EAAO,CAAC,CAAC0B,QAAT,EAAmBlC,WAAnB,EAAgCwB,GAAhC,CAA/C,GAAsF,IADxF;MAGA,oBACE,8FAAkBhB,IAAI,CAACiB,OAAvB;QAAgC,SAAS,EAAEC,SAAS,cAAc,EAAlE;QAAA,WACGY,GAAG,iBAAIC,iBAAA,CAAMC,cAAN,CAAqBF,GAArB,CAAP,IAAoCA,GADvC,EAEG,CAACA,GAAD,IAAQ,CAAC9B,IAAI,CAACiC,WAAd,IAA6BjC,IAAI,CAACkC,IAFrC,EAGG,CAACJ,GAAD,IACC9B,IAAI,CAACiC,WADN,iBAECF,iBAAA,CAAMI,aAAN,CACE,QADF;UAGIC,IAAI,EAAE,QAHV;UAIIC,GAAG,EAAErB,GAJT;UAKIU,QAAQ,EAARA,QALJ;UAMI,aAAa1B,IAAI,CAACN;QANtB,GAOOM,IAAI,CAACiC,WAPZ;UAQIK,OAAO,EAAE,iBAACC,GAAD,EAA0D;YACjEA,GAAG,CAACC,eAAJ;YACAhD,WAAW,CAACQ,IAAD,EAAOA,IAAI,CAACC,SAAZ,CAAX;UACD;QAXL,IAaED,IAAI,CAACkC,IAbP,CALJ,EAoBGlC,IAAI,CAACoB,QAAL,iBACC,qBAAC,iBAAD;UACE,QAAQ,EAAEvC,QADZ;UAEE,SAAS,EAAEmB,IAAI,CAACC,SAFlB;UAGE,SAAS,EAAErB,SAHb;UAIE,QAAQ,EAAEuC,SAJZ;UAKE,QAAQ,EAAEsB,KAAK,CAACC,OAAN,CAAc1C,IAAI,CAACoB,QAAnB,IAA+BpB,IAAI,CAACoB,QAApC,GAA+CG;QAL3D,EArBJ;MAAA,IAASP,GAAT,CADF;IAgCD,CArDA;EADH,EADF;AA0DD;;AAEc,SAAS2B,OAAT,GAA4C;EAAA,IAA3BhE,KAA2B,uEAAJ,EAAI;EACzD,IAAQC,SAAR,GAA2DD,KAA3D,CAAQC,SAAR;EAAA,oBAA2DD,KAA3D,CAAmBiE,MAAnB;EAAA,IAAmBA,MAAnB,8BAA4B,EAA5B;EAAA,IAAgCC,aAAhC,GAA2DlE,KAA3D,CAAgCkE,aAAhC;EAAA,IAA+CC,OAA/C,GAA2DnE,KAA3D,CAA+CmE,OAA/C;;EACA,mBAAoC,IAAAhE,iBAAA,EAAWC,sBAAX,CAApC;EAAA,IAAQe,QAAR,gBAAQA,QAAR;EAAA,IAAkBiD,aAAlB,gBAAkBA,aAAlB;;EACA,IAAMC,eAAe,GAAGH,aAAa,GAAG,QAAH,GAAc,EAAnD;EACA,oBACE;IAAK,SAAS,YAAKjE,SAAL,sBAA0BoE,eAA1B,CAAd;IAA2D,KAAK,EAAE;MAAEJ,MAAM,EAANA;IAAF,CAAlE;IAAA,wBACE,qBAAC,YAAD,oEAAkBjE,KAAlB;MAAyB,QAAQ,EAAEA,KAAK,CAACmB,QAAN,IAAkBA,QAAlB,IAA8B;IAAjE,GADF,EAEG,CAACgD,OAAD,iBAAY,qBAAC,YAAD,oEAAkBnE,KAAlB;MAAyB,QAAQ,EAAEoE,aAAa,IAAI;IAApD,GAFf;EAAA,EADF;AAMD"
|
|
78
83
|
}
|
package/lib/index.less
CHANGED
package/markdown-editor.css
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uiw/react-md-editor",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.17.0",
|
|
4
4
|
"description": "A markdown editor with preview, implemented with React.js and TypeScript.",
|
|
5
5
|
"homepage": "https://uiwjs.github.io/react-md-editor/",
|
|
6
6
|
"author": "kenny wang <wowohoo@qq.com>",
|
package/src/Context.tsx
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ICommand, TextAreaCommandOrchestrator } from './commands';
|
|
3
|
+
import { MDEditorProps } from './Editor';
|
|
3
4
|
|
|
4
5
|
export type PreviewType = 'live' | 'edit' | 'preview';
|
|
5
6
|
|
|
6
7
|
export type ContextStore = {
|
|
8
|
+
components?: MDEditorProps['components'];
|
|
7
9
|
commands?: ICommand<string>[];
|
|
8
10
|
extraCommands?: ICommand<string>[];
|
|
9
11
|
markdown?: string;
|
|
10
12
|
preview?: PreviewType;
|
|
11
|
-
height?:
|
|
13
|
+
height?: React.CSSProperties['height'];
|
|
12
14
|
fullscreen?: boolean;
|
|
13
15
|
highlightEnable?: boolean;
|
|
14
16
|
autoFocus?: boolean;
|
package/src/Editor.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useReducer, useMemo, useRef, useImperativeHandle } from 'react';
|
|
1
|
+
import React, { useEffect, useReducer, useMemo, useRef, useImperativeHandle, CSSProperties } from 'react';
|
|
2
2
|
import MarkdownPreview, { MarkdownPreviewProps, MarkdownPreviewRef } from '@uiw/react-markdown-preview';
|
|
3
3
|
import TextArea, { ITextAreaProps } from './components/TextArea';
|
|
4
4
|
import Toolbar from './components/Toolbar';
|
|
@@ -24,7 +24,7 @@ export interface MDEditorProps extends Omit<React.HTMLAttributes<HTMLDivElement>
|
|
|
24
24
|
/**
|
|
25
25
|
* editor height change listener
|
|
26
26
|
*/
|
|
27
|
-
onHeightChange?: (value?:
|
|
27
|
+
onHeightChange?: (value?: CSSProperties['height'], oldValue?: CSSProperties['height'], state?: ContextStore) => void;
|
|
28
28
|
/**
|
|
29
29
|
* Can be used to make `Markdown Editor` focus itself on initialization. Defaults to on.
|
|
30
30
|
* it will be set to true when either the source `textarea` is focused,
|
|
@@ -33,8 +33,9 @@ export interface MDEditorProps extends Omit<React.HTMLAttributes<HTMLDivElement>
|
|
|
33
33
|
autoFocus?: ITextAreaProps['autoFocus'];
|
|
34
34
|
/**
|
|
35
35
|
* The height of the editor.
|
|
36
|
+
* ⚠️ `Dragbar` is invalid when **`height`** parameter percentage.
|
|
36
37
|
*/
|
|
37
|
-
height?:
|
|
38
|
+
height?: CSSProperties['height'];
|
|
38
39
|
/**
|
|
39
40
|
* Custom toolbar heigth
|
|
40
41
|
* @default 29px
|
|
@@ -76,8 +77,23 @@ export interface MDEditorProps extends Omit<React.HTMLAttributes<HTMLDivElement>
|
|
|
76
77
|
* Set the `textarea` related props.
|
|
77
78
|
*/
|
|
78
79
|
textareaProps?: ITextAreaProps;
|
|
79
|
-
/**
|
|
80
|
+
/**
|
|
81
|
+
* Use div to replace TextArea or re-render TextArea
|
|
82
|
+
* @deprecated Please use ~~`renderTextarea`~~ -> `components`
|
|
83
|
+
*/
|
|
80
84
|
renderTextarea?: ITextAreaProps['renderTextarea'];
|
|
85
|
+
/**
|
|
86
|
+
* re-render element
|
|
87
|
+
*/
|
|
88
|
+
components?: {
|
|
89
|
+
/** Use div to replace TextArea or re-render TextArea */
|
|
90
|
+
textarea?: ITextAreaProps['renderTextarea'];
|
|
91
|
+
/**
|
|
92
|
+
* Override the default command element
|
|
93
|
+
* _`toolbar`_ < _`command[].render`_
|
|
94
|
+
*/
|
|
95
|
+
toolbar?: ICommand['render'];
|
|
96
|
+
};
|
|
81
97
|
/**
|
|
82
98
|
* Disable editing area code highlighting. The value is `false`, which increases the editing speed.
|
|
83
99
|
* @default true
|
|
@@ -152,6 +168,7 @@ const InternalMDEditor = (
|
|
|
152
168
|
onHeightChange,
|
|
153
169
|
hideToolbar,
|
|
154
170
|
toolbarBottom = false,
|
|
171
|
+
components,
|
|
155
172
|
renderTextarea,
|
|
156
173
|
...other
|
|
157
174
|
} = props || {};
|
|
@@ -164,6 +181,7 @@ const InternalMDEditor = (
|
|
|
164
181
|
let [state, dispatch] = useReducer(reducer, {
|
|
165
182
|
markdown: propsValue,
|
|
166
183
|
preview: previewType,
|
|
184
|
+
components,
|
|
167
185
|
height,
|
|
168
186
|
highlightEnable,
|
|
169
187
|
tabSize,
|
|
@@ -287,7 +305,6 @@ const InternalMDEditor = (
|
|
|
287
305
|
),
|
|
288
306
|
[prefixCls, previewOptions, state.markdown],
|
|
289
307
|
);
|
|
290
|
-
|
|
291
308
|
return (
|
|
292
309
|
<EditorContext.Provider value={{ ...state, dispatch }}>
|
|
293
310
|
<div
|
|
@@ -299,7 +316,7 @@ const InternalMDEditor = (
|
|
|
299
316
|
}}
|
|
300
317
|
style={{
|
|
301
318
|
...other.style,
|
|
302
|
-
height: state.
|
|
319
|
+
height: state.height || '100%',
|
|
303
320
|
}}
|
|
304
321
|
>
|
|
305
322
|
{!hideToolbar && !toolbarBottom && (
|
|
@@ -308,7 +325,7 @@ const InternalMDEditor = (
|
|
|
308
325
|
<div
|
|
309
326
|
className={`${prefixCls}-content`}
|
|
310
327
|
style={{
|
|
311
|
-
height:
|
|
328
|
+
height: `calc(100% - ${toolbarHeight}px)`,
|
|
312
329
|
}}
|
|
313
330
|
>
|
|
314
331
|
{/(edit|live)/.test(state.preview || '') && (
|
|
@@ -323,7 +340,7 @@ const InternalMDEditor = (
|
|
|
323
340
|
textareaProps.onChange(evn);
|
|
324
341
|
}
|
|
325
342
|
}}
|
|
326
|
-
renderTextarea={renderTextarea}
|
|
343
|
+
renderTextarea={components?.textarea || renderTextarea}
|
|
327
344
|
onScroll={(e) => handleScroll(e, 'text')}
|
|
328
345
|
/>
|
|
329
346
|
)}
|
package/src/commands/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { bold } from './bold';
|
|
2
3
|
import { code, codeBlock } from './code';
|
|
3
4
|
import { italic } from './italic';
|
|
@@ -50,6 +51,12 @@ export interface ICommandBase<T> {
|
|
|
50
51
|
position?: 'right';
|
|
51
52
|
liProps?: React.LiHTMLAttributes<HTMLLIElement>;
|
|
52
53
|
buttonProps?: React.ButtonHTMLAttributes<HTMLButtonElement> | null;
|
|
54
|
+
render?: (
|
|
55
|
+
command: ICommand<T>,
|
|
56
|
+
disabled: boolean,
|
|
57
|
+
executeCommand: (command: ICommand<T>, name?: string) => void,
|
|
58
|
+
index: number,
|
|
59
|
+
) => void | undefined | null | React.ReactElement;
|
|
53
60
|
execute?: (
|
|
54
61
|
state: TextState,
|
|
55
62
|
api: TextAreaTextApi,
|
|
@@ -16,7 +16,7 @@ export interface IToolbarProps extends IProps {
|
|
|
16
16
|
|
|
17
17
|
export function ToolbarItems(props: IToolbarProps) {
|
|
18
18
|
const { prefixCls, overflow } = props;
|
|
19
|
-
const { fullscreen, preview, barPopup = {}, commandOrchestrator, dispatch } = useContext(EditorContext);
|
|
19
|
+
const { fullscreen, preview, barPopup = {}, components, commandOrchestrator, dispatch } = useContext(EditorContext);
|
|
20
20
|
const originalOverflow = useRef('');
|
|
21
21
|
|
|
22
22
|
function handleClick(command: ICommand<string>, name?: string) {
|
|
@@ -83,10 +83,16 @@ export function ToolbarItems(props: IToolbarProps) {
|
|
|
83
83
|
})
|
|
84
84
|
: undefined;
|
|
85
85
|
const disabled = barPopup && preview && preview === 'preview' && !/(preview|fullscreen)/.test(item.keyCommand);
|
|
86
|
+
const render = components?.toolbar || item.render;
|
|
87
|
+
const com = (
|
|
88
|
+
render && typeof render === 'function' ? render(item, !!disabled, handleClick, idx) : null
|
|
89
|
+
) as React.ReactElement;
|
|
86
90
|
return (
|
|
87
91
|
<li key={idx} {...item.liProps} className={activeBtn ? `active` : ''}>
|
|
88
|
-
{
|
|
89
|
-
{item.buttonProps &&
|
|
92
|
+
{com && React.isValidElement(com) && com}
|
|
93
|
+
{!com && !item.buttonProps && item.icon}
|
|
94
|
+
{!com &&
|
|
95
|
+
item.buttonProps &&
|
|
90
96
|
React.createElement(
|
|
91
97
|
'button',
|
|
92
98
|
{
|