UNPKG

@atlaskit/editor-plugin-quick-insert

Version:

Quick insert plugin for @atlaskit/editor-core

161 lines (160 loc) 6.31 kB
/* BlockControlQuickInsertButton.tsx generated by @compiled/babel-plugin v3.0.2 */ import "./BlockControlQuickInsertButton.compiled.css"; import { ax, ix } from "@compiled/react/runtime"; import React, { useCallback } from 'react'; import { useIntl } from 'react-intl'; import { ToolTipContent } from '@atlaskit/editor-common/keymaps'; import { blockControlsMessages as messages } from '@atlaskit/editor-common/messages'; import { NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state'; import { findParentNode, findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils'; import { CellSelection } from '@atlaskit/editor-tables/cell-selection'; import AddIcon from '@atlaskit/icon/core/add'; import { Pressable } from '@atlaskit/primitives/compiled'; import Tooltip from '@atlaskit/tooltip/Tooltip'; const TEXT_PARENT_TYPES = ['paragraph', 'heading', 'blockquote', 'taskItem', 'decisionItem']; // @atlaskit/css intentionally restricts height and width values, so Compiled owns only the // dimensions that scale at runtime with the editor's dense-mode font-size custom property. const quickInsertButtonContainerStyles = { root: "_1e0c1txw _4t3i9xsi _1bsb9xsi", reservedDragHandleSpace: "_12l21xcw" }; const quickInsertButtonStyles = { root: "_19itglyw _2rko1rr0 _v564k6bl _1rjcze3t _18zrze3t _4cvr1h6o _bfhksm61 _vchhusvi _syazazsu _80omtlke _1e0c1txw _4t3i1osq _1bah1h6o _1bsb1osq _mizu1v1w _1ah3v77o _ra3xnqa1 _128mdkaa _irr31dpa _1ggl5xtf _1di6fcek" }; const createNewLine = start => ({ tr }) => { var _tr$doc$nodeAt; const nodeSize = (_tr$doc$nodeAt = tr.doc.nodeAt(start)) === null || _tr$doc$nodeAt === void 0 ? void 0 : _tr$doc$nodeAt.nodeSize; if (nodeSize === undefined) { return tr; } const position = start + nodeSize; tr.insert(position, tr.doc.type.schema.nodes.paragraph.create()); return tr.setSelection(TextSelection.near(tr.doc.resolve(position))); }; const isSelectionInNode = (start, view) => { const node = view.state.doc.nodeAt(start); if (!node) { return false; } const { $from, $to } = view.state.selection; return $from.pos >= start && $to.pos <= start + node.nodeSize; }; const isNonEditableBlock = (start, view) => { const node = view.state.doc.nodeAt(start); if (!node) { return false; } if (node.type.name === 'mediaGroup' || node.type.name === 'mediaSingle') { return true; } return node.isBlock && (node.isAtom || node.isLeaf); }; const openQuickInsert = (api, view, start, openTypeAhead) => { const isSelectionInsideNode = isSelectionInNode(start, view); if (!isSelectionInsideNode || isNonEditableBlock(start, view)) { api.core.actions.execute(createNewLine(start)); } const { codeBlock } = view.state.schema.nodes; const { selection } = view.state; const codeBlockParentNode = findParentNodeOfType(codeBlock)(selection); if (codeBlockParentNode) { api.core.actions.execute(createNewLine(codeBlockParentNode.pos)); } else if (isSelectionInsideNode) { const currentSelection = view.state.selection; if ((currentSelection instanceof TextSelection || currentSelection instanceof NodeSelection && currentSelection.node.isInline) && currentSelection.from !== currentSelection.to) { const currentParagraphNode = findParentNode(node => TEXT_PARENT_TYPES.includes(node.type.name))(currentSelection); if (currentParagraphNode) { const newPos = currentSelection.anchor === currentSelection.to ? currentParagraphNode.pos : currentParagraphNode.pos + currentParagraphNode.node.nodeSize - 1; api.core.actions.execute(({ tr }) => { tr.setSelection(TextSelection.create(view.state.selection.$from.doc, newPos)); return tr; }); } } if (currentSelection instanceof NodeSelection && currentSelection.$from.depth > 0) { if (isNonEditableBlock(view.state.selection.from, view)) { api.core.actions.execute(createNewLine(view.state.selection.from)); } else { api.core.actions.execute(({ tr }) => { createNewLine(view.state.selection.from)({ tr }); tr.setSelection(TextSelection.create(tr.doc, view.state.selection.from)); return tr; }); } } if (currentSelection instanceof CellSelection) { const lastInlinePosition = TextSelection.near(view.state.selection.$to, -1); if (lastInlinePosition) { api.core.actions.execute(({ tr }) => { if (!(lastInlinePosition instanceof TextSelection)) { createNewLine(lastInlinePosition.from)({ tr }); tr.setSelection(TextSelection.create(tr.doc, lastInlinePosition.to)); } else { tr.setSelection(lastInlinePosition); } return tr; }); } } } openTypeAhead(); }; export const BlockControlQuickInsertButton = ({ api, openTypeAhead, reserveDragHandleSpace = false, start, view }) => { const { formatMessage } = useIntl(); const label = formatMessage(messages.insert); const handleMouseDown = useCallback(() => { var _api$typeAhead; if ((_api$typeAhead = api.typeAhead) !== null && _api$typeAhead !== void 0 && _api$typeAhead.actions.isOpen(view.state)) { api.typeAhead.actions.close({ insertCurrentQueryAsRawText: false }); } }, [api, view]); const handleClick = useCallback(() => openQuickInsert(api, view, start, openTypeAhead), [api, openTypeAhead, start, view]); return /*#__PURE__*/React.createElement(Tooltip, { position: "top", content: /*#__PURE__*/React.createElement(ToolTipContent, { description: label }) }, /*#__PURE__*/React.createElement("span", { className: ax([quickInsertButtonContainerStyles.root, reserveDragHandleSpace && quickInsertButtonContainerStyles.reservedDragHandleSpace]) }, /*#__PURE__*/React.createElement(Pressable, { "aria-label": label, onClick: handleClick, onMouseDown: handleMouseDown, testId: "editor-quick-insert-button", type: "button", xcss: quickInsertButtonStyles.root }, /*#__PURE__*/React.createElement(AddIcon, { label: "", color: "var(--ds-icon-subtle, #505258)", size: "small" })))); };