@milkdown/plugin-tooltip 7.6.1 → 7.6.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/README.md CHANGED
@@ -4,7 +4,7 @@ The tooltip plugin of [milkdown](https://milkdown.dev/).
4
4
 
5
5
  # Official Documentation
6
6
 
7
- Documentation can be found on the [Milkdown website](https://milkdown.dev/docs/api/plugin-tooltip).
7
+ Documentation can be found on the [Milkdown website](https://milkdown.dev/).
8
8
 
9
9
  # License
10
10
 
package/lib/index.es.js CHANGED
@@ -1,92 +1,93 @@
1
- var S = (s) => {
2
- throw TypeError(s);
1
+ var S = (o) => {
2
+ throw TypeError(o);
3
3
  };
4
- var P = (s, t, e) => t.has(s) || S("Cannot " + e);
5
- var i = (s, t, e) => (P(s, t, "read from private field"), e ? e.call(s) : t.get(s)), n = (s, t, e) => t.has(s) ? S("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(s) : t.set(s, e), l = (s, t, e, o) => (P(s, t, "write to private field"), o ? o.call(s, e) : t.set(s, e), e), b = (s, t, e) => (P(s, t, "access private method"), e);
4
+ var T = (o, t, e) => t.has(o) || S("Cannot " + e);
5
+ var i = (o, t, e) => (T(o, t, "read from private field"), e ? e.call(o) : t.get(o)), n = (o, t, e) => t.has(o) ? S("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(o) : t.set(o, e), l = (o, t, e, s) => (T(o, t, "write to private field"), s ? s.call(o, e) : t.set(o, e), e), b = (o, t, e) => (T(o, t, "access private method"), e);
6
6
  import { TextSelection as H, Plugin as M, PluginKey as R } from "@milkdown/prose/state";
7
7
  import U from "lodash.throttle";
8
8
  import { computePosition as C, flip as E, offset as I, shift as j } from "@floating-ui/dom";
9
9
  import { posToDOMRect as q } from "@milkdown/prose";
10
10
  import { $ctx as K, $prose as L } from "@milkdown/utils";
11
- var d, f, u, a, c, m, g, $, _;
11
+ var d, u, f, c, g, r, m, y, x, _;
12
12
  class V {
13
13
  constructor(t) {
14
- n(this, $);
14
+ n(this, x);
15
15
  /// @internal
16
16
  n(this, d);
17
17
  /// @internal
18
- n(this, f);
19
- /// @internal
20
18
  n(this, u);
21
19
  /// @internal
22
- n(this, a);
20
+ n(this, f);
21
+ /// @internal
23
22
  n(this, c);
24
23
  /// @internal
25
- n(this, m);
26
24
  n(this, g);
27
- l(this, c, !1), this.onShow = () => {
25
+ n(this, r);
26
+ /// @internal
27
+ n(this, m);
28
+ n(this, y);
29
+ l(this, r, !1), this.onShow = () => {
28
30
  }, this.onHide = () => {
29
- }, l(this, g, (e, o) => {
30
- var T;
31
- const { state: h, composing: p } = e, { selection: y, doc: x } = h, { ranges: w } = y, k = Math.min(...w.map((r) => r.$from.pos)), O = Math.max(...w.map((r) => r.$to.pos)), B = o && o.doc.eq(x) && o.selection.eq(y);
32
- if (i(this, c) || ((T = e.dom.parentElement) == null || T.appendChild(this.element), l(this, c, !0)), p || B) return;
33
- if (!i(this, f).call(this, e, o)) {
31
+ }, l(this, y, (e, s) => {
32
+ const { state: h, composing: p } = e, { selection: w, doc: k } = h, { ranges: $ } = w, O = Math.min(...$.map((a) => a.$from.pos)), P = Math.max(...$.map((a) => a.$to.pos)), B = s && s.doc.eq(k) && s.selection.eq(w);
33
+ if (i(this, r) || ((i(this, g) ?? e.dom.parentElement ?? document.body).appendChild(this.element), l(this, r, !0)), p || B) return;
34
+ if (!i(this, u).call(this, e, s)) {
34
35
  this.hide();
35
36
  return;
36
37
  }
37
38
  C({
38
- getBoundingClientRect: () => q(e, k, O)
39
+ getBoundingClientRect: () => q(e, O, P)
39
40
  }, this.element, {
40
- placement: i(this, a).placement ?? "top",
41
- middleware: [E(), I(i(this, m)), j(), ...i(this, u)]
42
- }).then(({ x: r, y: F }) => {
41
+ placement: i(this, c).placement ?? "top",
42
+ middleware: [E(), I(i(this, m)), j(), ...i(this, f)]
43
+ }).then(({ x: a, y: F }) => {
43
44
  Object.assign(this.element.style, {
44
- left: `${r}px`,
45
+ left: `${a}px`,
45
46
  top: `${F}px`
46
47
  });
47
48
  }), this.show();
48
- }), this.update = (e, o) => {
49
- U(i(this, g), i(this, d))(e, o);
49
+ }), this.update = (e, s) => {
50
+ U(i(this, y), i(this, d))(e, s);
50
51
  }, this.destroy = () => {
51
52
  }, this.show = (e) => {
52
53
  this.element.dataset.show = "true", e && C(e, this.element, {
53
54
  placement: "top",
54
55
  middleware: [E(), I(i(this, m))],
55
- ...i(this, a)
56
- }).then(({ x: o, y: h }) => {
56
+ ...i(this, c)
57
+ }).then(({ x: s, y: h }) => {
57
58
  Object.assign(this.element.style, {
58
- left: `${o}px`,
59
+ left: `${s}px`,
59
60
  top: `${h}px`
60
61
  });
61
62
  }), this.onShow();
62
63
  }, this.hide = () => {
63
64
  this.element.dataset.show !== "false" && (this.element.dataset.show = "false", this.onHide());
64
- }, this.element = t.content, l(this, d, t.debounce ?? 200), l(this, f, t.shouldShow ?? b(this, $, _)), l(this, m, t.offset), l(this, u, t.middleware ?? []), l(this, a, t.floatingUIOptions ?? {}), this.element.dataset.show = "false";
65
+ }, this.element = t.content, l(this, d, t.debounce ?? 200), l(this, u, t.shouldShow ?? b(this, x, _)), l(this, m, t.offset), l(this, f, t.middleware ?? []), l(this, c, t.floatingUIOptions ?? {}), l(this, g, t.root), this.element.dataset.show = "false";
65
66
  }
66
67
  }
67
- d = new WeakMap(), f = new WeakMap(), u = new WeakMap(), a = new WeakMap(), c = new WeakMap(), m = new WeakMap(), g = new WeakMap(), $ = new WeakSet(), /// @internal
68
+ d = new WeakMap(), u = new WeakMap(), f = new WeakMap(), c = new WeakMap(), g = new WeakMap(), r = new WeakMap(), m = new WeakMap(), y = new WeakMap(), x = new WeakSet(), /// @internal
68
69
  _ = function(t) {
69
- const { doc: e, selection: o } = t.state, { empty: h, from: p, to: y } = o, x = !e.textBetween(p, y).length && t.state.selection instanceof H, w = this.element.contains(document.activeElement), k = !t.hasFocus() && !w, O = !t.editable;
70
- return !(k || h || x || O);
70
+ const { doc: e, selection: s } = t.state, { empty: h, from: p, to: w } = s, k = !e.textBetween(p, w).length && t.state.selection instanceof H, $ = this.element.contains(document.activeElement), O = !t.hasFocus() && !$, P = !t.editable;
71
+ return !(O || h || k || P);
71
72
  };
72
- function W(s) {
73
+ function W(o) {
73
74
  const t = K(
74
75
  {},
75
- `${s}_TOOLTIP_SPEC`
76
+ `${o}_TOOLTIP_SPEC`
76
77
  ), e = L((h) => {
77
78
  const p = h.get(t.key);
78
79
  return new M({
79
- key: new R(`${s}_TOOLTIP`),
80
+ key: new R(`${o}_TOOLTIP`),
80
81
  ...p
81
82
  });
82
- }), o = [t, e];
83
- return o.key = t.key, o.pluginKey = e.key, t.meta = {
83
+ }), s = [t, e];
84
+ return s.key = t.key, s.pluginKey = e.key, t.meta = {
84
85
  package: "@milkdown/plugin-tooltip",
85
- displayName: `Ctx<tooltipSpec>|${s}`
86
+ displayName: `Ctx<tooltipSpec>|${o}`
86
87
  }, e.meta = {
87
88
  package: "@milkdown/plugin-tooltip",
88
- displayName: `Prose<tooltip>|${s}`
89
- }, o;
89
+ displayName: `Prose<tooltip>|${o}`
90
+ }, s;
90
91
  }
91
92
  export {
92
93
  V as TooltipProvider,
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/tooltip-provider.ts","../src/tooltip-plugin.ts"],"sourcesContent":["import type { EditorState } from '@milkdown/prose/state'\nimport { TextSelection } from '@milkdown/prose/state'\nimport type { EditorView } from '@milkdown/prose/view'\nimport throttle from 'lodash.throttle'\nimport type {\n ComputePositionConfig,\n Middleware,\n VirtualElement,\n} from '@floating-ui/dom'\nimport { computePosition, flip, offset, shift } from '@floating-ui/dom'\nimport { posToDOMRect } from '@milkdown/prose'\n\n/// Options for tooltip provider.\nexport interface TooltipProviderOptions {\n /// The tooltip content.\n content: HTMLElement\n /// The debounce time for updating tooltip, 200ms by default.\n debounce?: number\n /// The function to determine whether the tooltip should be shown.\n shouldShow?: (view: EditorView, prevState?: EditorState) => boolean\n /// The offset to get the block. Default is 0.\n offset?:\n | number\n | {\n mainAxis?: number\n crossAxis?: number\n alignmentAxis?: number | null\n }\n /// Other middlewares for floating ui. This will be added after the internal middlewares.\n middleware?: Middleware[]\n /// Options for floating ui. If you pass `middleware` or `placement`, it will override the internal settings.\n floatingUIOptions?: Partial<ComputePositionConfig>\n}\n\n/// A provider for creating tooltip.\nexport class TooltipProvider {\n /// @internal\n readonly #debounce: number\n\n /// @internal\n readonly #shouldShow: (view: EditorView, prevState?: EditorState) => boolean\n\n /// @internal\n readonly #middleware: Middleware[]\n\n /// @internal\n readonly #floatingUIOptions: Partial<ComputePositionConfig>\n\n /// @internal\n #initialized = false\n\n /// @internal\n readonly #offset?:\n | number\n | {\n mainAxis?: number\n crossAxis?: number\n alignmentAxis?: number | null\n }\n\n /// The root element of the tooltip.\n element: HTMLElement\n\n /// On show callback.\n onShow = () => {}\n\n /// On hide callback.\n onHide = () => {}\n\n constructor(options: TooltipProviderOptions) {\n this.element = options.content\n this.#debounce = options.debounce ?? 200\n this.#shouldShow = options.shouldShow ?? this.#_shouldShow\n this.#offset = options.offset\n this.#middleware = options.middleware ?? []\n this.#floatingUIOptions = options.floatingUIOptions ?? {}\n this.element.dataset.show = 'false'\n }\n\n /// @internal\n #onUpdate = (view: EditorView, prevState?: EditorState): void => {\n const { state, composing } = view\n const { selection, doc } = state\n const { ranges } = selection\n const from = Math.min(...ranges.map((range) => range.$from.pos))\n const to = Math.max(...ranges.map((range) => range.$to.pos))\n const isSame =\n prevState && prevState.doc.eq(doc) && prevState.selection.eq(selection)\n\n if (!this.#initialized) {\n view.dom.parentElement?.appendChild(this.element)\n this.#initialized = true\n }\n\n if (composing || isSame) return\n\n if (!this.#shouldShow(view, prevState)) {\n this.hide()\n return\n }\n\n const virtualEl: VirtualElement = {\n getBoundingClientRect: () => posToDOMRect(view, from, to),\n }\n computePosition(virtualEl, this.element, {\n placement: this.#floatingUIOptions.placement ?? 'top',\n middleware: [flip(), offset(this.#offset), shift(), ...this.#middleware],\n }).then(({ x, y }) => {\n Object.assign(this.element.style, {\n left: `${x}px`,\n top: `${y}px`,\n })\n })\n\n this.show()\n }\n\n /// Update provider state by editor view.\n update = (view: EditorView, prevState?: EditorState): void => {\n const updater = throttle(this.#onUpdate, this.#debounce)\n\n updater(view, prevState)\n }\n\n /// @internal\n #_shouldShow(view: EditorView): boolean {\n const { doc, selection } = view.state\n const { empty, from, to } = selection\n\n const isEmptyTextBlock =\n !doc.textBetween(from, to).length &&\n view.state.selection instanceof TextSelection\n\n const isTooltipChildren = this.element.contains(document.activeElement)\n\n const notHasFocus = !view.hasFocus() && !isTooltipChildren\n\n const isReadonly = !view.editable\n\n if (notHasFocus || empty || isEmptyTextBlock || isReadonly) return false\n\n return true\n }\n\n /// Destroy the tooltip.\n destroy = () => {}\n\n /// Show the tooltip.\n show = (virtualElement?: VirtualElement) => {\n this.element.dataset.show = 'true'\n\n if (virtualElement) {\n computePosition(virtualElement, this.element, {\n placement: 'top',\n middleware: [flip(), offset(this.#offset)],\n ...this.#floatingUIOptions,\n }).then(({ x, y }) => {\n Object.assign(this.element.style, {\n left: `${x}px`,\n top: `${y}px`,\n })\n })\n }\n\n this.onShow()\n }\n\n /// Hide the tooltip.\n hide = () => {\n if (this.element.dataset.show === 'false') return\n this.element.dataset.show = 'false'\n\n this.onHide()\n }\n}\n","import type { SliceType } from '@milkdown/ctx'\nimport type { PluginSpec } from '@milkdown/prose/state'\nimport { Plugin, PluginKey } from '@milkdown/prose/state'\nimport type { $Ctx, $Prose } from '@milkdown/utils'\nimport { $ctx, $prose } from '@milkdown/utils'\n\n/// @internal\nexport type TooltipSpecId<Id extends string> = `${Id}_TOOLTIP_SPEC`\n\n/// @internal\nexport type TooltipPlugin<Id extends string, State = any> = [\n $Ctx<PluginSpec<State>, TooltipSpecId<Id>>,\n $Prose,\n] & {\n key: SliceType<PluginSpec<State>, TooltipSpecId<Id>>\n pluginKey: $Prose['key']\n}\n\n/// Create a tooltip plugin with a unique id.\nexport function tooltipFactory<Id extends string, State = any>(id: Id) {\n const tooltipSpec = $ctx<PluginSpec<State>, TooltipSpecId<Id>>(\n {},\n `${id}_TOOLTIP_SPEC`\n )\n const tooltipPlugin = $prose((ctx) => {\n const spec = ctx.get(tooltipSpec.key)\n return new Plugin({\n key: new PluginKey(`${id}_TOOLTIP`),\n ...spec,\n })\n })\n const result = [tooltipSpec, tooltipPlugin] as TooltipPlugin<Id>\n result.key = tooltipSpec.key\n result.pluginKey = tooltipPlugin.key\n tooltipSpec.meta = {\n package: '@milkdown/plugin-tooltip',\n displayName: `Ctx<tooltipSpec>|${id}`,\n }\n tooltipPlugin.meta = {\n package: '@milkdown/plugin-tooltip',\n displayName: `Prose<tooltip>|${id}`,\n }\n\n return result\n}\n"],"names":["TooltipProvider","options","__privateAdd","_TooltipProvider_instances","_debounce","_shouldShow","_middleware","_floatingUIOptions","_initialized","_offset","_onUpdate","__privateSet","view","prevState","state","composing","selection","doc","ranges","from","range","to","isSame","__privateGet","_a","computePosition","posToDOMRect","flip","offset","shift","x","y","throttle","virtualElement","__privateMethod","_shouldShow_fn","empty","isEmptyTextBlock","TextSelection","isTooltipChildren","notHasFocus","isReadonly","tooltipFactory","id","tooltipSpec","$ctx","tooltipPlugin","$prose","ctx","spec","Plugin","PluginKey","result"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/tooltip-provider.ts","../src/tooltip-plugin.ts"],"sourcesContent":["import type { EditorState } from '@milkdown/prose/state'\nimport { TextSelection } from '@milkdown/prose/state'\nimport type { EditorView } from '@milkdown/prose/view'\nimport throttle from 'lodash.throttle'\nimport type {\n ComputePositionConfig,\n Middleware,\n VirtualElement,\n} from '@floating-ui/dom'\nimport { computePosition, flip, offset, shift } from '@floating-ui/dom'\nimport { posToDOMRect } from '@milkdown/prose'\n\n/// Options for tooltip provider.\nexport interface TooltipProviderOptions {\n /// The tooltip content.\n content: HTMLElement\n /// The debounce time for updating tooltip, 200ms by default.\n debounce?: number\n /// The function to determine whether the tooltip should be shown.\n shouldShow?: (view: EditorView, prevState?: EditorState) => boolean\n /// The offset to get the block. Default is 0.\n offset?:\n | number\n | {\n mainAxis?: number\n crossAxis?: number\n alignmentAxis?: number | null\n }\n /// Other middlewares for floating ui. This will be added after the internal middlewares.\n middleware?: Middleware[]\n /// Options for floating ui. If you pass `middleware` or `placement`, it will override the internal settings.\n floatingUIOptions?: Partial<ComputePositionConfig>\n /// The root element that the tooltip will be appended to.\n root?: HTMLElement\n}\n\n/// A provider for creating tooltip.\nexport class TooltipProvider {\n /// @internal\n readonly #debounce: number\n\n /// @internal\n readonly #shouldShow: (view: EditorView, prevState?: EditorState) => boolean\n\n /// @internal\n readonly #middleware: Middleware[]\n\n /// @internal\n readonly #floatingUIOptions: Partial<ComputePositionConfig>\n\n /// @internal\n readonly #root?: HTMLElement\n\n /// @internal\n #initialized = false\n\n /// @internal\n readonly #offset?:\n | number\n | {\n mainAxis?: number\n crossAxis?: number\n alignmentAxis?: number | null\n }\n\n /// The root element of the tooltip.\n element: HTMLElement\n\n /// On show callback.\n onShow = () => {}\n\n /// On hide callback.\n onHide = () => {}\n\n constructor(options: TooltipProviderOptions) {\n this.element = options.content\n this.#debounce = options.debounce ?? 200\n this.#shouldShow = options.shouldShow ?? this.#_shouldShow\n this.#offset = options.offset\n this.#middleware = options.middleware ?? []\n this.#floatingUIOptions = options.floatingUIOptions ?? {}\n this.#root = options.root\n this.element.dataset.show = 'false'\n }\n\n /// @internal\n #onUpdate = (view: EditorView, prevState?: EditorState): void => {\n const { state, composing } = view\n const { selection, doc } = state\n const { ranges } = selection\n const from = Math.min(...ranges.map((range) => range.$from.pos))\n const to = Math.max(...ranges.map((range) => range.$to.pos))\n const isSame =\n prevState && prevState.doc.eq(doc) && prevState.selection.eq(selection)\n\n if (!this.#initialized) {\n const root = this.#root ?? view.dom.parentElement ?? document.body\n root.appendChild(this.element)\n this.#initialized = true\n }\n\n if (composing || isSame) return\n\n if (!this.#shouldShow(view, prevState)) {\n this.hide()\n return\n }\n\n const virtualEl: VirtualElement = {\n getBoundingClientRect: () => posToDOMRect(view, from, to),\n }\n computePosition(virtualEl, this.element, {\n placement: this.#floatingUIOptions.placement ?? 'top',\n middleware: [flip(), offset(this.#offset), shift(), ...this.#middleware],\n }).then(({ x, y }) => {\n Object.assign(this.element.style, {\n left: `${x}px`,\n top: `${y}px`,\n })\n })\n\n this.show()\n }\n\n /// Update provider state by editor view.\n update = (view: EditorView, prevState?: EditorState): void => {\n const updater = throttle(this.#onUpdate, this.#debounce)\n\n updater(view, prevState)\n }\n\n /// @internal\n #_shouldShow(view: EditorView): boolean {\n const { doc, selection } = view.state\n const { empty, from, to } = selection\n\n const isEmptyTextBlock =\n !doc.textBetween(from, to).length &&\n view.state.selection instanceof TextSelection\n\n const isTooltipChildren = this.element.contains(document.activeElement)\n\n const notHasFocus = !view.hasFocus() && !isTooltipChildren\n\n const isReadonly = !view.editable\n\n if (notHasFocus || empty || isEmptyTextBlock || isReadonly) return false\n\n return true\n }\n\n /// Destroy the tooltip.\n destroy = () => {}\n\n /// Show the tooltip.\n show = (virtualElement?: VirtualElement) => {\n this.element.dataset.show = 'true'\n\n if (virtualElement) {\n computePosition(virtualElement, this.element, {\n placement: 'top',\n middleware: [flip(), offset(this.#offset)],\n ...this.#floatingUIOptions,\n }).then(({ x, y }) => {\n Object.assign(this.element.style, {\n left: `${x}px`,\n top: `${y}px`,\n })\n })\n }\n\n this.onShow()\n }\n\n /// Hide the tooltip.\n hide = () => {\n if (this.element.dataset.show === 'false') return\n this.element.dataset.show = 'false'\n\n this.onHide()\n }\n}\n","import type { SliceType } from '@milkdown/ctx'\nimport type { PluginSpec } from '@milkdown/prose/state'\nimport { Plugin, PluginKey } from '@milkdown/prose/state'\nimport type { $Ctx, $Prose } from '@milkdown/utils'\nimport { $ctx, $prose } from '@milkdown/utils'\n\n/// @internal\nexport type TooltipSpecId<Id extends string> = `${Id}_TOOLTIP_SPEC`\n\n/// @internal\nexport type TooltipPlugin<Id extends string, State = any> = [\n $Ctx<PluginSpec<State>, TooltipSpecId<Id>>,\n $Prose,\n] & {\n key: SliceType<PluginSpec<State>, TooltipSpecId<Id>>\n pluginKey: $Prose['key']\n}\n\n/// Create a tooltip plugin with a unique id.\nexport function tooltipFactory<Id extends string, State = any>(id: Id) {\n const tooltipSpec = $ctx<PluginSpec<State>, TooltipSpecId<Id>>(\n {},\n `${id}_TOOLTIP_SPEC`\n )\n const tooltipPlugin = $prose((ctx) => {\n const spec = ctx.get(tooltipSpec.key)\n return new Plugin({\n key: new PluginKey(`${id}_TOOLTIP`),\n ...spec,\n })\n })\n const result = [tooltipSpec, tooltipPlugin] as TooltipPlugin<Id>\n result.key = tooltipSpec.key\n result.pluginKey = tooltipPlugin.key\n tooltipSpec.meta = {\n package: '@milkdown/plugin-tooltip',\n displayName: `Ctx<tooltipSpec>|${id}`,\n }\n tooltipPlugin.meta = {\n package: '@milkdown/plugin-tooltip',\n displayName: `Prose<tooltip>|${id}`,\n }\n\n return result\n}\n"],"names":["TooltipProvider","options","__privateAdd","_TooltipProvider_instances","_debounce","_shouldShow","_middleware","_floatingUIOptions","_root","_initialized","_offset","_onUpdate","__privateSet","view","prevState","state","composing","selection","doc","ranges","from","range","to","isSame","__privateGet","computePosition","posToDOMRect","flip","offset","shift","x","y","throttle","virtualElement","__privateMethod","_shouldShow_fn","empty","isEmptyTextBlock","TextSelection","isTooltipChildren","notHasFocus","isReadonly","tooltipFactory","id","tooltipSpec","$ctx","tooltipPlugin","$prose","ctx","spec","Plugin","PluginKey","result"],"mappings":"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"}
@@ -12,6 +12,7 @@ export interface TooltipProviderOptions {
12
12
  };
13
13
  middleware?: Middleware[];
14
14
  floatingUIOptions?: Partial<ComputePositionConfig>;
15
+ root?: HTMLElement;
15
16
  }
16
17
  export declare class TooltipProvider {
17
18
  #private;
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip-provider.d.ts","sourceRoot":"","sources":["../src/tooltip-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EACV,qBAAqB,EACrB,UAAU,EACV,cAAc,EACf,MAAM,kBAAkB,CAAA;AAKzB,MAAM,WAAW,sBAAsB;IAErC,OAAO,EAAE,WAAW,CAAA;IAEpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,WAAW,KAAK,OAAO,CAAA;IAEnE,MAAM,CAAC,EACH,MAAM,GACN;QACE,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAC9B,CAAA;IAEL,UAAU,CAAC,EAAE,UAAU,EAAE,CAAA;IAEzB,iBAAiB,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAA;CACnD;AAGD,qBAAa,eAAe;;IA0B1B,OAAO,EAAE,WAAW,CAAA;IAGpB,MAAM,aAAW;IAGjB,MAAM,aAAW;gBAEL,OAAO,EAAE,sBAAsB;IAiD3C,MAAM,SAAU,UAAU,cAAc,WAAW,KAAG,IAAI,CAIzD;IAuBD,OAAO,aAAW;IAGlB,IAAI,oBAAqB,cAAc,UAiBtC;IAGD,IAAI,aAKH;CACF"}
1
+ {"version":3,"file":"tooltip-provider.d.ts","sourceRoot":"","sources":["../src/tooltip-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,KAAK,EACV,qBAAqB,EACrB,UAAU,EACV,cAAc,EACf,MAAM,kBAAkB,CAAA;AAKzB,MAAM,WAAW,sBAAsB;IAErC,OAAO,EAAE,WAAW,CAAA;IAEpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,WAAW,KAAK,OAAO,CAAA;IAEnE,MAAM,CAAC,EACH,MAAM,GACN;QACE,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAC9B,CAAA;IAEL,UAAU,CAAC,EAAE,UAAU,EAAE,CAAA;IAEzB,iBAAiB,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAA;IAElD,IAAI,CAAC,EAAE,WAAW,CAAA;CACnB;AAGD,qBAAa,eAAe;;IA6B1B,OAAO,EAAE,WAAW,CAAA;IAGpB,MAAM,aAAW;IAGjB,MAAM,aAAW;gBAEL,OAAO,EAAE,sBAAsB;IAmD3C,MAAM,SAAU,UAAU,cAAc,WAAW,KAAG,IAAI,CAIzD;IAuBD,OAAO,aAAW;IAGlB,IAAI,oBAAqB,cAAc,UAiBtC;IAGD,IAAI,aAKH;CACF"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@milkdown/plugin-tooltip",
3
3
  "type": "module",
4
- "version": "7.6.1",
4
+ "version": "7.6.3",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -35,13 +35,13 @@
35
35
  "lodash.throttle": "^4.1.1",
36
36
  "tippy.js": "^6.3.7",
37
37
  "tslib": "^2.8.1",
38
- "@milkdown/utils": "7.6.1",
39
- "@milkdown/exception": "7.6.1"
38
+ "@milkdown/exception": "7.6.3",
39
+ "@milkdown/utils": "7.6.3"
40
40
  },
41
41
  "devDependencies": {
42
- "@milkdown/ctx": "7.6.1",
43
- "@milkdown/prose": "7.6.1",
44
- "@milkdown/core": "7.6.1"
42
+ "@milkdown/ctx": "7.6.3",
43
+ "@milkdown/prose": "7.6.3",
44
+ "@milkdown/core": "7.6.3"
45
45
  },
46
46
  "nx": {
47
47
  "targets": {
@@ -30,6 +30,8 @@ export interface TooltipProviderOptions {
30
30
  middleware?: Middleware[]
31
31
  /// Options for floating ui. If you pass `middleware` or `placement`, it will override the internal settings.
32
32
  floatingUIOptions?: Partial<ComputePositionConfig>
33
+ /// The root element that the tooltip will be appended to.
34
+ root?: HTMLElement
33
35
  }
34
36
 
35
37
  /// A provider for creating tooltip.
@@ -46,6 +48,9 @@ export class TooltipProvider {
46
48
  /// @internal
47
49
  readonly #floatingUIOptions: Partial<ComputePositionConfig>
48
50
 
51
+ /// @internal
52
+ readonly #root?: HTMLElement
53
+
49
54
  /// @internal
50
55
  #initialized = false
51
56
 
@@ -74,6 +79,7 @@ export class TooltipProvider {
74
79
  this.#offset = options.offset
75
80
  this.#middleware = options.middleware ?? []
76
81
  this.#floatingUIOptions = options.floatingUIOptions ?? {}
82
+ this.#root = options.root
77
83
  this.element.dataset.show = 'false'
78
84
  }
79
85
 
@@ -88,7 +94,8 @@ export class TooltipProvider {
88
94
  prevState && prevState.doc.eq(doc) && prevState.selection.eq(selection)
89
95
 
90
96
  if (!this.#initialized) {
91
- view.dom.parentElement?.appendChild(this.element)
97
+ const root = this.#root ?? view.dom.parentElement ?? document.body
98
+ root.appendChild(this.element)
92
99
  this.#initialized = true
93
100
  }
94
101