@nldd/design-system 0.8.86 → 0.8.88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/custom-elements.json +662 -144
  2. package/dist/components/actions/icon-button/icon-button.d.ts +2 -2
  3. package/dist/components/actions/icon-button/icon-button.d.ts.map +1 -1
  4. package/dist/components/actions/icon-button/icon-button.js +3 -3
  5. package/dist/components/actions/icon-button/icon-button.js.map +1 -1
  6. package/dist/components/components.js +1263 -273
  7. package/dist/components/content/avatar/avatar.d.ts +6 -6
  8. package/dist/components/content/avatar/avatar.d.ts.map +1 -1
  9. package/dist/components/content/avatar/avatar.js +9 -9
  10. package/dist/components/content/avatar/avatar.js.map +1 -1
  11. package/dist/components/content/icon/icon-aliases.d.ts.map +1 -1
  12. package/dist/components/content/icon/icon-aliases.js +4 -0
  13. package/dist/components/content/icon/icon-aliases.js.map +1 -1
  14. package/dist/components/content/icon/icon-gallery-status.d.ts.map +1 -1
  15. package/dist/components/content/icon/icon-gallery-status.js +3 -26
  16. package/dist/components/content/icon/icon-gallery-status.js.map +1 -1
  17. package/dist/components/content/icon/icon-registry.d.ts.map +1 -1
  18. package/dist/components/content/icon/icon-registry.js +2 -0
  19. package/dist/components/content/icon/icon-registry.js.map +1 -1
  20. package/dist/components/content/icon/icon.d.ts +2 -2
  21. package/dist/components/content/icon/icon.d.ts.map +1 -1
  22. package/dist/components/content/icon/icon.js +3 -3
  23. package/dist/components/content/icon/icon.js.map +1 -1
  24. package/dist/components/content/icon/icon.styles.d.ts.map +1 -1
  25. package/dist/components/content/icon/icon.styles.js +8 -2
  26. package/dist/components/content/icon/icon.styles.js.map +1 -1
  27. package/dist/components/content/rich-text/rich-text.d.ts +7 -6
  28. package/dist/components/content/rich-text/rich-text.d.ts.map +1 -1
  29. package/dist/components/content/rich-text/rich-text.js +8 -7
  30. package/dist/components/content/rich-text/rich-text.js.map +1 -1
  31. package/dist/components/content/text/text.d.ts +2 -2
  32. package/dist/components/content/text/text.js +3 -3
  33. package/dist/components/content/title/title.d.ts +5 -5
  34. package/dist/components/content/title/title.d.ts.map +1 -1
  35. package/dist/components/content/title/title.js +6 -6
  36. package/dist/components/content/title/title.js.map +1 -1
  37. package/dist/components/content/tooltip/tooltip.d.ts +2 -2
  38. package/dist/components/content/tooltip/tooltip.d.ts.map +1 -1
  39. package/dist/components/content/tooltip/tooltip.js +4 -4
  40. package/dist/components/content/tooltip/tooltip.js.map +1 -1
  41. package/dist/components/{dist-C09E9-dJ.js → dist-B_Mnmrj4.js} +1 -1
  42. package/dist/components/{dist-CjaG8dOI.js → dist-ByH8hQze.js} +2 -2
  43. package/dist/components/{dist-BB7TxeMK.js → dist-CRwuSgMM.js} +2 -2
  44. package/dist/components/{dist-la_b3ZSq.js → dist-CSrO_mYe.js} +1 -1
  45. package/dist/components/{dist-762GHPyH.js → dist-CX3DK4i7.js} +3 -3
  46. package/dist/components/{dist-DZoFKUO-.js → dist-CbCO0WCd.js} +1 -1
  47. package/dist/components/{dist-B_3OW7pC.js → dist-CgDuh26K.js} +1 -1
  48. package/dist/components/{dist-DaavuU6W.js → dist-DXZ-cFAl.js} +2 -2
  49. package/dist/components/{dist-CRsR6ckU.js → dist-LX8LuMac.js} +1 -1
  50. package/dist/components/{dist-BJI4-6iQ.js → dist-eVFegyjM.js} +1 -1
  51. package/dist/components/{dist-C6gnorjP.js → dist-fIxe0l7k.js} +9 -1
  52. package/dist/components/{icon-Cd4BloIM.js → icon-C_zwJZ_g.js} +14 -4
  53. package/dist/components/{icon-button-CXN0yaVx.js → icon-button-CEz4MB9H.js} +10 -10
  54. package/dist/components/inputs/code-editor/code-editor.styles.js +2 -2
  55. package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.d.ts +3 -5
  56. package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.d.ts.map +1 -1
  57. package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.js +30 -44
  58. package/dist/components/inputs/text-editor/text-editor.annotation-sentinels.js.map +1 -1
  59. package/dist/components/inputs/text-editor/text-editor.annotations.d.ts.map +1 -1
  60. package/dist/components/inputs/text-editor/text-editor.annotations.js +31 -5
  61. package/dist/components/inputs/text-editor/text-editor.annotations.js.map +1 -1
  62. package/dist/components/inputs/text-editor/text-editor.commands.d.ts +14 -2
  63. package/dist/components/inputs/text-editor/text-editor.commands.d.ts.map +1 -1
  64. package/dist/components/inputs/text-editor/text-editor.commands.js +115 -36
  65. package/dist/components/inputs/text-editor/text-editor.commands.js.map +1 -1
  66. package/dist/components/inputs/text-editor/text-editor.cursor.d.ts +7 -0
  67. package/dist/components/inputs/text-editor/text-editor.cursor.d.ts.map +1 -0
  68. package/dist/components/inputs/text-editor/text-editor.cursor.js +207 -0
  69. package/dist/components/inputs/text-editor/text-editor.cursor.js.map +1 -0
  70. package/dist/components/inputs/text-editor/text-editor.d.ts +65 -13
  71. package/dist/components/inputs/text-editor/text-editor.d.ts.map +1 -1
  72. package/dist/components/inputs/text-editor/text-editor.emphasis.d.ts +32 -0
  73. package/dist/components/inputs/text-editor/text-editor.emphasis.d.ts.map +1 -0
  74. package/dist/components/inputs/text-editor/text-editor.emphasis.js +229 -0
  75. package/dist/components/inputs/text-editor/text-editor.emphasis.js.map +1 -0
  76. package/dist/components/inputs/text-editor/text-editor.js +177 -18
  77. package/dist/components/inputs/text-editor/text-editor.js.map +1 -1
  78. package/dist/components/inputs/text-editor/text-editor.links.d.ts +8 -0
  79. package/dist/components/inputs/text-editor/text-editor.links.d.ts.map +1 -1
  80. package/dist/components/inputs/text-editor/text-editor.links.js +30 -4
  81. package/dist/components/inputs/text-editor/text-editor.links.js.map +1 -1
  82. package/dist/components/inputs/text-editor/text-editor.markdown.d.ts.map +1 -1
  83. package/dist/components/inputs/text-editor/text-editor.markdown.js +52 -18
  84. package/dist/components/inputs/text-editor/text-editor.markdown.js.map +1 -1
  85. package/dist/components/inputs/text-editor/text-editor.mentions.d.ts +78 -11
  86. package/dist/components/inputs/text-editor/text-editor.mentions.d.ts.map +1 -1
  87. package/dist/components/inputs/text-editor/text-editor.mentions.js +190 -41
  88. package/dist/components/inputs/text-editor/text-editor.mentions.js.map +1 -1
  89. package/dist/components/inputs/text-editor/text-editor.ordered-list.d.ts +0 -2
  90. package/dist/components/inputs/text-editor/text-editor.ordered-list.d.ts.map +1 -1
  91. package/dist/components/inputs/text-editor/text-editor.ordered-list.js +21 -1
  92. package/dist/components/inputs/text-editor/text-editor.ordered-list.js.map +1 -1
  93. package/dist/components/inputs/text-editor/text-editor.styles.d.ts.map +1 -1
  94. package/dist/components/inputs/text-editor/text-editor.styles.js +11 -10
  95. package/dist/components/inputs/text-editor/text-editor.styles.js.map +1 -1
  96. package/dist/components/inputs/text-editor/text-editor.syntax.d.ts +9 -0
  97. package/dist/components/inputs/text-editor/text-editor.syntax.d.ts.map +1 -0
  98. package/dist/components/inputs/text-editor/text-editor.syntax.js +20 -0
  99. package/dist/components/inputs/text-editor/text-editor.syntax.js.map +1 -0
  100. package/dist/components/layout/page/page.d.ts +23 -5
  101. package/dist/components/layout/page/page.d.ts.map +1 -1
  102. package/dist/components/layout/page/page.js +39 -34
  103. package/dist/components/layout/page/page.js.map +1 -1
  104. package/dist/components/layout/page/page.styles.d.ts.map +1 -1
  105. package/dist/components/layout/page/page.styles.js +2 -0
  106. package/dist/components/layout/page/page.styles.js.map +1 -1
  107. package/dist/components/layout/page-sections/page-section-controls.d.ts +0 -70
  108. package/dist/components/layout/page-sections/page-section-controls.d.ts.map +1 -1
  109. package/dist/components/layout/page-sections/page-section-controls.js +0 -3
  110. package/dist/components/layout/page-sections/page-section-controls.js.map +1 -1
  111. package/dist/components/layout/sheet/sheet.d.ts +3 -7
  112. package/dist/components/layout/sheet/sheet.d.ts.map +1 -1
  113. package/dist/components/layout/sheet/sheet.js +4 -18
  114. package/dist/components/layout/sheet/sheet.js.map +1 -1
  115. package/dist/components/layout/sheet/sheet.styles.d.ts.map +1 -1
  116. package/dist/components/layout/sheet/sheet.styles.js +0 -4
  117. package/dist/components/layout/sheet/sheet.styles.js.map +1 -1
  118. package/dist/components/layout/sheet/sheet.template.d.ts.map +1 -1
  119. package/dist/components/layout/sheet/sheet.template.js +5 -2
  120. package/dist/components/layout/sheet/sheet.template.js.map +1 -1
  121. package/dist/components/layout/window/window.d.ts +2 -4
  122. package/dist/components/layout/window/window.d.ts.map +1 -1
  123. package/dist/components/layout/window/window.js +4 -14
  124. package/dist/components/layout/window/window.js.map +1 -1
  125. package/dist/components/layout/window/window.template.d.ts.map +1 -1
  126. package/dist/components/layout/window/window.template.js +5 -2
  127. package/dist/components/layout/window/window.template.js.map +1 -1
  128. package/dist/components/lists-and-tables/cells/icon-cell/icon-cell.d.ts +2 -2
  129. package/dist/components/lists-and-tables/cells/icon-cell/icon-cell.js +3 -3
  130. package/dist/components/lists-and-tables/cells/text-cell/text-cell.d.ts +2 -2
  131. package/dist/components/lists-and-tables/cells/text-cell/text-cell.js +3 -3
  132. package/dist/components/lists-and-tables/cells/title-cell/title-cell.d.ts +2 -2
  133. package/dist/components/lists-and-tables/cells/title-cell/title-cell.js +3 -3
  134. package/dist/components/lists-and-tables/list/list.d.ts +4 -2
  135. package/dist/components/lists-and-tables/list/list.d.ts.map +1 -1
  136. package/dist/components/lists-and-tables/list/list.js +23 -5
  137. package/dist/components/lists-and-tables/list/list.js.map +1 -1
  138. package/dist/components/navigation/document-tab-bar/document-tab-bar.template.js +1 -1
  139. package/dist/components/navigation/document-tab-bar/document-tab-bar.template.js.map +1 -1
  140. package/dist/components/navigation/link/link.d.ts +2 -2
  141. package/dist/components/navigation/link/link.d.ts.map +1 -1
  142. package/dist/components/navigation/link/link.js +3 -2
  143. package/dist/components/navigation/link/link.js.map +1 -1
  144. package/dist/components/navigation/menu-bar/menu-bar.d.ts +4 -2
  145. package/dist/components/navigation/menu-bar/menu-bar.d.ts.map +1 -1
  146. package/dist/components/navigation/menu-bar/menu-bar.js +4 -2
  147. package/dist/components/navigation/menu-bar/menu-bar.js.map +1 -1
  148. package/dist/components/status-and-feedback/activity-indicator/activity-indicator.d.ts +3 -3
  149. package/dist/components/status-and-feedback/activity-indicator/activity-indicator.d.ts.map +1 -1
  150. package/dist/components/status-and-feedback/activity-indicator/activity-indicator.js +4 -4
  151. package/dist/components/status-and-feedback/activity-indicator/activity-indicator.js.map +1 -1
  152. package/dist/components/status-and-feedback/inline-dialog/inline-dialog.d.ts +8 -0
  153. package/dist/components/status-and-feedback/inline-dialog/inline-dialog.d.ts.map +1 -1
  154. package/dist/components/status-and-feedback/inline-dialog/inline-dialog.js +14 -0
  155. package/dist/components/status-and-feedback/inline-dialog/inline-dialog.js.map +1 -1
  156. package/dist/components/status-and-feedback/inline-dialog/inline-dialog.styles.d.ts.map +1 -1
  157. package/dist/components/status-and-feedback/inline-dialog/inline-dialog.styles.js +22 -1
  158. package/dist/components/status-and-feedback/inline-dialog/inline-dialog.styles.js.map +1 -1
  159. package/dist/components/status-and-feedback/inline-dialog/inline-dialog.template.d.ts.map +1 -1
  160. package/dist/components/status-and-feedback/inline-dialog/inline-dialog.template.js +6 -2
  161. package/dist/components/status-and-feedback/inline-dialog/inline-dialog.template.js.map +1 -1
  162. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.d.ts +3 -1
  163. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.d.ts.map +1 -1
  164. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.js +5 -0
  165. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.js.map +1 -1
  166. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.d.ts.map +1 -1
  167. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.js +4 -0
  168. package/dist/components/status-and-feedback/modal-dialog/modal-dialog.template.js.map +1 -1
  169. package/dist/components/status-and-feedback/notification/notification-region.d.ts.map +1 -1
  170. package/dist/components/status-and-feedback/notification/notification-region.js +74 -1
  171. package/dist/components/status-and-feedback/notification/notification-region.js.map +1 -1
  172. package/dist/components/status-and-feedback/notification/notification.d.ts +11 -0
  173. package/dist/components/status-and-feedback/notification/notification.d.ts.map +1 -1
  174. package/dist/components/status-and-feedback/notification/notification.js +13 -0
  175. package/dist/components/status-and-feedback/notification/notification.js.map +1 -1
  176. package/dist/favicon.svg +8 -2
  177. package/dist/nldd.min.js +536 -496
  178. package/dist/types/vue.d.ts +33 -25
  179. package/package.json +1 -1
