@milkdown/plugin-tooltip 6.5.2 → 6.5.3
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/lib/button-manager/calc-button-pos.d.ts +1 -1
- package/lib/button-manager/calc-button-pos.d.ts.map +1 -1
- package/lib/button-manager/create-tooltip.d.ts +2 -2
- package/lib/button-manager/create-tooltip.d.ts.map +1 -1
- package/lib/button-manager/filter-button.d.ts +2 -2
- package/lib/button-manager/filter-button.d.ts.map +1 -1
- package/lib/button-manager/index.d.ts.map +1 -1
- package/lib/button-manager/no-active.d.ts +2 -2
- package/lib/button-manager/no-active.d.ts.map +1 -1
- package/lib/button-manager/style.d.ts +1 -1
- package/lib/button-manager/style.d.ts.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.es.js.map +1 -1
- package/lib/item.d.ts +13 -13
- package/lib/item.d.ts.map +1 -1
- package/lib/selection-marks-tooltip.d.ts +2 -2
- package/lib/selection-marks-tooltip.d.ts.map +1 -1
- package/lib/utility/element.d.ts.map +1 -1
- package/lib/utility/index.d.ts.map +1 -1
- package/lib/utility/prosemirror.d.ts +4 -4
- package/lib/utility/prosemirror.d.ts.map +1 -1
- package/package.json +15 -15
- package/src/button-manager/calc-button-pos.ts +23 -23
- package/src/button-manager/create-tooltip.ts +25 -26
- package/src/button-manager/filter-button.ts +21 -21
- package/src/button-manager/index.ts +40 -39
- package/src/button-manager/no-active.ts +6 -6
- package/src/button-manager/style.ts +7 -6
- package/src/index.ts +38 -37
- package/src/item.ts +53 -52
- package/src/selection-marks-tooltip.ts +46 -45
- package/src/utility/element.ts +1 -1
- package/src/utility/index.ts +2 -2
- package/src/utility/prosemirror.ts +27 -25
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calc-button-pos.d.ts","sourceRoot":"","sources":["../../src/button-manager/calc-button-pos.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"calc-button-pos.d.ts","sourceRoot":"","sources":["../../src/button-manager/calc-button-pos.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,eAAO,MAAM,aAAa,YAAa,WAAW,QAAQ,UAAU,YAAY,OAAO,SAuBtF,CAAA"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { EditorView } from '@milkdown/prose/view';
|
|
2
2
|
import type { ThemeUtils } from '@milkdown/utils';
|
|
3
3
|
import type { ButtonList } from '../item';
|
|
4
|
-
|
|
4
|
+
interface Tooltip {
|
|
5
5
|
dom: HTMLDivElement;
|
|
6
6
|
render: (editorView: EditorView) => void;
|
|
7
|
-
}
|
|
7
|
+
}
|
|
8
8
|
export declare const createTooltip: (buttonMap: ButtonList, utils: ThemeUtils, className: string) => Tooltip;
|
|
9
9
|
export {};
|
|
10
10
|
//# sourceMappingURL=create-tooltip.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-tooltip.d.ts","sourceRoot":"","sources":["../../src/button-manager/create-tooltip.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"create-tooltip.d.ts","sourceRoot":"","sources":["../../src/button-manager/create-tooltip.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAGzC,UAAU,OAAO;IACf,GAAG,EAAE,cAAc,CAAA;IACnB,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAA;CACzC;AAED,eAAO,MAAM,aAAa,iCAAkC,UAAU,aAAa,MAAM,KAAG,OAoB3F,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EditorView } from '@milkdown/prose/view';
|
|
2
|
-
import { ButtonList } from '../item';
|
|
1
|
+
import type { EditorView } from '@milkdown/prose/view';
|
|
2
|
+
import type { ButtonList } from '../item';
|
|
3
3
|
export declare const filterButton: (buttons: ButtonList, view: EditorView) => boolean;
|
|
4
4
|
//# sourceMappingURL=filter-button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-button.d.ts","sourceRoot":"","sources":["../../src/button-manager/filter-button.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"filter-button.d.ts","sourceRoot":"","sources":["../../src/button-manager/filter-button.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAGzC,eAAO,MAAM,YAAY,8BAA+B,UAAU,YAqBjE,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/button-manager/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/button-manager/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAKzC,eAAO,MAAM,mBAAmB,+BAEvB,UAAU,UACT,OAAO,sBACK,MAAM;;;yBA0BH,UAAU;;CAUlC,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EditorView } from '@milkdown/prose/view';
|
|
2
|
-
import { ButtonList } from '../item';
|
|
1
|
+
import type { EditorView } from '@milkdown/prose/view';
|
|
2
|
+
import type { ButtonList } from '../item';
|
|
3
3
|
export declare const noActive: (buttonMap: ButtonList, view: EditorView) => boolean;
|
|
4
4
|
//# sourceMappingURL=no-active.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-active.d.ts","sourceRoot":"","sources":["../../src/button-manager/no-active.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,
|
|
1
|
+
{"version":3,"file":"no-active.d.ts","sourceRoot":"","sources":["../../src/button-manager/no-active.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,eAAO,MAAM,QAAQ,gCAAiC,UAAU,YAI/D,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/button-manager/style.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,OAAO,
|
|
1
|
+
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/button-manager/style.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAS,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAGlE,eAAO,MAAM,WAAW,iBAAkB,YAAY,WAAW,OAAO,WA8CvE,CAAA"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PluginKey } from '@milkdown/prose/state';
|
|
2
2
|
import { AtomList } from '@milkdown/utils';
|
|
3
|
-
import { TooltipOptions } from './item';
|
|
3
|
+
import type { TooltipOptions } from './item';
|
|
4
4
|
export declare const key: PluginKey<any>;
|
|
5
5
|
export * from './item';
|
|
6
6
|
export declare const tooltipPlugin: import("@milkdown/utils").WithExtend<string, TooltipOptions, import("@milkdown/utils").TypeMapping<string, string>, import("@milkdown/utils").PluginRest<string, string>>;
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,SAAS,EAAE,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,QAAQ,EAA0B,MAAM,iBAAiB,CAAA;AAElE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAI5C,eAAO,MAAM,GAAG,gBAAoC,CAAA;AACpD,cAAc,QAAQ,CAAA;AAEtB,eAAO,MAAM,aAAa,2KA+BxB,CAAA;AAEF,eAAO,MAAM,OAAO,qJAAqC,CAAA"}
|
package/lib/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../src/utility/prosemirror.ts","../src/item.ts","../src/button-manager/calc-button-pos.ts","../src/button-manager/style.ts","../src/button-manager/create-tooltip.ts","../src/button-manager/no-active.ts","../src/button-manager/filter-button.ts","../src/button-manager/index.ts","../src/selection-marks-tooltip.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { findParentNode } from '@milkdown/prose';\nimport { MarkType, Node, NodeType } from '@milkdown/prose/model';\nimport { EditorState, TextSelection } from '@milkdown/prose/state';\n\nexport type Position = {\n start: number;\n end: number;\n};\n\nexport const hasMark = (editorState: EditorState, type?: MarkType): boolean => {\n if (!type) {\n return false;\n }\n const { from, to } = editorState.selection;\n\n return editorState.doc.rangeHasMark(from, from === to ? to + 1 : to, type);\n};\n\nexport const isTextSelection = (editorState: EditorState): boolean => {\n const { selection } = editorState;\n if (selection instanceof TextSelection) {\n const text = editorState.doc.textBetween(selection.from, selection.to);\n\n if (!text) return false;\n\n return true;\n }\n return false;\n};\n\nexport const isInCodeFence = (editorState: EditorState): boolean =>\n Boolean(findParentNode((node) => !!node.type.spec.code)(editorState.selection));\n\nexport const isTextAndNotHasMark = (editorState: EditorState, mark?: MarkType): boolean =>\n !isTextSelection(editorState) || isInCodeFence(editorState) || hasMark(editorState, mark);\n\nexport const equalNodeType = (nodeType: NodeType, node: Node) => {\n return (Array.isArray(nodeType) && nodeType.indexOf(node.type) > -1) || node.type === nodeType;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { commandsCtx, Ctx, schemaCtx, ThemeIcon, themeManagerCtx } from '@milkdown/core';\nimport type { Icon } from '@milkdown/design-system';\nimport type { MarkType } from '@milkdown/prose/model';\nimport { EditorView } from '@milkdown/prose/view';\n\nimport { hasMark, isTextAndNotHasMark } from './utility';\n\nexport type Pred = (view: EditorView) => boolean;\nexport type Updater = (view: EditorView, $: HTMLElement) => void;\nexport type Event2Command = (e: Event) => void;\n\nexport type OnClick = (ctx: Ctx) => void;\n\nexport type Item = {\n icon: Icon | ((ctx: Ctx) => HTMLElement);\n onClick: string | ((ctx: Ctx) => () => void);\n isHidden: (ctx: Ctx) => Pred;\n isActive: (ctx: Ctx) => Pred;\n canAddToDOM: (ctx: Ctx) => Pred;\n};\n\nexport type ButtonItem = {\n $: HTMLElement;\n command: () => void;\n active: Pred;\n disable?: Pred;\n enable: Pred;\n};\n\nexport const createToggleIcon = (icon: Icon, onClick: string, mark?: MarkType, disableForMark?: MarkType): Item => ({\n icon,\n onClick,\n isHidden: () => (view: EditorView) => isTextAndNotHasMark(view.state, disableForMark),\n isActive: () => (view: EditorView) => hasMark(view.state, mark),\n canAddToDOM: () => (view: EditorView) => !!mark && !!view.state.schema.marks[mark.name],\n});\n\nexport const defaultButtons = (ctx: Ctx) => {\n const marks = ctx.get(schemaCtx).marks;\n return [\n createToggleIcon('bold', 'ToggleBold', marks['strong']),\n createToggleIcon('italic', 'ToggleItalic', marks['em']),\n createToggleIcon('strikeThrough', 'ToggleStrikeThrough', marks['strike_through']),\n createToggleIcon('code', 'ToggleInlineCode', marks['code_inline']),\n createToggleIcon('link', 'ToggleLink', marks['link']),\n ];\n};\n\nexport type ButtonList = ButtonItem[];\n\nexport type TooltipOptions = {\n bottom: boolean;\n items: (ctx: Ctx) => Array<Item>;\n};\n\nexport const buttonMap = (ctx: Ctx, items: (ctx: Ctx) => Array<Item> = defaultButtons): ButtonList => {\n const toButton = ({ icon, onClick, isHidden, isActive, canAddToDOM }: Item): ButtonItem => ({\n $: typeof icon === 'function' ? icon(ctx) : (ctx.get(themeManagerCtx).get(ThemeIcon, icon)?.dom as HTMLElement),\n command: typeof onClick === 'string' ? () => ctx.get(commandsCtx).call(onClick) : onClick(ctx),\n disable: isHidden(ctx),\n active: isActive(ctx),\n enable: canAddToDOM(ctx),\n });\n return items(ctx).map(toButton);\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { missingRootElement } from '@milkdown/exception';\nimport { calculateTextPosition } from '@milkdown/prose';\nimport { EditorView } from '@milkdown/prose/view';\n\nexport const calcButtonPos = (buttons: HTMLElement, view: EditorView, isBottom: boolean) => {\n buttons.classList.remove('hide');\n calculateTextPosition(view, buttons, (start, end, target, parent) => {\n const $editor = buttons.parentElement;\n if (!$editor) {\n throw missingRootElement();\n }\n const selectionWidth = end.left - start.left;\n let left = start.left - parent.left - (target.width - selectionWidth) / 2;\n let top = start.top - parent.top - target.height - 14 + $editor.scrollTop;\n\n if (left < 0) left = 0;\n\n const maxLeft = $editor.clientWidth - (target.width + 4);\n if (left > maxLeft) {\n left = maxLeft;\n }\n\n if (top < $editor.scrollTop || (isBottom && parent.bottom - start.bottom > target.height)) {\n top = start.bottom - parent.top + 14 + $editor.scrollTop;\n }\n return [top, left];\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Color, Emotion, ThemeBorder, ThemeColor, ThemeManager, ThemeShadow, ThemeSize } from '@milkdown/core';\n\nexport const injectStyle = (themeManager: ThemeManager, { css }: Emotion) => {\n const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);\n const lineWidth = themeManager.get(ThemeSize, 'lineWidth');\n return css`\n display: inline-flex;\n cursor: pointer;\n justify-content: space-evenly;\n position: absolute;\n border-radius: ${themeManager.get(ThemeSize, 'radius')};\n z-index: 2;\n\n ${themeManager.get(ThemeBorder, undefined)}\n ${themeManager.get(ThemeShadow, undefined)}\n\n overflow: hidden;\n background: ${palette('surface')};\n\n .icon {\n position: relative;\n color: ${palette('solid', 0.87)};\n\n width: 48px;\n line-height: 48px;\n text-align: center;\n transition: all 0.4s ease-in-out;\n &:hover {\n background-color: ${palette('secondary', 0.12)};\n }\n &.active {\n color: ${palette('primary')};\n }\n &:not(:last-child)::after {\n content: '';\n position: absolute;\n top: 0;\n right: calc(-0.5 * ${lineWidth});\n width: ${lineWidth};\n bottom: 0;\n background: ${palette('line')};\n }\n }\n &.hide,\n .hide {\n display: none;\n }\n `;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view';\nimport type { ThemeUtils } from '@milkdown/utils';\n\nimport type { ButtonList } from '../item';\nimport { injectStyle } from './style';\n\ntype Tooltip = {\n dom: HTMLDivElement;\n render: (editorView: EditorView) => void;\n};\n\nexport const createTooltip = (buttonMap: ButtonList, utils: ThemeUtils, className: string): Tooltip => {\n const div = document.createElement('div');\n utils.themeManager.onFlush(() => {\n const style = utils.getStyle((emotion) => injectStyle(utils.themeManager, emotion)) || '';\n if (style) {\n div.classList.add(style);\n }\n });\n\n div.classList.add(utils.getClassName({}, className));\n\n return {\n dom: div,\n render: (editorView: EditorView) => {\n buttonMap\n .filter((item) => item.enable(editorView) && item.$ != null)\n .forEach(({ $ }) => div.appendChild($));\n\n editorView.dom.parentNode?.appendChild(div);\n },\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { EditorView } from '@milkdown/prose/view';\n\nimport { ButtonList } from '../item';\n\nexport const noActive = (buttonMap: ButtonList, view: EditorView) => {\n return Object.values(buttonMap)\n .filter((item) => item.enable(view) && item.$ != null)\n .every(({ $ }) => $.classList.contains('hide'));\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { EditorView } from '@milkdown/prose/view';\n\nimport { ButtonList } from '../item';\nimport { noActive } from './no-active';\n\nexport const filterButton = (buttons: ButtonList, view: EditorView) => {\n buttons\n .filter((item) => item.enable(view) && item.$ != null)\n .forEach((item) => {\n const disable = item.disable?.(view);\n if (disable) {\n item.$.classList.add('hide');\n return;\n }\n\n item.$.classList.remove('hide');\n\n const active = item.active(view);\n if (active) {\n item.$.classList.add('active');\n return;\n }\n item.$.classList.remove('active');\n });\n\n return noActive(buttons, view);\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view';\nimport type { ThemeUtils } from '@milkdown/utils';\n\nimport type { ButtonList } from '../item';\nimport { calcButtonPos } from './calc-button-pos';\nimport { createTooltip } from './create-tooltip';\nimport { filterButton } from './filter-button';\n\nexport const createButtonManager = (\n buttons: ButtonList,\n utils: ThemeUtils,\n bottom: boolean,\n containerClassName: string,\n) => {\n const { dom: buttonDOM, render } = createTooltip(buttons, utils, containerClassName);\n\n const onClick = (e: Event) => {\n const target = buttons.find(({ $ }) => e.target instanceof Element && $.contains(e.target));\n if (!target) return;\n\n e.stopPropagation();\n e.preventDefault();\n target.command();\n };\n\n const hide = () => {\n buttonDOM.classList.add('hide');\n };\n\n buttonDOM.addEventListener('mousedown', onClick);\n\n return {\n destroy: () => {\n buttonDOM.removeEventListener('mousedown', onClick);\n buttonDOM.remove();\n },\n hide,\n update: (editorView: EditorView) => {\n const noActive = filterButton(buttons, editorView);\n if (noActive) {\n hide();\n return;\n }\n calcButtonPos(buttonDOM, editorView, bottom);\n },\n render,\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { EditorState } from '@milkdown/prose/state';\nimport type { EditorView } from '@milkdown/prose/view';\nimport { ThemeUtils } from '@milkdown/utils';\n\nimport { createButtonManager } from './button-manager';\nimport type { ButtonList } from './item';\n\nexport const createPlugin = (buttonMap: ButtonList, utils: ThemeUtils, bottom: boolean, containerClassName: string) => {\n let buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName);\n let shouldHide = false;\n\n const hide = () => {\n buttonManager.hide();\n };\n\n const update = (view: EditorView, prevState?: EditorState) => {\n const { state } = view;\n\n if (!view.editable || shouldHide) {\n hide();\n return;\n }\n\n const isEqualSelection = prevState?.doc.eq(state.doc) && prevState.selection.eq(state.selection);\n if (isEqualSelection) return;\n\n buttonManager.update(view);\n };\n\n return {\n recreate: (editorView: EditorView) => {\n buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName);\n buttonManager.render(editorView);\n update(editorView);\n },\n update,\n destroy: () => {\n buttonManager.destroy();\n },\n render: (editorView: EditorView) => {\n buttonManager.render(editorView);\n update(editorView);\n },\n setHide: (isTyping: boolean) => {\n shouldHide = isTyping;\n },\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Plugin, PluginKey } from '@milkdown/prose/state';\nimport { AtomList, createPlugin as create } from '@milkdown/utils';\n\nimport { buttonMap, TooltipOptions } from './item';\nimport { createPlugin } from './selection-marks-tooltip';\n\nexport const key = new PluginKey('MILKDOWN_TOOLTIP');\nexport * from './item';\n\nexport const tooltipPlugin = create<string, TooltipOptions>((utils, options) => {\n return {\n id: 'tooltip',\n prosePlugins: (_, ctx) => {\n const manager = createPlugin(buttonMap(ctx, options?.items), utils, options?.bottom ?? false, 'tooltip');\n const plugin = new Plugin({\n key,\n props: {\n handleClick: (view) => {\n manager.setHide(false);\n manager.update(view);\n return false;\n },\n handleDOMEvents: {\n mousedown: () => {\n manager.setHide(false);\n return false;\n },\n },\n },\n view: (editorView) => {\n manager.recreate(editorView);\n return {\n update: manager.update,\n destroy: manager.destroy,\n };\n },\n });\n return [plugin];\n },\n };\n});\n\nexport const tooltip = AtomList.create([tooltipPlugin()]);\n"],"names":["hasMark","editorState","type","from","to","isTextSelection","selection","TextSelection","isInCodeFence","findParentNode","node","isTextAndNotHasMark","mark","createToggleIcon","icon","onClick","disableForMark","view","defaultButtons","ctx","marks","schemaCtx","buttonMap","items","toButton","isHidden","isActive","canAddToDOM","_a","themeManagerCtx","ThemeIcon","commandsCtx","calcButtonPos","buttons","isBottom","calculateTextPosition","start","end","target","parent","$editor","missingRootElement","selectionWidth","left","top","maxLeft","injectStyle","themeManager","css","palette","color","opacity","ThemeColor","lineWidth","ThemeSize","ThemeBorder","ThemeShadow","createTooltip","utils","className","div","style","emotion","editorView","item","$","noActive","filterButton","createButtonManager","bottom","containerClassName","buttonDOM","render","e","hide","createPlugin","buttonManager","shouldHide","update","prevState","state","isTyping","key","PluginKey","tooltipPlugin","create","options","_","manager","Plugin","tooltip","AtomList"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/utility/prosemirror.ts","../src/item.ts","../src/button-manager/calc-button-pos.ts","../src/button-manager/style.ts","../src/button-manager/create-tooltip.ts","../src/button-manager/no-active.ts","../src/button-manager/filter-button.ts","../src/button-manager/index.ts","../src/selection-marks-tooltip.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { findParentNode } from '@milkdown/prose'\nimport type { MarkType, Node, NodeType } from '@milkdown/prose/model'\nimport type { EditorState } from '@milkdown/prose/state'\nimport { TextSelection } from '@milkdown/prose/state'\n\nexport interface Position {\n start: number\n end: number\n}\n\nexport const hasMark = (editorState: EditorState, type?: MarkType): boolean => {\n if (!type)\n return false\n\n const { from, to } = editorState.selection\n\n return editorState.doc.rangeHasMark(from, from === to ? to + 1 : to, type)\n}\n\nexport const isTextSelection = (editorState: EditorState): boolean => {\n const { selection } = editorState\n if (selection instanceof TextSelection) {\n const text = editorState.doc.textBetween(selection.from, selection.to)\n\n if (!text)\n return false\n\n return true\n }\n return false\n}\n\nexport const isInCodeFence = (editorState: EditorState): boolean =>\n Boolean(findParentNode(node => !!node.type.spec.code)(editorState.selection))\n\nexport const isTextAndNotHasMark = (editorState: EditorState, mark?: MarkType): boolean =>\n !isTextSelection(editorState) || isInCodeFence(editorState) || hasMark(editorState, mark)\n\nexport const equalNodeType = (nodeType: NodeType, node: Node) => {\n return (Array.isArray(nodeType) && nodeType.includes(node.type)) || node.type === nodeType\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { Ctx } from '@milkdown/core'\nimport { ThemeIcon, commandsCtx, schemaCtx, themeManagerCtx } from '@milkdown/core'\nimport type { Icon } from '@milkdown/design-system'\nimport type { MarkType } from '@milkdown/prose/model'\nimport type { EditorView } from '@milkdown/prose/view'\n\nimport { hasMark, isTextAndNotHasMark } from './utility'\n\nexport type Pred = (view: EditorView) => boolean\nexport type Updater = (view: EditorView, $: HTMLElement) => void\nexport type Event2Command = (e: Event) => void\n\nexport type OnClick = (ctx: Ctx) => void\n\nexport interface Item {\n icon: Icon | ((ctx: Ctx) => HTMLElement)\n onClick: string | ((ctx: Ctx) => () => void)\n isHidden: (ctx: Ctx) => Pred\n isActive: (ctx: Ctx) => Pred\n canAddToDOM: (ctx: Ctx) => Pred\n}\n\nexport interface ButtonItem {\n $: HTMLElement\n command: () => void\n active: Pred\n disable?: Pred\n enable: Pred\n}\n\nexport const createToggleIcon = (icon: Icon, onClick: string, mark?: MarkType, disableForMark?: MarkType): Item => ({\n icon,\n onClick,\n isHidden: () => (view: EditorView) => isTextAndNotHasMark(view.state, disableForMark),\n isActive: () => (view: EditorView) => hasMark(view.state, mark),\n canAddToDOM: () => (view: EditorView) => !!mark && !!view.state.schema.marks[mark.name],\n})\n\nexport const defaultButtons = (ctx: Ctx) => {\n const marks = ctx.get(schemaCtx).marks\n return [\n createToggleIcon('bold', 'ToggleBold', marks.strong),\n createToggleIcon('italic', 'ToggleItalic', marks.em),\n createToggleIcon('strikeThrough', 'ToggleStrikeThrough', marks.strike_through),\n createToggleIcon('code', 'ToggleInlineCode', marks.code_inline),\n createToggleIcon('link', 'ToggleLink', marks.link),\n ]\n}\n\nexport type ButtonList = ButtonItem[]\n\nexport interface TooltipOptions {\n bottom: boolean\n items: (ctx: Ctx) => Array<Item>\n}\n\nexport const buttonMap = (ctx: Ctx, items: (ctx: Ctx) => Array<Item> = defaultButtons): ButtonList => {\n const toButton = ({ icon, onClick, isHidden, isActive, canAddToDOM }: Item): ButtonItem => ({\n $: typeof icon === 'function' ? icon(ctx) : (ctx.get(themeManagerCtx).get(ThemeIcon, icon)?.dom as HTMLElement),\n command: typeof onClick === 'string' ? () => ctx.get(commandsCtx).call(onClick) : onClick(ctx),\n disable: isHidden(ctx),\n active: isActive(ctx),\n enable: canAddToDOM(ctx),\n })\n return items(ctx).map(toButton)\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { missingRootElement } from '@milkdown/exception'\nimport { calculateTextPosition } from '@milkdown/prose'\nimport type { EditorView } from '@milkdown/prose/view'\n\nexport const calcButtonPos = (buttons: HTMLElement, view: EditorView, isBottom: boolean) => {\n buttons.classList.remove('hide')\n calculateTextPosition(view, buttons, (start, end, target, parent) => {\n const $editor = buttons.parentElement\n if (!$editor)\n throw missingRootElement()\n\n const selectionWidth = end.left - start.left\n let left = start.left - parent.left - (target.width - selectionWidth) / 2\n let top = start.top - parent.top - target.height - 14 + $editor.scrollTop\n\n if (left < 0)\n left = 0\n\n const maxLeft = $editor.clientWidth - (target.width + 4)\n if (left > maxLeft)\n left = maxLeft\n\n if (top < $editor.scrollTop || (isBottom && parent.bottom - start.bottom > target.height))\n top = start.bottom - parent.top + 14 + $editor.scrollTop\n\n return [top, left]\n })\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { Color, Emotion, ThemeManager } from '@milkdown/core'\nimport { ThemeBorder, ThemeColor, ThemeShadow, ThemeSize } from '@milkdown/core'\n\nexport const injectStyle = (themeManager: ThemeManager, { css }: Emotion) => {\n const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity])\n const lineWidth = themeManager.get(ThemeSize, 'lineWidth')\n return css`\n display: inline-flex;\n cursor: pointer;\n justify-content: space-evenly;\n position: absolute;\n border-radius: ${themeManager.get(ThemeSize, 'radius')};\n z-index: 2;\n\n ${themeManager.get(ThemeBorder, undefined)}\n ${themeManager.get(ThemeShadow, undefined)}\n\n overflow: hidden;\n background: ${palette('surface')};\n\n .icon {\n position: relative;\n color: ${palette('solid', 0.87)};\n\n width: 48px;\n line-height: 48px;\n text-align: center;\n transition: all 0.4s ease-in-out;\n &:hover {\n background-color: ${palette('secondary', 0.12)};\n }\n &.active {\n color: ${palette('primary')};\n }\n &:not(:last-child)::after {\n content: '';\n position: absolute;\n top: 0;\n right: calc(-0.5 * ${lineWidth});\n width: ${lineWidth};\n bottom: 0;\n background: ${palette('line')};\n }\n }\n &.hide,\n .hide {\n display: none;\n }\n `\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view'\nimport type { ThemeUtils } from '@milkdown/utils'\n\nimport type { ButtonList } from '../item'\nimport { injectStyle } from './style'\n\ninterface Tooltip {\n dom: HTMLDivElement\n render: (editorView: EditorView) => void\n}\n\nexport const createTooltip = (buttonMap: ButtonList, utils: ThemeUtils, className: string): Tooltip => {\n const div = document.createElement('div')\n utils.themeManager.onFlush(() => {\n const style = utils.getStyle(emotion => injectStyle(utils.themeManager, emotion)) || ''\n if (style)\n div.classList.add(style)\n })\n\n div.classList.add(utils.getClassName({}, className))\n\n return {\n dom: div,\n render: (editorView: EditorView) => {\n buttonMap\n .filter(item => item.enable(editorView) && item.$ != null)\n .forEach(({ $ }) => div.appendChild($))\n\n editorView.dom.parentNode?.appendChild(div)\n },\n }\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view'\n\nimport type { ButtonList } from '../item'\n\nexport const noActive = (buttonMap: ButtonList, view: EditorView) => {\n return Object.values(buttonMap)\n .filter(item => item.enable(view) && item.$ != null)\n .every(({ $ }) => $.classList.contains('hide'))\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view'\n\nimport type { ButtonList } from '../item'\nimport { noActive } from './no-active'\n\nexport const filterButton = (buttons: ButtonList, view: EditorView) => {\n buttons\n .filter(item => item.enable(view) && item.$ != null)\n .forEach((item) => {\n const disable = item.disable?.(view)\n if (disable) {\n item.$.classList.add('hide')\n return\n }\n\n item.$.classList.remove('hide')\n\n const active = item.active(view)\n if (active) {\n item.$.classList.add('active')\n return\n }\n item.$.classList.remove('active')\n })\n\n return noActive(buttons, view)\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose/view'\nimport type { ThemeUtils } from '@milkdown/utils'\n\nimport type { ButtonList } from '../item'\nimport { calcButtonPos } from './calc-button-pos'\nimport { createTooltip } from './create-tooltip'\nimport { filterButton } from './filter-button'\n\nexport const createButtonManager = (\n buttons: ButtonList,\n utils: ThemeUtils,\n bottom: boolean,\n containerClassName: string,\n) => {\n const { dom: buttonDOM, render } = createTooltip(buttons, utils, containerClassName)\n\n const onClick = (e: Event) => {\n const target = buttons.find(({ $ }) => e.target instanceof Element && $.contains(e.target))\n if (!target)\n return\n\n e.stopPropagation()\n e.preventDefault()\n target.command()\n }\n\n const hide = () => {\n buttonDOM.classList.add('hide')\n }\n\n buttonDOM.addEventListener('mousedown', onClick)\n\n return {\n destroy: () => {\n buttonDOM.removeEventListener('mousedown', onClick)\n buttonDOM.remove()\n },\n hide,\n update: (editorView: EditorView) => {\n const noActive = filterButton(buttons, editorView)\n if (noActive) {\n hide()\n return\n }\n calcButtonPos(buttonDOM, editorView, bottom)\n },\n render,\n }\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorState } from '@milkdown/prose/state'\nimport type { EditorView } from '@milkdown/prose/view'\nimport type { ThemeUtils } from '@milkdown/utils'\n\nimport { createButtonManager } from './button-manager'\nimport type { ButtonList } from './item'\n\nexport const createPlugin = (buttonMap: ButtonList, utils: ThemeUtils, bottom: boolean, containerClassName: string) => {\n let buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName)\n let shouldHide = false\n\n const hide = () => {\n buttonManager.hide()\n }\n\n const update = (view: EditorView, prevState?: EditorState) => {\n const { state } = view\n\n if (!view.editable || shouldHide) {\n hide()\n return\n }\n\n const isEqualSelection = prevState?.doc.eq(state.doc) && prevState.selection.eq(state.selection)\n if (isEqualSelection)\n return\n\n buttonManager.update(view)\n }\n\n return {\n recreate: (editorView: EditorView) => {\n buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName)\n buttonManager.render(editorView)\n update(editorView)\n },\n update,\n destroy: () => {\n buttonManager.destroy()\n },\n render: (editorView: EditorView) => {\n buttonManager.render(editorView)\n update(editorView)\n },\n setHide: (isTyping: boolean) => {\n shouldHide = isTyping\n },\n }\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Plugin, PluginKey } from '@milkdown/prose/state'\nimport { AtomList, createPlugin as create } from '@milkdown/utils'\n\nimport type { TooltipOptions } from './item'\nimport { buttonMap } from './item'\nimport { createPlugin } from './selection-marks-tooltip'\n\nexport const key = new PluginKey('MILKDOWN_TOOLTIP')\nexport * from './item'\n\nexport const tooltipPlugin = create<string, TooltipOptions>((utils, options) => {\n return {\n id: 'tooltip',\n prosePlugins: (_, ctx) => {\n const manager = createPlugin(buttonMap(ctx, options?.items), utils, options?.bottom ?? false, 'tooltip')\n const plugin = new Plugin({\n key,\n props: {\n handleClick: (view) => {\n manager.setHide(false)\n manager.update(view)\n return false\n },\n handleDOMEvents: {\n mousedown: () => {\n manager.setHide(false)\n return false\n },\n },\n },\n view: (editorView) => {\n manager.recreate(editorView)\n return {\n update: manager.update,\n destroy: manager.destroy,\n }\n },\n })\n return [plugin]\n },\n }\n})\n\nexport const tooltip = AtomList.create([tooltipPlugin()])\n"],"names":["hasMark","editorState","type","from","to","isTextSelection","selection","TextSelection","isInCodeFence","findParentNode","node","isTextAndNotHasMark","mark","createToggleIcon","icon","onClick","disableForMark","view","defaultButtons","ctx","marks","schemaCtx","buttonMap","items","toButton","isHidden","isActive","canAddToDOM","_a","themeManagerCtx","ThemeIcon","commandsCtx","calcButtonPos","buttons","isBottom","calculateTextPosition","start","end","target","parent","$editor","missingRootElement","selectionWidth","left","top","maxLeft","injectStyle","themeManager","css","palette","color","opacity","ThemeColor","lineWidth","ThemeSize","ThemeBorder","ThemeShadow","createTooltip","utils","className","div","style","emotion","editorView","item","$","noActive","filterButton","createButtonManager","bottom","containerClassName","buttonDOM","render","e","hide","createPlugin","buttonManager","shouldHide","update","prevState","state","isTyping","key","PluginKey","tooltipPlugin","create","options","_","manager","Plugin","tooltip","AtomList"],"mappings":"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"}
|
package/lib/item.d.ts
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import { Ctx } from '@milkdown/core';
|
|
1
|
+
import type { Ctx } from '@milkdown/core';
|
|
2
2
|
import type { Icon } from '@milkdown/design-system';
|
|
3
3
|
import type { MarkType } from '@milkdown/prose/model';
|
|
4
|
-
import { EditorView } from '@milkdown/prose/view';
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
export
|
|
4
|
+
import type { EditorView } from '@milkdown/prose/view';
|
|
5
|
+
export type Pred = (view: EditorView) => boolean;
|
|
6
|
+
export type Updater = (view: EditorView, $: HTMLElement) => void;
|
|
7
|
+
export type Event2Command = (e: Event) => void;
|
|
8
|
+
export type OnClick = (ctx: Ctx) => void;
|
|
9
|
+
export interface Item {
|
|
10
10
|
icon: Icon | ((ctx: Ctx) => HTMLElement);
|
|
11
11
|
onClick: string | ((ctx: Ctx) => () => void);
|
|
12
12
|
isHidden: (ctx: Ctx) => Pred;
|
|
13
13
|
isActive: (ctx: Ctx) => Pred;
|
|
14
14
|
canAddToDOM: (ctx: Ctx) => Pred;
|
|
15
|
-
}
|
|
16
|
-
export
|
|
15
|
+
}
|
|
16
|
+
export interface ButtonItem {
|
|
17
17
|
$: HTMLElement;
|
|
18
18
|
command: () => void;
|
|
19
19
|
active: Pred;
|
|
20
20
|
disable?: Pred;
|
|
21
21
|
enable: Pred;
|
|
22
|
-
}
|
|
22
|
+
}
|
|
23
23
|
export declare const createToggleIcon: (icon: Icon, onClick: string, mark?: MarkType, disableForMark?: MarkType) => Item;
|
|
24
24
|
export declare const defaultButtons: (ctx: Ctx) => Item[];
|
|
25
|
-
export
|
|
26
|
-
export
|
|
25
|
+
export type ButtonList = ButtonItem[];
|
|
26
|
+
export interface TooltipOptions {
|
|
27
27
|
bottom: boolean;
|
|
28
28
|
items: (ctx: Ctx) => Array<Item>;
|
|
29
|
-
}
|
|
29
|
+
}
|
|
30
30
|
export declare const buttonMap: (ctx: Ctx, items?: (ctx: Ctx) => Array<Item>) => ButtonList;
|
|
31
31
|
//# sourceMappingURL=item.d.ts.map
|
package/lib/item.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../src/item.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../src/item.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AAEzC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAA;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAItD,MAAM,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAA;AAChD,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,KAAK,IAAI,CAAA;AAChE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAA;AAE9C,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;AAExC,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,WAAW,CAAC,CAAA;IACxC,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,IAAI,CAAC,CAAA;IAC5C,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;IAC5B,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;IAC5B,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,WAAW,CAAA;IACd,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,MAAM,EAAE,IAAI,CAAA;IACZ,OAAO,CAAC,EAAE,IAAI,CAAA;IACd,MAAM,EAAE,IAAI,CAAA;CACb;AAED,eAAO,MAAM,gBAAgB,SAAU,IAAI,WAAW,MAAM,SAAS,QAAQ,mBAAmB,QAAQ,KAAG,IAMzG,CAAA;AAEF,eAAO,MAAM,cAAc,QAAS,GAAG,WAStC,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,EAAE,CAAA;AAErC,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,CAAA;CACjC;AAED,eAAO,MAAM,SAAS,QAAS,GAAG,gBAAe,GAAG,KAAK,MAAM,IAAI,CAAC,eASnE,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { EditorState } from '@milkdown/prose/state';
|
|
1
|
+
import type { EditorState } from '@milkdown/prose/state';
|
|
2
2
|
import type { EditorView } from '@milkdown/prose/view';
|
|
3
|
-
import { ThemeUtils } from '@milkdown/utils';
|
|
3
|
+
import type { ThemeUtils } from '@milkdown/utils';
|
|
4
4
|
import type { ButtonList } from './item';
|
|
5
5
|
export declare const createPlugin: (buttonMap: ButtonList, utils: ThemeUtils, bottom: boolean, containerClassName: string) => {
|
|
6
6
|
recreate: (editorView: EditorView) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection-marks-tooltip.d.ts","sourceRoot":"","sources":["../src/selection-marks-tooltip.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"selection-marks-tooltip.d.ts","sourceRoot":"","sources":["../src/selection-marks-tooltip.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAGjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAExC,eAAO,MAAM,YAAY,iCAAkC,UAAU,UAAU,OAAO,sBAAsB,MAAM;2BAwBvF,UAAU;mBAhBb,UAAU,cAAc,WAAW;;yBAyBlC,UAAU;wBAIX,OAAO;CAI9B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/utility/element.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,YAAa,WAAW,WAAW,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/utility/element.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,YAAa,WAAW,WAAW,MAAM,KAAG,OAC1B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utility/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utility/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { MarkType, Node, NodeType } from '@milkdown/prose/model';
|
|
2
|
-
import { EditorState } from '@milkdown/prose/state';
|
|
3
|
-
export
|
|
1
|
+
import type { MarkType, Node, NodeType } from '@milkdown/prose/model';
|
|
2
|
+
import type { EditorState } from '@milkdown/prose/state';
|
|
3
|
+
export interface Position {
|
|
4
4
|
start: number;
|
|
5
5
|
end: number;
|
|
6
|
-
}
|
|
6
|
+
}
|
|
7
7
|
export declare const hasMark: (editorState: EditorState, type?: MarkType) => boolean;
|
|
8
8
|
export declare const isTextSelection: (editorState: EditorState) => boolean;
|
|
9
9
|
export declare const isInCodeFence: (editorState: EditorState) => boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prosemirror.d.ts","sourceRoot":"","sources":["../../src/utility/prosemirror.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"prosemirror.d.ts","sourceRoot":"","sources":["../../src/utility/prosemirror.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGxD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,eAAO,MAAM,OAAO,gBAAiB,WAAW,SAAS,QAAQ,KAAG,OAOnE,CAAA;AAED,eAAO,MAAM,eAAe,gBAAiB,WAAW,KAAG,OAW1D,CAAA;AAED,eAAO,MAAM,aAAa,gBAAiB,WAAW,KAAG,OACsB,CAAA;AAE/E,eAAO,MAAM,mBAAmB,gBAAiB,WAAW,SAAS,QAAQ,KAAG,OACW,CAAA;AAE3F,eAAO,MAAM,aAAa,aAAc,QAAQ,QAAQ,IAAI,YAE3D,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkdown/plugin-tooltip",
|
|
3
|
-
"version": "6.5.2",
|
|
4
3
|
"type": "module",
|
|
4
|
+
"version": "6.5.3",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"milkdown",
|
|
8
|
+
"milkdown plugin"
|
|
9
|
+
],
|
|
10
|
+
"sideEffects": false,
|
|
5
11
|
"main": "./lib/index.es.js",
|
|
6
12
|
"types": "./lib/index.d.ts",
|
|
7
|
-
"sideEffects": false,
|
|
8
|
-
"license": "MIT",
|
|
9
13
|
"files": [
|
|
10
14
|
"lib",
|
|
11
15
|
"src"
|
|
12
16
|
],
|
|
13
|
-
"keywords": [
|
|
14
|
-
"milkdown",
|
|
15
|
-
"milkdown plugin"
|
|
16
|
-
],
|
|
17
|
-
"devDependencies": {
|
|
18
|
-
"@milkdown/core": "6.5.2",
|
|
19
|
-
"@milkdown/prose": "6.5.2",
|
|
20
|
-
"@milkdown/design-system": "6.5.2"
|
|
21
|
-
},
|
|
22
17
|
"peerDependencies": {
|
|
23
18
|
"@milkdown/core": "^6.0.1",
|
|
24
19
|
"@milkdown/prose": "^6.0.1"
|
|
25
20
|
},
|
|
26
21
|
"dependencies": {
|
|
27
|
-
"
|
|
28
|
-
"@milkdown/exception": "6.5.
|
|
29
|
-
"
|
|
22
|
+
"tslib": "^2.4.0",
|
|
23
|
+
"@milkdown/exception": "6.5.3",
|
|
24
|
+
"@milkdown/utils": "6.5.3"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@milkdown/core": "6.5.3",
|
|
28
|
+
"@milkdown/design-system": "6.5.3",
|
|
29
|
+
"@milkdown/prose": "6.5.3"
|
|
30
30
|
},
|
|
31
31
|
"nx": {
|
|
32
32
|
"targets": {
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { missingRootElement } from '@milkdown/exception'
|
|
3
|
-
import { calculateTextPosition } from '@milkdown/prose'
|
|
4
|
-
import { EditorView } from '@milkdown/prose/view'
|
|
2
|
+
import { missingRootElement } from '@milkdown/exception'
|
|
3
|
+
import { calculateTextPosition } from '@milkdown/prose'
|
|
4
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
5
5
|
|
|
6
6
|
export const calcButtonPos = (buttons: HTMLElement, view: EditorView, isBottom: boolean) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
const selectionWidth = end.left - start.left;
|
|
14
|
-
let left = start.left - parent.left - (target.width - selectionWidth) / 2;
|
|
15
|
-
let top = start.top - parent.top - target.height - 14 + $editor.scrollTop;
|
|
7
|
+
buttons.classList.remove('hide')
|
|
8
|
+
calculateTextPosition(view, buttons, (start, end, target, parent) => {
|
|
9
|
+
const $editor = buttons.parentElement
|
|
10
|
+
if (!$editor)
|
|
11
|
+
throw missingRootElement()
|
|
16
12
|
|
|
17
|
-
|
|
13
|
+
const selectionWidth = end.left - start.left
|
|
14
|
+
let left = start.left - parent.left - (target.width - selectionWidth) / 2
|
|
15
|
+
let top = start.top - parent.top - target.height - 14 + $editor.scrollTop
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
left = maxLeft;
|
|
22
|
-
}
|
|
17
|
+
if (left < 0)
|
|
18
|
+
left = 0
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
const maxLeft = $editor.clientWidth - (target.width + 4)
|
|
21
|
+
if (left > maxLeft)
|
|
22
|
+
left = maxLeft
|
|
23
|
+
|
|
24
|
+
if (top < $editor.scrollTop || (isBottom && parent.bottom - start.bottom > target.height))
|
|
25
|
+
top = start.bottom - parent.top + 14 + $editor.scrollTop
|
|
26
|
+
|
|
27
|
+
return [top, left]
|
|
28
|
+
})
|
|
29
|
+
}
|
|
@@ -1,34 +1,33 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import type { EditorView } from '@milkdown/prose/view'
|
|
3
|
-
import type { ThemeUtils } from '@milkdown/utils'
|
|
2
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
3
|
+
import type { ThemeUtils } from '@milkdown/utils'
|
|
4
4
|
|
|
5
|
-
import type { ButtonList } from '../item'
|
|
6
|
-
import { injectStyle } from './style'
|
|
5
|
+
import type { ButtonList } from '../item'
|
|
6
|
+
import { injectStyle } from './style'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
8
|
+
interface Tooltip {
|
|
9
|
+
dom: HTMLDivElement
|
|
10
|
+
render: (editorView: EditorView) => void
|
|
11
|
+
}
|
|
12
12
|
|
|
13
13
|
export const createTooltip = (buttonMap: ButtonList, utils: ThemeUtils, className: string): Tooltip => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
});
|
|
14
|
+
const div = document.createElement('div')
|
|
15
|
+
utils.themeManager.onFlush(() => {
|
|
16
|
+
const style = utils.getStyle(emotion => injectStyle(utils.themeManager, emotion)) || ''
|
|
17
|
+
if (style)
|
|
18
|
+
div.classList.add(style)
|
|
19
|
+
})
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
div.classList.add(utils.getClassName({}, className))
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
return {
|
|
24
|
+
dom: div,
|
|
25
|
+
render: (editorView: EditorView) => {
|
|
26
|
+
buttonMap
|
|
27
|
+
.filter(item => item.enable(editorView) && item.$ != null)
|
|
28
|
+
.forEach(({ $ }) => div.appendChild($))
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
30
|
+
editorView.dom.parentNode?.appendChild(div)
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { EditorView } from '@milkdown/prose/view'
|
|
2
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
3
3
|
|
|
4
|
-
import { ButtonList } from '../item'
|
|
5
|
-
import { noActive } from './no-active'
|
|
4
|
+
import type { ButtonList } from '../item'
|
|
5
|
+
import { noActive } from './no-active'
|
|
6
6
|
|
|
7
7
|
export const filterButton = (buttons: ButtonList, view: EditorView) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
buttons
|
|
9
|
+
.filter(item => item.enable(view) && item.$ != null)
|
|
10
|
+
.forEach((item) => {
|
|
11
|
+
const disable = item.disable?.(view)
|
|
12
|
+
if (disable) {
|
|
13
|
+
item.$.classList.add('hide')
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
item.$.classList.remove('hide')
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
const active = item.active(view)
|
|
20
|
+
if (active) {
|
|
21
|
+
item.$.classList.add('active')
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
item.$.classList.remove('active')
|
|
25
|
+
})
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
}
|
|
27
|
+
return noActive(buttons, view)
|
|
28
|
+
}
|
|
@@ -1,49 +1,50 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import type { EditorView } from '@milkdown/prose/view'
|
|
3
|
-
import type { ThemeUtils } from '@milkdown/utils'
|
|
2
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
3
|
+
import type { ThemeUtils } from '@milkdown/utils'
|
|
4
4
|
|
|
5
|
-
import type { ButtonList } from '../item'
|
|
6
|
-
import { calcButtonPos } from './calc-button-pos'
|
|
7
|
-
import { createTooltip } from './create-tooltip'
|
|
8
|
-
import { filterButton } from './filter-button'
|
|
5
|
+
import type { ButtonList } from '../item'
|
|
6
|
+
import { calcButtonPos } from './calc-button-pos'
|
|
7
|
+
import { createTooltip } from './create-tooltip'
|
|
8
|
+
import { filterButton } from './filter-button'
|
|
9
9
|
|
|
10
10
|
export const createButtonManager = (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
buttons: ButtonList,
|
|
12
|
+
utils: ThemeUtils,
|
|
13
|
+
bottom: boolean,
|
|
14
|
+
containerClassName: string,
|
|
15
15
|
) => {
|
|
16
|
-
|
|
16
|
+
const { dom: buttonDOM, render } = createTooltip(buttons, utils, containerClassName)
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const onClick = (e: Event) => {
|
|
19
|
+
const target = buttons.find(({ $ }) => e.target instanceof Element && $.contains(e.target))
|
|
20
|
+
if (!target)
|
|
21
|
+
return
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
e.stopPropagation()
|
|
24
|
+
e.preventDefault()
|
|
25
|
+
target.command()
|
|
26
|
+
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
const hide = () => {
|
|
29
|
+
buttonDOM.classList.add('hide')
|
|
30
|
+
}
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
buttonDOM.addEventListener('mousedown', onClick)
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
34
|
+
return {
|
|
35
|
+
destroy: () => {
|
|
36
|
+
buttonDOM.removeEventListener('mousedown', onClick)
|
|
37
|
+
buttonDOM.remove()
|
|
38
|
+
},
|
|
39
|
+
hide,
|
|
40
|
+
update: (editorView: EditorView) => {
|
|
41
|
+
const noActive = filterButton(buttons, editorView)
|
|
42
|
+
if (noActive) {
|
|
43
|
+
hide()
|
|
44
|
+
return
|
|
45
|
+
}
|
|
46
|
+
calcButtonPos(buttonDOM, editorView, bottom)
|
|
47
|
+
},
|
|
48
|
+
render,
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { EditorView } from '@milkdown/prose/view'
|
|
2
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
3
3
|
|
|
4
|
-
import { ButtonList } from '../item'
|
|
4
|
+
import type { ButtonList } from '../item'
|
|
5
5
|
|
|
6
6
|
export const noActive = (buttonMap: ButtonList, view: EditorView) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
7
|
+
return Object.values(buttonMap)
|
|
8
|
+
.filter(item => item.enable(view) && item.$ != null)
|
|
9
|
+
.every(({ $ }) => $.classList.contains('hide'))
|
|
10
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { Color, Emotion,
|
|
2
|
+
import type { Color, Emotion, ThemeManager } from '@milkdown/core'
|
|
3
|
+
import { ThemeBorder, ThemeColor, ThemeShadow, ThemeSize } from '@milkdown/core'
|
|
3
4
|
|
|
4
5
|
export const injectStyle = (themeManager: ThemeManager, { css }: Emotion) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity])
|
|
7
|
+
const lineWidth = themeManager.get(ThemeSize, 'lineWidth')
|
|
8
|
+
return css`
|
|
8
9
|
display: inline-flex;
|
|
9
10
|
cursor: pointer;
|
|
10
11
|
justify-content: space-evenly;
|
|
@@ -46,5 +47,5 @@ export const injectStyle = (themeManager: ThemeManager, { css }: Emotion) => {
|
|
|
46
47
|
.hide {
|
|
47
48
|
display: none;
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
-
}
|
|
50
|
+
`
|
|
51
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,44 +1,45 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { Plugin, PluginKey } from '@milkdown/prose/state'
|
|
3
|
-
import { AtomList, createPlugin as create } from '@milkdown/utils'
|
|
2
|
+
import { Plugin, PluginKey } from '@milkdown/prose/state'
|
|
3
|
+
import { AtomList, createPlugin as create } from '@milkdown/utils'
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import type { TooltipOptions } from './item'
|
|
6
|
+
import { buttonMap } from './item'
|
|
7
|
+
import { createPlugin } from './selection-marks-tooltip'
|
|
7
8
|
|
|
8
|
-
export const key = new PluginKey('MILKDOWN_TOOLTIP')
|
|
9
|
-
export * from './item'
|
|
9
|
+
export const key = new PluginKey('MILKDOWN_TOOLTIP')
|
|
10
|
+
export * from './item'
|
|
10
11
|
|
|
11
12
|
export const tooltipPlugin = create<string, TooltipOptions>((utils, options) => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
view: (editorView) => {
|
|
32
|
-
manager.recreate(editorView);
|
|
33
|
-
return {
|
|
34
|
-
update: manager.update,
|
|
35
|
-
destroy: manager.destroy,
|
|
36
|
-
};
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
return [plugin];
|
|
13
|
+
return {
|
|
14
|
+
id: 'tooltip',
|
|
15
|
+
prosePlugins: (_, ctx) => {
|
|
16
|
+
const manager = createPlugin(buttonMap(ctx, options?.items), utils, options?.bottom ?? false, 'tooltip')
|
|
17
|
+
const plugin = new Plugin({
|
|
18
|
+
key,
|
|
19
|
+
props: {
|
|
20
|
+
handleClick: (view) => {
|
|
21
|
+
manager.setHide(false)
|
|
22
|
+
manager.update(view)
|
|
23
|
+
return false
|
|
24
|
+
},
|
|
25
|
+
handleDOMEvents: {
|
|
26
|
+
mousedown: () => {
|
|
27
|
+
manager.setHide(false)
|
|
28
|
+
return false
|
|
29
|
+
},
|
|
30
|
+
},
|
|
40
31
|
},
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
view: (editorView) => {
|
|
33
|
+
manager.recreate(editorView)
|
|
34
|
+
return {
|
|
35
|
+
update: manager.update,
|
|
36
|
+
destroy: manager.destroy,
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
return [plugin]
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
})
|
|
43
44
|
|
|
44
|
-
export const tooltip = AtomList.create([tooltipPlugin()])
|
|
45
|
+
export const tooltip = AtomList.create([tooltipPlugin()])
|
package/src/item.ts
CHANGED
|
@@ -1,66 +1,67 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import type {
|
|
5
|
-
import {
|
|
2
|
+
import type { Ctx } from '@milkdown/core'
|
|
3
|
+
import { ThemeIcon, commandsCtx, schemaCtx, themeManagerCtx } from '@milkdown/core'
|
|
4
|
+
import type { Icon } from '@milkdown/design-system'
|
|
5
|
+
import type { MarkType } from '@milkdown/prose/model'
|
|
6
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
6
7
|
|
|
7
|
-
import { hasMark, isTextAndNotHasMark } from './utility'
|
|
8
|
+
import { hasMark, isTextAndNotHasMark } from './utility'
|
|
8
9
|
|
|
9
|
-
export type Pred = (view: EditorView) => boolean
|
|
10
|
-
export type Updater = (view: EditorView, $: HTMLElement) => void
|
|
11
|
-
export type Event2Command = (e: Event) => void
|
|
10
|
+
export type Pred = (view: EditorView) => boolean
|
|
11
|
+
export type Updater = (view: EditorView, $: HTMLElement) => void
|
|
12
|
+
export type Event2Command = (e: Event) => void
|
|
12
13
|
|
|
13
|
-
export type OnClick = (ctx: Ctx) => void
|
|
14
|
+
export type OnClick = (ctx: Ctx) => void
|
|
14
15
|
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
16
|
+
export interface Item {
|
|
17
|
+
icon: Icon | ((ctx: Ctx) => HTMLElement)
|
|
18
|
+
onClick: string | ((ctx: Ctx) => () => void)
|
|
19
|
+
isHidden: (ctx: Ctx) => Pred
|
|
20
|
+
isActive: (ctx: Ctx) => Pred
|
|
21
|
+
canAddToDOM: (ctx: Ctx) => Pred
|
|
22
|
+
}
|
|
22
23
|
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
24
|
+
export interface ButtonItem {
|
|
25
|
+
$: HTMLElement
|
|
26
|
+
command: () => void
|
|
27
|
+
active: Pred
|
|
28
|
+
disable?: Pred
|
|
29
|
+
enable: Pred
|
|
30
|
+
}
|
|
30
31
|
|
|
31
32
|
export const createToggleIcon = (icon: Icon, onClick: string, mark?: MarkType, disableForMark?: MarkType): Item => ({
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
})
|
|
33
|
+
icon,
|
|
34
|
+
onClick,
|
|
35
|
+
isHidden: () => (view: EditorView) => isTextAndNotHasMark(view.state, disableForMark),
|
|
36
|
+
isActive: () => (view: EditorView) => hasMark(view.state, mark),
|
|
37
|
+
canAddToDOM: () => (view: EditorView) => !!mark && !!view.state.schema.marks[mark.name],
|
|
38
|
+
})
|
|
38
39
|
|
|
39
40
|
export const defaultButtons = (ctx: Ctx) => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
41
|
+
const marks = ctx.get(schemaCtx).marks
|
|
42
|
+
return [
|
|
43
|
+
createToggleIcon('bold', 'ToggleBold', marks.strong),
|
|
44
|
+
createToggleIcon('italic', 'ToggleItalic', marks.em),
|
|
45
|
+
createToggleIcon('strikeThrough', 'ToggleStrikeThrough', marks.strike_through),
|
|
46
|
+
createToggleIcon('code', 'ToggleInlineCode', marks.code_inline),
|
|
47
|
+
createToggleIcon('link', 'ToggleLink', marks.link),
|
|
48
|
+
]
|
|
49
|
+
}
|
|
49
50
|
|
|
50
|
-
export type ButtonList = ButtonItem[]
|
|
51
|
+
export type ButtonList = ButtonItem[]
|
|
51
52
|
|
|
52
|
-
export
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
53
|
+
export interface TooltipOptions {
|
|
54
|
+
bottom: boolean
|
|
55
|
+
items: (ctx: Ctx) => Array<Item>
|
|
56
|
+
}
|
|
56
57
|
|
|
57
58
|
export const buttonMap = (ctx: Ctx, items: (ctx: Ctx) => Array<Item> = defaultButtons): ButtonList => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
59
|
+
const toButton = ({ icon, onClick, isHidden, isActive, canAddToDOM }: Item): ButtonItem => ({
|
|
60
|
+
$: typeof icon === 'function' ? icon(ctx) : (ctx.get(themeManagerCtx).get(ThemeIcon, icon)?.dom as HTMLElement),
|
|
61
|
+
command: typeof onClick === 'string' ? () => ctx.get(commandsCtx).call(onClick) : onClick(ctx),
|
|
62
|
+
disable: isHidden(ctx),
|
|
63
|
+
active: isActive(ctx),
|
|
64
|
+
enable: canAddToDOM(ctx),
|
|
65
|
+
})
|
|
66
|
+
return items(ctx).map(toButton)
|
|
67
|
+
}
|
|
@@ -1,49 +1,50 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { EditorState } from '@milkdown/prose/state'
|
|
3
|
-
import type { EditorView } from '@milkdown/prose/view'
|
|
4
|
-
import { ThemeUtils } from '@milkdown/utils'
|
|
2
|
+
import type { EditorState } from '@milkdown/prose/state'
|
|
3
|
+
import type { EditorView } from '@milkdown/prose/view'
|
|
4
|
+
import type { ThemeUtils } from '@milkdown/utils'
|
|
5
5
|
|
|
6
|
-
import { createButtonManager } from './button-manager'
|
|
7
|
-
import type { ButtonList } from './item'
|
|
6
|
+
import { createButtonManager } from './button-manager'
|
|
7
|
+
import type { ButtonList } from './item'
|
|
8
8
|
|
|
9
9
|
export const createPlugin = (buttonMap: ButtonList, utils: ThemeUtils, bottom: boolean, containerClassName: string) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
}
|
|
10
|
+
let buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName)
|
|
11
|
+
let shouldHide = false
|
|
12
|
+
|
|
13
|
+
const hide = () => {
|
|
14
|
+
buttonManager.hide()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const update = (view: EditorView, prevState?: EditorState) => {
|
|
18
|
+
const { state } = view
|
|
19
|
+
|
|
20
|
+
if (!view.editable || shouldHide) {
|
|
21
|
+
hide()
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const isEqualSelection = prevState?.doc.eq(state.doc) && prevState.selection.eq(state.selection)
|
|
26
|
+
if (isEqualSelection)
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
buttonManager.update(view)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
recreate: (editorView: EditorView) => {
|
|
34
|
+
buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName)
|
|
35
|
+
buttonManager.render(editorView)
|
|
36
|
+
update(editorView)
|
|
37
|
+
},
|
|
38
|
+
update,
|
|
39
|
+
destroy: () => {
|
|
40
|
+
buttonManager.destroy()
|
|
41
|
+
},
|
|
42
|
+
render: (editorView: EditorView) => {
|
|
43
|
+
buttonManager.render(editorView)
|
|
44
|
+
update(editorView)
|
|
45
|
+
},
|
|
46
|
+
setHide: (isTyping: boolean) => {
|
|
47
|
+
shouldHide = isTyping
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
}
|
package/src/utility/element.ts
CHANGED
package/src/utility/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
export * from './element'
|
|
3
|
-
export * from './prosemirror'
|
|
2
|
+
export * from './element'
|
|
3
|
+
export * from './prosemirror'
|
|
@@ -1,40 +1,42 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { findParentNode } from '@milkdown/prose'
|
|
3
|
-
import { MarkType, Node, NodeType } from '@milkdown/prose/model'
|
|
4
|
-
import { EditorState
|
|
2
|
+
import { findParentNode } from '@milkdown/prose'
|
|
3
|
+
import type { MarkType, Node, NodeType } from '@milkdown/prose/model'
|
|
4
|
+
import type { EditorState } from '@milkdown/prose/state'
|
|
5
|
+
import { TextSelection } from '@milkdown/prose/state'
|
|
5
6
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
7
|
+
export interface Position {
|
|
8
|
+
start: number
|
|
9
|
+
end: number
|
|
10
|
+
}
|
|
10
11
|
|
|
11
12
|
export const hasMark = (editorState: EditorState, type?: MarkType): boolean => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
const { from, to } = editorState.selection;
|
|
13
|
+
if (!type)
|
|
14
|
+
return false
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const { from, to } = editorState.selection
|
|
17
|
+
|
|
18
|
+
return editorState.doc.rangeHasMark(from, from === to ? to + 1 : to, type)
|
|
19
|
+
}
|
|
19
20
|
|
|
20
21
|
export const isTextSelection = (editorState: EditorState): boolean => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const { selection } = editorState
|
|
23
|
+
if (selection instanceof TextSelection) {
|
|
24
|
+
const text = editorState.doc.textBetween(selection.from, selection.to)
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
if (!text)
|
|
27
|
+
return false
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
29
|
+
return true
|
|
30
|
+
}
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
31
33
|
|
|
32
34
|
export const isInCodeFence = (editorState: EditorState): boolean =>
|
|
33
|
-
|
|
35
|
+
Boolean(findParentNode(node => !!node.type.spec.code)(editorState.selection))
|
|
34
36
|
|
|
35
37
|
export const isTextAndNotHasMark = (editorState: EditorState, mark?: MarkType): boolean =>
|
|
36
|
-
|
|
38
|
+
!isTextSelection(editorState) || isInCodeFence(editorState) || hasMark(editorState, mark)
|
|
37
39
|
|
|
38
40
|
export const equalNodeType = (nodeType: NodeType, node: Node) => {
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
+
return (Array.isArray(nodeType) && nodeType.includes(node.type)) || node.type === nodeType
|
|
42
|
+
}
|