@uiw/react-md-editor
Version:
A markdown editor with preview, implemented with React.js and TypeScript.
333 lines (285 loc) • 13.2 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard")["default"];
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _react = _interopRequireWildcard(require("react"));
var _reactMarkdownPreview = _interopRequireDefault(require("@uiw/react-markdown-preview"));
var _TextArea = _interopRequireDefault(require("./components/TextArea"));
var _Toolbar = _interopRequireDefault(require("./components/Toolbar"));
var _DragBar = _interopRequireDefault(require("./components/DragBar"));
var _commands = require("./commands");
var _Context = require("./Context");
var _jsxRuntime = require("react/jsx-runtime");
var _excluded = ["prefixCls", "className", "value", "commands", "commandsFilter", "extraCommands", "height", "enableScroll", "visibleDragbar", "highlightEnable", "preview", "fullscreen", "overflow", "previewOptions", "textareaProps", "maxHeight", "minHeight", "autoFocus", "tabSize", "defaultTabEnable", "onChange", "onHeightChange", "hideToolbar", "toolbarBottom", "components", "renderTextarea"];
function setGroupPopFalse() {
var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
Object.keys(data).forEach(function (keyname) {
data[keyname] = false;
});
return data;
}
var InternalMDEditor = function InternalMDEditor(props, ref) {
var _ref = props || {},
_ref$prefixCls = _ref.prefixCls,
prefixCls = _ref$prefixCls === void 0 ? 'w-md-editor' : _ref$prefixCls,
className = _ref.className,
propsValue = _ref.value,
_ref$commands = _ref.commands,
commands = _ref$commands === void 0 ? (0, _commands.getCommands)() : _ref$commands,
commandsFilter = _ref.commandsFilter,
_ref$extraCommands = _ref.extraCommands,
extraCommands = _ref$extraCommands === void 0 ? (0, _commands.getExtraCommands)() : _ref$extraCommands,
_ref$height = _ref.height,
height = _ref$height === void 0 ? 200 : _ref$height,
_ref$enableScroll = _ref.enableScroll,
enableScroll = _ref$enableScroll === void 0 ? true : _ref$enableScroll,
_ref$visibleDragbar = _ref.visibleDragbar,
visibleDragbar = _ref$visibleDragbar === void 0 ? typeof props.visiableDragbar === 'boolean' ? props.visiableDragbar : true : _ref$visibleDragbar,
_ref$highlightEnable = _ref.highlightEnable,
highlightEnable = _ref$highlightEnable === void 0 ? true : _ref$highlightEnable,
_ref$preview = _ref.preview,
previewType = _ref$preview === void 0 ? 'live' : _ref$preview,
_ref$fullscreen = _ref.fullscreen,
fullscreen = _ref$fullscreen === void 0 ? false : _ref$fullscreen,
_ref$overflow = _ref.overflow,
overflow = _ref$overflow === void 0 ? true : _ref$overflow,
_ref$previewOptions = _ref.previewOptions,
previewOptions = _ref$previewOptions === void 0 ? {} : _ref$previewOptions,
textareaProps = _ref.textareaProps,
_ref$maxHeight = _ref.maxHeight,
maxHeight = _ref$maxHeight === void 0 ? 1200 : _ref$maxHeight,
_ref$minHeight = _ref.minHeight,
minHeight = _ref$minHeight === void 0 ? 100 : _ref$minHeight,
autoFocus = _ref.autoFocus,
_ref$tabSize = _ref.tabSize,
tabSize = _ref$tabSize === void 0 ? 2 : _ref$tabSize,
_ref$defaultTabEnable = _ref.defaultTabEnable,
defaultTabEnable = _ref$defaultTabEnable === void 0 ? false : _ref$defaultTabEnable,
_onChange = _ref.onChange,
onHeightChange = _ref.onHeightChange,
hideToolbar = _ref.hideToolbar,
_ref$toolbarBottom = _ref.toolbarBottom,
toolbarBottom = _ref$toolbarBottom === void 0 ? false : _ref$toolbarBottom,
components = _ref.components,
renderTextarea = _ref.renderTextarea,
other = (0, _objectWithoutProperties2["default"])(_ref, _excluded);
var cmds = commands.map(function (item) {
return commandsFilter ? commandsFilter(item, false) : item;
}).filter(Boolean);
var extraCmds = extraCommands.map(function (item) {
return commandsFilter ? commandsFilter(item, true) : item;
}).filter(Boolean);
var _useReducer = (0, _react.useReducer)(_Context.reducer, {
markdown: propsValue,
preview: previewType,
components: components,
height: height,
highlightEnable: highlightEnable,
tabSize: tabSize,
defaultTabEnable: defaultTabEnable,
scrollTop: 0,
scrollTopPreview: 0,
commands: cmds,
extraCommands: extraCmds,
fullscreen: fullscreen,
barPopup: {}
}),
_useReducer2 = (0, _slicedToArray2["default"])(_useReducer, 2),
state = _useReducer2[0],
dispatch = _useReducer2[1];
var container = (0, _react.useRef)(null);
var previewRef = (0, _react.useRef)(null);
var enableScrollRef = (0, _react.useRef)(enableScroll);
(0, _react.useImperativeHandle)(ref, function () {
return (0, _objectSpread2["default"])({}, state);
});
(0, _react.useMemo)(function () {
return enableScrollRef.current = enableScroll;
}, [enableScroll]);
(0, _react.useEffect)(function () {
var stateInit = {};
if (container.current) {
stateInit.container = container.current || undefined;
}
stateInit.markdown = propsValue || '';
stateInit.barPopup = {};
if (dispatch) {
dispatch((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, state), stateInit));
} // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
var cls = [className, 'wmde-markdown-var', prefixCls, state.preview ? "".concat(prefixCls, "-show-").concat(state.preview) : null, state.fullscreen ? "".concat(prefixCls, "-fullscreen") : null].filter(Boolean).join(' ').trim();
(0, _react.useMemo)(function () {
return propsValue !== state.markdown && dispatch({
markdown: propsValue || ''
});
}, [propsValue, state.markdown]); // eslint-disable-next-line react-hooks/exhaustive-deps
(0, _react.useMemo)(function () {
return previewType !== state.preview && dispatch({
preview: previewType
});
}, [previewType]); // eslint-disable-next-line react-hooks/exhaustive-deps
(0, _react.useMemo)(function () {
return tabSize !== state.tabSize && dispatch({
tabSize: tabSize
});
}, [tabSize]);
(0, _react.useMemo)(function () {
return highlightEnable !== state.highlightEnable && dispatch({
highlightEnable: highlightEnable
});
}, // eslint-disable-next-line react-hooks/exhaustive-deps
[highlightEnable]); // eslint-disable-next-line react-hooks/exhaustive-deps
(0, _react.useMemo)(function () {
return autoFocus !== state.autoFocus && dispatch({
autoFocus: autoFocus
});
}, [autoFocus]);
(0, _react.useMemo)(function () {
return fullscreen !== state.fullscreen && dispatch({
fullscreen: fullscreen
});
}, // eslint-disable-next-line react-hooks/exhaustive-deps
[fullscreen]); // eslint-disable-next-line react-hooks/exhaustive-deps
(0, _react.useMemo)(function () {
return height !== state.height && dispatch({
height: height
});
}, [height]);
(0, _react.useMemo)(function () {
return height !== state.height && onHeightChange && onHeightChange(state.height, height, state);
}, [height, onHeightChange, state]);
var textareaDomRef = (0, _react.useRef)();
var active = (0, _react.useRef)('preview');
var initScroll = (0, _react.useRef)(false);
(0, _react.useMemo)(function () {
textareaDomRef.current = state.textareaWarp;
if (state.textareaWarp) {
state.textareaWarp.addEventListener('mouseover', function () {
active.current = 'text';
});
state.textareaWarp.addEventListener('mouseleave', function () {
active.current = 'preview';
});
}
}, [state.textareaWarp]);
var handleScroll = function handleScroll(e, type) {
if (!enableScrollRef.current) return;
var textareaDom = textareaDomRef.current;
var previewDom = previewRef.current ? previewRef.current : undefined;
if (!initScroll.current) {
active.current = type;
initScroll.current = true;
}
if (textareaDom && previewDom) {
var scale = (textareaDom.scrollHeight - textareaDom.offsetHeight) / (previewDom.scrollHeight - previewDom.offsetHeight);
if (e.target === textareaDom && active.current === 'text') {
previewDom.scrollTop = textareaDom.scrollTop / scale;
}
if (e.target === previewDom && active.current === 'preview') {
textareaDom.scrollTop = previewDom.scrollTop * scale;
}
var scrollTop = 0;
if (active.current === 'text') {
scrollTop = textareaDom.scrollTop || 0;
} else if (active.current === 'preview') {
scrollTop = previewDom.scrollTop || 0;
}
dispatch({
scrollTop: scrollTop
});
}
};
var previewClassName = "".concat(prefixCls, "-preview ").concat(previewOptions.className || '');
var handlePreviewScroll = function handlePreviewScroll(e) {
return handleScroll(e, 'preview');
};
var mdPreview = (0, _react.useMemo)(function () {
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
ref: previewRef,
className: previewClassName,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactMarkdownPreview["default"], (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, previewOptions), {}, {
onScroll: handlePreviewScroll,
source: state.markdown || ''
}))
});
}, [previewClassName, previewOptions, state.markdown]);
var preview = (components === null || components === void 0 ? void 0 : components.preview) && (components === null || components === void 0 ? void 0 : components.preview(state.markdown || '', state, dispatch));
if (preview && /*#__PURE__*/_react["default"].isValidElement(preview)) {
mdPreview = /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
className: previewClassName,
ref: previewRef,
onScroll: handlePreviewScroll,
children: preview
});
}
var containerStyle = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, other.style), {}, {
height: state.height || '100%'
});
var containerClick = function containerClick() {
return dispatch({
barPopup: (0, _objectSpread2["default"])({}, setGroupPopFalse(state.barPopup))
});
};
var dragBarChange = function dragBarChange(newHeight) {
return dispatch({
height: newHeight
});
};
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Context.EditorContext.Provider, {
value: (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, state), {}, {
dispatch: dispatch
}),
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
ref: container,
className: cls
}, other), {}, {
onClick: containerClick,
style: containerStyle,
children: [!hideToolbar && !toolbarBottom && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbar["default"], {
prefixCls: prefixCls,
overflow: overflow,
toolbarBottom: toolbarBottom
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
className: "".concat(prefixCls, "-content"),
children: [/(edit|live)/.test(state.preview || '') && /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextArea["default"], (0, _objectSpread2["default"])((0, _objectSpread2["default"])({
className: "".concat(prefixCls, "-input"),
prefixCls: prefixCls,
autoFocus: autoFocus
}, textareaProps), {}, {
onChange: function onChange(evn) {
_onChange && _onChange(evn.target.value, evn, state);
if (textareaProps && textareaProps.onChange) {
textareaProps.onChange(evn);
}
},
renderTextarea: (components === null || components === void 0 ? void 0 : components.textarea) || renderTextarea,
onScroll: function onScroll(e) {
return handleScroll(e, 'text');
}
})), /(live|preview)/.test(state.preview || '') && mdPreview]
}), visibleDragbar && !state.fullscreen && /*#__PURE__*/(0, _jsxRuntime.jsx)(_DragBar["default"], {
prefixCls: prefixCls,
height: state.height,
maxHeight: maxHeight,
minHeight: minHeight,
onChange: dragBarChange
}), !hideToolbar && toolbarBottom && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Toolbar["default"], {
prefixCls: prefixCls,
overflow: overflow,
toolbarBottom: toolbarBottom
})]
}))
});
};
var mdEditor = /*#__PURE__*/_react["default"].forwardRef(InternalMDEditor);
mdEditor.Markdown = _reactMarkdownPreview["default"];
var _default = mdEditor;
exports["default"] = _default;
module.exports = exports.default;
//# sourceMappingURL=Editor.js.map