@@ -0,0 +1,229 @@
1
+ import { EditorSelection, StateEffect, StateField } from '@codemirror/state';
2
+ import { ViewPlugin } from '@codemirror/view';
3
+ import { enclosingNamed, enclosingNode } from './text-editor.syntax.js';
4
+ /* Emphasis that holds while you type inside it.
5
+ *
6
+ * CommonMark's flanking rules decide whether a `**` opens or closes, and a
7
+ * closing run may not follow whitespace. So `**woord**` is bold and, the moment
8
+ * a space is typed before the closing markers, `**woord **` is not: the line
9
+ * falls back to plain text (the weight, the markers' size, the line height)
10
+ * until the next letter arrives. A bold sentence flickers on every word
11
+ * boundary (#213).
12
+ *
13
+ * The parse is right; showing it that eagerly is not. So the emphasis the caret
14
+ * is in is remembered, and while the caret stays between its markers the styling
15
+ * is held whatever the parser says. When the hold ends (the caret leaves, the
16
+ * editor blurs, a paragraph break cuts the run) the whitespace that broke it is
17
+ * moved outside the markers, `**woord** `. That is what wrapping a selection
18
+ * produces too (#212), so bold made by typing and bold made by selecting end
19
+ * the same. */
20
+ /** The emphasis nodes that live by the flanking rules, with the marker the
21
+ * editor writes for them. Inline code is not among them: a code span keeps its
22
+ * whitespace and never fails to close. */
23
+ export const EMPHASIS_MARKERS = new Map([
24
+ ['StrongEmphasis', '**'],
25
+ ['Emphasis', '*'],
26
+ ['Strikethrough', '~~'],
27
+ ]);
28
+ /** The blocks that hold inline content. A held emphasis must stay within one:
29
+ * a paragraph break inside it (Enter twice) ends the run for good. */
30
+ const INLINE_BLOCKS = new Set([
31
+ 'Paragraph', 'ATXHeading1', 'ATXHeading2', 'ATXHeading3', 'ATXHeading4', 'ATXHeading5', 'ATXHeading6',
32
+ 'SetextHeading1', 'SetextHeading2', 'TableCell',
33
+ ]);
34
+ /** What may sit between the end of a run's text and its closing marker for the
35
+ * marker to be moved back to the text: whitespace, and after a line break the
36
+ * scaffolding Enter writes for the next list item, task or quote line. Text
37
+ * there means the break fell inside the run, and that is left alone. */
38
+ const TRAIL_RE = /^\s*(?:\n\s*(?:(?:[-*+]|\d+[.)]|>|\[[ xX]\])\s*)*)*$/;
39
+ /** Starts a hold on markers just written around an empty selection: `****`
40
+ * parses as nothing, so there is no node to remember, but what is typed
41
+ * between them is meant to be bold. */
42
+ export const holdEmphasis = StateEffect.define({
43
+ map: (value, mapping) => ({ ...value, from: mapping.mapPos(value.from, 1), to: mapping.mapPos(value.to, -1) }),
44
+ });
45
+ function emphasisAround(state, pos, side) {
46
+ return enclosingNode(state, pos, side, (node) => EMPHASIS_MARKERS.has(node.name));
47
+ }
48
+ function inlineBlockAt(state, pos) {
49
+ return enclosingNamed(state, pos, 1, INLINE_BLOCKS);
50
+ }
51
+ /** The innermost emphasis the main selection is inside of on both of its sides,
52
+ * as the tree parses it now. Just before the opening marker or just after the
53
+ * closing one is outside: text typed there lands outside the emphasis. */
54
+ function liveEmphasis(state) {
55
+ const { from, to } = state.selection.main;
56
+ const left = emphasisAround(state, from, -1);
57
+ const right = left && emphasisAround(state, to, 1);
58
+ if (!left || !right || left.from !== right.from || left.to !== right.to)
59
+ return null;
60
+ const len = EMPHASIS_MARKERS.get(left.name).length;
61
+ return { from: left.from, to: left.to, name: left.name, marker: state.sliceDoc(left.from, left.from + len), live: true };
62
+ }
63
+ /** Whether a remembered emphasis is still worth holding: the selection is between
64
+ * its markers, both markers are still there, no paragraph break cut it, and
65
+ * the parser has not made something else of its start. (Typing `**` inside
66
+ * bold splits it, and then the tree's own reading should show.) */
67
+ function holds(state, held) {
68
+ const len = held.marker.length;
69
+ const { from, to } = state.selection.main;
70
+ if (from < held.from + len || to > held.to - len)
71
+ return false;
72
+ const text = state.sliceDoc(held.from, held.to);
73
+ if (text.length < 2 * len || !text.startsWith(held.marker) || !text.endsWith(held.marker))
74
+ return false;
75
+ const block = inlineBlockAt(state, held.from);
76
+ if (!block || block.to < held.to)
77
+ return false;
78
+ const parsed = emphasisAround(state, held.from, 1);
79
+ return !(parsed && parsed.name === held.name && parsed.from === held.from);
80
+ }
81
+ function mapHeld(held, through) {
82
+ return { ...held, from: through.changes.mapPos(held.from, 1), to: through.changes.mapPos(held.to, -1) };
83
+ }
84
+ /** The emphasis the caret is in: the tree's own while it parses, and the held
85
+ * one, mapped along through edits, once it does not. Null outside any. */
86
+ export const heldEmphasisField = StateField.define({
87
+ create: (state) => liveEmphasis(state),
88
+ update(prev, tr) {
89
+ // The run the caret was in comes first, live or held: if the tree has let
90
+ // go of it (or still has not taken it up) it is held from here. The tree
91
+ // may well parse an outer emphasis around it, and that one needs no holding.
92
+ if (prev) {
93
+ const held = mapHeld({ ...prev, live: false }, tr);
94
+ if (holds(tr.state, held))
95
+ return held;
96
+ }
97
+ const live = liveEmphasis(tr.state);
98
+ if (live)
99
+ return live;
100
+ const seed = tr.effects.find((effect) => effect.is(holdEmphasis));
101
+ return seed ? { ...seed.value, live: false } : null;
102
+ },
103
+ });
104
+ /** The whitespace at the inside edges of `held`, or null when there is nothing
105
+ * to move: no whitespace at the edges, nothing but whitespace inside, or the
106
+ * markers are gone. The text ends where the opening block's text does: past
107
+ * a paragraph break the rest of the run can never be inside the emphasis, so
108
+ * it counts as trail, provided it is scaffolding and not text. */
109
+ function repairFor(state, held) {
110
+ const len = held.marker.length;
111
+ const text = state.sliceDoc(held.from, held.to);
112
+ if (text.length < 2 * len || !text.startsWith(held.marker) || !text.endsWith(held.marker))
113
+ return null;
114
+ const inner = text.slice(len, text.length - len);
115
+ const lead = /^\s*/.exec(inner)[0].length;
116
+ const block = inlineBlockAt(state, held.from);
117
+ const inBlock = state.sliceDoc(held.from + len, Math.min(held.to - len, block ? block.to : held.to - len));
118
+ const contentEnd = held.from + len + inBlock.replace(/\s+$/, '').length;
119
+ if (contentEnd <= held.from + len + lead)
120
+ return null;
121
+ const trail = held.to - len - contentEnd;
122
+ if (!lead && !trail)
123
+ return null;
124
+ if (!TRAIL_RE.test(state.sliceDoc(contentEnd, held.to - len)))
125
+ return null;
126
+ return { from: held.from, to: held.to, len, lead, trail };
127
+ }
128
+ /** Moves the lead in front of the opening marker and the trail past the closing
129
+ * one. Moving the whitespace rather than the markers keeps an annotation on
130
+ * the text on the text. */
131
+ function repairChanges(state, r) {
132
+ const changes = [];
133
+ if (r.lead) {
134
+ changes.push({ from: r.from, insert: state.sliceDoc(r.from + r.len, r.from + r.len + r.lead) }, { from: r.from + r.len, to: r.from + r.len + r.lead });
135
+ }
136
+ if (r.trail) {
137
+ changes.push({ from: r.to - r.len - r.trail, to: r.to - r.len }, { from: r.to, insert: state.sliceDoc(r.to - r.len - r.trail, r.to - r.len) });
138
+ }
139
+ return changes;
140
+ }
141
+ /** Where a position lands after the repair. The markers and the whitespace swap
142
+ * places, and a caret in the whitespace goes with it past the marker: after
143
+ * the space it typed, outside the run. With `stay` it stays with the text,
144
+ * inside the markers. That is what a blur wants: a toolbar click blurs the
145
+ * editor before its command runs, and the command must find the caret where
146
+ * the typing was. */
147
+ function mapRepair(pos, r, stay) {
148
+ const contentStart = r.from + r.len + r.lead;
149
+ const contentEnd = r.to - r.len - r.trail;
150
+ if (r.lead) {
151
+ if (pos > r.from && pos < r.from + r.len)
152
+ return pos + r.lead;
153
+ if (pos >= r.from + r.len && pos < contentStart)
154
+ return stay ? contentStart : pos - r.len;
155
+ }
156
+ if (r.trail) {
157
+ if (pos > contentEnd && pos <= r.to - r.len)
158
+ return stay ? contentEnd : pos + r.len;
159
+ if (pos > r.to - r.len && pos < r.to)
160
+ return pos - r.trail;
161
+ }
162
+ return pos;
163
+ }
164
+ function repairSpec(state, held, stay) {
165
+ const r = repairFor(state, held);
166
+ if (!r)
167
+ return null;
168
+ const sel = state.selection;
169
+ return {
170
+ changes: repairChanges(state, r),
171
+ selection: EditorSelection.create(sel.ranges.map((range) => EditorSelection.range(mapRepair(range.anchor, r, stay), mapRepair(range.head, r, stay))), sel.mainIndex),
172
+ userEvent: 'input.emphasis',
173
+ };
174
+ }
175
+ /** The changes that move edge whitespace out of `held`, for a command that
176
+ * steps out of the run itself. Empty when there is nothing to move. */
177
+ export function repairChangesFor(state, held) {
178
+ const r = repairFor(state, held);
179
+ return r ? repairChanges(state, r) : [];
180
+ }
181
+ /** Ends a hold at once, for a blur. The display must be right while the editor
182
+ * is unfocused, and the value it commits must be markdown that renders the way
183
+ * it looked. */
184
+ export function repairHeldEmphasis(view) {
185
+ const held = view.state.field(heldEmphasisField, false);
186
+ if (!held || held.live || view.state.readOnly)
187
+ return;
188
+ const spec = repairSpec(view.state, held, true);
189
+ if (spec)
190
+ view.dispatch(spec);
191
+ }
192
+ /** Repairs an emphasis the moment its hold ends: the caret left it, or a
193
+ * paragraph break cut it. A dispatch during an update is an error, so the
194
+ * repair waits for the update to finish. A microtask is soon enough to land
195
+ * before the paint, so nothing flickers. */
196
+ const repairOnRelease = ViewPlugin.fromClass(class {
197
+ constructor(view) {
198
+ this.view = view;
199
+ this.pending = null;
200
+ this.destroyed = false;
201
+ }
202
+ update(update) {
203
+ if (this.pending)
204
+ this.pending = mapHeld(this.pending, update);
205
+ const before = update.startState.field(heldEmphasisField);
206
+ if (!before)
207
+ return;
208
+ const gone = mapHeld(before, update);
209
+ const after = update.state.field(heldEmphasisField);
210
+ if (after && after.name === gone.name && after.from === gone.from && after.to === gone.to)
211
+ return;
212
+ this.pending = gone;
213
+ queueMicrotask(() => this.flush());
214
+ }
215
+ flush() {
216
+ const held = this.pending;
217
+ this.pending = null;
218
+ if (!held || this.destroyed || this.view.state.readOnly)
219
+ return;
220
+ const spec = repairSpec(this.view.state, held, false);
221
+ if (spec)
222
+ this.view.dispatch(spec);
223
+ }
224
+ destroy() {
225
+ this.destroyed = true;
226
+ }
227
+ });
228
+ export const heldEmphasis = [heldEmphasisField, repairOnRelease];
229
+ //# sourceMappingURL=text-editor.emphasis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-editor.emphasis.js","sourceRoot":"","sources":["../../../../src/components/inputs/text-editor/text-editor.emphasis.ts"],"names":[],"mappings":"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"}
@@ -19,12 +19,20 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
19
19
  *
