@milkdown/plugin-tooltip 5.5.0 → 6.0.0

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.
Files changed (75) hide show
  1. package/README.md +3 -13
  2. package/lib/{src/button-manager → button-manager}/calc-button-pos.d.ts +1 -1
  3. package/lib/button-manager/calc-button-pos.d.ts.map +1 -0
  4. package/lib/{src/button-manager → button-manager}/create-tooltip.d.ts +1 -1
  5. package/lib/button-manager/create-tooltip.d.ts.map +1 -0
  6. package/lib/{src/button-manager → button-manager}/filter-button.d.ts +0 -0
  7. package/lib/button-manager/filter-button.d.ts.map +1 -0
  8. package/lib/{src/button-manager → button-manager}/index.d.ts +1 -1
  9. package/lib/button-manager/index.d.ts.map +1 -0
  10. package/lib/{src/button-manager → button-manager}/no-active.d.ts +0 -0
  11. package/lib/button-manager/no-active.d.ts.map +1 -0
  12. package/lib/button-manager/style.d.ts +3 -0
  13. package/lib/button-manager/style.d.ts.map +1 -0
  14. package/lib/index.d.ts +21 -1
  15. package/lib/index.d.ts.map +1 -0
  16. package/lib/index.es.js +64 -387
  17. package/lib/index.es.js.map +1 -1
  18. package/lib/item.d.ts +34 -0
  19. package/lib/item.d.ts.map +1 -0
  20. package/lib/{src/selection-marks-tooltip.d.ts → selection-marks-tooltip.d.ts} +3 -2
  21. package/lib/selection-marks-tooltip.d.ts.map +1 -0
  22. package/lib/{src/utility → utility}/element.d.ts +0 -0
  23. package/lib/utility/element.d.ts.map +1 -0
  24. package/lib/{src/utility → utility}/index.d.ts +0 -1
  25. package/lib/utility/index.d.ts.map +1 -0
  26. package/lib/{src/utility → utility}/prosemirror.d.ts +0 -0
  27. package/lib/utility/prosemirror.d.ts.map +1 -0
  28. package/lib/{src/utility → utility}/toggle.d.ts +0 -0
  29. package/lib/utility/toggle.d.ts.map +1 -0
  30. package/package.json +34 -10
  31. package/src/button-manager/calc-button-pos.ts +2 -3
  32. package/src/button-manager/create-tooltip.ts +9 -7
  33. package/src/button-manager/filter-button.ts +1 -1
  34. package/src/button-manager/index.ts +8 -3
  35. package/src/button-manager/no-active.ts +1 -1
  36. package/src/button-manager/style.ts +11 -10
  37. package/src/index.ts +6 -20
  38. package/src/item.ts +34 -75
  39. package/src/selection-marks-tooltip.ts +8 -9
  40. package/src/utility/index.ts +0 -1
  41. package/src/utility/toggle.ts +3 -3
  42. package/lib/src/button-manager/calc-button-pos.d.ts.map +0 -1
  43. package/lib/src/button-manager/create-tooltip.d.ts.map +0 -1
  44. package/lib/src/button-manager/filter-button.d.ts.map +0 -1
  45. package/lib/src/button-manager/index.d.ts.map +0 -1
  46. package/lib/src/button-manager/no-active.d.ts.map +0 -1
  47. package/lib/src/button-manager/style.d.ts +0 -3
  48. package/lib/src/button-manager/style.d.ts.map +0 -1
  49. package/lib/src/index.d.ts +0 -21
  50. package/lib/src/index.d.ts.map +0 -1
  51. package/lib/src/input-manager/calc-input-pos.d.ts +0 -3
  52. package/lib/src/input-manager/calc-input-pos.d.ts.map +0 -1
  53. package/lib/src/input-manager/create-input.d.ts +0 -7
  54. package/lib/src/input-manager/create-input.d.ts.map +0 -1
  55. package/lib/src/input-manager/filter-input.d.ts +0 -19
  56. package/lib/src/input-manager/filter-input.d.ts.map +0 -1
  57. package/lib/src/input-manager/index.d.ts +0 -10
  58. package/lib/src/input-manager/index.d.ts.map +0 -1
  59. package/lib/src/input-manager/style.d.ts +0 -3
  60. package/lib/src/input-manager/style.d.ts.map +0 -1
  61. package/lib/src/item.d.ts +0 -53
  62. package/lib/src/item.d.ts.map +0 -1
  63. package/lib/src/selection-marks-tooltip.d.ts.map +0 -1
  64. package/lib/src/utility/element.d.ts.map +0 -1
  65. package/lib/src/utility/index.d.ts.map +0 -1
  66. package/lib/src/utility/input.d.ts +0 -9
  67. package/lib/src/utility/input.d.ts.map +0 -1
  68. package/lib/src/utility/prosemirror.d.ts.map +0 -1
  69. package/lib/src/utility/toggle.d.ts.map +0 -1
  70. package/src/input-manager/calc-input-pos.ts +0 -19
  71. package/src/input-manager/create-input.ts +0 -39
  72. package/src/input-manager/filter-input.ts +0 -33
  73. package/src/input-manager/index.ts +0 -64
  74. package/src/input-manager/style.ts +0 -66
  75. package/src/utility/input.ts +0 -137
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/utility/element.ts","../src/utility/input.ts","../src/utility/prosemirror.ts","../src/utility/toggle.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/input-manager/calc-input-pos.ts","../src/input-manager/style.ts","../src/input-manager/create-input.ts","../src/input-manager/filter-input.ts","../src/input-manager/index.ts","../src/selection-marks-tooltip.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nexport const elementIsTag = (element: HTMLElement, tagName: string): boolean =>\n element.tagName === tagName.toUpperCase();\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { commandsCtx, Ctx } from '@milkdown/core';\nimport { findSelectedNodeOfType, Node as ProseNode } from '@milkdown/prose';\n\nimport { Event2Command, Updater } from '../item';\nimport { elementIsTag } from './element';\n\nexport const modifyLink =\n (ctx: Ctx): Event2Command =>\n (e: Event | KeyboardEvent) => {\n const { target } = e;\n if (!(target instanceof HTMLElement)) {\n return () => true;\n }\n if (elementIsTag(target, 'input')) {\n if (!('key' in e) || e.key !== 'Enter') {\n target.focus();\n return () => false;\n }\n }\n const parent = target.parentNode;\n if (!parent) return () => false;\n\n const inputEl = Array.from(parent.children).find((el) => el.tagName === 'INPUT');\n if (!(inputEl instanceof HTMLInputElement)) return () => false;\n\n return ctx.get(commandsCtx).callByName('ModifyLink', inputEl.value);\n };\n\nexport const modifyInlineMath =\n (ctx: Ctx): Event2Command =>\n (e) => {\n const { target } = e;\n if (!(target instanceof HTMLElement)) {\n return () => true;\n }\n const parent = target.parentNode;\n if (!parent) return () => false;\n\n const inputEl = Array.from(parent.children).find((el) => el.tagName === 'INPUT');\n if (!(inputEl instanceof HTMLInputElement)) return () => false;\n\n return ctx.get(commandsCtx).callByName('ModifyInlineMath', inputEl.value);\n };\n\nexport const modifyImage =\n (ctx: Ctx): Event2Command =>\n (e: Event | KeyboardEvent) => {\n const { target } = e;\n if (!(target instanceof HTMLElement)) {\n return () => true;\n }\n if (elementIsTag(target, 'input')) {\n if (!('key' in e) || e.key !== 'Enter') {\n target.focus();\n return () => false;\n }\n }\n const parent = target.parentNode;\n if (!parent) return () => false;\n\n const inputEl = Array.from(parent.children).find((el) => el.tagName === 'INPUT');\n if (!(inputEl instanceof HTMLInputElement)) return () => false;\n\n return ctx.get(commandsCtx).callByName('ModifyImage', inputEl.value);\n };\n\nexport const updateLinkView: Updater = (view, $) => {\n const { marks } = view.state.schema;\n const { firstChild, lastElementChild } = $;\n if (!(firstChild instanceof HTMLInputElement) || !(lastElementChild instanceof HTMLButtonElement)) return;\n\n const { selection } = view.state;\n let node: ProseNode | undefined;\n const { from, to } = selection;\n view.state.doc.nodesBetween(from, from === to ? to + 1 : to, (n) => {\n if (marks.link.isInSet(n.marks)) {\n node = n;\n return false;\n }\n return;\n });\n if (!node) return;\n\n const mark = node.marks.find((m) => m.type === marks.link);\n if (!mark) return;\n\n const value = mark.attrs['href'];\n firstChild.value = value;\n if (!value) {\n lastElementChild.classList.add('disable');\n return;\n }\n if (lastElementChild.classList.contains('disable')) {\n lastElementChild.classList.remove('disable');\n }\n};\n\nexport const updateInlineMathView: Updater = (view, $) => {\n const { nodes } = view.state.schema;\n const { firstChild, lastElementChild } = $;\n if (!(firstChild instanceof HTMLInputElement) || !(lastElementChild instanceof HTMLButtonElement)) return;\n\n const result = findSelectedNodeOfType(view.state.selection, nodes.math_inline);\n if (!result) return;\n const { node } = result;\n\n const value = node.attrs['value'];\n firstChild.value = value;\n if (!value) {\n lastElementChild.classList.add('disable');\n return;\n }\n if (lastElementChild.classList.contains('disable')) {\n lastElementChild.classList.remove('disable');\n }\n};\n\nexport const updateImageView: Updater = (view, $) => {\n const { nodes } = view.state.schema;\n const { firstChild, lastElementChild } = $;\n if (!(firstChild instanceof HTMLInputElement) || !(lastElementChild instanceof HTMLButtonElement)) return;\n\n const result = findSelectedNodeOfType(view.state.selection, nodes.image);\n if (!result) return;\n const { node } = result;\n\n const value = node.attrs['src'];\n firstChild.value = value.length > 50 ? 'Url is too long to display.' : value;\n if (!value) {\n lastElementChild.classList.add('disable');\n return;\n }\n if (lastElementChild.classList.contains('disable')) {\n lastElementChild.classList.remove('disable');\n }\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { EditorState, findParentNode, MarkType, Node, NodeType, TextSelection } from '@milkdown/prose';\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, themeToolCtx } from '@milkdown/core';\nimport type { Icon } from '@milkdown/design-system';\nimport type { MarkType } from '@milkdown/prose';\n\nimport type { ButtonItem } from '../item';\nimport { hasMark, isTextAndNotHasMark } from './prosemirror';\n\nexport const createToggleIcon = (\n ctx: Ctx,\n iconName: Icon,\n key: string,\n mark: MarkType | undefined,\n disableForMark: MarkType | undefined,\n): ButtonItem => ({\n $: ctx.get(themeToolCtx).slots.icon(iconName),\n command: () => ctx.get(commandsCtx).callByName(key),\n active: (view) => hasMark(view.state, mark),\n disable: (view) => isTextAndNotHasMark(view.state, disableForMark),\n enable: (view) => !!mark && !!view.state.schema.marks[mark.name],\n});\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport { EditorView, findSelectedNodeOfType, Schema, TextSelection } from '@milkdown/prose';\n\nimport {\n createToggleIcon,\n hasMark,\n modifyImage,\n modifyInlineMath,\n modifyLink,\n updateImageView,\n updateInlineMathView,\n updateLinkView,\n} 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 ButtonItem = {\n $: HTMLElement;\n command: () => void;\n active: Pred;\n disable?: Pred;\n enable: Pred;\n};\n\nexport type InputItem = {\n command: Event2Command;\n display: Pred;\n update: Updater;\n placeholder: string;\n} & (\n | {\n bind: true;\n }\n | {\n bind?: false;\n buttonText: string;\n }\n);\n\nexport enum ButtonAction {\n ToggleBold,\n ToggleItalic,\n ToggleStrike,\n ToggleCode,\n ToggleLink,\n}\n\nexport enum InputAction {\n ModifyLink,\n ModifyImage,\n ModifyInlineMath,\n}\n\nexport type ButtonMap = Record<ButtonAction, ButtonItem>;\nexport type InputMap = Record<InputAction, InputItem>;\n\nexport type InputOptions = {\n link: {\n placeholder: string;\n buttonText: string;\n };\n image: {\n placeholder: string;\n buttonText: string;\n };\n inlineMath: {\n placeholder: string;\n };\n};\n\nexport const inputMap = (schema: Schema, ctx: Ctx, inputOptions: InputOptions): InputMap => {\n const { marks, nodes } = schema;\n return {\n [InputAction.ModifyLink]: {\n display: (view) =>\n view.state.selection.empty &&\n view.state.selection instanceof TextSelection &&\n hasMark(view.state, marks['link']),\n command: modifyLink(ctx),\n update: updateLinkView,\n ...inputOptions.link,\n },\n [InputAction.ModifyInlineMath]: {\n display: (view) =>\n Boolean(nodes['math_inline'] && findSelectedNodeOfType(view.state.selection, nodes['math_inline'])),\n command: modifyInlineMath(ctx),\n update: updateInlineMathView,\n bind: true,\n ...inputOptions.inlineMath,\n },\n [InputAction.ModifyImage]: {\n display: (view) => Boolean(nodes['image'] && findSelectedNodeOfType(view.state.selection, nodes['image'])),\n command: modifyImage(ctx),\n update: updateImageView,\n ...inputOptions.image,\n },\n };\n};\n\nexport const buttonMap = (schema: Schema, ctx: Ctx): ButtonMap => {\n const { marks } = schema;\n return {\n [ButtonAction.ToggleBold]: createToggleIcon(ctx, 'bold', 'ToggleBold', marks['strong'], marks['code_inline']),\n [ButtonAction.ToggleItalic]: createToggleIcon(ctx, 'italic', 'ToggleItalic', marks['em'], marks['code_inline']),\n [ButtonAction.ToggleStrike]: createToggleIcon(\n ctx,\n 'strikeThrough',\n 'ToggleStrikeThrough',\n marks['strike_through'],\n marks['code_inline'],\n ),\n [ButtonAction.ToggleCode]: createToggleIcon(\n ctx,\n 'code',\n 'ToggleInlineCode',\n marks['code_inline'],\n marks['link'],\n ),\n [ButtonAction.ToggleLink]: createToggleIcon(ctx, 'link', 'ToggleLink', marks['link'], marks['code_inline']),\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { calculateTextPosition, EditorView } from '@milkdown/prose';\n\nexport const calcButtonPos = (buttons: HTMLElement, view: EditorView) => {\n buttons.classList.remove('hide');\n calculateTextPosition(view, buttons, (start, end, target, parent) => {\n const $editor = buttons.parentElement;\n if (!$editor) {\n throw new Error();\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 if (start.top < target.height) {\n top = start.bottom - parent.top + 14 + $editor.scrollTop;\n }\n\n return [top, left];\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Emotion, ThemeTool } from '@milkdown/core';\n\nexport const injectStyle = (themeTool: ThemeTool, { css }: Emotion) => {\n const { palette, mixin, size } = themeTool;\n return css`\n display: inline-flex;\n cursor: pointer;\n justify-content: space-evenly;\n position: absolute;\n border-radius: ${size.radius};\n z-index: 2;\n\n ${mixin.border?.()};\n ${mixin.shadow?.()};\n\n overflow: hidden;\n background: ${palette('surface')};\n\n .icon {\n position: relative;\n color: ${palette('solid', 0.87)};\n\n width: 3rem;\n line-height: 3rem;\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 * ${size.lineWidth});\n width: ${size.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';\nimport type { Utils } from '@milkdown/utils';\n\nimport type { ButtonMap } from '../item';\nimport { injectStyle } from './style';\n\ntype Tooltip = {\n dom: HTMLDivElement;\n render: (editorView: EditorView) => void;\n};\n\nexport const createTooltip = (buttonMap: ButtonMap, utils: Utils): Tooltip => {\n const div = document.createElement('div');\n const style = utils.getStyle(injectStyle) || '';\n if (style) {\n div.classList.add(style);\n }\n\n div.classList.add('tooltip');\n\n return {\n dom: div,\n render: (editorView: EditorView) => {\n Object.values(buttonMap)\n .filter((item) => item.enable(editorView))\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';\n\nimport { ButtonMap } from '../item';\n\nexport const noActive = (buttonMap: ButtonMap, view: EditorView) => {\n return Object.values(buttonMap)\n .filter((item) => item.enable(view))\n .every(({ $ }) => $.classList.contains('hide'));\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { EditorView } from '@milkdown/prose';\n\nimport { ButtonMap } from '../item';\nimport { noActive } from './no-active';\n\nexport const filterButton = (buttonMap: ButtonMap, view: EditorView) => {\n Object.values(buttonMap)\n .filter((item) => item.enable(view))\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(buttonMap, view);\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose';\nimport type { Utils } from '@milkdown/utils';\n\nimport type { ButtonMap } from '../item';\nimport { calcButtonPos } from './calc-button-pos';\nimport { createTooltip } from './create-tooltip';\nimport { filterButton } from './filter-button';\n\nexport const createButtonManager = (buttonMap: ButtonMap, utils: Utils) => {\n const { dom: buttons, render } = createTooltip(buttonMap, utils);\n\n const onClick = (e: Event) => {\n const target = Object.values(buttonMap).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 buttons.classList.add('hide');\n };\n\n buttons.addEventListener('mousedown', onClick);\n\n return {\n destroy: () => {\n buttons.removeEventListener('mousedown', onClick);\n buttons.remove();\n },\n hide,\n update: (editorView: EditorView) => {\n const noActive = filterButton(buttonMap, editorView);\n if (noActive) {\n hide();\n return;\n }\n calcButtonPos(buttons, editorView);\n },\n render,\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { calculateTextPosition, EditorView } from '@milkdown/prose';\n\nexport const calcInputPos = (view: EditorView, input: HTMLDivElement) => {\n calculateTextPosition(view, input, (start, end, target, parent) => {\n const $editor = input.parentElement;\n if (!$editor) {\n throw new Error();\n }\n\n const selectionWidth = end.left - start.left;\n let left = start.left - parent.left - (target.width - selectionWidth) / 2;\n const top = start.bottom - parent.top + 14 + $editor.scrollTop;\n\n if (left < 0) left = 0;\n\n return [top, left];\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Emotion, ThemeTool } from '@milkdown/core';\n\nexport const injectStyle = (themeTool: ThemeTool, { css }: Emotion) => {\n const { palette, mixin, size } = themeTool;\n\n return css`\n ${mixin.border?.()};\n ${mixin.shadow?.()};\n\n display: inline-flex;\n justify-content: space-between;\n align-items: center;\n position: absolute;\n background: ${palette('surface')};\n border-radius: ${size.radius};\n font-size: 1rem;\n\n height: 3.5rem;\n box-sizing: border-box;\n width: 25.5rem;\n padding: 0 1rem;\n gap: 1rem;\n z-index: 2;\n\n input,\n button {\n all: unset;\n }\n\n input {\n flex-grow: 1;\n caret-color: ${palette('primary')};\n &::placeholder {\n color: ${palette('neutral', 0.6)};\n }\n }\n\n button {\n cursor: pointer;\n height: 2.25rem;\n color: ${palette('primary')};\n font-size: 0.875rem;\n padding: 0 0.5rem;\n font-weight: 500;\n letter-spacing: 1.25px;\n &:hover {\n background-color: ${palette('secondary', 0.12)};\n }\n &.disable {\n color: ${palette('neutral', 0.38)};\n cursor: not-allowed;\n &:hover {\n background: transparent;\n }\n }\n &.hide {\n display: none;\n }\n }\n\n &.hide {\n display: none;\n }\n `;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { Utils } from '@milkdown/utils';\n\nimport { injectStyle } from './style';\n\nexport const createInput = (utils: Utils) => {\n const div = document.createElement('div');\n const style = utils.getStyle(injectStyle);\n if (style) {\n div.classList.add(style);\n }\n\n div.classList.add('tooltip-input');\n\n const input = document.createElement('input');\n div.appendChild(input);\n const button = document.createElement('button');\n div.appendChild(button);\n\n input.addEventListener('input', (e) => {\n const { target } = e;\n if (!(target instanceof HTMLInputElement)) {\n return;\n }\n\n if (!target.value) {\n button.classList.add('disable');\n return;\n }\n\n button.classList.remove('disable');\n });\n\n return {\n div,\n input,\n button,\n } as const;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose';\n\nimport type { InputMap } from '../item';\n\nexport const filterInput = (\n currentView: EditorView,\n inputMap: InputMap,\n div: HTMLDivElement,\n input: HTMLInputElement,\n button: HTMLButtonElement,\n) => {\n const target = Object.values(inputMap).find((input) => input.display(currentView));\n\n if (!target) {\n div.classList.add('hide');\n return;\n }\n\n div.classList.remove('hide');\n\n if (target.bind) {\n button.classList.add('hide');\n } else {\n button.classList.remove('hide');\n button.textContent = target.buttonText;\n }\n\n input.placeholder = target.placeholder;\n target.update(currentView, div);\n\n return target;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose';\nimport { Utils } from '@milkdown/utils';\n\nimport type { Event2Command, InputMap } from '../item';\nimport { calcInputPos } from './calc-input-pos';\nimport { createInput } from './create-input';\nimport { filterInput } from './filter-input';\n\nexport const createInputManager = (inputMap: InputMap, utils: Utils) => {\n let inputCommand: Event2Command | undefined;\n let binding = false;\n const setCommand = (x?: Event2Command) => (inputCommand = x);\n\n const { div, button, input } = createInput(utils);\n\n const onClick = (e: Event) => {\n if (!inputCommand || button.classList.contains('disable')) return;\n\n e.stopPropagation();\n inputCommand(e);\n div.classList.add('hide');\n };\n const onInput = (e: Event) => {\n if (!binding || !inputCommand) return;\n inputCommand(e);\n };\n const onKeydown = (e: KeyboardEvent) => {\n if (!inputCommand) return;\n if ('key' in e && e.key === 'Enter') {\n inputCommand(e);\n div.classList.add('hide');\n }\n };\n\n input.addEventListener('input', onInput);\n input.addEventListener('keydown', onKeydown);\n button.addEventListener('mousedown', onClick);\n\n return {\n destroy: () => {\n input.removeEventListener('input', onInput);\n input.removeEventListener('keydown', onKeydown);\n div.removeEventListener('mousedown', onClick);\n div.remove();\n },\n hide: () => {\n div.classList.add('hide');\n setCommand();\n },\n update: (editorView: EditorView) => {\n const result = filterInput(editorView, inputMap, div, input, button);\n if (!result) return;\n binding = !!result.bind;\n setCommand(result.command);\n calcInputPos(editorView, div);\n },\n render: (editorView: EditorView) => {\n const wrapper = editorView.dom.parentNode;\n if (!wrapper) throw new Error();\n wrapper.appendChild(div);\n },\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorState, EditorView } from '@milkdown/prose';\nimport { Utils } from '@milkdown/utils';\n\nimport { createButtonManager } from './button-manager';\nimport { createInputManager } from './input-manager';\nimport type { ButtonMap, InputMap } from './item';\n\nexport const createPlugin = (buttonMap: ButtonMap, inputMap: InputMap, utils: Utils) => {\n const buttonManager = createButtonManager(buttonMap, utils);\n const inputManager = createInputManager(inputMap, utils);\n let shouldHide = false;\n\n const hide = () => {\n buttonManager.hide();\n inputManager.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 inputManager.update(view);\n };\n\n return {\n update,\n destroy: () => {\n buttonManager.destroy();\n inputManager.destroy();\n },\n render: (editorView: EditorView) => {\n buttonManager.render(editorView);\n inputManager.render(editorView);\n update(editorView);\n },\n setHide: (isTyping: boolean) => {\n shouldHide = isTyping;\n },\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { schemaCtx } from '@milkdown/core';\nimport { Plugin, PluginKey } from '@milkdown/prose';\nimport { AtomList, createPlugin as create } from '@milkdown/utils';\n\nimport { buttonMap, inputMap, InputOptions } from './item';\nimport { createPlugin } from './selection-marks-tooltip';\n\nexport const key = new PluginKey('MILKDOWN_PLUGIN_TOOLTIP');\n\nexport const tooltipPlugin = create<string, InputOptions>((utils, options) => {\n return {\n id: 'tooltip',\n prosePlugins: (_, ctx) => {\n const schema = ctx.get(schemaCtx);\n const manager = createPlugin(\n buttonMap(schema, ctx),\n inputMap(schema, ctx, {\n link: {\n placeholder: 'Input Web Link',\n buttonText: 'APPLY',\n ...(options?.link ?? {}),\n },\n image: {\n placeholder: 'Input Image Link',\n buttonText: 'APPLY',\n ...(options?.image ?? {}),\n },\n inlineMath: {\n placeholder: 'Input Math',\n ...(options?.inlineMath ?? {}),\n },\n }),\n utils,\n );\n const plugin = new Plugin({\n key,\n props: {\n handleKeyDown: () => {\n manager.setHide(true);\n return false;\n },\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.render(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":["injectStyle","create"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/utility/prosemirror.ts","../src/utility/toggle.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 { EditorState, findParentNode, MarkType, Node, NodeType, TextSelection } from '@milkdown/prose';\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, ThemeIcon, themeManagerCtx } from '@milkdown/core';\nimport type { Icon } from '@milkdown/design-system';\nimport type { MarkType } from '@milkdown/prose';\n\nimport type { ButtonItem } from '../item';\nimport { hasMark, isTextAndNotHasMark } from './prosemirror';\n\nexport const createToggleIcon = (\n ctx: Ctx,\n iconName: Icon,\n key: string,\n mark: MarkType | undefined,\n disableForMark: MarkType | undefined,\n): ButtonItem => ({\n $: ctx.get(themeManagerCtx).get(ThemeIcon, iconName)?.dom as HTMLElement,\n command: () => ctx.get(commandsCtx).call(key),\n active: (view) => hasMark(view.state, mark),\n disable: (view) => isTextAndNotHasMark(view.state, disableForMark),\n enable: (view) => !!mark && !!view.state.schema.marks[mark.name],\n});\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { commandsCtx, Ctx, ThemeIcon, themeManagerCtx } from '@milkdown/core';\nimport type { Icon } from '@milkdown/design-system';\nimport { EditorView, Schema } from '@milkdown/prose';\n\nimport { createToggleIcon } 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\n onClick: string | ((ctx: Ctx) => () => void);\n\n isHidden: (ctx: Ctx) => Pred;\n\n isActive: (ctx: Ctx) => Pred;\n};\n\nexport type ButtonItem = {\n $: HTMLElement;\n command: () => void;\n active: Pred;\n disable?: Pred;\n enable: Pred;\n};\n\nconst Buttonize = ({ icon, onClick, isHidden, isActive }: Item, ctx: Ctx): 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: (view: EditorView) => !isHidden(ctx)(view),\n});\n\nexport enum ButtonAction {\n ToggleBold,\n ToggleItalic,\n ToggleStrike,\n ToggleCode,\n ToggleLink,\n}\n\nexport type ButtonMap = Record<ButtonAction, ButtonItem>;\n\nexport type TooltipOptions = {\n bottom: boolean;\n items: Array<Item> | undefined;\n};\n\nexport const buttonMap = (schema: Schema, ctx: Ctx, items: Array<Item> | undefined): ButtonMap => {\n const { marks } = schema;\n const ButtonItems = Array<ButtonItem>();\n if (typeof items !== 'undefined') {\n (items as Array<Item>).forEach((item) => {\n ButtonItems.push(Buttonize(item, ctx));\n });\n }\n return {\n [ButtonAction.ToggleBold]: createToggleIcon(ctx, 'bold', 'ToggleBold', marks['strong'], marks['code_inline']),\n [ButtonAction.ToggleItalic]: createToggleIcon(ctx, 'italic', 'ToggleItalic', marks['em'], marks['code_inline']),\n [ButtonAction.ToggleStrike]: createToggleIcon(\n ctx,\n 'strikeThrough',\n 'ToggleStrikeThrough',\n marks['strike_through'],\n marks['code_inline'],\n ),\n [ButtonAction.ToggleCode]: createToggleIcon(\n ctx,\n 'code',\n 'ToggleInlineCode',\n marks['code_inline'],\n marks['link'],\n ),\n [ButtonAction.ToggleLink]: createToggleIcon(ctx, 'link', 'ToggleLink', marks['link'], marks['code_inline']),\n ...ButtonItems,\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { calculateTextPosition, EditorView } from '@milkdown/prose';\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 new Error();\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 if (start.top - parent.top < target.height || (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: 2em;\n line-height: 2em;\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';\nimport type { Utils } from '@milkdown/utils';\n\nimport type { ButtonMap } from '../item';\nimport { injectStyle } from './style';\n\ntype Tooltip = {\n dom: HTMLDivElement;\n render: (editorView: EditorView) => void;\n};\n\nexport const createTooltip = (buttonMap: ButtonMap, utils: Utils, 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 Object.values(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';\n\nimport { ButtonMap } from '../item';\n\nexport const noActive = (buttonMap: ButtonMap, 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';\n\nimport { ButtonMap } from '../item';\nimport { noActive } from './no-active';\n\nexport const filterButton = (buttonMap: ButtonMap, view: EditorView) => {\n Object.values(buttonMap)\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(buttonMap, view);\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorView } from '@milkdown/prose';\nimport type { Utils } from '@milkdown/utils';\n\nimport type { ButtonMap } from '../item';\nimport { calcButtonPos } from './calc-button-pos';\nimport { createTooltip } from './create-tooltip';\nimport { filterButton } from './filter-button';\n\nexport const createButtonManager = (\n buttonMap: ButtonMap,\n utils: Utils,\n bottom: boolean,\n containerClassName: string,\n) => {\n const { dom: buttons, render } = createTooltip(buttonMap, utils, containerClassName);\n\n const onClick = (e: Event) => {\n const target = Object.values(buttonMap).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 buttons.classList.add('hide');\n };\n\n buttons.addEventListener('mousedown', onClick);\n\n return {\n destroy: () => {\n buttons.removeEventListener('mousedown', onClick);\n buttons.remove();\n },\n hide,\n update: (editorView: EditorView) => {\n const noActive = filterButton(buttonMap, editorView);\n if (noActive) {\n hide();\n return;\n }\n calcButtonPos(buttons, editorView, bottom);\n },\n render,\n };\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { EditorState, EditorView } from '@milkdown/prose';\nimport { Utils } from '@milkdown/utils';\n\nimport { createButtonManager } from './button-manager';\nimport type { ButtonMap } from './item';\n\nexport const createPlugin = (buttonMap: ButtonMap, utils: Utils, 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 { schemaCtx } from '@milkdown/core';\nimport { Plugin, PluginKey } from '@milkdown/prose';\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_PLUGIN_TOOLTIP');\n\nexport const tooltipPlugin = create<string, TooltipOptions>((utils, options) => {\n return {\n id: 'tooltip',\n prosePlugins: (_, ctx) => {\n const schema = ctx.get(schemaCtx);\n const manager = createPlugin(\n buttonMap(schema, ctx, options?.items),\n utils,\n options?.bottom ?? false,\n 'tooltip',\n );\n const plugin = new Plugin({\n key,\n props: {\n handleKeyDown: () => {\n manager.setHide(true);\n return false;\n },\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":["create"],"mappings":";;;;;;;;;;;;;;;;;;;MAQa,UAAU,CAAC,aAA0B,SAA6B;MACvE,CAAC,MAAM;WACA;AAAA;QAEL,EAAE,MAAM,OAAO,YAAY;SAE1B,YAAY,IAAI,aAAa,MAAM,SAAS,KAAK,KAAK,IAAI,IAAI;AAAA;MAG5D,kBAAkB,CAAC,gBAAsC;QAC5D,EAAE,cAAc;MAClB,qBAAqB,eAAe;UAC9B,OAAO,YAAY,IAAI,YAAY,UAAU,MAAM,UAAU;QAE/D,CAAC;aAAa;WAEX;AAAA;SAEJ;AAAA;MAGE,gBAAgB,CAAC,gBAC1B,QAAQ,eAAe,CAAC,SAAS,CAAC,CAAC,KAAK,KAAK,KAAK,MAAM,YAAY;MAE3D,sBAAsB,CAAC,aAA0B,SAC1D,CAAC,gBAAgB,gBAAgB,cAAc,gBAAgB,QAAQ,aAAa;MCzB3E,mBAAmB,CAC5B,KACA,UACA,MACA,MACA;;;IAEA,GAAG,UAAI,IAAI,iBAAiB,IAAI,WAAW,cAAxC,mBAAmD;AAAA,IACtD,SAAS,MAAM,IAAI,IAAI,aAAa,KAAK;AAAA,IACzC,QAAQ,CAAC,SAAS,QAAQ,KAAK,OAAO;AAAA,IACtC,SAAS,CAAC,SAAS,oBAAoB,KAAK,OAAO;AAAA,IACnD,QAAQ,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,MAAM,OAAO,MAAM,KAAK;AAAA;AAAA;ACY/D,MAAM,YAAY,CAAC,EAAE,MAAM,SAAS,UAAU,YAAkB;;;IAC5D,GAAG,OAAO,SAAS,aAAa,KAAK,OAAQ,UAAI,IAAI,iBAAiB,IAAI,WAAW,UAAxC,mBAA+C;AAAA,IAC5F,SAAS,OAAO,YAAY,WAAW,MAAM,IAAI,IAAI,aAAa,KAAK,WAAW,QAAQ;AAAA,IAC1F,SAAS,SAAS;AAAA,IAClB,QAAQ,SAAS;AAAA,IACjB,QAAQ,CAAC,SAAqB,CAAC,SAAS,KAAK;AAAA;AAAA;MAkBpC,YAAY,CAAC,QAAgB,KAAU,UAA8C;QACxF,EAAE,UAAU;QACZ,cAAc;MAChB,OAAO,UAAU,aAAa;AAC7B,UAAsB,QAAQ,CAAC,SAAS;kBACzB,KAAK,UAAU,MAAM;AAAA;AAAA;SAGlC;AAAA,KACF,IAA0B,iBAAiB,KAAK,QAAQ,cAAc,MAAM,WAAW,MAAM;AAAA,KAC7F,IAA4B,iBAAiB,KAAK,UAAU,gBAAgB,MAAM,OAAO,MAAM;AAAA,KAC/F,IAA4B,iBACzB,KACA,iBACA,uBACA,MAAM,mBACN,MAAM;AAAA,KAET,IAA0B,iBACvB,KACA,QACA,oBACA,MAAM,gBACN,MAAM;AAAA,KAET,IAA0B,iBAAiB,KAAK,QAAQ,cAAc,MAAM,SAAS,MAAM;AAAA,KACzF;AAAA;MC7EE,gBAAgB,CAAC,SAAsB,MAAkB,aAAsB;UAChF,UAAU,OAAO;wBACH,MAAM,SAAS,CAAC,OAAO,KAAK,QAAQ,WAAW;UAC3D,UAAU,QAAQ;QACpB,CAAC,SAAS;YACJ,IAAI;AAAA;UAER,iBAAiB,IAAI,OAAO,MAAM;QACpC,OAAO,MAAM,OAAO,OAAO,eAAe,QAAQ,kBAAkB;QACpE,MAAM,MAAM,MAAM,OAAO,MAAM,OAAO,SAAS,KAAK,QAAQ;QAE5D,OAAO;aAAU;QAEjB,MAAM,MAAM,OAAO,MAAM,OAAO,UAAW,YAAY,OAAO,SAAS,MAAM,SAAS,OAAO,QAAS;YAChG,MAAM,SAAS,OAAO,MAAM,KAAK,QAAQ;AAAA;WAE5C,CAAC,KAAK;AAAA;AAAA;MChBR,cAAc,CAAC,cAA4B,EAAE,UAAmB;QACnE,UAAU,CAAC,OAAc,UAAU,MAAM,aAAa,IAAI,YAAY,CAAC,OAAO;QAC9E,YAAY,aAAa,IAAI,WAAW;SACvC;AAAA;AAAA;AAAA;AAAA;AAAA,yBAKc,aAAa,IAAI,WAAW;AAAA;AAAA;AAAA,UAG3C,aAAa,IAAI,aAAa;AAAA,UAC9B,aAAa,IAAI,aAAa;AAAA;AAAA;AAAA,sBAGlB,QAAQ;AAAA;AAAA;AAAA;AAAA,qBAIT,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oCAOF,QAAQ,aAAa;AAAA;AAAA;AAAA,yBAGhC,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qCAMI;AAAA,yBACZ;AAAA;AAAA,8BAEK,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;MC7BzB,gBAAgB,CAAC,YAAsB,OAAc,cAA+B;QACvF,MAAM,SAAS,cAAc;QAC7B,aAAa,QAAQ,MAAM;UACvB,QAAQ,MAAM,SAAS,CAAC,YAAY,YAAY,MAAM,cAAc,aAAa;QACnF,OAAO;UACH,UAAU,IAAI;AAAA;AAAA;MAItB,UAAU,IAAI,MAAM,aAAa,IAAI;SAElC;AAAA,IACH,KAAK;AAAA,IACL,QAAQ,CAAC,eAA2B;;aACzB,OAAO,YACT,OAAO,CAAC,SAAS,KAAK,OAAO,eAAe,KAAK,KAAK,MACtD,QAAQ,CAAC,EAAE,QAAQ,IAAI,YAAY;uBAE7B,IAAI,kCAAY,YAAY;AAAA;AAAA;AAAA;MCzBtC,WAAW,CAAC,YAAsB,SAAqB;SACzD,OAAO,OAAO,YAChB,OAAO,CAAC,SAAS,KAAK,OAAO,SAAS,KAAK,KAAK,MAChD,MAAM,CAAC,EAAE,QAAQ,EAAE,UAAU,SAAS;AAAA;MCFlC,eAAe,CAAC,YAAsB,SAAqB;SAC7D,OAAO,YACT,OAAO,CAAC,SAAS,KAAK,OAAO,SAAS,KAAK,KAAK,MAChD,QAAQ,CAAC,SAAS;;UACT,UAAU,WAAK,YAAL,8BAAe;QAC3B,SAAS;WACJ,EAAE,UAAU,IAAI;;;SAIpB,EAAE,UAAU,OAAO;UAElB,SAAS,KAAK,OAAO;QACvB,QAAQ;WACH,EAAE,UAAU,IAAI;;;SAGpB,EAAE,UAAU,OAAO;AAAA;SAGzB,SAAS,YAAW;AAAA;MCjBlB,sBAAsB,CAC/B,YACA,OACA,QACA,uBACC;QACK,EAAE,KAAK,SAAS,WAAW,cAAc,YAAW,OAAO;QAE3D,UAAU,CAAC,MAAa;UACpB,SAAS,OAAO,OAAO,YAAW,KAAK,CAAC,EAAE,QAAQ,EAAE,kBAAkB,WAAW,EAAE,SAAS,EAAE;QAChG,CAAC;;MAEH;MACA;WACK;AAAA;QAGL,OAAO,MAAM;YACP,UAAU,IAAI;AAAA;UAGlB,iBAAiB,aAAa;SAE/B;AAAA,IACH,SAAS,MAAM;cACH,oBAAoB,aAAa;cACjC;AAAA;AAAA,IAEZ;AAAA,IACA,QAAQ,CAAC,eAA2B;YAC1B,YAAW,aAAa,YAAW;UACrC,WAAU;;;;oBAIA,SAAS,YAAY;AAAA;AAAA,IAEvC;AAAA;AAAA;MCvCK,eAAe,CAAC,YAAsB,OAAc,QAAiB,uBAA+B;MACzG,gBAAgB,oBAAoB,YAAW,OAAO,QAAQ;MAC9D,aAAa;QAEX,OAAO,MAAM;kBACD;AAAA;QAGZ,SAAS,CAAC,MAAkB,cAA4B;UACpD,EAAE,UAAU;QAEd,CAAC,KAAK,YAAY,YAAY;;;;UAK5B,mBAAmB,wCAAW,IAAI,GAAG,MAAM,SAAQ,UAAU,UAAU,GAAG,MAAM;QAClF;;kBAEU,OAAO;AAAA;SAGlB;AAAA,IACH,UAAU,CAAC,eAA2B;sBAClB,oBAAoB,YAAW,OAAO,QAAQ;oBAChD,OAAO;aACd;AAAA;AAAA,IAEX;AAAA,IACA,SAAS,MAAM;oBACG;AAAA;AAAA,IAElB,QAAQ,CAAC,eAA2B;oBAClB,OAAO;aACd;AAAA;AAAA,IAEX,SAAS,CAAC,aAAsB;mBACf;AAAA;AAAA;AAAA;MCpCZ,MAAM,IAAI,UAAU;MAEpB,gBAAgBA,eAA+B,CAAC,OAAO,YAAY;SACrE;AAAA,IACH,IAAI;AAAA,IACJ,cAAc,CAAC,GAAG,QAAQ;;YAChB,SAAS,IAAI,IAAI;YACjB,UAAU,aACZ,UAAU,QAAQ,KAAK,mCAAS,QAChC,OACA,yCAAS,WAAT,YAAmB,OACnB;YAEE,SAAS,IAAI,OAAO;AAAA,QACtB;AAAA,QACA,OAAO;AAAA,UACH,eAAe,MAAM;oBACT,QAAQ;mBACT;AAAA;AAAA,UAEX,aAAa,CAAC,SAAS;oBACX,QAAQ;oBACR,OAAO;mBACR;AAAA;AAAA,UAEX,iBAAiB;AAAA,YACb,WAAW,MAAM;sBACL,QAAQ;qBACT;AAAA;AAAA;AAAA;AAAA,QAInB,MAAM,CAAC,eAAe;kBACV,SAAS;iBACV;AAAA,YACH,QAAQ,QAAQ;AAAA,YAChB,SAAS,QAAQ;AAAA;AAAA;AAAA;aAItB,CAAC;AAAA;AAAA;AAAA;MAKP,UAAU,SAAS,OAAO,CAAC;;"}
package/lib/item.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { Ctx } from '@milkdown/core';
2
+ import type { Icon } from '@milkdown/design-system';
3
+ import { EditorView, Schema } from '@milkdown/prose';
4
+ export declare type Pred = (view: EditorView) => boolean;
5
+ export declare type Updater = (view: EditorView, $: HTMLElement) => void;
6
+ export declare type Event2Command = (e: Event) => void;
7
+ export declare type OnClick = (ctx: Ctx) => void;
8
+ export declare type Item = {
9
+ icon: Icon | ((ctx: Ctx) => HTMLElement);
10
+ onClick: string | ((ctx: Ctx) => () => void);
11
+ isHidden: (ctx: Ctx) => Pred;
12
+ isActive: (ctx: Ctx) => Pred;
13
+ };
14
+ export declare type ButtonItem = {
15
+ $: HTMLElement;
16
+ command: () => void;
17
+ active: Pred;
18
+ disable?: Pred;
19
+ enable: Pred;
20
+ };
21
+ export declare enum ButtonAction {
22
+ ToggleBold = 0,
23
+ ToggleItalic = 1,
24
+ ToggleStrike = 2,
25
+ ToggleCode = 3,
26
+ ToggleLink = 4
27
+ }
28
+ export declare type ButtonMap = Record<ButtonAction, ButtonItem>;
29
+ export declare type TooltipOptions = {
30
+ bottom: boolean;
31
+ items: Array<Item> | undefined;
32
+ };
33
+ export declare const buttonMap: (schema: Schema, ctx: Ctx, items: Array<Item> | undefined) => ButtonMap;
34
+ //# sourceMappingURL=item.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item.d.ts","sourceRoot":"","sources":["../src/item.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,GAAG,EAA8B,MAAM,gBAAgB,CAAC;AAC9E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIrD,oBAAY,IAAI,GAAG,CAAC,IAAI,EAAE,UAAU,KAAK,OAAO,CAAC;AACjD,oBAAY,OAAO,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC;AACjE,oBAAY,aAAa,GAAG,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;AAE/C,oBAAY,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;AAEzC,oBAAY,IAAI,GAAG;IACf,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,WAAW,CAAC,CAAC;IAEzC,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;IAE7C,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;IAE7B,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;CAChC,CAAC;AAEF,oBAAY,UAAU,GAAG;IACrB,CAAC,EAAE,WAAW,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,IAAI,CAAC;IACb,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,MAAM,EAAE,IAAI,CAAC;CAChB,CAAC;AAUF,oBAAY,YAAY;IACpB,UAAU,IAAA;IACV,YAAY,IAAA;IACZ,YAAY,IAAA;IACZ,UAAU,IAAA;IACV,UAAU,IAAA;CACb;AAED,oBAAY,SAAS,GAAG,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AAEzD,oBAAY,cAAc,GAAG;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,SAAS,WAAY,MAAM,OAAO,GAAG,SAAS,MAAM,IAAI,CAAC,GAAG,SAAS,KAAG,SA4BpF,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import type { EditorState, EditorView } from '@milkdown/prose';
2
2
  import { Utils } from '@milkdown/utils';
3
- import type { ButtonMap, InputMap } from './item';
4
- export declare const createPlugin: (buttonMap: ButtonMap, inputMap: InputMap, utils: Utils) => {
3
+ import type { ButtonMap } from './item';
4
+ export declare const createPlugin: (buttonMap: ButtonMap, utils: Utils, bottom: boolean, containerClassName: string) => {
5
+ recreate: (editorView: EditorView) => void;
5
6
  update: (view: EditorView, prevState?: EditorState<any> | undefined) => void;
6
7
  destroy: () => void;
7
8
  render: (editorView: EditorView) => void;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-marks-tooltip.d.ts","sourceRoot":"","sources":["../src/selection-marks-tooltip.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAGxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,eAAO,MAAM,YAAY,cAAe,SAAS,SAAS,KAAK,UAAU,OAAO,sBAAsB,MAAM;2BAuB7E,UAAU;mBAff,UAAU;;yBAwBP,UAAU;wBAIX,OAAO;CAIlC,CAAC"}
File without changes
@@ -0,0 +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,OACxB,CAAC"}
@@ -1,5 +1,4 @@
1
1
  export * from './element';
2
- export * from './input';
3
2
  export * from './prosemirror';
4
3
  export * from './toggle';
5
4
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utility/index.ts"],"names":[],"mappings":"AACA,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC"}
File without changes
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prosemirror.d.ts","sourceRoot":"","sources":["../../src/utility/prosemirror.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAkB,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAiB,MAAM,iBAAiB,CAAC;AAEvG,oBAAY,QAAQ,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,OAAO,gBAAiB,WAAW,uCAAoB,OAOnE,CAAC;AAEF,eAAO,MAAM,eAAe,gBAAiB,WAAW,KAAG,OAU1D,CAAC;AAEF,eAAO,MAAM,aAAa,gBAAiB,WAAW,KAAG,OAC0B,CAAC;AAEpF,eAAO,MAAM,mBAAmB,gBAAiB,WAAW,uCAAoB,OACa,CAAC;AAE9F,eAAO,MAAM,aAAa,aAAc,QAAQ,QAAQ,IAAI,YAE3D,CAAC"}
File without changes
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toggle.d.ts","sourceRoot":"","sources":["../../src/utility/toggle.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,GAAG,EAA8B,MAAM,gBAAgB,CAAC;AAC9E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAG1C,eAAO,MAAM,gBAAgB,QACpB,GAAG,YACE,IAAI,OACT,MAAM,QACL,QAAQ,GAAG,SAAS,kBACV,QAAQ,GAAG,SAAS,KACrC,UAMD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milkdown/plugin-tooltip",
3
- "version": "5.5.0",
3
+ "version": "6.0.0",
4
4
  "type": "module",
5
5
  "main": "./lib/index.es.js",
6
6
  "types": "./lib/index.d.ts",
@@ -15,23 +15,47 @@
15
15
  "milkdown plugin"
16
16
  ],
17
17
  "devDependencies": {
18
- "@milkdown/core": "5.5.0",
19
- "@milkdown/prose": "5.5.0",
20
- "@milkdown/design-system": "5.5.0"
18
+ "@milkdown/core": "6.0.0",
19
+ "@milkdown/prose": "6.0.0",
20
+ "@milkdown/design-system": "6.0.0"
21
21
  },
22
22
  "peerDependencies": {
23
- "@milkdown/core": "^5.4.0",
24
- "@milkdown/prose": "^5.4.0"
23
+ "@milkdown/core": "^6.0.0-next.0",
24
+ "@milkdown/prose": "^6.0.0-next.0"
25
25
  },
26
26
  "dependencies": {
27
- "@milkdown/utils": "5.5.0",
27
+ "@milkdown/utils": "6.0.0",
28
28
  "tslib": "^2.3.1"
29
29
  },
30
+ "nx": {
31
+ "targets": {
32
+ "build": {
33
+ "outputs": [
34
+ "packages/plugin-tooltip/lib"
35
+ ],
36
+ "dependsOn": [
37
+ {
38
+ "target": "build",
39
+ "projects": "dependencies"
40
+ }
41
+ ]
42
+ },
43
+ "tsc": {
44
+ "outputs": [],
45
+ "dependsOn": [
46
+ {
47
+ "target": "build",
48
+ "projects": "dependencies"
49
+ }
50
+ ]
51
+ }
52
+ }
53
+ },
30
54
  "scripts": {
31
- "start": "vite build --watch",
55
+ "start": "concurrently -n es,dts \"vite build --watch\" \"tsc --emitDeclarationOnly --watch\"",
32
56
  "test": "vitest",
33
57
  "tsc": "tsc --noEmit",
34
- "build": "vite build"
58
+ "build": "vite build && tsc --emitDeclarationOnly"
35
59
  },
36
- "readme": "# @milkdown/plugin-tooltip\n\nTooltip plugin for [milkdown](https://saul-mirone.github.io/milkdown/).\nAdd support for tooltip commands.\n\n# Example Usage\n\n```typescript\nimport { Editor } from '@milkdown/core';\nimport { commonmark } from '@milkdown/preset-commonmark';\nimport { nord } from '@milkdown/theme-nord';\n\nimport { tooltip } from '@milkdown/plugin-tooltip';\n\nEditor.make().use(nord).use(commonmark).use(tooltip).create();\n```\n\n# Placeholder\n\nModify the input widgets of link and image.\n\nExample:\n\n```typescript\nimport { tooltipPlugin, tooltip } from '@milkdown/plugin-tooltip';\n\nEditor.make().use(\n tooltip.configure(tooltipPlugin, {\n link: {\n placeholder: 'Please input link...',\n buttonText: 'Confirm',\n },\n image: {\n placeholder: 'Please input image link...',\n buttonText: 'OK',\n },\n inlineMath: {\n placeholder: 'Please input inline math...',\n },\n }),\n);\n```\n\n# License\n\nMilkdown is open sourced software licensed under [MIT license](https://github.com/Saul-Mirone/milkdown/blob/main/LICENSE).\n"
60
+ "readme": "# @milkdown/plugin-tooltip\n\nTooltip plugin for [milkdown](https://saul-mirone.github.io/milkdown/).\nAdd support for tooltip commands.\n\n# Example Usage\n\n```typescript\nimport { Editor } from '@milkdown/core';\nimport { commonmark } from '@milkdown/preset-commonmark';\nimport { nord } from '@milkdown/theme-nord';\n\nimport { tooltip } from '@milkdown/plugin-tooltip';\n\nEditor.make().use(nord).use(commonmark).use(tooltip).create();\n```\n\n# Position\n\nModify the tooltip widget's position, to show on the top or the bottom\n\nExample:\n\n```typescript\nimport { tooltipPlugin, tooltip } from '@milkdown/plugin-tooltip';\n\nEditor.make().use(\n tooltip.configure(tooltipPlugin, {\n bottom: true,\n }),\n);\n```\n\n# License\n\nMilkdown is open sourced software licensed under [MIT license](https://github.com/Saul-Mirone/milkdown/blob/main/LICENSE).\n"
37
61
  }
@@ -1,7 +1,7 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
2
  import { calculateTextPosition, EditorView } from '@milkdown/prose';
3
3
 
4
- export const calcButtonPos = (buttons: HTMLElement, view: EditorView) => {
4
+ export const calcButtonPos = (buttons: HTMLElement, view: EditorView, isBottom: boolean) => {
5
5
  buttons.classList.remove('hide');
6
6
  calculateTextPosition(view, buttons, (start, end, target, parent) => {
7
7
  const $editor = buttons.parentElement;
@@ -14,10 +14,9 @@ export const calcButtonPos = (buttons: HTMLElement, view: EditorView) => {
14
14
 
15
15
  if (left < 0) left = 0;
16
16
 
17
- if (start.top < target.height) {
17
+ if (start.top - parent.top < target.height || (isBottom && parent.bottom - start.bottom > target.height)) {
18
18
  top = start.bottom - parent.top + 14 + $editor.scrollTop;
19
19
  }
20
-
21
20
  return [top, left];
22
21
  });
23
22
  };
@@ -10,20 +10,22 @@ type Tooltip = {
10
10
  render: (editorView: EditorView) => void;
11
11
  };
12
12
 
13
- export const createTooltip = (buttonMap: ButtonMap, utils: Utils): Tooltip => {
13
+ export const createTooltip = (buttonMap: ButtonMap, utils: Utils, className: string): Tooltip => {
14
14
  const div = document.createElement('div');
15
- const style = utils.getStyle(injectStyle) || '';
16
- if (style) {
17
- div.classList.add(style);
18
- }
15
+ utils.themeManager.onFlush(() => {
16
+ const style = utils.getStyle((emotion) => injectStyle(utils.themeManager, emotion)) || '';
17
+ if (style) {
18
+ div.classList.add(style);
19
+ }
20
+ });
19
21
 
20
- div.classList.add('tooltip');
22
+ div.classList.add(utils.getClassName({}, className));
21
23
 
22
24
  return {
23
25
  dom: div,
24
26
  render: (editorView: EditorView) => {
25
27
  Object.values(buttonMap)
26
- .filter((item) => item.enable(editorView))
28
+ .filter((item) => item.enable(editorView) && item.$ != null)
27
29
  .forEach(({ $ }) => div.appendChild($));
28
30
 
29
31
  editorView.dom.parentNode?.appendChild(div);
@@ -6,7 +6,7 @@ import { noActive } from './no-active';
6
6
 
7
7
  export const filterButton = (buttonMap: ButtonMap, view: EditorView) => {
8
8
  Object.values(buttonMap)
9
- .filter((item) => item.enable(view))
9
+ .filter((item) => item.enable(view) && item.$ != null)
10
10
  .forEach((item) => {
11
11
  const disable = item.disable?.(view);
12
12
  if (disable) {
@@ -7,8 +7,13 @@ import { calcButtonPos } from './calc-button-pos';
7
7
  import { createTooltip } from './create-tooltip';
8
8
  import { filterButton } from './filter-button';
9
9
 
10
- export const createButtonManager = (buttonMap: ButtonMap, utils: Utils) => {
11
- const { dom: buttons, render } = createTooltip(buttonMap, utils);
10
+ export const createButtonManager = (
11
+ buttonMap: ButtonMap,
12
+ utils: Utils,
13
+ bottom: boolean,
14
+ containerClassName: string,
15
+ ) => {
16
+ const { dom: buttons, render } = createTooltip(buttonMap, utils, containerClassName);
12
17
 
13
18
  const onClick = (e: Event) => {
14
19
  const target = Object.values(buttonMap).find(({ $ }) => e.target instanceof Element && $.contains(e.target));
@@ -37,7 +42,7 @@ export const createButtonManager = (buttonMap: ButtonMap, utils: Utils) => {
37
42
  hide();
38
43
  return;
39
44
  }
40
- calcButtonPos(buttons, editorView);
45
+ calcButtonPos(buttons, editorView, bottom);
41
46
  },
42
47
  render,
43
48
  };
@@ -5,6 +5,6 @@ import { ButtonMap } from '../item';
5
5
 
6
6
  export const noActive = (buttonMap: ButtonMap, view: EditorView) => {
7
7
  return Object.values(buttonMap)
8
- .filter((item) => item.enable(view))
8
+ .filter((item) => item.enable(view) && item.$ != null)
9
9
  .every(({ $ }) => $.classList.contains('hide'));
10
10
  };
@@ -1,18 +1,19 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { Emotion, ThemeTool } from '@milkdown/core';
2
+ import { Color, Emotion, ThemeBorder, ThemeColor, ThemeManager, ThemeShadow, ThemeSize } from '@milkdown/core';
3
3
 
4
- export const injectStyle = (themeTool: ThemeTool, { css }: Emotion) => {
5
- const { palette, mixin, size } = themeTool;
4
+ export const injectStyle = (themeManager: ThemeManager, { css }: Emotion) => {
5
+ const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);
6
+ const lineWidth = themeManager.get(ThemeSize, 'lineWidth');
6
7
  return css`
7
8
  display: inline-flex;
8
9
  cursor: pointer;
9
10
  justify-content: space-evenly;
10
11
  position: absolute;
11
- border-radius: ${size.radius};
12
+ border-radius: ${themeManager.get(ThemeSize, 'radius')};
12
13
  z-index: 2;
13
14
 
14
- ${mixin.border?.()};
15
- ${mixin.shadow?.()};
15
+ ${themeManager.get(ThemeBorder, undefined)}
16
+ ${themeManager.get(ThemeShadow, undefined)}
16
17
 
17
18
  overflow: hidden;
18
19
  background: ${palette('surface')};
@@ -21,8 +22,8 @@ export const injectStyle = (themeTool: ThemeTool, { css }: Emotion) => {
21
22
  position: relative;
22
23
  color: ${palette('solid', 0.87)};
23
24
 
24
- width: 3rem;
25
- line-height: 3rem;
25
+ width: 2em;
26
+ line-height: 2em;
26
27
  text-align: center;
27
28
  transition: all 0.4s ease-in-out;
28
29
  &:hover {
@@ -35,8 +36,8 @@ export const injectStyle = (themeTool: ThemeTool, { css }: Emotion) => {
35
36
  content: '';
36
37
  position: absolute;
37
38
  top: 0;
38
- right: calc(-0.5 * ${size.lineWidth});
39
- width: ${size.lineWidth};
39
+ right: calc(-0.5 * ${lineWidth});
40
+ width: ${lineWidth};
40
41
  bottom: 0;
41
42
  background: ${palette('line')};
42
43
  }
package/src/index.ts CHANGED
@@ -3,35 +3,21 @@ import { schemaCtx } from '@milkdown/core';
3
3
  import { Plugin, PluginKey } from '@milkdown/prose';
4
4
  import { AtomList, createPlugin as create } from '@milkdown/utils';
5
5
 
6
- import { buttonMap, inputMap, InputOptions } from './item';
6
+ import { buttonMap, TooltipOptions } from './item';
7
7
  import { createPlugin } from './selection-marks-tooltip';
8
8
 
9
9
  export const key = new PluginKey('MILKDOWN_PLUGIN_TOOLTIP');
10
10
 
11
- export const tooltipPlugin = create<string, InputOptions>((utils, options) => {
11
+ export const tooltipPlugin = create<string, TooltipOptions>((utils, options) => {
12
12
  return {
13
13
  id: 'tooltip',
14
14
  prosePlugins: (_, ctx) => {
15
15
  const schema = ctx.get(schemaCtx);
16
16
  const manager = createPlugin(
17
- buttonMap(schema, ctx),
18
- inputMap(schema, ctx, {
19
- link: {
20
- placeholder: 'Input Web Link',
21
- buttonText: 'APPLY',
22
- ...(options?.link ?? {}),
23
- },
24
- image: {
25
- placeholder: 'Input Image Link',
26
- buttonText: 'APPLY',
27
- ...(options?.image ?? {}),
28
- },
29
- inlineMath: {
30
- placeholder: 'Input Math',
31
- ...(options?.inlineMath ?? {}),
32
- },
33
- }),
17
+ buttonMap(schema, ctx, options?.items),
34
18
  utils,
19
+ options?.bottom ?? false,
20
+ 'tooltip',
35
21
  );
36
22
  const plugin = new Plugin({
37
23
  key,
@@ -53,7 +39,7 @@ export const tooltipPlugin = create<string, InputOptions>((utils, options) => {
53
39
  },
54
40
  },
55
41
  view: (editorView) => {
56
- manager.render(editorView);
42
+ manager.recreate(editorView);
57
43
  return {
58
44
  update: manager.update,
59
45
  destroy: manager.destroy,
package/src/item.ts CHANGED
@@ -1,22 +1,26 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { Ctx } from '@milkdown/core';
3
- import { EditorView, findSelectedNodeOfType, Schema, TextSelection } from '@milkdown/prose';
2
+ import { commandsCtx, Ctx, ThemeIcon, themeManagerCtx } from '@milkdown/core';
3
+ import type { Icon } from '@milkdown/design-system';
4
+ import { EditorView, Schema } from '@milkdown/prose';
4
5
 
5
- import {
6
- createToggleIcon,
7
- hasMark,
8
- modifyImage,
9
- modifyInlineMath,
10
- modifyLink,
11
- updateImageView,
12
- updateInlineMathView,
13
- updateLinkView,
14
- } from './utility';
6
+ import { createToggleIcon } from './utility';
15
7
 
16
8
  export type Pred = (view: EditorView) => boolean;
17
9
  export type Updater = (view: EditorView, $: HTMLElement) => void;
18
10
  export type Event2Command = (e: Event) => void;
19
11
 
12
+ export type OnClick = (ctx: Ctx) => void;
13
+
14
+ export type Item = {
15
+ icon: Icon | ((ctx: Ctx) => HTMLElement);
16
+
17
+ onClick: string | ((ctx: Ctx) => () => void);
18
+
19
+ isHidden: (ctx: Ctx) => Pred;
20
+
21
+ isActive: (ctx: Ctx) => Pred;
22
+ };
23
+
20
24
  export type ButtonItem = {
21
25
  $: HTMLElement;
22
26
  command: () => void;
@@ -25,20 +29,13 @@ export type ButtonItem = {
25
29
  enable: Pred;
26
30
  };
27
31
 
28
- export type InputItem = {
29
- command: Event2Command;
30
- display: Pred;
31
- update: Updater;
32
- placeholder: string;
33
- } & (
34
- | {
35
- bind: true;
36
- }
37
- | {
38
- bind?: false;
39
- buttonText: string;
40
- }
41
- );
32
+ const Buttonize = ({ icon, onClick, isHidden, isActive }: Item, ctx: Ctx): ButtonItem => ({
33
+ $: typeof icon === 'function' ? icon(ctx) : (ctx.get(themeManagerCtx).get(ThemeIcon, icon)?.dom as HTMLElement),
34
+ command: typeof onClick === 'string' ? () => ctx.get(commandsCtx).call(onClick) : onClick(ctx),
35
+ disable: isHidden(ctx),
36
+ active: isActive(ctx),
37
+ enable: (view: EditorView) => !isHidden(ctx)(view),
38
+ });
42
39
 
43
40
  export enum ButtonAction {
44
41
  ToggleBold,
@@ -48,60 +45,21 @@ export enum ButtonAction {
48
45
  ToggleLink,
49
46
  }
50
47
 
51
- export enum InputAction {
52
- ModifyLink,
53
- ModifyImage,
54
- ModifyInlineMath,
55
- }
56
-
57
48
  export type ButtonMap = Record<ButtonAction, ButtonItem>;
58
- export type InputMap = Record<InputAction, InputItem>;
59
49
 
60
- export type InputOptions = {
61
- link: {
62
- placeholder: string;
63
- buttonText: string;
64
- };
65
- image: {
66
- placeholder: string;
67
- buttonText: string;
68
- };
69
- inlineMath: {
70
- placeholder: string;
71
- };
72
- };
73
-
74
- export const inputMap = (schema: Schema, ctx: Ctx, inputOptions: InputOptions): InputMap => {
75
- const { marks, nodes } = schema;
76
- return {
77
- [InputAction.ModifyLink]: {
78
- display: (view) =>
79
- view.state.selection.empty &&
80
- view.state.selection instanceof TextSelection &&
81
- hasMark(view.state, marks['link']),
82
- command: modifyLink(ctx),
83
- update: updateLinkView,
84
- ...inputOptions.link,
85
- },
86
- [InputAction.ModifyInlineMath]: {
87
- display: (view) =>
88
- Boolean(nodes['math_inline'] && findSelectedNodeOfType(view.state.selection, nodes['math_inline'])),
89
- command: modifyInlineMath(ctx),
90
- update: updateInlineMathView,
91
- bind: true,
92
- ...inputOptions.inlineMath,
93
- },
94
- [InputAction.ModifyImage]: {
95
- display: (view) => Boolean(nodes['image'] && findSelectedNodeOfType(view.state.selection, nodes['image'])),
96
- command: modifyImage(ctx),
97
- update: updateImageView,
98
- ...inputOptions.image,
99
- },
100
- };
50
+ export type TooltipOptions = {
51
+ bottom: boolean;
52
+ items: Array<Item> | undefined;
101
53
  };
102
54
 
103
- export const buttonMap = (schema: Schema, ctx: Ctx): ButtonMap => {
55
+ export const buttonMap = (schema: Schema, ctx: Ctx, items: Array<Item> | undefined): ButtonMap => {
104
56
  const { marks } = schema;
57
+ const ButtonItems = Array<ButtonItem>();
58
+ if (typeof items !== 'undefined') {
59
+ (items as Array<Item>).forEach((item) => {
60
+ ButtonItems.push(Buttonize(item, ctx));
61
+ });
62
+ }
105
63
  return {
106
64
  [ButtonAction.ToggleBold]: createToggleIcon(ctx, 'bold', 'ToggleBold', marks['strong'], marks['code_inline']),
107
65
  [ButtonAction.ToggleItalic]: createToggleIcon(ctx, 'italic', 'ToggleItalic', marks['em'], marks['code_inline']),
@@ -120,5 +78,6 @@ export const buttonMap = (schema: Schema, ctx: Ctx): ButtonMap => {
120
78
  marks['link'],
121
79
  ),
122
80
  [ButtonAction.ToggleLink]: createToggleIcon(ctx, 'link', 'ToggleLink', marks['link'], marks['code_inline']),
81
+ ...ButtonItems,
123
82
  };
124
83
  };