@milkdown/plugin-tooltip 6.0.0-next.0 → 6.0.1
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/create-tooltip.d.ts +1 -1
- package/lib/button-manager/create-tooltip.d.ts.map +1 -1
- package/lib/button-manager/index.d.ts +1 -1
- package/lib/button-manager/index.d.ts.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.es.js +53 -16
- package/lib/index.es.js.map +1 -1
- package/lib/item.d.ts +10 -12
- package/lib/item.d.ts.map +1 -1
- package/lib/selection-marks-tooltip.d.ts +2 -1
- package/lib/selection-marks-tooltip.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/button-manager/create-tooltip.ts +4 -4
- package/src/button-manager/filter-button.ts +1 -1
- package/src/button-manager/index.ts +7 -2
- package/src/button-manager/no-active.ts +1 -1
- package/src/index.ts +7 -2
- package/src/item.ts +31 -13
- package/src/selection-marks-tooltip.ts +7 -2
- package/src/utility/toggle.ts +1 -1
|
@@ -5,6 +5,6 @@ declare type Tooltip = {
|
|
|
5
5
|
dom: HTMLDivElement;
|
|
6
6
|
render: (editorView: EditorView) => void;
|
|
7
7
|
};
|
|
8
|
-
export declare const createTooltip: (buttonMap: ButtonMap, utils: Utils) => Tooltip;
|
|
8
|
+
export declare const createTooltip: (buttonMap: ButtonMap, utils: Utils, 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,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGzC,aAAK,OAAO,GAAG;IACX,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;CAC5C,CAAC;AAEF,eAAO,MAAM,aAAa,cAAe,SAAS,SAAS,KAAK,KAAG,
|
|
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,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGzC,aAAK,OAAO,GAAG;IACX,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;CAC5C,CAAC;AAEF,eAAO,MAAM,aAAa,cAAe,SAAS,SAAS,KAAK,aAAa,MAAM,KAAG,OAqBrF,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { EditorView } from '@milkdown/prose';
|
|
2
2
|
import type { Utils } from '@milkdown/utils';
|
|
3
3
|
import type { ButtonMap } from '../item';
|
|
4
|
-
export declare const createButtonManager: (buttonMap: ButtonMap, utils: Utils, bottom: boolean) => {
|
|
4
|
+
export declare const createButtonManager: (buttonMap: ButtonMap, utils: Utils, bottom: boolean, containerClassName: string) => {
|
|
5
5
|
destroy: () => void;
|
|
6
6
|
hide: () => void;
|
|
7
7
|
update: (editorView: EditorView) => void;
|
|
@@ -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,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAKzC,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/button-manager/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAKzC,eAAO,MAAM,mBAAmB,cACjB,SAAS,SACb,KAAK,UACJ,OAAO,sBACK,MAAM;;;yBAyBD,UAAU;;CAUtC,CAAC"}
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAA0B,MAAM,iBAAiB,CAAC;AAEnE,OAAO,EAAa,cAAc,EAAE,MAAM,QAAQ,CAAC;AAGnD,eAAO,MAAM,GAAG,qBAA2C,CAAC;AAE5D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAA0B,MAAM,iBAAiB,CAAC;AAEnE,OAAO,EAAa,cAAc,EAAE,MAAM,QAAQ,CAAC;AAGnD,eAAO,MAAM,GAAG,qBAA2C,CAAC;AAE5D,eAAO,MAAM,aAAa;;;;;;;;;;;;;;EAyCxB,CAAC;AAEH,eAAO,MAAM,OAAO,yKAAqC,CAAC"}
|
package/lib/index.es.js
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
+
var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
|
|
6
|
+
var __spreadValues = (a, b) => {
|
|
7
|
+
for (var prop in b || (b = {}))
|
|
8
|
+
if (__hasOwnProp.call(b, prop))
|
|
9
|
+
__defNormalProp(a, prop, b[prop]);
|
|
10
|
+
if (__getOwnPropSymbols)
|
|
11
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
+
if (__propIsEnum.call(b, prop))
|
|
13
|
+
__defNormalProp(a, prop, b[prop]);
|
|
14
|
+
}
|
|
15
|
+
return a;
|
|
16
|
+
};
|
|
1
17
|
import { themeManagerCtx, ThemeIcon, commandsCtx, ThemeSize, ThemeBorder, ThemeShadow, ThemeColor, schemaCtx } from "@milkdown/core";
|
|
2
18
|
import { findParentNode, TextSelection, calculateTextPosition, PluginKey, Plugin } from "@milkdown/prose";
|
|
3
19
|
import { createPlugin as createPlugin$1, AtomList } from "@milkdown/utils";
|
|
@@ -24,21 +40,37 @@ const createToggleIcon = (ctx, iconName, key2, mark, disableForMark) => {
|
|
|
24
40
|
var _a;
|
|
25
41
|
return {
|
|
26
42
|
$: (_a = ctx.get(themeManagerCtx).get(ThemeIcon, iconName)) == null ? void 0 : _a.dom,
|
|
27
|
-
command: () => ctx.get(commandsCtx).
|
|
43
|
+
command: () => ctx.get(commandsCtx).call(key2),
|
|
28
44
|
active: (view) => hasMark(view.state, mark),
|
|
29
45
|
disable: (view) => isTextAndNotHasMark(view.state, disableForMark),
|
|
30
46
|
enable: (view) => !!mark && !!view.state.schema.marks[mark.name]
|
|
31
47
|
};
|
|
32
48
|
};
|
|
33
|
-
const
|
|
34
|
-
|
|
49
|
+
const Buttonize = ({ icon, onClick, isHidden, isActive }, ctx) => {
|
|
50
|
+
var _a;
|
|
35
51
|
return {
|
|
52
|
+
$: typeof icon === "function" ? icon(ctx) : (_a = ctx.get(themeManagerCtx).get(ThemeIcon, icon)) == null ? void 0 : _a.dom,
|
|
53
|
+
command: typeof onClick === "string" ? () => ctx.get(commandsCtx).call(onClick) : onClick(ctx),
|
|
54
|
+
disable: isHidden(ctx),
|
|
55
|
+
active: isActive(ctx),
|
|
56
|
+
enable: (view) => !isHidden(ctx)(view)
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
const buttonMap = (schema, ctx, items) => {
|
|
60
|
+
const { marks } = schema;
|
|
61
|
+
const ButtonItems = Array();
|
|
62
|
+
if (typeof items !== "undefined") {
|
|
63
|
+
items.forEach((item) => {
|
|
64
|
+
ButtonItems.push(Buttonize(item, ctx));
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return __spreadValues({
|
|
36
68
|
[0]: createToggleIcon(ctx, "bold", "ToggleBold", marks["strong"], marks["code_inline"]),
|
|
37
69
|
[1]: createToggleIcon(ctx, "italic", "ToggleItalic", marks["em"], marks["code_inline"]),
|
|
38
70
|
[2]: createToggleIcon(ctx, "strikeThrough", "ToggleStrikeThrough", marks["strike_through"], marks["code_inline"]),
|
|
39
71
|
[3]: createToggleIcon(ctx, "code", "ToggleInlineCode", marks["code_inline"], marks["link"]),
|
|
40
72
|
[4]: createToggleIcon(ctx, "link", "ToggleLink", marks["link"], marks["code_inline"])
|
|
41
|
-
};
|
|
73
|
+
}, ButtonItems);
|
|
42
74
|
};
|
|
43
75
|
const calcButtonPos = (buttons, view, isBottom) => {
|
|
44
76
|
buttons.classList.remove("hide");
|
|
@@ -105,29 +137,29 @@ const injectStyle = (themeManager, { css }) => {
|
|
|
105
137
|
}
|
|
106
138
|
`;
|
|
107
139
|
};
|
|
108
|
-
const createTooltip = (buttonMap2, utils) => {
|
|
140
|
+
const createTooltip = (buttonMap2, utils, className) => {
|
|
109
141
|
const div = document.createElement("div");
|
|
110
142
|
utils.themeManager.onFlush(() => {
|
|
111
|
-
const style = utils.getStyle(injectStyle) || "";
|
|
143
|
+
const style = utils.getStyle((emotion) => injectStyle(utils.themeManager, emotion)) || "";
|
|
112
144
|
if (style) {
|
|
113
145
|
div.classList.add(style);
|
|
114
146
|
}
|
|
115
147
|
});
|
|
116
|
-
div.classList.add(
|
|
148
|
+
div.classList.add(utils.getClassName({}, className));
|
|
117
149
|
return {
|
|
118
150
|
dom: div,
|
|
119
151
|
render: (editorView) => {
|
|
120
152
|
var _a;
|
|
121
|
-
Object.values(buttonMap2).filter((item) => item.enable(editorView)).forEach(({ $ }) => div.appendChild($));
|
|
153
|
+
Object.values(buttonMap2).filter((item) => item.enable(editorView) && item.$ != null).forEach(({ $ }) => div.appendChild($));
|
|
122
154
|
(_a = editorView.dom.parentNode) == null ? void 0 : _a.appendChild(div);
|
|
123
155
|
}
|
|
124
156
|
};
|
|
125
157
|
};
|
|
126
158
|
const noActive = (buttonMap2, view) => {
|
|
127
|
-
return Object.values(buttonMap2).filter((item) => item.enable(view)).every(({ $ }) => $.classList.contains("hide"));
|
|
159
|
+
return Object.values(buttonMap2).filter((item) => item.enable(view) && item.$ != null).every(({ $ }) => $.classList.contains("hide"));
|
|
128
160
|
};
|
|
129
161
|
const filterButton = (buttonMap2, view) => {
|
|
130
|
-
Object.values(buttonMap2).filter((item) => item.enable(view)).forEach((item) => {
|
|
162
|
+
Object.values(buttonMap2).filter((item) => item.enable(view) && item.$ != null).forEach((item) => {
|
|
131
163
|
var _a;
|
|
132
164
|
const disable = (_a = item.disable) == null ? void 0 : _a.call(item, view);
|
|
133
165
|
if (disable) {
|
|
@@ -144,8 +176,8 @@ const filterButton = (buttonMap2, view) => {
|
|
|
144
176
|
});
|
|
145
177
|
return noActive(buttonMap2, view);
|
|
146
178
|
};
|
|
147
|
-
const createButtonManager = (buttonMap2, utils, bottom) => {
|
|
148
|
-
const { dom: buttons, render } = createTooltip(buttonMap2, utils);
|
|
179
|
+
const createButtonManager = (buttonMap2, utils, bottom, containerClassName) => {
|
|
180
|
+
const { dom: buttons, render } = createTooltip(buttonMap2, utils, containerClassName);
|
|
149
181
|
const onClick = (e) => {
|
|
150
182
|
const target = Object.values(buttonMap2).find(({ $ }) => e.target instanceof Element && $.contains(e.target));
|
|
151
183
|
if (!target)
|
|
@@ -175,8 +207,8 @@ const createButtonManager = (buttonMap2, utils, bottom) => {
|
|
|
175
207
|
render
|
|
176
208
|
};
|
|
177
209
|
};
|
|
178
|
-
const createPlugin = (buttonMap2, utils, bottom) => {
|
|
179
|
-
|
|
210
|
+
const createPlugin = (buttonMap2, utils, bottom, containerClassName) => {
|
|
211
|
+
let buttonManager = createButtonManager(buttonMap2, utils, bottom, containerClassName);
|
|
180
212
|
let shouldHide = false;
|
|
181
213
|
const hide = () => {
|
|
182
214
|
buttonManager.hide();
|
|
@@ -193,6 +225,11 @@ const createPlugin = (buttonMap2, utils, bottom) => {
|
|
|
193
225
|
buttonManager.update(view);
|
|
194
226
|
};
|
|
195
227
|
return {
|
|
228
|
+
recreate: (editorView) => {
|
|
229
|
+
buttonManager = createButtonManager(buttonMap2, utils, bottom, containerClassName);
|
|
230
|
+
buttonManager.render(editorView);
|
|
231
|
+
update(editorView);
|
|
232
|
+
},
|
|
196
233
|
update,
|
|
197
234
|
destroy: () => {
|
|
198
235
|
buttonManager.destroy();
|
|
@@ -213,7 +250,7 @@ const tooltipPlugin = createPlugin$1((utils, options) => {
|
|
|
213
250
|
prosePlugins: (_, ctx) => {
|
|
214
251
|
var _a;
|
|
215
252
|
const schema = ctx.get(schemaCtx);
|
|
216
|
-
const manager = createPlugin(buttonMap(schema, ctx), utils, (_a = options == null ? void 0 : options.bottom) != null ? _a : false);
|
|
253
|
+
const manager = createPlugin(buttonMap(schema, ctx, options == null ? void 0 : options.items), utils, (_a = options == null ? void 0 : options.bottom) != null ? _a : false, "tooltip");
|
|
217
254
|
const plugin = new Plugin({
|
|
218
255
|
key,
|
|
219
256
|
props: {
|
|
@@ -234,7 +271,7 @@ const tooltipPlugin = createPlugin$1((utils, options) => {
|
|
|
234
271
|
}
|
|
235
272
|
},
|
|
236
273
|
view: (editorView) => {
|
|
237
|
-
manager.
|
|
274
|
+
manager.recreate(editorView);
|
|
238
275
|
return {
|
|
239
276
|
update: manager.update,
|
|
240
277
|
destroy: manager.destroy
|
package/lib/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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).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, 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 ButtonItem = {\n $: HTMLElement;\n command: () => void;\n active: Pred;\n disable?: Pred;\n enable: Pred;\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 link: {\n placeholder: string;\n buttonText: string;\n };\n image: {\n placeholder: string;\n buttonText: string;\n };\n inlineMath: {\n placeholder: string;\n };\n bottom: boolean;\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, 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): Tooltip => {\n const div = document.createElement('div');\n utils.themeManager.onFlush(() => {\n const style = utils.getStyle(injectStyle) || '';\n if (style) {\n div.classList.add(style);\n }\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, bottom: boolean) => {\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, 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) => {\n const buttonManager = createButtonManager(buttonMap, utils, bottom);\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 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(buttonMap(schema, ctx), utils, options?.bottom ?? false);\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":["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,WAAW;AAAA,IAC/C,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;MCwBlD,YAAY,CAAC,QAAgB,QAAwB;QACxD,EAAE,UAAU;SACX;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;AAAA;MC3DvF,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,UAA0B;QACpE,MAAM,SAAS,cAAc;QAC7B,aAAa,QAAQ,MAAM;UACvB,QAAQ,MAAM,SAAS,gBAAgB;QACzC,OAAO;UACH,UAAU,IAAI;AAAA;AAAA;MAItB,UAAU,IAAI;SAEX;AAAA,IACH,KAAK;AAAA,IACL,QAAQ,CAAC,eAA2B;;aACzB,OAAO,YACT,OAAO,CAAC,SAAS,KAAK,OAAO,aAC7B,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,OAC7B,MAAM,CAAC,EAAE,QAAQ,EAAE,UAAU,SAAS;AAAA;MCFlC,eAAe,CAAC,YAAsB,SAAqB;SAC7D,OAAO,YACT,OAAO,CAAC,SAAS,KAAK,OAAO,OAC7B,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,CAAC,YAAsB,OAAc,WAAoB;QAClF,EAAE,KAAK,SAAS,WAAW,cAAc,YAAW;QAEpD,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;MClCK,eAAe,CAAC,YAAsB,OAAc,WAAoB;QAC3E,gBAAgB,oBAAoB,YAAW,OAAO;MACxD,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;AAAA,IACA,SAAS,MAAM;oBACG;AAAA;AAAA,IAElB,QAAQ,CAAC,eAA2B;oBAClB,OAAO;aACd;AAAA;AAAA,IAEX,SAAS,CAAC,aAAsB;mBACf;AAAA;AAAA;AAAA;MC/BZ,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,aAAa,UAAU,QAAQ,MAAM,OAAO,yCAAS,WAAT,YAAmB;YACzE,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,OAAO;iBACR;AAAA,YACH,QAAQ,QAAQ;AAAA,YAChB,SAAS,QAAQ;AAAA;AAAA;AAAA;aAItB,CAAC;AAAA;AAAA;AAAA;MAKP,UAAU,SAAS,OAAO,CAAC;;"}
|
|
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":"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"}
|
package/lib/item.d.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import { Ctx } from '@milkdown/core';
|
|
2
|
+
import type { Icon } from '@milkdown/design-system';
|
|
2
3
|
import { EditorView, Schema } from '@milkdown/prose';
|
|
3
4
|
export declare type Pred = (view: EditorView) => boolean;
|
|
4
5
|
export declare type Updater = (view: EditorView, $: HTMLElement) => void;
|
|
5
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
|
+
};
|
|
6
14
|
export declare type ButtonItem = {
|
|
7
15
|
$: HTMLElement;
|
|
8
16
|
command: () => void;
|
|
@@ -19,18 +27,8 @@ export declare enum ButtonAction {
|
|
|
19
27
|
}
|
|
20
28
|
export declare type ButtonMap = Record<ButtonAction, ButtonItem>;
|
|
21
29
|
export declare type TooltipOptions = {
|
|
22
|
-
link: {
|
|
23
|
-
placeholder: string;
|
|
24
|
-
buttonText: string;
|
|
25
|
-
};
|
|
26
|
-
image: {
|
|
27
|
-
placeholder: string;
|
|
28
|
-
buttonText: string;
|
|
29
|
-
};
|
|
30
|
-
inlineMath: {
|
|
31
|
-
placeholder: string;
|
|
32
|
-
};
|
|
33
30
|
bottom: boolean;
|
|
31
|
+
items: Array<Item> | undefined;
|
|
34
32
|
};
|
|
35
|
-
export declare const buttonMap: (schema: Schema, ctx: Ctx) => ButtonMap;
|
|
33
|
+
export declare const buttonMap: (schema: Schema, ctx: Ctx, items: Array<Item> | undefined) => ButtonMap;
|
|
36
34
|
//# 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,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
3
|
import type { ButtonMap } from './item';
|
|
4
|
-
export declare const createPlugin: (buttonMap: ButtonMap, utils: Utils, bottom: boolean) => {
|
|
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;
|
|
@@ -1 +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;
|
|
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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkdown/plugin-tooltip",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./lib/index.es.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -15,16 +15,16 @@
|
|
|
15
15
|
"milkdown plugin"
|
|
16
16
|
],
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@milkdown/core": "6.0.
|
|
19
|
-
"@milkdown/prose": "6.0.
|
|
20
|
-
"@milkdown/design-system": "6.0.
|
|
18
|
+
"@milkdown/core": "6.0.1",
|
|
19
|
+
"@milkdown/prose": "6.0.1",
|
|
20
|
+
"@milkdown/design-system": "6.0.1"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"@milkdown/core": "^6.0.
|
|
24
|
-
"@milkdown/prose": "^6.0.
|
|
23
|
+
"@milkdown/core": "^6.0.1",
|
|
24
|
+
"@milkdown/prose": "^6.0.1"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@milkdown/utils": "6.0.
|
|
27
|
+
"@milkdown/utils": "6.0.1",
|
|
28
28
|
"tslib": "^2.3.1"
|
|
29
29
|
},
|
|
30
30
|
"nx": {
|
|
@@ -10,22 +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
15
|
utils.themeManager.onFlush(() => {
|
|
16
|
-
const style = utils.getStyle(injectStyle) || '';
|
|
16
|
+
const style = utils.getStyle((emotion) => injectStyle(utils.themeManager, emotion)) || '';
|
|
17
17
|
if (style) {
|
|
18
18
|
div.classList.add(style);
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
21
|
|
|
22
|
-
div.classList.add(
|
|
22
|
+
div.classList.add(utils.getClassName({}, className));
|
|
23
23
|
|
|
24
24
|
return {
|
|
25
25
|
dom: div,
|
|
26
26
|
render: (editorView: EditorView) => {
|
|
27
27
|
Object.values(buttonMap)
|
|
28
|
-
.filter((item) => item.enable(editorView))
|
|
28
|
+
.filter((item) => item.enable(editorView) && item.$ != null)
|
|
29
29
|
.forEach(({ $ }) => div.appendChild($));
|
|
30
30
|
|
|
31
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 = (
|
|
11
|
-
|
|
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));
|
|
@@ -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
|
};
|
package/src/index.ts
CHANGED
|
@@ -13,7 +13,12 @@ export const tooltipPlugin = create<string, TooltipOptions>((utils, options) =>
|
|
|
13
13
|
id: 'tooltip',
|
|
14
14
|
prosePlugins: (_, ctx) => {
|
|
15
15
|
const schema = ctx.get(schemaCtx);
|
|
16
|
-
const manager = createPlugin(
|
|
16
|
+
const manager = createPlugin(
|
|
17
|
+
buttonMap(schema, ctx, options?.items),
|
|
18
|
+
utils,
|
|
19
|
+
options?.bottom ?? false,
|
|
20
|
+
'tooltip',
|
|
21
|
+
);
|
|
17
22
|
const plugin = new Plugin({
|
|
18
23
|
key,
|
|
19
24
|
props: {
|
|
@@ -34,7 +39,7 @@ export const tooltipPlugin = create<string, TooltipOptions>((utils, options) =>
|
|
|
34
39
|
},
|
|
35
40
|
},
|
|
36
41
|
view: (editorView) => {
|
|
37
|
-
manager.
|
|
42
|
+
manager.recreate(editorView);
|
|
38
43
|
return {
|
|
39
44
|
update: manager.update,
|
|
40
45
|
destroy: manager.destroy,
|
package/src/item.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { Ctx } from '@milkdown/core';
|
|
2
|
+
import { commandsCtx, Ctx, ThemeIcon, themeManagerCtx } from '@milkdown/core';
|
|
3
|
+
import type { Icon } from '@milkdown/design-system';
|
|
3
4
|
import { EditorView, Schema } from '@milkdown/prose';
|
|
4
5
|
|
|
5
6
|
import { createToggleIcon } from './utility';
|
|
@@ -8,6 +9,18 @@ export type Pred = (view: EditorView) => boolean;
|
|
|
8
9
|
export type Updater = (view: EditorView, $: HTMLElement) => void;
|
|
9
10
|
export type Event2Command = (e: Event) => void;
|
|
10
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
|
+
|
|
11
24
|
export type ButtonItem = {
|
|
12
25
|
$: HTMLElement;
|
|
13
26
|
command: () => void;
|
|
@@ -16,6 +29,14 @@ export type ButtonItem = {
|
|
|
16
29
|
enable: Pred;
|
|
17
30
|
};
|
|
18
31
|
|
|
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
|
+
});
|
|
39
|
+
|
|
19
40
|
export enum ButtonAction {
|
|
20
41
|
ToggleBold,
|
|
21
42
|
ToggleItalic,
|
|
@@ -27,22 +48,18 @@ export enum ButtonAction {
|
|
|
27
48
|
export type ButtonMap = Record<ButtonAction, ButtonItem>;
|
|
28
49
|
|
|
29
50
|
export type TooltipOptions = {
|
|
30
|
-
link: {
|
|
31
|
-
placeholder: string;
|
|
32
|
-
buttonText: string;
|
|
33
|
-
};
|
|
34
|
-
image: {
|
|
35
|
-
placeholder: string;
|
|
36
|
-
buttonText: string;
|
|
37
|
-
};
|
|
38
|
-
inlineMath: {
|
|
39
|
-
placeholder: string;
|
|
40
|
-
};
|
|
41
51
|
bottom: boolean;
|
|
52
|
+
items: Array<Item> | undefined;
|
|
42
53
|
};
|
|
43
54
|
|
|
44
|
-
export const buttonMap = (schema: Schema, ctx: Ctx): ButtonMap => {
|
|
55
|
+
export const buttonMap = (schema: Schema, ctx: Ctx, items: Array<Item> | undefined): ButtonMap => {
|
|
45
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
|
+
}
|
|
46
63
|
return {
|
|
47
64
|
[ButtonAction.ToggleBold]: createToggleIcon(ctx, 'bold', 'ToggleBold', marks['strong'], marks['code_inline']),
|
|
48
65
|
[ButtonAction.ToggleItalic]: createToggleIcon(ctx, 'italic', 'ToggleItalic', marks['em'], marks['code_inline']),
|
|
@@ -61,5 +78,6 @@ export const buttonMap = (schema: Schema, ctx: Ctx): ButtonMap => {
|
|
|
61
78
|
marks['link'],
|
|
62
79
|
),
|
|
63
80
|
[ButtonAction.ToggleLink]: createToggleIcon(ctx, 'link', 'ToggleLink', marks['link'], marks['code_inline']),
|
|
81
|
+
...ButtonItems,
|
|
64
82
|
};
|
|
65
83
|
};
|
|
@@ -5,8 +5,8 @@ import { Utils } from '@milkdown/utils';
|
|
|
5
5
|
import { createButtonManager } from './button-manager';
|
|
6
6
|
import type { ButtonMap } from './item';
|
|
7
7
|
|
|
8
|
-
export const createPlugin = (buttonMap: ButtonMap, utils: Utils, bottom: boolean) => {
|
|
9
|
-
|
|
8
|
+
export const createPlugin = (buttonMap: ButtonMap, utils: Utils, bottom: boolean, containerClassName: string) => {
|
|
9
|
+
let buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName);
|
|
10
10
|
let shouldHide = false;
|
|
11
11
|
|
|
12
12
|
const hide = () => {
|
|
@@ -28,6 +28,11 @@ export const createPlugin = (buttonMap: ButtonMap, utils: Utils, bottom: boolean
|
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
return {
|
|
31
|
+
recreate: (editorView: EditorView) => {
|
|
32
|
+
buttonManager = createButtonManager(buttonMap, utils, bottom, containerClassName);
|
|
33
|
+
buttonManager.render(editorView);
|
|
34
|
+
update(editorView);
|
|
35
|
+
},
|
|
31
36
|
update,
|
|
32
37
|
destroy: () => {
|
|
33
38
|
buttonManager.destroy();
|
package/src/utility/toggle.ts
CHANGED
|
@@ -14,7 +14,7 @@ export const createToggleIcon = (
|
|
|
14
14
|
disableForMark: MarkType | undefined,
|
|
15
15
|
): ButtonItem => ({
|
|
16
16
|
$: ctx.get(themeManagerCtx).get(ThemeIcon, iconName)?.dom as HTMLElement,
|
|
17
|
-
command: () => ctx.get(commandsCtx).
|
|
17
|
+
command: () => ctx.get(commandsCtx).call(key),
|
|
18
18
|
active: (view) => hasMark(view.state, mark),
|
|
19
19
|
disable: (view) => isTextAndNotHasMark(view.state, disableForMark),
|
|
20
20
|
enable: (view) => !!mark && !!view.state.schema.marks[mark.name],
|