20
20
  * Headless: there is no built-in toolbar. A consumer drives formatting via the
21
21
  * command methods (toggleBold/toggleItalic/toggleInlineCode/toggleStrikethrough/
22
- * toggleHeading/toggleBulletList/toggleQuote/toggleLink/runCommand to toggle, and
22
+ * toggleHeading/toggleBulletList/toggleTaskList/toggleQuote/toggleLink/runCommand
23
+ * to toggle, and
23
24
  * setHeading/setList for picker-style "set" semantics), reads the active formats
24
25
  * with getState(), listens to the nldd-text-editor-state event to render toggle
25
26
  * states, and forwards padding clicks with focusFromPoint(). Cmd/Ctrl+B/I/E/K are
26
- * bound out of the box. Commands keep focus on the editor. An @-mention typeahead
27
- * (mentionSource) collapses to an atomic token, and a W3C-style annotation overlay
27
+ * bound out of the box. Commands keep focus on the editor. An inline toggle wraps
28
+ * the selected text (whitespace at its edges stays outside the markers), unwraps
29
+ * a run the caret is in, and with the caret at the very end of a run steps out
30
+ * of it. Bold that a typed space has broken (`**woord **`) keeps its styling
31
+ * while the caret is inside; the space moves outside the markers when the caret
32
+ * leaves. insertAtCursor(text) puts text at the caret and replaceRange(from, to,
33
+ * text) writes at the same clean offsets getSelection() reads. An @-mention typeahead
34
+ * (mentionSource) collapses to an atomic token, further typeahead lists on their
35
+ * own trigger (typeaheads) write what you tell them to, and a W3C-style annotation overlay
28
36
  * (annotations) marks ranges with a dashed underline, light tint and a count badge
