UNPKG

react-kityminder

Version:

Mind map for react, based on kityminder.

491 lines (420 loc) 13.3 kB
import 'kity'; import 'kityminder-core'; import { useEffect, useState, createElement, useRef, useMemo, useCallback, forwardRef } from 'react'; function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function useValue(minder, value) { useEffect(function () { if (minder) { // const animationOptionName = 'layoutAnimationDuration' // const animationDuration = minder.getOption(animationOptionName) // if (animationDuration) { // minder.setOption(animationOptionName, 0) // } minder.importJson(value); // if (animationDuration) { // minder.setOption(animationOptionName, animationDuration) // } } }, [minder, value]); } var eventHandlerPrefixRE = /^on(\w+)$/; var getEventName = function getEventName(propName) { var name = eventHandlerPrefixRE.exec(propName); return name && name[1].toLowerCase(); }; var forEachHandler = function forEachHandler(minder, props, cb) { if (minder) { Object.keys(props).forEach(function (propName) { var eventName = getEventName(propName); if (eventName && handlerPropKeys.indexOf(eventName) >= 0) { cb(eventName, propName); } }); } }; var eventNames = ('click,dblclick,mousedown,mousemove,mouseup,mousewheel,keydown,keyup,keypress,touchstart,touchend,touchmove,' + 'execcommand,' + 'selectionchange,contentchange,interactchange,' + 'editnoterequest,shownoterequest,hidenoterequest,' + 'nodechange,editnode').split(','); var handlerPropKeys = []; eventNames.map(function (eventName) { handlerPropKeys = handlerPropKeys.concat([eventName, "before" + eventName, "pre" + eventName, "after" + eventName]); }); // 数据 function useEvents(minder, props) { // 事件监听 useEffect(function () { var handlers = {}; forEachHandler(minder, props, function (eventName, propName) { handlers[eventName] = props[propName]; minder.on(eventName, props[propName]); }); return function () { forEachHandler(minder, props, function (eventName) { minder.off(eventName, handlers[eventName]); }); }; }, [minder].concat(handlerPropKeys.map(function (handlerProp) { return props[handlerProp]; }))); } function useChangeHandler(minder, onChange) { useEffect(function () { var changeHandler = function changeHandler(e) { return onChange(e.minder.exportJson()); }; if (minder && onChange) { minder.on('contentchange', changeHandler); } return function () { if (minder && onChange) { minder.off('contentchange', changeHandler); } }; }, [minder, onChange]); } function getKeyCode(evt) { return evt.keyCode || evt.witch; } function Editor(props) { var _useState = useState(props.initialValue), value = _useState[0], setValue = _useState[1]; var onKeydown = function onKeydown(evt) { evt.stopPropagation(); var KeyMap = window.kityminder.KeyMap; var keyCode = getKeyCode(evt); if (keyCode === KeyMap.enter) { props.onSubmit(); } if (keyCode === KeyMap.esc) { props.onCancel(); } }; var onChange = function onChange(_ref) { var value = _ref.target.value; setValue(value); props.onChange(value); }; return /*#__PURE__*/createElement("input", { value: value, onChange: onChange, onKeyDown: onKeydown, onBlur: props.onSubmit }); } function isInputValue(e) { var keyCode = getKeyCode(e); // a-zA-Z if (keyCode >= 65 && keyCode <= 90) return true; // 0-9 以及其上面的符号 if (keyCode >= 48 && keyCode <= 57) return true; // 小键盘区域 (除回车外) if (keyCode !== 108 && keyCode >= 96 && keyCode <= 111) return true; return false; } function isIntendToInput(e) { var keyCode = getKeyCode(e); if (e.ctrlKey || e.metaKey || e.altKey) return false; if (isInputValue(e)) return true; // 输入法 if (keyCode === 229 || keyCode === 0) return true; return false; } function EditorWrapper(minder, props) { var valueRef = useRef(); var editingNodeRef = useRef(); var editorRef = useRef(); var _useState = useState(), initialValue = _useState[0], setInitialValue = _useState[1]; var _useState2 = useState(), editingNode = _useState2[0], setEditingNode = _useState2[1]; var Editor = props.Editor, onEdit = props.onEdit, onEditEnd = props.onEditEnd; var setEditorValue = function setEditorValue(v) { valueRef.current = v; }; var setEditorEditingNode = function setEditorEditingNode(v) { editingNodeRef.current = v; setEditingNode(v); }; var exitEdit = function exitEdit() { setEditorEditingNode(); minder.focus(); }; var onSubmit = function onSubmit() { var _ref = editingNodeRef.current || {}, node = _ref.node; if (node && (!onEditEnd || onEditEnd && onEditEnd.apply(void 0, [].slice.call(arguments)) !== false)) { node.setText(valueRef.current); minder.select(node, true); minder.fire('nodechange', { node: node }); minder.fire('contentchange'); minder.getRoot().renderTree(); minder.layout(300); } exitEdit(); }; useEffect(function () { var edit = function edit(e) { if (onEdit && onEdit(e) !== false || !onEdit) { var node = minder.getSelectedNode(); if (node) { var box = node.getRenderer('OutlineRenderer').getRenderShape().getRenderBox('view'); var _node$data$text = node.data.text, text = _node$data$text === void 0 ? '' : _node$data$text; var _editingNode = { node: node, box: box }; if (box.x > 0 || box.y > 0) { var value = text; if (props.appendKey) { value += isInputValue(e.originEvent) ? e.originEvent.key : ''; } setEditorEditingNode(_editingNode); setInitialValue(value); setEditorValue(value); } } } }; var editNodeName = 'editnode'; var editNodeHandler = edit; var dblclickName = 'dblclick'; var dblclickHandler = edit; var keydownName = 'keydown'; var keydownHandler = function keydownHandler(e) { if (isIntendToInput(e.originEvent) && minder.getSelectedNode()) { edit(e); } }; if (minder) { minder.on(editNodeName, editNodeHandler); minder.on(dblclickName, dblclickHandler); minder.on(keydownName, keydownHandler); } return function () { if (minder) { minder.off(editNodeName, editNodeHandler); minder.off(dblclickName, dblclickHandler); minder.off(keydownName, keydownHandler); } }; }, [minder, onEdit]); useEffect(function () { var escHandler = function escHandler(evt) { var keyCode = getKeyCode(evt); if (keyCode === window.kityminder.KeyMap.esc) { exitEdit(); } }; document.addEventListener('keydown', escHandler); return function () { document.removeEventListener('keydown', escHandler); }; }, [minder]); useEffect(function () { if (minder && editingNode && editorRef.current) { var inputEl; for (var _i = 0, _arr = ['input', 'textarea', 'select']; _i < _arr.length; _i++) { var type = _arr[_i]; inputEl = editorRef.current.querySelector(type); if (inputEl) { inputEl.focus(); break; } } } }, [minder, Editor, initialValue, editingNode]); return useMemo(function () { return function (props) { return editingNode ? /*#__PURE__*/createElement("div", { style: { position: 'absolute', top: 0, bottom: 0, left: 0, right: 0 }, onClick: onSubmit }, /*#__PURE__*/createElement("div", { ref: editorRef, style: { position: 'absolute', top: editingNode.box.y + editingNode.box.height / 2 + "px", left: editingNode.box.x + "px", transform: 'translateY(-50%)' }, onClick: function onClick(e) { return e.stopPropagation(); } }, /*#__PURE__*/createElement(Editor, _extends({}, props, { minder: minder, initialValue: initialValue, onSubmit: onSubmit, onChange: setEditorValue, onCancel: exitEdit })))) : null; }; }, [minder, Editor, initialValue, editingNode]); } function Note(props) { return /*#__PURE__*/createElement("div", { style: { background: '#fff', height: '100%' } }, props.node.data.note); } function NoteWrapper(minder, props) { var _useState = useState(), showingNode = _useState[0], setShowingNode = _useState[1]; var Note = props.Note; var showNote = useCallback(function (_ref) { var node = _ref.node; if (node) { var box = node.getRenderer('OutlineRenderer').getRenderShape().getRenderBox('view'); var editingNode = { node: node, box: box }; if (box.x > 0 || box.y > 0) { setShowingNode(editingNode); } } }, []); var hideNote = useCallback(function () { setShowingNode(); }, []); useEffect(function () { var showNodeName = 'shownoterequest'; var mousewheel = 'mousewheel'; if (minder) { minder.on(showNodeName, showNote); minder.on(mousewheel, hideNote); document.addEventListener(mousewheel, hideNote); } return function () { if (minder) { minder.off(showNodeName, showNote); minder.off(mousewheel, hideNote); document.removeEventListener(mousewheel, hideNote); } }; }, [minder]); return useMemo(function () { return function (props) { return showingNode ? /*#__PURE__*/createElement("div", { style: { position: 'absolute', top: showingNode.box.y + showingNode.box.height / 2 + "px", left: showingNode.box.x + "px", width: showingNode.box.width + "px", height: showingNode.box.height + "px", transform: 'translateY(-50%)' }, onMouseOut: hideNote }, /*#__PURE__*/createElement(Note, _extends({}, props, { node: showingNode.node }))) : null; }; }, [minder, Note, showingNode]); } var domPropNames = ['id', 'className', 'style', 'title', 'tabIndex']; var Kityminder = /*#__PURE__*/forwardRef(function Kityminder(props, ref) { var minderRef = useRef(); var minder = minderRef.current; var domProps = {}; Object.keys(props).forEach(function (propKey) { if (domPropNames.indexOf(propKey) >= 0) { domProps[propKey] = props[propKey]; } }); if (!minder) { minder = minderRef.current = new window.kityminder.Minder(props); if (props.onMinderChange) { setTimeout(function () { // fix warning: Cannot update a component while rendering a different component. props.onMinderChange(minder); }, 0); } if (ref) { ref.current = minder; } } useValue(minder, props.value); useEvents(minder, props); useChangeHandler(minder, props.onChange); var EditorComponent = EditorWrapper(minder, Object.assign({ Editor: Editor }, props)); var NoteComponent = NoteWrapper(minder, Object.assign({ Note: Note }, props)); return /*#__PURE__*/createElement("div", _extends({}, domProps, { style: _extends({ position: 'relative', width: '100%', height: '400px' }, domProps.style) }), useMemo(function () { return /*#__PURE__*/createElement("div", { ref: function ref(div) { if (div) { minder.renderTo(div); var receiver = div.querySelector('.km-receiver'); if (receiver) { Object.assign(receiver.style, { position: 'absolute', left: '-99999px', top: '-99999px' }); } } }, style: { position: 'absolute', top: 0, bottom: 0, left: 0, right: 0 } }); }, [minder]), /*#__PURE__*/createElement(EditorComponent, props), /*#__PURE__*/createElement(NoteComponent, props)); }); function extendsKityminder(kityminder) { // fix: detached node getMinder() returns undefined kityminder.Minder.prototype.attachNode = function (node) { var _this = this; var rc = _this.getRenderContainer(); node.traverse(function (current) { current.attached = true; current.minder = _this; rc.addShape(current.getRenderContainer()); }); rc.addShape(node.getRenderContainer()); _this.fire('nodeattach', { node: node }); }; kityminder.Node.prototype.getMinder = function () { return this.getRoot().minder || this.minder; }; } var kity = window.kity; var kityminder = window.kityminder; extendsKityminder(kityminder); export default Kityminder; export { Kityminder, kity, kityminder }; //# sourceMappingURL=react-kityminder.esm.js.map