UNPKG

@uiw/react-md-editor

Version:

A markdown editor with preview, implemented with React.js and TypeScript.

245 lines (213 loc) 9.2 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; import React, { Fragment, useMemo, useRef, useState } from 'react'; import classnames from 'classnames'; import MarkdownPreview from '@uiw/react-markdown-preview'; import TextArea from './components/TextArea'; import Toolbar from './components/Toolbar'; import DragBar from './components/DragBar'; import { getCommands, TextAreaCommandOrchestrator } from './commands'; import "./index.css"; function setGroupPopFalse(data) { Object.keys(data).forEach(function (keyname) { data[keyname] = false; }); return data; } var InternalMDEditor = function InternalMDEditor(props, ref) { var _classnames; 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 ? getCommands() : _ref$commands, _ref$height = _ref.height, heightWarp = _ref$height === void 0 ? 200 : _ref$height, _ref$visiableDragbar = _ref.visiableDragbar, visiableDragbar = _ref$visiableDragbar === void 0 ? true : _ref$visiableDragbar, _ref$preview = _ref.preview, previewType = _ref$preview === void 0 ? 'live' : _ref$preview, isfullscreen = _ref.fullscreen, previewOptions = _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, onChange = _ref.onChange, hideToolbar = _ref.hideToolbar, other = _objectWithoutProperties(_ref, ["prefixCls", "className", "value", "commands", "height", "visiableDragbar", "preview", "fullscreen", "previewOptions", "textareaProps", "maxHeight", "minHeight", "autoFocus", "tabSize", "onChange", "hideToolbar"]); var _useState = useState(propsValue || ''), _useState2 = _slicedToArray(_useState, 2), value = _useState2[0], setValue = _useState2[1]; var _useState3 = useState(previewType), _useState4 = _slicedToArray(_useState3, 2), preview = _useState4[0], setPreview = _useState4[1]; var _useState5 = useState(isfullscreen || false), _useState6 = _slicedToArray(_useState5, 2), isFullscreen = _useState6[0], setIsFullscreen = _useState6[1]; var _useState7 = useState({}), _useState8 = _slicedToArray(_useState7, 2), groupPop = _useState8[0], setGroupPop = _useState8[1]; var leftScroll = useRef(false); var previewRef = /*#__PURE__*/React.createRef(); var _useState9 = useState(heightWarp), _useState10 = _slicedToArray(_useState9, 2), height = _useState10[0], setHeight = _useState10[1]; var textarea = /*#__PURE__*/React.createRef(); var commandOrchestrator = useRef(); var selectionRange = useRef({ count: 0, scrollTop: 0 }); var cls = classnames(className, prefixCls, (_classnames = {}, _defineProperty(_classnames, "".concat(prefixCls, "-show-").concat(preview), preview), _defineProperty(_classnames, "".concat(prefixCls, "-fullscreen"), isFullscreen), _classnames)); var commandOrchestratorHandle = function commandOrchestratorHandle() { if (textarea.current && textarea.current.text) { commandOrchestrator.current = new TextAreaCommandOrchestrator(textarea.current.text || null); } return commandOrchestrator.current; }; useMemo(function () { return preview !== props.preview && props.preview && setPreview(props.preview); }, [props.preview]); useMemo(function () { return value !== props.value && setValue(props.value); }, [props.value]); useMemo(function () { return height !== props.height && setHeight(heightWarp); }, [heightWarp]); function handleTextAreaMount(isMount) { if (textarea.current && textarea.current.text && textarea.current.warp && isMount) { if (autoFocus) { textarea.current.text.blur(); textarea.current.text.focus(); } textarea.current.text.selectionStart = selectionRange.current.count; textarea.current.text.selectionEnd = selectionRange.current.count; textarea.current.warp.scrollTo(0, selectionRange.current.scrollTop); } } function modifySelectionRange() { if (textarea.current && textarea.current.text && textarea.current.warp) { selectionRange.current.count = textarea.current.text.selectionStart; selectionRange.current.scrollTop = textarea.current.warp.scrollTop; } } function handleChange(event) { modifySelectionRange(); setValue(event.target.value); onChange && onChange(event.target.value || ''); } function handleCommand(command, groupName) { commandOrchestratorHandle(); modifySelectionRange(); if (command.keyCommand === 'preview') { setPreview(command.value); } if (command.keyCommand === 'fullscreen') { setIsFullscreen(!isFullscreen); document.body.style.overflow = isFullscreen ? 'initial' : 'hidden'; } if (command.keyCommand === 'group') { setGroupPop(_objectSpread(_objectSpread({}, setGroupPopFalse(groupPop)), {}, _defineProperty({}, "".concat(groupName), true))); } if (groupName && command.keyCommand !== 'group') { setGroupPop(_objectSpread(_objectSpread({}, groupPop), {}, _defineProperty({}, "".concat(groupName), false))); } commandOrchestrator.current && commandOrchestrator.current.executeCommand(command); } function handleScroll(e) { if (!textarea.current || !previewRef.current || !previewRef.current.mdp.current || !textarea.current.warp) { return; } var previewDom = previewRef.current.mdp.current; var textareaDom = textarea.current.warp; if (textareaDom && previewDom) { var scale = (textareaDom.scrollHeight - textareaDom.offsetHeight) / (previewDom.scrollHeight - previewDom.offsetHeight); if (e.target === textareaDom && leftScroll.current) { previewDom.scrollTop = textareaDom.scrollTop / scale; } if (e.target === previewDom && !leftScroll.current) { textareaDom.scrollTop = previewDom.scrollTop * scale; } } } var chestratorObj = useMemo(function () { return commandOrchestratorHandle(); }, [textarea.current, commandOrchestrator.current]); var mdProps = _objectSpread(_objectSpread({}, previewOptions), {}, { ref: previewRef, onScroll: handleScroll, source: value || '' }); return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", _extends({ className: cls, onClick: function onClick() { return setGroupPop(_objectSpread({}, setGroupPopFalse(groupPop))); }, style: { height: isFullscreen ? '100%' : hideToolbar ? Number(height) - 29 : height } }, other), !hideToolbar && /*#__PURE__*/React.createElement(Toolbar, { active: _objectSpread({ fullscreen: isFullscreen, preview: preview }, groupPop), prefixCls: prefixCls, commands: commands, commandHelp: _objectSpread({ getState: commandOrchestrator.current && commandOrchestrator.current.getState, textApi: commandOrchestrator.current && commandOrchestrator.current.textApi }, chestratorObj), onCommand: handleCommand }), /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-content"), style: { height: isFullscreen ? 'calc(100% - 29px)' : Number(height) - 29 } }, /(edit|live)/.test(preview) && /*#__PURE__*/React.createElement(TextArea, _extends({ ref: textarea, tabSize: tabSize, className: "".concat(prefixCls, "-input"), prefixCls: prefixCls, value: value || '', autoFocus: autoFocus }, textareaProps, { onScroll: handleScroll, onMouseOver: function onMouseOver() { return leftScroll.current = true; }, onMouseLeave: function onMouseLeave() { return leftScroll.current = false; }, onMount: handleTextAreaMount, onChange: handleChange })), /(live|preview)/.test(preview) && /*#__PURE__*/React.createElement(MarkdownPreview, _extends({}, mdProps, { className: "".concat(prefixCls, "-preview") }))), visiableDragbar && !isFullscreen && /*#__PURE__*/React.createElement(DragBar, { prefixCls: prefixCls, height: height, maxHeight: maxHeight, minHeight: minHeight, onChange: function onChange(newHeight) { setHeight(newHeight); } }))); }; var MDEditor = /*#__PURE__*/React.forwardRef(InternalMDEditor); MDEditor.Markdown = MarkdownPreview; export default MDEditor; //# sourceMappingURL=Editor.js.map