@milkdown/plugin-emoji 5.5.0 → 6.0.0-next.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.
- package/lib/{src/constant.d.ts → constant.d.ts} +0 -0
- package/lib/constant.d.ts.map +1 -0
- package/lib/{src/filter → filter}/helper.d.ts +0 -0
- package/lib/filter/helper.d.ts.map +1 -0
- package/lib/{src/filter → filter}/index.d.ts +0 -0
- package/lib/filter/index.d.ts.map +1 -0
- package/lib/filter/style.d.ts +3 -0
- package/lib/filter/style.d.ts.map +1 -0
- package/lib/index.d.ts +4 -1
- package/lib/index.d.ts.map +1 -0
- package/lib/index.es.js +65 -43
- package/lib/index.es.js.map +1 -1
- package/lib/{src/node.d.ts → node.d.ts} +1 -1
- package/lib/node.d.ts.map +1 -0
- package/lib/{src/parse.d.ts → parse.d.ts} +0 -0
- package/lib/parse.d.ts.map +1 -0
- package/lib/{src/picker.d.ts → picker.d.ts} +0 -0
- package/lib/picker.d.ts.map +1 -0
- package/lib/{src/remark-twemoji.d.ts → remark-twemoji.d.ts} +0 -0
- package/lib/remark-twemoji.d.ts.map +1 -0
- package/package.json +34 -10
- package/src/filter/helper.ts +16 -8
- package/src/filter/index.ts +18 -8
- package/src/filter/style.ts +22 -10
- package/src/node.ts +20 -16
- package/src/picker.ts +6 -3
- package/lib/src/constant.d.ts.map +0 -1
- package/lib/src/filter/helper.d.ts.map +0 -1
- package/lib/src/filter/index.d.ts.map +0 -1
- package/lib/src/filter/style.d.ts +0 -3
- package/lib/src/filter/style.d.ts.map +0 -1
- package/lib/src/index.d.ts +0 -4
- package/lib/src/index.d.ts.map +0 -1
- package/lib/src/node.d.ts.map +0 -1
- package/lib/src/parse.d.ts.map +0 -1
- package/lib/src/picker.d.ts.map +0 -1
- package/lib/src/remark-twemoji.d.ts.map +0 -1
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constant.d.ts","sourceRoot":"","sources":["../src/constant.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,IAAI,QAAqB,CAAC;AACvC,eAAO,MAAM,IAAI,QAAwB,CAAC;AAC1C,eAAO,MAAM,KAAK,QAAmB,CAAC;AACtC,eAAO,MAAM,OAAO,YAAY,CAAC"}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/filter/helper.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAKnC,eAAO,MAAM,YAAY,SACf,UAAU,QACV,MAAM,MACR,MAAM,QACJ,MAAM,mBACK,MAAM,MAAM,MAAM,KAAK,IAAI,qBACzB,MAAM,KAAK,IAAI,YAoBrC,CAAC;AAEF,eAAO,MAAM,kBAAkB,SACrB,KAAK,EAAE,YACH,WAAW,WACZ,WAAW,GAAG,IAAI,aAChB,MAAM,IAAI,sBACD,WAAW,GAAG,IAAI,KAAK,IAAI,SAmDlD,CAAC"}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/filter/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyB,MAAM,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAMxC,eAAO,MAAM,GAAG,qBAAgD,CAAC;AAEjE,eAAO,MAAM,MAAM,UAAW,KAAK,qBAmKlC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/filter/style.ts"],"names":[],"mappings":"AACA,OAAO,EAEH,OAAO,EAIP,YAAY,EAGf,MAAM,gBAAgB,CAAC;AAExB,eAAO,MAAM,WAAW,iBAAkB,YAAY,eAAe,OAAO,WAyC3E,CAAC"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { AtomList } from '@milkdown/utils';
|
|
2
|
+
export declare const emoji: AtomList<import("@milkdown/utils/lib/types").Metadata<import("@milkdown/utils/lib/types").GetPlugin<string, import("@milkdown/utils").UnknownRecord>> & import("@milkdown/core").MilkdownPlugin>;
|
|
3
|
+
export { emojiNode } from './node';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAI3C,eAAO,MAAM,KAAK,kMAAiC,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC"}
|
package/lib/index.es.js
CHANGED
|
@@ -22,6 +22,7 @@ import { PluginKey, Plugin, calculateNodePosition, DecorationSet, Decoration, In
|
|
|
22
22
|
import nodeEmoji, { search } from "node-emoji";
|
|
23
23
|
import remarkEmoji from "remark-emoji";
|
|
24
24
|
import twemoji from "twemoji";
|
|
25
|
+
import { ThemeBorder, ThemeShadow, ThemeSize, ThemeFont, ThemeColor } from "@milkdown/core";
|
|
25
26
|
import { EmojiButton } from "@joeattardi/emoji-button";
|
|
26
27
|
import emojiRegex from "emoji-regex";
|
|
27
28
|
const part = /:\+1|:-1|:[\w-]+/;
|
|
@@ -49,7 +50,9 @@ const checkTrigger$1 = (view, from, to, text, setRange, setSearch) => {
|
|
|
49
50
|
return false;
|
|
50
51
|
};
|
|
51
52
|
const renderDropdownList = (list, dropDown, $active, onConfirm, setActive) => {
|
|
52
|
-
dropDown.
|
|
53
|
+
while (dropDown.firstChild) {
|
|
54
|
+
dropDown.firstChild.remove();
|
|
55
|
+
}
|
|
53
56
|
list.forEach(({ emoji: emoji2, key: key2 }, i) => {
|
|
54
57
|
const container = document.createElement("div");
|
|
55
58
|
container.className = "milkdown-emoji-filter_item";
|
|
@@ -66,7 +69,7 @@ const renderDropdownList = (list, dropDown, $active, onConfirm, setActive) => {
|
|
|
66
69
|
container.classList.add("active");
|
|
67
70
|
setActive(container);
|
|
68
71
|
}
|
|
69
|
-
|
|
72
|
+
const onEnter = (e) => {
|
|
70
73
|
if ($active) {
|
|
71
74
|
$active.classList.remove("active");
|
|
72
75
|
}
|
|
@@ -75,43 +78,48 @@ const renderDropdownList = (list, dropDown, $active, onConfirm, setActive) => {
|
|
|
75
78
|
return;
|
|
76
79
|
target.classList.add("active");
|
|
77
80
|
setActive(target);
|
|
78
|
-
}
|
|
79
|
-
|
|
81
|
+
};
|
|
82
|
+
const onLeave = (e) => {
|
|
80
83
|
const { target } = e;
|
|
81
84
|
if (!(target instanceof HTMLElement))
|
|
82
85
|
return;
|
|
83
86
|
target.classList.remove("active");
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
onConfirm();
|
|
87
|
+
};
|
|
88
|
+
const onClick = (e) => {
|
|
87
89
|
e.preventDefault();
|
|
88
|
-
|
|
90
|
+
onConfirm();
|
|
91
|
+
};
|
|
92
|
+
container.addEventListener("mouseenter", onEnter);
|
|
93
|
+
container.addEventListener("mouseleave", onLeave);
|
|
94
|
+
container.addEventListener("mousedown", onClick);
|
|
89
95
|
});
|
|
90
96
|
};
|
|
91
|
-
const injectStyle = (
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
const
|
|
97
|
+
const injectStyle = (themeManager, { css, cx }) => {
|
|
98
|
+
const border = themeManager.get(ThemeBorder, void 0);
|
|
99
|
+
const shadow = themeManager.get(ThemeShadow, void 0);
|
|
100
|
+
const radius = themeManager.get(ThemeSize, "radius");
|
|
101
|
+
const typography = themeManager.get(ThemeFont, "typography");
|
|
102
|
+
const palette = (color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);
|
|
95
103
|
const style = css`
|
|
96
104
|
position: absolute;
|
|
97
105
|
&.hide {
|
|
98
106
|
display: none;
|
|
99
107
|
}
|
|
100
108
|
|
|
101
|
-
border-radius: ${
|
|
109
|
+
border-radius: ${radius};
|
|
102
110
|
background: ${palette("surface")};
|
|
103
111
|
|
|
104
112
|
.milkdown-emoji-filter_item {
|
|
105
113
|
display: flex;
|
|
106
|
-
gap: 0.
|
|
107
|
-
height: 2.
|
|
108
|
-
padding: 0
|
|
114
|
+
gap: 0.5em;
|
|
115
|
+
height: 2.57143em;
|
|
116
|
+
padding: 0 1em;
|
|
109
117
|
align-items: center;
|
|
110
118
|
justify-content: flex-start;
|
|
111
119
|
cursor: pointer;
|
|
112
120
|
line-height: 2;
|
|
113
|
-
font-family: ${
|
|
114
|
-
font-size: 0.
|
|
121
|
+
font-family: ${typography};
|
|
122
|
+
font-size: 0.875em;
|
|
115
123
|
&.active {
|
|
116
124
|
background: ${palette("secondary", 0.12)};
|
|
117
125
|
color: ${palette("primary")};
|
|
@@ -175,10 +183,12 @@ const filter = (utils) => {
|
|
|
175
183
|
throw new Error();
|
|
176
184
|
}
|
|
177
185
|
const dropDown = document.createElement("div");
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
186
|
+
utils.themeManager.onFlush(() => {
|
|
187
|
+
const style = utils.getStyle(injectStyle);
|
|
188
|
+
if (style) {
|
|
189
|
+
style.split(" ").forEach((x) => dropDown.classList.add(x));
|
|
190
|
+
}
|
|
191
|
+
});
|
|
182
192
|
dropDown.classList.add("milkdown-emoji-filter", "hide");
|
|
183
193
|
const replace = () => {
|
|
184
194
|
var _a;
|
|
@@ -191,7 +201,7 @@ const filter = (utils) => {
|
|
|
191
201
|
dropDown.classList.add("hide");
|
|
192
202
|
};
|
|
193
203
|
parentNode.appendChild(dropDown);
|
|
194
|
-
|
|
204
|
+
const onKeydown = (e) => {
|
|
195
205
|
if (!trigger || !(e instanceof KeyboardEvent))
|
|
196
206
|
return;
|
|
197
207
|
const { key: key2 } = e;
|
|
@@ -210,14 +220,16 @@ const filter = (utils) => {
|
|
|
210
220
|
$active = next;
|
|
211
221
|
return;
|
|
212
222
|
}
|
|
213
|
-
}
|
|
214
|
-
|
|
223
|
+
};
|
|
224
|
+
const onClick = (e) => {
|
|
215
225
|
if (!trigger)
|
|
216
226
|
return;
|
|
217
227
|
e.stopPropagation();
|
|
218
228
|
off();
|
|
219
229
|
dropDown.classList.add("hide");
|
|
220
|
-
}
|
|
230
|
+
};
|
|
231
|
+
parentNode.addEventListener("keydown", onKeydown);
|
|
232
|
+
parentNode.addEventListener("mousedown", onClick);
|
|
221
233
|
return {
|
|
222
234
|
update: (view) => {
|
|
223
235
|
const { selection } = view.state;
|
|
@@ -253,6 +265,11 @@ const filter = (utils) => {
|
|
|
253
265
|
return [top, left];
|
|
254
266
|
});
|
|
255
267
|
return null;
|
|
268
|
+
},
|
|
269
|
+
destroy: () => {
|
|
270
|
+
parentNode.removeEventListener("keydown", onKeydown);
|
|
271
|
+
parentNode.removeEventListener("mousedown", onClick);
|
|
272
|
+
dropDown.remove();
|
|
256
273
|
}
|
|
257
274
|
};
|
|
258
275
|
}
|
|
@@ -316,7 +333,9 @@ const picker = (utils) => {
|
|
|
316
333
|
if (!parentNode) {
|
|
317
334
|
throw new Error();
|
|
318
335
|
}
|
|
319
|
-
utils.getStyle((
|
|
336
|
+
utils.getStyle((themeManager, { injectGlobal }) => {
|
|
337
|
+
const palette = (color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);
|
|
338
|
+
const typography = themeManager.get(ThemeFont, "typography");
|
|
320
339
|
const css = injectGlobal;
|
|
321
340
|
css`
|
|
322
341
|
.emoji-picker {
|
|
@@ -328,8 +347,8 @@ const picker = (utils) => {
|
|
|
328
347
|
--dark-blue-color: ${palette("primary")} !important;
|
|
329
348
|
--dark-search-icon-color: ${palette("primary")} !important;
|
|
330
349
|
--dark-category-button-color: ${palette("secondary", 0.4)} !important;
|
|
331
|
-
--font: ${
|
|
332
|
-
--font-size:
|
|
350
|
+
--font: ${typography} !important;
|
|
351
|
+
--font-size: 1em !important;
|
|
333
352
|
}
|
|
334
353
|
`;
|
|
335
354
|
});
|
|
@@ -423,18 +442,18 @@ const twemojiPlugin = () => {
|
|
|
423
442
|
return transformer;
|
|
424
443
|
};
|
|
425
444
|
const emojiNode = createNode((utils) => {
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
445
|
+
const getStyle = () => utils.getStyle((_, { css }) => css`
|
|
446
|
+
display: inline-flex;
|
|
447
|
+
justify-content: center;
|
|
448
|
+
align-items: center;
|
|
430
449
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
450
|
+
.emoji {
|
|
451
|
+
height: 1em;
|
|
452
|
+
width: 1em;
|
|
453
|
+
margin: 0 0.05em 0 0.1em;
|
|
454
|
+
vertical-align: -0.1em;
|
|
455
|
+
}
|
|
456
|
+
`);
|
|
438
457
|
return {
|
|
439
458
|
id: "emoji",
|
|
440
459
|
schema: () => ({
|
|
@@ -460,9 +479,12 @@ const emojiNode = createNode((utils) => {
|
|
|
460
479
|
toDOM: (node) => {
|
|
461
480
|
const span = document.createElement("span");
|
|
462
481
|
span.dataset["type"] = "emoji";
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
482
|
+
utils.themeManager.onFlush(() => {
|
|
483
|
+
const style = getStyle();
|
|
484
|
+
if (style) {
|
|
485
|
+
span.classList.add(style);
|
|
486
|
+
}
|
|
487
|
+
});
|
|
466
488
|
span.classList.add("emoji-wrapper");
|
|
467
489
|
span.innerHTML = node.attrs["html"];
|
|
468
490
|
return { dom: span };
|
package/lib/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../src/constant.ts","../src/parse.ts","../src/filter/helper.ts","../src/filter/style.ts","../src/filter/index.ts","../src/picker.ts","../src/remark-twemoji.ts","../src/node.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nexport const part = /:\\+1|:-1|:[\\w-]+/;\nexport const full = /:\\+1:|:-1:|:[\\w-]+:/;\nexport const input = /(:([^:\\s]+):)$/;\nexport const keyword = ':emoji:';\n","/* Copyright 2021, Milkdown by Mirone. */\nimport twemoji from 'twemoji';\n\nexport const parse = (emoji: string) => twemoji.parse(emoji, { attributes: (text) => ({ title: text }) });\n","/* Copyright 2021, Milkdown by Mirone. */\n\nimport { EditorView } from '@milkdown/prose';\nimport { Emoji } from 'node-emoji';\n\nimport { full, part } from '../constant';\nimport { parse } from '../parse';\n\nexport const checkTrigger = (\n view: EditorView,\n from: number,\n to: number,\n text: string,\n setRange: (from: number, to: number) => void,\n setSearch: (words: string) => void,\n) => {\n if (view.composing) return false;\n const { state } = view;\n const $from = state.doc.resolve(from);\n if ($from.parent.type.spec.code) return false;\n const textBefore = (\n $from.parent.textBetween(Math.max(0, $from.parentOffset - 10), $from.parentOffset, undefined, '\\ufffc') + text\n ).toLowerCase();\n if (full.test(textBefore)) {\n return false;\n }\n const regex = part.exec(textBefore);\n if (regex && regex[0] && textBefore.endsWith(regex[0])) {\n const match = regex[0];\n setRange(from - (match.length - text.length), to);\n setSearch(match);\n return true;\n }\n return false;\n};\n\nexport const renderDropdownList = (\n list: Emoji[],\n dropDown: HTMLElement,\n $active: HTMLElement | null,\n onConfirm: () => void,\n setActive: (active: HTMLElement | null) => void,\n) => {\n dropDown.innerHTML = '';\n list.forEach(({ emoji, key }, i) => {\n const container = document.createElement('div');\n container.className = 'milkdown-emoji-filter_item';\n\n const emojiSpan = document.createElement('span');\n emojiSpan.innerHTML = parse(emoji);\n\n emojiSpan.className = 'milkdown-emoji-filter_item-emoji';\n const keySpan = document.createElement('span');\n keySpan.textContent = ':' + key + ':';\n keySpan.className = 'milkdown-emoji-filter_item-key';\n\n container.appendChild(emojiSpan);\n container.appendChild(keySpan);\n dropDown.appendChild(container);\n\n if (i === 0) {\n container.classList.add('active');\n setActive(container);\n }\n\n container.addEventListener('mouseenter', (e) => {\n if ($active) {\n $active.classList.remove('active');\n }\n const { target } = e;\n if (!(target instanceof HTMLElement)) return;\n target.classList.add('active');\n setActive(target);\n });\n container.addEventListener('mouseleave', (e) => {\n const { target } = e;\n if (!(target instanceof HTMLElement)) return;\n target.classList.remove('active');\n });\n container.addEventListener('mousedown', (e) => {\n onConfirm();\n e.preventDefault();\n });\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { Emotion, ThemeTool } from '@milkdown/core';\n\nexport const injectStyle = ({ size, mixin, palette, font }: ThemeTool, { css, cx }: Emotion) => {\n const border = mixin.border?.();\n const shadow = mixin.shadow?.();\n\n const style = css`\n position: absolute;\n &.hide {\n display: none;\n }\n\n border-radius: ${size.radius};\n background: ${palette('surface')};\n\n .milkdown-emoji-filter_item {\n display: flex;\n gap: 0.5rem;\n height: 2.25rem;\n padding: 0 1rem;\n align-items: center;\n justify-content: flex-start;\n cursor: pointer;\n line-height: 2;\n font-family: ${font.typography};\n font-size: 0.875rem;\n &.active {\n background: ${palette('secondary', 0.12)};\n color: ${palette('primary')};\n }\n }\n\n .emoji {\n height: 1em;\n width: 1em;\n margin: 0 0.05em 0 0.1em;\n vertical-align: -0.1em;\n }\n `;\n return cx(border, shadow, style);\n};\n","/* Copyright 2021, Milkdown by Mirone. */\n\nimport { calculateNodePosition, Plugin, PluginKey } from '@milkdown/prose';\nimport { Utils } from '@milkdown/utils';\nimport { search } from 'node-emoji';\n\nimport { checkTrigger, renderDropdownList } from './helper';\nimport { injectStyle } from './style';\n\nexport const key = new PluginKey('MILKDOWN_PLUGIN_EMOJI_FILTER');\n\nexport const filter = (utils: Utils) => {\n let trigger = false;\n let _from = 0;\n let _search = '';\n let $active: null | HTMLElement = null;\n\n const off = () => {\n trigger = false;\n _from = 0;\n _search = '';\n $active = null;\n };\n\n return new Plugin({\n key,\n props: {\n handleKeyDown(_, event) {\n if (['Delete', 'Backspace'].includes(event.key)) {\n _search = _search.slice(0, -1);\n if (_search.length <= 1) {\n off();\n }\n return false;\n }\n if (!trigger) return false;\n if (!['ArrowUp', 'ArrowDown', 'Enter'].includes(event.key)) {\n return false;\n }\n return true;\n },\n handleTextInput(view, from, to, text) {\n trigger = checkTrigger(\n view,\n from,\n to,\n text,\n (from) => {\n _from = from;\n },\n (search) => {\n _search = search;\n },\n );\n if (!trigger) {\n off();\n }\n return false;\n },\n },\n view: (editorView) => {\n const { parentNode } = editorView.dom;\n if (!parentNode) {\n throw new Error();\n }\n\n const dropDown = document.createElement('div');\n const style = utils.getStyle(injectStyle);\n\n if (style) {\n style.split(' ').forEach((x) => dropDown.classList.add(x));\n }\n\n dropDown.classList.add('milkdown-emoji-filter', 'hide');\n\n const replace = () => {\n if (!$active) return;\n\n const { tr } = editorView.state;\n const node = editorView.state.schema.node('emoji', { html: $active.firstElementChild?.innerHTML });\n\n editorView.dispatch(tr.delete(_from, _from + _search.length).insert(_from, node));\n off();\n dropDown.classList.add('hide');\n };\n\n parentNode.appendChild(dropDown);\n parentNode.addEventListener('keydown', (e) => {\n if (!trigger || !(e instanceof KeyboardEvent)) return;\n\n const { key } = e;\n\n if (key === 'Enter') {\n replace();\n return;\n }\n\n if (['ArrowDown', 'ArrowUp'].includes(key)) {\n const next =\n key === 'ArrowDown'\n ? $active?.nextElementSibling || dropDown.firstElementChild\n : $active?.previousElementSibling || dropDown.lastElementChild;\n if ($active) {\n $active.classList.remove('active');\n }\n if (!next) return;\n next.classList.add('active');\n $active = next as HTMLElement;\n\n return;\n }\n });\n parentNode.addEventListener('mousedown', (e) => {\n if (!trigger) return;\n\n e.stopPropagation();\n off();\n dropDown.classList.add('hide');\n });\n\n return {\n update: (view) => {\n const { selection } = view.state;\n\n if (selection.from - selection.to !== 0 || !trigger) {\n off();\n dropDown.classList.add('hide');\n return null;\n }\n const result = search(_search).slice(0, 5);\n const { node } = view.domAtPos(_from);\n if (result.length === 0 || !node) {\n dropDown.classList.add('hide');\n return null;\n }\n\n dropDown.classList.remove('hide');\n renderDropdownList(result, dropDown, $active, replace, (a) => {\n $active = a;\n });\n calculateNodePosition(view, dropDown, (selected, target, parent) => {\n const $editor = dropDown.parentElement;\n if (!$editor) {\n throw new Error();\n }\n const start = view.coordsAtPos(_from);\n let left = start.left - parent.left;\n let top = selected.bottom - parent.top + 14 + $editor.scrollTop;\n\n if (left < 0) {\n left = 0;\n }\n\n if (window.innerHeight - start.bottom < target.height) {\n top = selected.top - parent.top - target.height - 14 + $editor.scrollTop;\n }\n return [top, left];\n });\n\n return null;\n },\n };\n },\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { EmojiButton } from '@joeattardi/emoji-button';\nimport { Decoration, DecorationSet, EditorView, Plugin, PluginKey } from '@milkdown/prose';\nimport { Utils } from '@milkdown/utils';\n\nimport { parse } from './parse';\n\nconst keyword = ':emoji:';\nexport const key = new PluginKey('MILKDOWN_PLUGIN_EMOJI_PICKER');\n\nconst checkTrigger = (\n view: EditorView,\n from: number,\n to: number,\n text: string,\n setRange: (from: number, to: number) => void,\n) => {\n if (view.composing) return false;\n const { state } = view;\n const $from = state.doc.resolve(from);\n if ($from.parent.type.spec.code) return false;\n const textBefore =\n $from.parent.textBetween($from.parentOffset - keyword.length + 1, $from.parentOffset, undefined, '\\ufffc') +\n text;\n if (textBefore === keyword) {\n setRange(from - keyword.length + 1, to + 1);\n return true;\n }\n return false;\n};\n\nexport const picker = (utils: Utils) => {\n let trigger = false;\n const holder = document.createElement('span');\n let _from = 0;\n let _to = 0;\n const off = () => {\n trigger = false;\n _from = 0;\n _to = 0;\n };\n\n const plugin = new Plugin({\n key,\n props: {\n handleKeyDown() {\n off();\n return false;\n },\n handleClick() {\n off();\n return false;\n },\n handleTextInput(view, from, to, text) {\n trigger = checkTrigger(view, from, to, text, (from, to) => {\n _from = from;\n _to = to;\n });\n\n if (!trigger) {\n off();\n }\n return false;\n },\n decorations(state) {\n if (!trigger) return null;\n\n return DecorationSet.create(state.doc, [Decoration.widget(state.selection.to, holder)]);\n },\n },\n view: (editorView) => {\n const { parentNode } = editorView.dom;\n if (!parentNode) {\n throw new Error();\n }\n utils.getStyle(({ palette, font }, { injectGlobal }) => {\n const css = injectGlobal;\n css`\n .emoji-picker {\n --dark-search-background-color: ${palette('surface')} !important;\n --dark-text-color: ${palette('neutral', 0.87)} !important;\n --dark-background-color: ${palette('background')} !important;\n --dark-border-color: ${palette('shadow')} !important;\n --dark-hover-color: ${palette('secondary', 0.12)} !important;\n --dark-blue-color: ${palette('primary')} !important;\n --dark-search-icon-color: ${palette('primary')} !important;\n --dark-category-button-color: ${palette('secondary', 0.4)} !important;\n --font: ${font.typography} !important;\n --font-size: 1rem !important;\n }\n `;\n });\n const emojiPicker = new EmojiButton({\n rootElement: parentNode as HTMLElement,\n autoFocusSearch: false,\n style: 'twemoji',\n theme: 'dark',\n zIndex: 99,\n });\n emojiPicker.on('emoji', (selection) => {\n const start = _from;\n const end = _to;\n off();\n const html = parse(selection.emoji);\n const node = editorView.state.schema.node('emoji', { html });\n const { tr } = editorView.state;\n\n editorView.dispatch(tr.replaceRangeWith(start, end, node));\n });\n return {\n update: () => {\n if (!trigger) {\n emojiPicker.hidePicker();\n return null;\n }\n emojiPicker.showPicker(holder);\n return null;\n },\n destroy: () => {\n emojiPicker.destroyPicker();\n },\n };\n },\n });\n\n return plugin;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport emojiRegex from 'emoji-regex';\nimport { Literal, Node, Parent } from 'unist';\n\nimport { parse } from './parse';\n\nconst regex = emojiRegex();\n\nconst isParent = (node: Node): node is Parent => !!(node as Parent).children;\nconst isLiteral = (node: Node): node is Literal => !!(node as Literal).value;\n\nfunction flatMap(ast: Node, fn: (node: Node, index: number, parent: Node | null) => Node[]) {\n return transform(ast, 0, null)[0];\n\n function transform(node: Node, index: number, parent: Node | null) {\n if (isParent(node)) {\n const out = [];\n for (let i = 0, n = node.children.length; i < n; i++) {\n const nthChild = node.children[i];\n if (nthChild) {\n const xs = transform(nthChild, i, node);\n if (xs) {\n for (let j = 0, m = xs.length; j < m; j++) {\n const item = xs[j];\n if (item) {\n out.push(item);\n }\n }\n }\n }\n }\n node.children = out;\n }\n\n return fn(node, index, parent);\n }\n}\n\nexport const twemojiPlugin = () => {\n function transformer(tree: Node) {\n flatMap(tree, (node) => {\n if (!isLiteral(node)) {\n return [node];\n }\n const value = node.value as string;\n const output: Literal<string>[] = [];\n let match;\n let str = value;\n while ((match = regex.exec(str))) {\n const { index } = match;\n const emoji = match[0];\n if (emoji) {\n if (index > 0) {\n output.push({ ...node, value: str.slice(0, index) });\n }\n output.push({ ...node, value: parse(emoji), type: 'emoji' });\n str = str.slice(index + emoji.length);\n }\n }\n if (str.length) {\n output.push({ ...node, value: str });\n }\n return output;\n });\n }\n return transformer;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { RemarkPlugin } from '@milkdown/core';\nimport { InputRule } from '@milkdown/prose';\nimport { createNode } from '@milkdown/utils';\nimport nodeEmoji from 'node-emoji';\nimport remarkEmoji from 'remark-emoji';\n\nimport { input } from './constant';\nimport { filter } from './filter';\nimport { parse } from './parse';\nimport { picker } from './picker';\nimport { twemojiPlugin } from './remark-twemoji';\n\nexport const emojiNode = createNode((utils) => {\n const style = utils.getStyle(\n (_, { css }) => css`\n display: inline-flex;\n justify-content: center;\n align-items: center;\n\n .emoji {\n height: 1em;\n width: 1em;\n margin: 0 0.05em 0 0.1em;\n vertical-align: -0.1em;\n }\n `,\n );\n return {\n id: 'emoji',\n schema: () => ({\n group: 'inline',\n inline: true,\n selectable: false,\n attrs: {\n html: {\n default: '',\n },\n },\n parseDOM: [\n {\n tag: 'span[data-type=\"emoji\"]',\n getAttrs: (dom) => {\n if (!(dom instanceof HTMLElement)) {\n throw new Error();\n }\n return { html: dom.innerHTML };\n },\n },\n ],\n toDOM: (node) => {\n const span = document.createElement('span');\n span.dataset['type'] = 'emoji';\n if (style) {\n span.classList.add(style);\n }\n span.classList.add('emoji-wrapper');\n span.innerHTML = node.attrs['html'];\n return { dom: span };\n },\n parseMarkdown: {\n match: ({ type }) => type === 'emoji',\n runner: (state, node, type) => {\n state.addNode(type, { html: node['value'] as string });\n },\n },\n toMarkdown: {\n match: (node) => node.type.name === 'emoji',\n runner: (state, node) => {\n const span = document.createElement('span');\n span.innerHTML = node.attrs['html'];\n const img = span.querySelector('img');\n const title = img?.title;\n span.remove();\n state.addNode('text', undefined, title);\n },\n },\n }),\n inputRules: (nodeType) => [\n new InputRule(input, (state, match, start, end) => {\n const content = match[0];\n if (!content) return null;\n const got = nodeEmoji.get(content);\n if (!got || content.includes(got)) return null;\n\n const html = parse(got);\n\n return state.tr\n .setMeta('emoji', true)\n .replaceRangeWith(start, end, nodeType.create({ html }))\n .scrollIntoView();\n }),\n ],\n remarkPlugins: () => [remarkEmoji as RemarkPlugin, twemojiPlugin],\n prosePlugins: () => [picker(utils), filter(utils)],\n };\n});\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { AtomList } from '@milkdown/utils';\n\nimport { emojiNode } from './node';\n\nexport const emoji = AtomList.create([emojiNode()]);\n\nexport { emojiNode } from './node';\n"],"names":["checkTrigger","key"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/constant.ts","../src/parse.ts","../src/filter/helper.ts","../src/filter/style.ts","../src/filter/index.ts","../src/picker.ts","../src/remark-twemoji.ts","../src/node.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nexport const part = /:\\+1|:-1|:[\\w-]+/;\nexport const full = /:\\+1:|:-1:|:[\\w-]+:/;\nexport const input = /(:([^:\\s]+):)$/;\nexport const keyword = ':emoji:';\n","/* Copyright 2021, Milkdown by Mirone. */\nimport twemoji from 'twemoji';\n\nexport const parse = (emoji: string) => twemoji.parse(emoji, { attributes: (text) => ({ title: text }) });\n","/* Copyright 2021, Milkdown by Mirone. */\n\nimport { EditorView } from '@milkdown/prose';\nimport { Emoji } from 'node-emoji';\n\nimport { full, part } from '../constant';\nimport { parse } from '../parse';\n\nexport const checkTrigger = (\n view: EditorView,\n from: number,\n to: number,\n text: string,\n setRange: (from: number, to: number) => void,\n setSearch: (words: string) => void,\n) => {\n if (view.composing) return false;\n const { state } = view;\n const $from = state.doc.resolve(from);\n if ($from.parent.type.spec.code) return false;\n const textBefore = (\n $from.parent.textBetween(Math.max(0, $from.parentOffset - 10), $from.parentOffset, undefined, '\\ufffc') + text\n ).toLowerCase();\n if (full.test(textBefore)) {\n return false;\n }\n const regex = part.exec(textBefore);\n if (regex && regex[0] && textBefore.endsWith(regex[0])) {\n const match = regex[0];\n setRange(from - (match.length - text.length), to);\n setSearch(match);\n return true;\n }\n return false;\n};\n\nexport const renderDropdownList = (\n list: Emoji[],\n dropDown: HTMLElement,\n $active: HTMLElement | null,\n onConfirm: () => void,\n setActive: (active: HTMLElement | null) => void,\n) => {\n while (dropDown.firstChild) {\n dropDown.firstChild.remove();\n }\n list.forEach(({ emoji, key }, i) => {\n const container = document.createElement('div');\n container.className = 'milkdown-emoji-filter_item';\n\n const emojiSpan = document.createElement('span');\n emojiSpan.innerHTML = parse(emoji);\n\n emojiSpan.className = 'milkdown-emoji-filter_item-emoji';\n const keySpan = document.createElement('span');\n keySpan.textContent = ':' + key + ':';\n keySpan.className = 'milkdown-emoji-filter_item-key';\n\n container.appendChild(emojiSpan);\n container.appendChild(keySpan);\n dropDown.appendChild(container);\n\n if (i === 0) {\n container.classList.add('active');\n setActive(container);\n }\n\n const onEnter = (e: MouseEvent) => {\n if ($active) {\n $active.classList.remove('active');\n }\n const { target } = e;\n if (!(target instanceof HTMLElement)) return;\n target.classList.add('active');\n setActive(target);\n };\n\n const onLeave = (e: MouseEvent) => {\n const { target } = e;\n if (!(target instanceof HTMLElement)) return;\n target.classList.remove('active');\n };\n\n const onClick = (e: MouseEvent) => {\n e.preventDefault();\n onConfirm();\n };\n\n container.addEventListener('mouseenter', onEnter);\n container.addEventListener('mouseleave', onLeave);\n container.addEventListener('mousedown', onClick);\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport {\n Color,\n Emotion,\n ThemeBorder,\n ThemeColor,\n ThemeFont,\n ThemeManager,\n ThemeShadow,\n ThemeSize,\n} from '@milkdown/core';\n\nexport const injectStyle = (themeManager: ThemeManager, { css, cx }: Emotion) => {\n const border = themeManager.get(ThemeBorder, undefined);\n const shadow = themeManager.get(ThemeShadow, undefined);\n const radius = themeManager.get(ThemeSize, 'radius');\n const typography = themeManager.get(ThemeFont, 'typography');\n const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);\n\n const style = css`\n position: absolute;\n &.hide {\n display: none;\n }\n\n border-radius: ${radius};\n background: ${palette('surface')};\n\n .milkdown-emoji-filter_item {\n display: flex;\n gap: 0.5em;\n height: 2.57143em;\n padding: 0 1em;\n align-items: center;\n justify-content: flex-start;\n cursor: pointer;\n line-height: 2;\n font-family: ${typography};\n font-size: 0.875em;\n &.active {\n background: ${palette('secondary', 0.12)};\n color: ${palette('primary')};\n }\n }\n\n .emoji {\n height: 1em;\n width: 1em;\n margin: 0 0.05em 0 0.1em;\n vertical-align: -0.1em;\n }\n `;\n return cx(border, shadow, style);\n};\n","/* Copyright 2021, Milkdown by Mirone. */\n\nimport { calculateNodePosition, Plugin, PluginKey } from '@milkdown/prose';\nimport { Utils } from '@milkdown/utils';\nimport { search } from 'node-emoji';\n\nimport { checkTrigger, renderDropdownList } from './helper';\nimport { injectStyle } from './style';\n\nexport const key = new PluginKey('MILKDOWN_PLUGIN_EMOJI_FILTER');\n\nexport const filter = (utils: Utils) => {\n let trigger = false;\n let _from = 0;\n let _search = '';\n let $active: null | HTMLElement = null;\n\n const off = () => {\n trigger = false;\n _from = 0;\n _search = '';\n $active = null;\n };\n\n return new Plugin({\n key,\n props: {\n handleKeyDown(_, event) {\n if (['Delete', 'Backspace'].includes(event.key)) {\n _search = _search.slice(0, -1);\n if (_search.length <= 1) {\n off();\n }\n return false;\n }\n if (!trigger) return false;\n if (!['ArrowUp', 'ArrowDown', 'Enter'].includes(event.key)) {\n return false;\n }\n return true;\n },\n handleTextInput(view, from, to, text) {\n trigger = checkTrigger(\n view,\n from,\n to,\n text,\n (from) => {\n _from = from;\n },\n (search) => {\n _search = search;\n },\n );\n if (!trigger) {\n off();\n }\n return false;\n },\n },\n view: (editorView) => {\n const { parentNode } = editorView.dom;\n if (!parentNode) {\n throw new Error();\n }\n\n const dropDown = document.createElement('div');\n\n utils.themeManager.onFlush(() => {\n const style = utils.getStyle(injectStyle);\n if (style) {\n style.split(' ').forEach((x) => dropDown.classList.add(x));\n }\n });\n\n dropDown.classList.add('milkdown-emoji-filter', 'hide');\n\n const replace = () => {\n if (!$active) return;\n\n const { tr } = editorView.state;\n const node = editorView.state.schema.node('emoji', { html: $active.firstElementChild?.innerHTML });\n\n editorView.dispatch(tr.delete(_from, _from + _search.length).insert(_from, node));\n off();\n dropDown.classList.add('hide');\n };\n\n parentNode.appendChild(dropDown);\n const onKeydown = (e: Event) => {\n if (!trigger || !(e instanceof KeyboardEvent)) return;\n\n const { key } = e;\n\n if (key === 'Enter') {\n replace();\n return;\n }\n\n if (['ArrowDown', 'ArrowUp'].includes(key)) {\n const next =\n key === 'ArrowDown'\n ? $active?.nextElementSibling || dropDown.firstElementChild\n : $active?.previousElementSibling || dropDown.lastElementChild;\n if ($active) {\n $active.classList.remove('active');\n }\n if (!next) return;\n next.classList.add('active');\n $active = next as HTMLElement;\n\n return;\n }\n };\n const onClick = (e: Event) => {\n if (!trigger) return;\n\n e.stopPropagation();\n off();\n dropDown.classList.add('hide');\n };\n parentNode.addEventListener('keydown', onKeydown);\n parentNode.addEventListener('mousedown', onClick);\n\n return {\n update: (view) => {\n const { selection } = view.state;\n\n if (selection.from - selection.to !== 0 || !trigger) {\n off();\n dropDown.classList.add('hide');\n return null;\n }\n const result = search(_search).slice(0, 5);\n const { node } = view.domAtPos(_from);\n if (result.length === 0 || !node) {\n dropDown.classList.add('hide');\n return null;\n }\n\n dropDown.classList.remove('hide');\n renderDropdownList(result, dropDown, $active, replace, (a) => {\n $active = a;\n });\n calculateNodePosition(view, dropDown, (selected, target, parent) => {\n const $editor = dropDown.parentElement;\n if (!$editor) {\n throw new Error();\n }\n const start = view.coordsAtPos(_from);\n let left = start.left - parent.left;\n let top = selected.bottom - parent.top + 14 + $editor.scrollTop;\n\n if (left < 0) {\n left = 0;\n }\n\n if (window.innerHeight - start.bottom < target.height) {\n top = selected.top - parent.top - target.height - 14 + $editor.scrollTop;\n }\n return [top, left];\n });\n\n return null;\n },\n\n destroy: () => {\n parentNode.removeEventListener('keydown', onKeydown);\n parentNode.removeEventListener('mousedown', onClick);\n dropDown.remove();\n },\n };\n },\n });\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { EmojiButton } from '@joeattardi/emoji-button';\nimport { Color, ThemeColor, ThemeFont } from '@milkdown/core';\nimport { Decoration, DecorationSet, EditorView, Plugin, PluginKey } from '@milkdown/prose';\nimport { Utils } from '@milkdown/utils';\n\nimport { parse } from './parse';\n\nconst keyword = ':emoji:';\nexport const key = new PluginKey('MILKDOWN_PLUGIN_EMOJI_PICKER');\n\nconst checkTrigger = (\n view: EditorView,\n from: number,\n to: number,\n text: string,\n setRange: (from: number, to: number) => void,\n) => {\n if (view.composing) return false;\n const { state } = view;\n const $from = state.doc.resolve(from);\n if ($from.parent.type.spec.code) return false;\n const textBefore =\n $from.parent.textBetween($from.parentOffset - keyword.length + 1, $from.parentOffset, undefined, '\\ufffc') +\n text;\n if (textBefore === keyword) {\n setRange(from - keyword.length + 1, to + 1);\n return true;\n }\n return false;\n};\n\nexport const picker = (utils: Utils) => {\n let trigger = false;\n const holder = document.createElement('span');\n let _from = 0;\n let _to = 0;\n const off = () => {\n trigger = false;\n _from = 0;\n _to = 0;\n };\n\n const plugin = new Plugin({\n key,\n props: {\n handleKeyDown() {\n off();\n return false;\n },\n handleClick() {\n off();\n return false;\n },\n handleTextInput(view, from, to, text) {\n trigger = checkTrigger(view, from, to, text, (from, to) => {\n _from = from;\n _to = to;\n });\n\n if (!trigger) {\n off();\n }\n return false;\n },\n decorations(state) {\n if (!trigger) return null;\n\n return DecorationSet.create(state.doc, [Decoration.widget(state.selection.to, holder)]);\n },\n },\n view: (editorView) => {\n const { parentNode } = editorView.dom;\n if (!parentNode) {\n throw new Error();\n }\n utils.getStyle((themeManager, { injectGlobal }) => {\n const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);\n const typography = themeManager.get(ThemeFont, 'typography');\n const css = injectGlobal;\n css`\n .emoji-picker {\n --dark-search-background-color: ${palette('surface')} !important;\n --dark-text-color: ${palette('neutral', 0.87)} !important;\n --dark-background-color: ${palette('background')} !important;\n --dark-border-color: ${palette('shadow')} !important;\n --dark-hover-color: ${palette('secondary', 0.12)} !important;\n --dark-blue-color: ${palette('primary')} !important;\n --dark-search-icon-color: ${palette('primary')} !important;\n --dark-category-button-color: ${palette('secondary', 0.4)} !important;\n --font: ${typography} !important;\n --font-size: 1em !important;\n }\n `;\n });\n const emojiPicker = new EmojiButton({\n rootElement: parentNode as HTMLElement,\n autoFocusSearch: false,\n style: 'twemoji',\n theme: 'dark',\n zIndex: 99,\n });\n emojiPicker.on('emoji', (selection) => {\n const start = _from;\n const end = _to;\n off();\n const html = parse(selection.emoji);\n const node = editorView.state.schema.node('emoji', { html });\n const { tr } = editorView.state;\n\n editorView.dispatch(tr.replaceRangeWith(start, end, node));\n });\n return {\n update: () => {\n if (!trigger) {\n emojiPicker.hidePicker();\n return null;\n }\n emojiPicker.showPicker(holder);\n return null;\n },\n destroy: () => {\n emojiPicker.destroyPicker();\n },\n };\n },\n });\n\n return plugin;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport emojiRegex from 'emoji-regex';\nimport { Literal, Node, Parent } from 'unist';\n\nimport { parse } from './parse';\n\nconst regex = emojiRegex();\n\nconst isParent = (node: Node): node is Parent => !!(node as Parent).children;\nconst isLiteral = (node: Node): node is Literal => !!(node as Literal).value;\n\nfunction flatMap(ast: Node, fn: (node: Node, index: number, parent: Node | null) => Node[]) {\n return transform(ast, 0, null)[0];\n\n function transform(node: Node, index: number, parent: Node | null) {\n if (isParent(node)) {\n const out = [];\n for (let i = 0, n = node.children.length; i < n; i++) {\n const nthChild = node.children[i];\n if (nthChild) {\n const xs = transform(nthChild, i, node);\n if (xs) {\n for (let j = 0, m = xs.length; j < m; j++) {\n const item = xs[j];\n if (item) {\n out.push(item);\n }\n }\n }\n }\n }\n node.children = out;\n }\n\n return fn(node, index, parent);\n }\n}\n\nexport const twemojiPlugin = () => {\n function transformer(tree: Node) {\n flatMap(tree, (node) => {\n if (!isLiteral(node)) {\n return [node];\n }\n const value = node.value as string;\n const output: Literal<string>[] = [];\n let match;\n let str = value;\n while ((match = regex.exec(str))) {\n const { index } = match;\n const emoji = match[0];\n if (emoji) {\n if (index > 0) {\n output.push({ ...node, value: str.slice(0, index) });\n }\n output.push({ ...node, value: parse(emoji), type: 'emoji' });\n str = str.slice(index + emoji.length);\n }\n }\n if (str.length) {\n output.push({ ...node, value: str });\n }\n return output;\n });\n }\n return transformer;\n};\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { RemarkPlugin } from '@milkdown/core';\nimport { InputRule } from '@milkdown/prose';\nimport { createNode } from '@milkdown/utils';\nimport nodeEmoji from 'node-emoji';\nimport remarkEmoji from 'remark-emoji';\n\nimport { input } from './constant';\nimport { filter } from './filter';\nimport { parse } from './parse';\nimport { picker } from './picker';\nimport { twemojiPlugin } from './remark-twemoji';\n\nexport const emojiNode = createNode((utils) => {\n const getStyle = () =>\n utils.getStyle(\n (_, { css }) => css`\n display: inline-flex;\n justify-content: center;\n align-items: center;\n\n .emoji {\n height: 1em;\n width: 1em;\n margin: 0 0.05em 0 0.1em;\n vertical-align: -0.1em;\n }\n `,\n );\n return {\n id: 'emoji',\n schema: () => ({\n group: 'inline',\n inline: true,\n selectable: false,\n attrs: {\n html: {\n default: '',\n },\n },\n parseDOM: [\n {\n tag: 'span[data-type=\"emoji\"]',\n getAttrs: (dom) => {\n if (!(dom instanceof HTMLElement)) {\n throw new Error();\n }\n return { html: dom.innerHTML };\n },\n },\n ],\n toDOM: (node) => {\n const span = document.createElement('span');\n span.dataset['type'] = 'emoji';\n utils.themeManager.onFlush(() => {\n const style = getStyle();\n if (style) {\n span.classList.add(style);\n }\n });\n span.classList.add('emoji-wrapper');\n span.innerHTML = node.attrs['html'];\n return { dom: span };\n },\n parseMarkdown: {\n match: ({ type }) => type === 'emoji',\n runner: (state, node, type) => {\n state.addNode(type, { html: node['value'] as string });\n },\n },\n toMarkdown: {\n match: (node) => node.type.name === 'emoji',\n runner: (state, node) => {\n const span = document.createElement('span');\n span.innerHTML = node.attrs['html'];\n const img = span.querySelector('img');\n const title = img?.title;\n span.remove();\n state.addNode('text', undefined, title);\n },\n },\n }),\n inputRules: (nodeType) => [\n new InputRule(input, (state, match, start, end) => {\n const content = match[0];\n if (!content) return null;\n const got = nodeEmoji.get(content);\n if (!got || content.includes(got)) return null;\n\n const html = parse(got);\n\n return state.tr\n .setMeta('emoji', true)\n .replaceRangeWith(start, end, nodeType.create({ html }))\n .scrollIntoView();\n }),\n ],\n remarkPlugins: () => [remarkEmoji as RemarkPlugin, twemojiPlugin],\n prosePlugins: () => [picker(utils), filter(utils)],\n };\n});\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { AtomList } from '@milkdown/utils';\n\nimport { emojiNode } from './node';\n\nexport const emoji = AtomList.create([emojiNode()]);\n\nexport { emojiNode } from './node';\n"],"names":["checkTrigger","key"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const emojiNode: import("@milkdown/utils/lib/
|
|
1
|
+
export declare const emojiNode: import("@milkdown/utils/lib/types").WithExtend<string, import("@milkdown/utils").UnknownRecord, import("prosemirror-model").NodeType<any>, {
|
|
2
2
|
id: string;
|
|
3
3
|
schema: (ctx: import("@milkdown/core").Ctx) => import("@milkdown/core").NodeSchema;
|
|
4
4
|
view?: ((ctx: import("@milkdown/core").Ctx) => import("@milkdown/prose").NodeViewFactory) | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,SAAS;;;;EAuFpB,CAAC"}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,KAAK,UAAW,MAAM,WAAsE,CAAC"}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"picker.d.ts","sourceRoot":"","sources":["../src/picker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAyC,MAAM,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC3F,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAKxC,eAAO,MAAM,GAAG,qBAAgD,CAAC;AAuBjE,eAAO,MAAM,MAAM,UAAW,KAAK,qBAiGlC,CAAC"}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remark-twemoji.d.ts","sourceRoot":"","sources":["../src/remark-twemoji.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,IAAI,EAAU,MAAM,OAAO,CAAC;AAoC9C,eAAO,MAAM,aAAa,eACK,IAAI,SA2BlC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkdown/plugin-emoji",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0-next.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./lib/index.es.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -15,30 +15,54 @@
|
|
|
15
15
|
"milkdown plugin"
|
|
16
16
|
],
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@milkdown/core": "
|
|
19
|
-
"@milkdown/prose": "
|
|
18
|
+
"@milkdown/core": "6.0.0-next.0",
|
|
19
|
+
"@milkdown/prose": "6.0.0-next.0"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"@milkdown/core": "^
|
|
23
|
-
"@milkdown/prose": "^
|
|
22
|
+
"@milkdown/core": "^6.0.0-next.0",
|
|
23
|
+
"@milkdown/prose": "^6.0.0-next.0"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@joeattardi/emoji-button": "^4.6.
|
|
27
|
-
"@milkdown/utils": "
|
|
26
|
+
"@joeattardi/emoji-button": "^4.6.4",
|
|
27
|
+
"@milkdown/utils": "6.0.0-next.0",
|
|
28
28
|
"@types/node-emoji": "^1.8.1",
|
|
29
29
|
"@types/twemoji": "^12.1.2",
|
|
30
30
|
"emoji-regex": "^10.0.0",
|
|
31
31
|
"node-emoji": "^1.10.0",
|
|
32
32
|
"remark-emoji": "^3.0.1",
|
|
33
33
|
"tslib": "^2.3.1",
|
|
34
|
-
"twemoji": "
|
|
34
|
+
"twemoji": "~12.1.2",
|
|
35
35
|
"unist-util-visit": "^4.0.0"
|
|
36
36
|
},
|
|
37
|
+
"nx": {
|
|
38
|
+
"targets": {
|
|
39
|
+
"build": {
|
|
40
|
+
"outputs": [
|
|
41
|
+
"packages/plugin-emoji/lib"
|
|
42
|
+
],
|
|
43
|
+
"dependsOn": [
|
|
44
|
+
{
|
|
45
|
+
"target": "build",
|
|
46
|
+
"projects": "dependencies"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"tsc": {
|
|
51
|
+
"outputs": [],
|
|
52
|
+
"dependsOn": [
|
|
53
|
+
{
|
|
54
|
+
"target": "build",
|
|
55
|
+
"projects": "dependencies"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
37
61
|
"scripts": {
|
|
38
|
-
"start": "vite build --watch",
|
|
62
|
+
"start": "concurrently -n es,dts \"vite build --watch\" \"tsc --emitDeclarationOnly --watch\"",
|
|
39
63
|
"test": "vitest",
|
|
40
64
|
"tsc": "tsc --noEmit",
|
|
41
|
-
"build": "vite build"
|
|
65
|
+
"build": "vite build && tsc --emitDeclarationOnly"
|
|
42
66
|
},
|
|
43
67
|
"readme": "# @milkdown/plugin-emoji\n\nEmoji plugin for [milkdown](https://saul-mirone.github.io/milkdown/).\nAdd support for emoji through [shortcuts](https://www.webfx.com/tools/emoji-cheat-sheet/).\nRendered by [twemoji](https://github.com/twitter/twemoji).\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 { emoji } from '@milkdown/plugin-emoji';\n\nEditor.make().use(nord).use(commonmark).use(emoji).create();\n```\n\n# License\n\nMilkdown is open sourced software licensed under [MIT license](https://github.com/Saul-Mirone/milkdown/blob/main/LICENSE).\n"
|
|
44
68
|
}
|
package/src/filter/helper.ts
CHANGED
|
@@ -41,7 +41,9 @@ export const renderDropdownList = (
|
|
|
41
41
|
onConfirm: () => void,
|
|
42
42
|
setActive: (active: HTMLElement | null) => void,
|
|
43
43
|
) => {
|
|
44
|
-
dropDown.
|
|
44
|
+
while (dropDown.firstChild) {
|
|
45
|
+
dropDown.firstChild.remove();
|
|
46
|
+
}
|
|
45
47
|
list.forEach(({ emoji, key }, i) => {
|
|
46
48
|
const container = document.createElement('div');
|
|
47
49
|
container.className = 'milkdown-emoji-filter_item';
|
|
@@ -63,7 +65,7 @@ export const renderDropdownList = (
|
|
|
63
65
|
setActive(container);
|
|
64
66
|
}
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
const onEnter = (e: MouseEvent) => {
|
|
67
69
|
if ($active) {
|
|
68
70
|
$active.classList.remove('active');
|
|
69
71
|
}
|
|
@@ -71,15 +73,21 @@ export const renderDropdownList = (
|
|
|
71
73
|
if (!(target instanceof HTMLElement)) return;
|
|
72
74
|
target.classList.add('active');
|
|
73
75
|
setActive(target);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const onLeave = (e: MouseEvent) => {
|
|
76
79
|
const { target } = e;
|
|
77
80
|
if (!(target instanceof HTMLElement)) return;
|
|
78
81
|
target.classList.remove('active');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const onClick = (e: MouseEvent) => {
|
|
82
85
|
e.preventDefault();
|
|
83
|
-
|
|
86
|
+
onConfirm();
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
container.addEventListener('mouseenter', onEnter);
|
|
90
|
+
container.addEventListener('mouseleave', onLeave);
|
|
91
|
+
container.addEventListener('mousedown', onClick);
|
|
84
92
|
});
|
|
85
93
|
};
|
package/src/filter/index.ts
CHANGED
|
@@ -65,11 +65,13 @@ export const filter = (utils: Utils) => {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
const dropDown = document.createElement('div');
|
|
68
|
-
const style = utils.getStyle(injectStyle);
|
|
69
68
|
|
|
70
|
-
|
|
71
|
-
style
|
|
72
|
-
|
|
69
|
+
utils.themeManager.onFlush(() => {
|
|
70
|
+
const style = utils.getStyle(injectStyle);
|
|
71
|
+
if (style) {
|
|
72
|
+
style.split(' ').forEach((x) => dropDown.classList.add(x));
|
|
73
|
+
}
|
|
74
|
+
});
|
|
73
75
|
|
|
74
76
|
dropDown.classList.add('milkdown-emoji-filter', 'hide');
|
|
75
77
|
|
|
@@ -85,7 +87,7 @@ export const filter = (utils: Utils) => {
|
|
|
85
87
|
};
|
|
86
88
|
|
|
87
89
|
parentNode.appendChild(dropDown);
|
|
88
|
-
|
|
90
|
+
const onKeydown = (e: Event) => {
|
|
89
91
|
if (!trigger || !(e instanceof KeyboardEvent)) return;
|
|
90
92
|
|
|
91
93
|
const { key } = e;
|
|
@@ -109,14 +111,16 @@ export const filter = (utils: Utils) => {
|
|
|
109
111
|
|
|
110
112
|
return;
|
|
111
113
|
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
+
};
|
|
115
|
+
const onClick = (e: Event) => {
|
|
114
116
|
if (!trigger) return;
|
|
115
117
|
|
|
116
118
|
e.stopPropagation();
|
|
117
119
|
off();
|
|
118
120
|
dropDown.classList.add('hide');
|
|
119
|
-
}
|
|
121
|
+
};
|
|
122
|
+
parentNode.addEventListener('keydown', onKeydown);
|
|
123
|
+
parentNode.addEventListener('mousedown', onClick);
|
|
120
124
|
|
|
121
125
|
return {
|
|
122
126
|
update: (view) => {
|
|
@@ -159,6 +163,12 @@ export const filter = (utils: Utils) => {
|
|
|
159
163
|
|
|
160
164
|
return null;
|
|
161
165
|
},
|
|
166
|
+
|
|
167
|
+
destroy: () => {
|
|
168
|
+
parentNode.removeEventListener('keydown', onKeydown);
|
|
169
|
+
parentNode.removeEventListener('mousedown', onClick);
|
|
170
|
+
dropDown.remove();
|
|
171
|
+
},
|
|
162
172
|
};
|
|
163
173
|
},
|
|
164
174
|
});
|
package/src/filter/style.ts
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import
|
|
2
|
+
import {
|
|
3
|
+
Color,
|
|
4
|
+
Emotion,
|
|
5
|
+
ThemeBorder,
|
|
6
|
+
ThemeColor,
|
|
7
|
+
ThemeFont,
|
|
8
|
+
ThemeManager,
|
|
9
|
+
ThemeShadow,
|
|
10
|
+
ThemeSize,
|
|
11
|
+
} from '@milkdown/core';
|
|
3
12
|
|
|
4
|
-
export const injectStyle = (
|
|
5
|
-
const border =
|
|
6
|
-
const shadow =
|
|
13
|
+
export const injectStyle = (themeManager: ThemeManager, { css, cx }: Emotion) => {
|
|
14
|
+
const border = themeManager.get(ThemeBorder, undefined);
|
|
15
|
+
const shadow = themeManager.get(ThemeShadow, undefined);
|
|
16
|
+
const radius = themeManager.get(ThemeSize, 'radius');
|
|
17
|
+
const typography = themeManager.get(ThemeFont, 'typography');
|
|
18
|
+
const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);
|
|
7
19
|
|
|
8
20
|
const style = css`
|
|
9
21
|
position: absolute;
|
|
@@ -11,20 +23,20 @@ export const injectStyle = ({ size, mixin, palette, font }: ThemeTool, { css, cx
|
|
|
11
23
|
display: none;
|
|
12
24
|
}
|
|
13
25
|
|
|
14
|
-
border-radius: ${
|
|
26
|
+
border-radius: ${radius};
|
|
15
27
|
background: ${palette('surface')};
|
|
16
28
|
|
|
17
29
|
.milkdown-emoji-filter_item {
|
|
18
30
|
display: flex;
|
|
19
|
-
gap: 0.
|
|
20
|
-
height: 2.
|
|
21
|
-
padding: 0
|
|
31
|
+
gap: 0.5em;
|
|
32
|
+
height: 2.57143em;
|
|
33
|
+
padding: 0 1em;
|
|
22
34
|
align-items: center;
|
|
23
35
|
justify-content: flex-start;
|
|
24
36
|
cursor: pointer;
|
|
25
37
|
line-height: 2;
|
|
26
|
-
font-family: ${
|
|
27
|
-
font-size: 0.
|
|
38
|
+
font-family: ${typography};
|
|
39
|
+
font-size: 0.875em;
|
|
28
40
|
&.active {
|
|
29
41
|
background: ${palette('secondary', 0.12)};
|
|
30
42
|
color: ${palette('primary')};
|
package/src/node.ts
CHANGED
|
@@ -12,20 +12,21 @@ import { picker } from './picker';
|
|
|
12
12
|
import { twemojiPlugin } from './remark-twemoji';
|
|
13
13
|
|
|
14
14
|
export const emojiNode = createNode((utils) => {
|
|
15
|
-
const
|
|
16
|
-
(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
const getStyle = () =>
|
|
16
|
+
utils.getStyle(
|
|
17
|
+
(_, { css }) => css`
|
|
18
|
+
display: inline-flex;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
align-items: center;
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
.emoji {
|
|
23
|
+
height: 1em;
|
|
24
|
+
width: 1em;
|
|
25
|
+
margin: 0 0.05em 0 0.1em;
|
|
26
|
+
vertical-align: -0.1em;
|
|
27
|
+
}
|
|
28
|
+
`,
|
|
29
|
+
);
|
|
29
30
|
return {
|
|
30
31
|
id: 'emoji',
|
|
31
32
|
schema: () => ({
|
|
@@ -51,9 +52,12 @@ export const emojiNode = createNode((utils) => {
|
|
|
51
52
|
toDOM: (node) => {
|
|
52
53
|
const span = document.createElement('span');
|
|
53
54
|
span.dataset['type'] = 'emoji';
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
utils.themeManager.onFlush(() => {
|
|
56
|
+
const style = getStyle();
|
|
57
|
+
if (style) {
|
|
58
|
+
span.classList.add(style);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
57
61
|
span.classList.add('emoji-wrapper');
|
|
58
62
|
span.innerHTML = node.attrs['html'];
|
|
59
63
|
return { dom: span };
|
package/src/picker.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
2
|
import { EmojiButton } from '@joeattardi/emoji-button';
|
|
3
|
+
import { Color, ThemeColor, ThemeFont } from '@milkdown/core';
|
|
3
4
|
import { Decoration, DecorationSet, EditorView, Plugin, PluginKey } from '@milkdown/prose';
|
|
4
5
|
import { Utils } from '@milkdown/utils';
|
|
5
6
|
|
|
@@ -73,7 +74,9 @@ export const picker = (utils: Utils) => {
|
|
|
73
74
|
if (!parentNode) {
|
|
74
75
|
throw new Error();
|
|
75
76
|
}
|
|
76
|
-
utils.getStyle((
|
|
77
|
+
utils.getStyle((themeManager, { injectGlobal }) => {
|
|
78
|
+
const palette = (color: Color, opacity = 1) => themeManager.get(ThemeColor, [color, opacity]);
|
|
79
|
+
const typography = themeManager.get(ThemeFont, 'typography');
|
|
77
80
|
const css = injectGlobal;
|
|
78
81
|
css`
|
|
79
82
|
.emoji-picker {
|
|
@@ -85,8 +88,8 @@ export const picker = (utils: Utils) => {
|
|
|
85
88
|
--dark-blue-color: ${palette('primary')} !important;
|
|
86
89
|
--dark-search-icon-color: ${palette('primary')} !important;
|
|
87
90
|
--dark-category-button-color: ${palette('secondary', 0.4)} !important;
|
|
88
|
-
--font: ${
|
|
89
|
-
--font-size:
|
|
91
|
+
--font: ${typography} !important;
|
|
92
|
+
--font-size: 1em !important;
|
|
90
93
|
}
|
|
91
94
|
`;
|
|
92
95
|
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constant.d.ts","sourceRoot":"","sources":["constant.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,IAAI,QAAqB,CAAC;AACvC,eAAO,MAAM,IAAI,QAAwB,CAAC;AAC1C,eAAO,MAAM,KAAK,QAAmB,CAAC;AACtC,eAAO,MAAM,OAAO,YAAY,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["helper.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAKnC,eAAO,MAAM,YAAY,SACf,UAAU,QACV,MAAM,MACR,MAAM,QACJ,MAAM,mBACK,MAAM,MAAM,MAAM,KAAK,IAAI,qBACzB,MAAM,KAAK,IAAI,YAoBrC,CAAC;AAEF,eAAO,MAAM,kBAAkB,SACrB,KAAK,EAAE,YACH,WAAW,WACZ,WAAW,GAAG,IAAI,aAChB,MAAM,IAAI,sBACD,WAAW,GAAG,IAAI,KAAK,IAAI,SA2ClD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyB,MAAM,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAMxC,eAAO,MAAM,GAAG,qBAAgD,CAAC;AAEjE,eAAO,MAAM,MAAM,UAAW,KAAK,qBAyJlC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["style.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEzD,eAAO,MAAM,WAAW,mCAAoC,SAAS,eAAe,OAAO,WAsC1F,CAAC"}
|
package/lib/src/index.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { AtomList } from '@milkdown/utils';
|
|
2
|
-
export declare const emoji: AtomList<import("@milkdown/utils/lib/src/types").Metadata<import("@milkdown/utils/lib/src/types").GetPlugin<string, import("@milkdown/utils").UnknownRecord>> & import("@milkdown/core").MilkdownPlugin>;
|
|
3
|
-
export { emojiNode } from './node';
|
|
4
|
-
//# sourceMappingURL=index.d.ts.map
|
package/lib/src/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAI3C,eAAO,MAAM,KAAK,0MAAiC,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC"}
|
package/lib/src/node.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["node.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,SAAS;;;;EAmFpB,CAAC"}
|
package/lib/src/parse.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["parse.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,KAAK,UAAW,MAAM,WAAsE,CAAC"}
|
package/lib/src/picker.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"picker.d.ts","sourceRoot":"","sources":["picker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAyC,MAAM,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC3F,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAKxC,eAAO,MAAM,GAAG,qBAAgD,CAAC;AAuBjE,eAAO,MAAM,MAAM,UAAW,KAAK,qBA+FlC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"remark-twemoji.d.ts","sourceRoot":"","sources":["remark-twemoji.ts"],"names":[],"mappings":"AAEA,OAAO,EAAW,IAAI,EAAU,MAAM,OAAO,CAAC;AAoC9C,eAAO,MAAM,aAAa,eACK,IAAI,SA2BlC,CAAC"}
|