29
37
  * without touching the underlying text.
30
38
  *
@@ -44,6 +52,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
44
52
  * @attr {string} accessible-label - Accessible label forwarded to the editor. Set automatically by nldd-form-field.
45
53
  *
46
54
  * @prop {MentionSource} mentionSource - Consumer-supplied @-mention candidate source (property only). Without it, @-typeahead is inert.
55
+ * @prop {Typeahead[]} typeaheads - Your own typeahead lists next to the @-mention (property only): each a trigger character (`#`, `:`, `/`), a `source` that returns candidates for the text typed after it, and an optional `insert` that decides what a choice writes (by default the trigger, the text and a space). Lists on one trigger are merged in order. A candidate is `{ id, text, supportingText? }` and can carry an `avatar` (its row then takes two lines, the supporting text under the text), an `icon` or a `symbol` for its row.
47
56
  * @attr {boolean} annotatable - Enable the annotation overlay (off by default). Annotations only render when this is set.
48
57
  * @prop {Annotation[]} annotations - Consumer-supplied annotation overlay (property only). Anchored by offset and mapped through edits; the text stays clean. Requires `annotatable`. Assign a NEW array to apply changes (Lit dirty-checks by identity, so in-place mutation like `.push()` won't re-render): `editor.annotations = [...editor.annotations, next]`.
49
58
  * @attr {object} translations - Override the editor's assistive-tech strings (the open-in-new-tab link badge and the annotation count badge). Unset keys fall back to Dutch.
@@ -52,7 +61,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
52
61
  * @fires input - When the content changes (detail: { value })
53
62
  * @fires change - When the content is committed on blur (detail: { value })
54
63
  * @fires nldd-text-editor-state - When the selection or content changes (detail: TextEditorState), for toolbar toggle state
55
- * @fires nldd-text-editor-mention - When an @-mention is inserted (detail: MentionInsertedDetail with id, label, from, to)
64
+ * @fires nldd-text-editor-mention - When an @-mention is inserted (detail: MentionInsertedDetail with id, text, from, to; clean offsets, like getSelection())
65
+ * @fires nldd-text-editor-typeahead - When a candidate from one of the `typeaheads` is chosen (detail: TypeaheadChosenDetail with trigger, candidate, from, to; clean offsets)
56
66
  * @fires nldd-text-editor-annotation-click - When an annotation's count badge is clicked (detail: { ids: string[], rect: DOMRect }); rect is the badge's viewport box so a consumer can anchor its own note UI to it
57
67
  */
58
68
  import { LitElement } from 'lit';
@@ -65,15 +75,17 @@ import { defaultKeymap, history, historyKeymap, undo as cmUndo, redo as cmRedo,
65
75
  import { NLDDCodeMirrorElement } from '../../../utilities/codemirror/codemirror-element.js';
66
76
  import { nlddCodeMirrorTheme } from '../../../utilities/codemirror/theme.js';
67
77
  import { markdownEditing, mentionRangeAt, mentionRangeEndingAt, mentionRangeStartingAt } from './text-editor.markdown.js';
68
- import { mentions } from './text-editor.mentions.js';
78
+ import { typeaheads as typeaheadExtension, mentionInsert, mentionToken, } from './text-editor.mentions.js';
79
+ import { repairHeldEmphasis } from './text-editor.emphasis.js';
69
80
  import { annotations as annotationExtension, setAnnotations, pasteAnnotations, currentAnnotations } from './text-editor.annotations.js';
70
81
  import { orderedListRenumber } from './text-editor.ordered-list.js';
71
82
  import { dragToMove, dragMovePlugin } from './text-editor.drag.js';
72
83
  import { linkOpenBadge } from './text-editor.links.js';
73
- import { toggleInlineWrap, indentListItems as cmIndentListItems, outdentListItems as cmOutdentListItems, canIndentListItem as cmCanIndent, canOutdentListItem as cmCanOutdent, toggleHeading as cmToggleHeading, setHeading as cmSetHeading, toggleBulletList as cmToggleBulletList, setList as cmSetList, toggleQuote as cmToggleQuote, toggleLink as cmToggleLink, toggleCodeBlock as cmToggleCodeBlock, clearListMarkerBackward, readActiveFormats, EMPTY_FORMATS, } from './text-editor.commands.js';
84
+ import { stableCursor } from './text-editor.cursor.js';
85
+ import { toggleInlineWrap, indentListItems as cmIndentListItems, outdentListItems as cmOutdentListItems, canIndentListItem as cmCanIndent, canOutdentListItem as cmCanOutdent, toggleHeading as cmToggleHeading, setHeading as cmSetHeading, toggleBulletList as cmToggleBulletList, toggleTaskList as cmToggleTaskList, setList as cmSetList, toggleQuote as cmToggleQuote, toggleLink as cmToggleLink, toggleCodeBlock as cmToggleCodeBlock, clearListMarkerBackward, readActiveFormats, EMPTY_FORMATS, } from './text-editor.commands.js';
74
86
  import { textEditorStyles } from './text-editor.styles.js';
75
87
  import { textEditorTemplate } from './text-editor.template.js';
76
- import { stripSentinels, docToClean } from './text-editor.annotation-sentinels.js';
88
+ import { stripSentinels, docToClean, cleanToDoc, sentinelPositions } from './text-editor.annotation-sentinels.js';
77
89
  import { nlddTextEditorTranslations } from './text-editor.i18n.js';
78
90
  import { DescribedBy } from '../../../utilities/described-by-mixin.js';
79
91
  let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLDDCodeMirrorElement)) {
@@ -94,6 +106,18 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
94
106
  this.resize = 'auto';
95
107
  this.variant = 'simple';
96
108
  this.accessibleLabel = '';
109
+ /** Your own typeahead lists next to the @-mention, each on its own trigger
110
+ * character. Property only. Read on every keystroke, so a new array takes
111
+ * effect at once. */
112
+ this.typeaheads = [];
113
+ /** The built-in mention as a typeahead: the `@` list fed by `mentionSource`,
114
+ * writing the token. One object, so a choice can be told apart from a
115
+ * consumer's own `@` list and fire the mention event. */
116
+ this._mentionTypeahead = {
117
+ trigger: '@',
118
+ source: (query) => this.mentionSource?.(query) ?? [],
119
+ insert: mentionInsert,
120
+ };
97
121
  /** Whether the annotation overlay is enabled. Off by default; set the
98
122
  * `annotatable` attribute to turn it on (so the comment affordance and the
99
123
  * overlay only appear when the consumer opts in). */
@@ -131,6 +155,11 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
131
155
  /** Text and annotations of the last cut, so a same-editor paste can move the
132
156
  * annotations along with their text. Cleared by copy and by a matching paste. */
133
157
  this._cutBuffer = null;
158
+ /** The last state handed out, to keep from repeating it. The event drives a
159
+ * toolbar's toggles, and moving the caret within one paragraph leaves every
160
+ * one of them where it was: a consumer would re-render its whole bar on every
161
+ * arrow key for nothing. */
162
+ this._lastState = null;
134
163
  /* # Internals */
135
164
  this._onScrollerPointerDown = (event) => {
136
165
  if (event.target !== this.view?.scrollDOM)
@@ -201,7 +230,7 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
201
230
  return [
202
231
  nlddCodeMirrorTheme,
203
232
  markdownEditing,
204
- mentions(() => this.mentionSource, (detail) => this._emitMention(detail)),
233
+ typeaheadExtension(() => this._typeaheadLists(), (choice) => this._onTypeaheadChosen(choice)),
205
234
  // Prec.low so this transaction filter runs *before* the annotation filter
206
235
  // (filters run low-precedence first), letting the annotation map through the
207
236
  // renumber changes too — otherwise a marker growing from 1 to 11 drifts a
@@ -222,6 +251,10 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
222
251
  Prec.highest(linkOpenBadge((url) => this._t('components.text-editor.open-in-new-tab-label', { url }))),
223
252
  this._historyCompartment.of(history()),
224
253
  drawSelection(),
254
+ // Draws the caret in drawSelection's place, on a side that does not depend on
255
+ // the direction it arrived from unless that direction means something (a
256
+ // widget, a line wrap). See text-editor.cursor.ts.
257
+ stableCursor,
225
258
  dropCursor(),
226
259
  dragToMove,
227
260
  // Prec.highest so this beats the markdown language's deleteMarkupBackward,
@@ -237,6 +270,12 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
237
270
  // selects the whole token, the second removes it.
238
271
  { key: 'Backspace', run: (view) => this._selectMentionBeforeDelete(view, -1) },
239
272
  { key: 'Delete', run: (view) => this._selectMentionBeforeDelete(view, 1) },
273
+ // Cmd/Ctrl+] and +[ nest and un-nest list items. defaultKeymap binds them
274
+ // to indentMore/indentLess, whose four-space indent turns plain text into
275
+ // an indented code block. Consumed here in every case: off a list item
276
+ // they do nothing, which beats a code block nobody asked for.
277
+ { key: 'Mod-]', run: (view) => { cmIndentListItems(view); return true; } },
278
+ { key: 'Mod-[', run: (view) => { cmOutdentListItems(view); return true; } },
240
279
  ...defaultKeymap,
241
280
  ...historyKeymap,
242
281
  ]),
@@ -254,7 +293,10 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
254
293
  focus: () => {
255
294
  this._valueAtFocus = this.value;
256
295
  },
257
- blur: () => {
296
+ blur: (_event, view) => {
297
+ // An emphasis held together while it was being typed is closed
298
+ // properly first, so the committed value renders the way it looked.
299
+ repairHeldEmphasis(view);
258
300
  if (this.value !== this._valueAtFocus)
259
301
  this._emitChange();
260
302
  },
@@ -315,7 +357,9 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
315
357
  firstUpdated() {
316
358
  this._initialValue = this.value;
317
359
  this.style.setProperty('--_rows', String(this.rows));
318
- this.mountEditor(this.value);
360
+ // The sentinels are the overlay's own; a value that carries one (an editor
361
+ // whose text was round-tripped through another) hands it back stripped.
362
+ this.mountEditor(stripSentinels(this.value));
319
363
  this.onEditorMounted();
320
364
  }
321
365
  /* Runs on the initial mount and on every re-mount after a detach/reattach
@@ -349,7 +393,7 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
349
393
  // mirrors the current (sentinel-stripped) doc must not trigger a rewrite,
350
394
  // which would strip the sentinels the filter then re-adds (caret churn).
351
395
  if (stripSentinels(this.doc) !== this.value)
352
- this.setDoc(this.value);
396
+ this.setDoc(stripSentinels(this.value));
353
397
  this.commitFormValue();
354
398
  }
355
399
  if (changed.has('disabled') || changed.has('readonly')) {
@@ -425,8 +469,15 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
425
469
  if (this.view)
426
470
  cmToggleBulletList(this.view);
427
471
  }
472
+ /** Turn the selected lines into GFM task items (`- [ ] `), or back into
473
+ * bullets when they all are tasks. Checking a box is not a command. */
474
+ toggleTaskList() {
475
+ if (this.view)
476
+ cmToggleTaskList(this.view);
477
+ }
428
478
  /** Set the list type, replacing any existing list ('none' strips it) — for an
429
- * exclusive list picker. */
479
+ * exclusive list picker. A task keeps its checkbox only within its own type:
480
+ * switching to bullet or ordered takes the box along with the marker. */
430
481
  setList(type) {
431
482
  if (this.view)
432
483
  cmSetList(this.view, type);
@@ -551,6 +602,41 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
551
602
  this._pasteText(stripSentinels(raw));
552
603
  this.view?.focus();
553
604
  }
605
+ /** Puts `text` at the caret, in place of the selection when there is one, and
606
+ * leaves the caret after it, with focus on the editor. Plain text: markdown
607
+ * in it stays as written and is styled like anything typed. Does nothing on
608
+ * a read-only editor. */
609
+ insertAtCursor(text) {
610
+ if (!this.view || this.view.state.readOnly)
611
+ return;
612
+ const clean = stripSentinels(text);
613
+ if (clean)
614
+ this.view.dispatch({ ...this.view.state.replaceSelection(clean), userEvent: 'input' });
615
+ this.view.focus();
616
+ }
617
+ /** Replaces the text between two offsets with `text`, and leaves the caret
618
+ * after it. The offsets are CLEAN, the same coordinates `getSelection()` and
619
+ * the annotations speak, so a consumer can act on what it read there. Both
620
+ * are clamped into the text, and `to` below `from` counts as an insert at
621
+ * `from`. Does nothing on a read-only editor. */
622
+ replaceRange(from, to, text) {
623
+ if (!this.view || this.view.state.readOnly)
624
+ return;
625
+ const doc = this.view.state.doc.toString();
626
+ const sentinels = sentinelPositions(doc);
627
+ const cleanLength = doc.length - sentinels.length;
628
+ const start = Math.max(0, Math.min(from, cleanLength));
629
+ const end = Math.max(start, Math.min(to, cleanLength));
630
+ const insert = stripSentinels(text);
631
+ const docFrom = cleanToDoc(sentinels, start);
632
+ const docTo = cleanToDoc(sentinels, end);
633
+ this.view.dispatch({
634
+ changes: { from: docFrom, to: docTo, insert },
635
+ selection: { anchor: docFrom + insert.length },
636
+ userEvent: 'input',
637
+ });
638
+ this.view.focus();
639
+ }
554
640
  /** Insert `text` at the selection, re-attaching the cut annotations when it matches
555
641
  * a cut made in this editor (a move, one-shot). Shared by the toolbar's paste()
556
642
  * and the native Cmd/Ctrl+V handler. */
@@ -566,16 +652,28 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
566
652
  const sameText = (a, b) => a.replace(/\r\n/g, '\n') === b.replace(/\r\n/g, '\n');
567
653
  const carry = !!(buffer && sameText(buffer.text, text) && buffer.anns.length > 0);
568
654
  const at = docToClean(this.view.state.doc.toString(), this.view.state.selection.main.from);
569
- const spec = this.view.state.replaceSelection(text);
655
+ // input.paste, like CodeMirror's own paste: history groups it as one step and
656
+ // a transaction filter can tell a paste from typing.
657
+ const spec = { ...this.view.state.replaceSelection(text), userEvent: 'input.paste' };
570
658
  this.view.dispatch(carry ? { ...spec, effects: pasteAnnotations.of({ at, anns: buffer.anns }) } : spec);
571
659
  // One-shot: a second paste of the same cut would duplicate the ids, so drop it.
572
660
  if (carry)
573
661
  this._cutBuffer = null;
574
662
  }
575
- /** Escape hatch: run a command by name (bold, italic, inlineCode,
576
- * strikethrough, bulletList, quote, heading [payload: level], link
577
- * [payload: href], copy, cut, paste). */
663
+ /** Escape hatch: run a command by name, so a toolbar can carry the name in its
664
+ * markup instead of a method reference. Every method above is reachable.
665
+ *
666
+ * Toggles (no payload): `bold`, `italic`, `inlineCode`, `strikethrough`,
667
+ * `bulletList`, `taskList`, `quote`, `codeBlock`, `heading` (payload: the
668
+ * level, default 1), `link` (payload: the href).
669
+ * Setters: `setHeading` (payload: the level, 0 for a paragraph), `setList`
670
+ * (payload: 'none' | 'bullet' | 'ordered' | 'task').
671
+ * The rest: `indent`, `outdent`, `undo`, `redo`, `copy`, `cut`, `paste`.
672
+ *
673
+ * An unknown name warns rather than doing nothing quietly: a typo in a
674
+ * toolbar is otherwise invisible. */
578
675
  runCommand(name, payload) {
676
+ const level = (fallback) => (typeof payload === 'number' ? payload : fallback);
579
677
  switch (name) {
580
678
  case 'bold':
581
679
  this.toggleBold();
@@ -592,15 +690,39 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
592
690
  case 'bulletList':
593
691
  this.toggleBulletList();
594
692
  break;
693
+ case 'taskList':
694
+ this.toggleTaskList();
695
+ break;
595
696
  case 'quote':
596
697
  this.toggleQuote();
597
698
  break;
699
+ case 'codeBlock':
700
+ this.toggleCodeBlock();
701
+ break;
598
702
  case 'heading':
599
- this.toggleHeading((typeof payload === 'number' ? payload : 1));
703
+ this.toggleHeading(level(1));
704
+ break;
705
+ case 'setHeading':
706
+ this.setHeading(level(0));
707
+ break;
708
+ case 'setList':
709
+ this.setList(typeof payload === 'string' ? payload : 'none');
600
710
  break;
601
711
  case 'link':
602
712
  this.toggleLink(typeof payload === 'string' ? payload : '');
603
713
  break;
714
+ case 'indent':
715
+ this.indent();
716
+ break;
717
+ case 'outdent':
718
+ this.outdent();
719
+ break;
720
+ case 'undo':
721
+ this.undo();
722
+ break;
723
+ case 'redo':
724
+ this.redo();
725
+ break;
604
726
  case 'copy':
605
727
  void this.copy();
606
728
  break;
@@ -610,6 +732,7 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
610
732
  case 'paste':
611
733
  void this.paste();
612
734
  break;
735
+ default: console.warn(`<nldd-text-editor>: runCommand('${name}') is not a command.`);
613
736
  }
614
737
  }
615
738
  /** The formats active at the current selection (drives a toolbar's state). */
@@ -667,8 +790,41 @@ let NLDDTextEditor = class NLDDTextEditor extends DescribedBy(FormAssociated(NLD
667
790
  }));
668
791
  }
669
792
  _emitState() {
793
+ const state = this.getState();
794
+ const last = this._lastState;
795
+ if (last
796
+ && last.empty === state.empty
797
+ && last.canIndent === state.canIndent
798
+ && last.canOutdent === state.canOutdent
799
+ && last.canUndo === state.canUndo
800
+ && last.canRedo === state.canRedo
801
+ && Object.keys(state.active).every((key) => last.active[key] === state.active[key]))
802
+ return;
803
+ this._lastState = state;
670
804
  this.dispatchEvent(new CustomEvent('nldd-text-editor-state', {
671
- detail: this.getState(),
805
+ detail: state,
806
+ bubbles: true,
807
+ composed: true,
808
+ }));
809
+ }
810
+ _typeaheadLists() {
811
+ return this.mentionSource ? [this._mentionTypeahead, ...this.typeaheads] : this.typeaheads;
812
+ }
813
+ /** A choice from any list. Offsets in the events are clean, like
814
+ * getSelection() and the annotations: the document carries sentinels the
815
+ * value never shows. */
816
+ _onTypeaheadChosen(choice) {
817
+ if (!this.view)
818
+ return;
819
+ const doc = this.view.state.doc.toString();
820
+ const from = docToClean(doc, choice.from);
821
+ if (choice.typeahead === this._mentionTypeahead) {
822
+ const { id, text } = choice.candidate;
823
+ this._emitMention({ id, text, from, to: from + mentionToken(choice.candidate).length });
824
+ return;
825
+ }
826
+ this.dispatchEvent(new CustomEvent('nldd-text-editor-typeahead', {
827
+ detail: { trigger: choice.trigger, candidate: choice.candidate, from, to: docToClean(doc, choice.to) },
672
828
  bubbles: true,
673
829
  composed: true,
674
830
  }));
@@ -774,6 +930,9 @@ __decorate([
774
930
  __decorate([
775
931
  property({ attribute: false })
776
932
  ], NLDDTextEditor.prototype, "mentionSource", void 0);
933
+ __decorate([
934
+ property({ attribute: false })
935
+ ], NLDDTextEditor.prototype, "typeaheads", void 0);
777
936
  __decorate([
778
937
  property({ type: Boolean, reflect: true })
779
938
  ], NLDDTextEditor.prototype, "annotatable", void 0);