laif-ds 0.2.83 → 0.2.85

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/dist/index.d.ts CHANGED
@@ -260,22 +260,49 @@ export declare interface AppDialogProps extends Omit<DialogContentProps, "title"
260
260
  preventClose?: "overlay" | "all";
261
261
  }
262
262
 
263
- export declare function AppEditor({ defaultValue, onMarkdownEdit, plugins, toolbars, placeholder, onlyMarkdown, className, wrpClassName, }: AppEditorProps): JSX.Element;
263
+ export declare function AppEditor({ defaultValue, onMarkdownEdit, onValueChange, plugins, toolbars, placeholder, onlyMarkdown, className, wrpClassName, mentions, mentionTrigger, }: AppEditorProps): JSX.Element;
264
264
 
265
- declare type AppEditorPlugin = "clear" | "counter";
265
+ /** Metadata emitted alongside the markdown on every change. */
266
+ export declare interface AppEditorChangeMeta {
267
+ /** Deduped list (by `String(id)`) of mentions currently present in the text. */
268
+ mentions: MentionItem[];
269
+ }
270
+
271
+ export declare type AppEditorPlugin = "clear" | "counter";
266
272
 
267
- declare interface AppEditorProps {
273
+ export declare interface AppEditorProps {
268
274
  defaultValue?: string;
275
+ /**
276
+ * @deprecated Use `onValueChange` instead. Still honored as a fallback when
277
+ * `onValueChange` is not provided, but it never receives mention metadata.
278
+ */
269
279
  onMarkdownEdit?: (markdown: string) => void;
280
+ /**
281
+ * Fires on every edit with the current markdown and a metadata object.
282
+ * `meta.mentions` is the deduped (by `id`) list of mentions in the text —
283
+ * empty when mentions are disabled. Takes precedence over `onMarkdownEdit`.
284
+ */
285
+ onValueChange?: (markdown: string, meta: AppEditorChangeMeta) => void;
270
286
  plugins?: AppEditorPlugin[];
271
287
  toolbars?: AppEditorToolbar[];
272
288
  placeholder?: string;
273
289
  onlyMarkdown?: boolean;
274
290
  className?: string;
275
291
  wrpClassName?: string;
292
+ /**
293
+ * Enables @mention support when provided. Either a ready `MentionItem[]`
294
+ * (filtered client-side) or a loader called ONCE the first time the menu
295
+ * opens — so a large list is never preloaded on mount. The typeahead menu
296
+ * filters by label (case-insensitive, word-prefix). When undefined, the
297
+ * MentionNode, mention plugin and mention transformer are NOT registered and
298
+ * behavior/output is identical to a mention-less editor.
299
+ */
300
+ mentions?: MentionSource;
301
+ /** Single character that opens the mention menu. Default "@". */
302
+ mentionTrigger?: string;
276
303
  }
277
304
 
278
- declare type AppEditorToolbar = "block-format" | "font-format" | "history";
305
+ export declare type AppEditorToolbar = "block-format" | "font-format" | "history";
279
306
 
280
307
  export declare const AppForm: <TFormValues extends FieldValues = FieldValues, TAsyncOption = unknown>({ items, cols, form, submitText, onSubmit, isSubmitting, showSubmitButton, }: AppFormProps<TFormValues, TAsyncOption>) => JSX.Element;
281
308
 
@@ -2405,6 +2432,15 @@ declare interface MarkdownRendererProps {
2405
2432
  children: string;
2406
2433
  }
2407
2434
 
2435
+ export declare interface MentionItem {
2436
+ id: string | number;
2437
+ label: string;
2438
+ value?: string;
2439
+ sublabel?: string;
2440
+ }
2441
+
2442
+ export declare type MentionSource = MentionItem[] | (() => MentionItem[] | Promise<MentionItem[]>);
2443
+
2408
2444
  export declare function Menubar({ className, ...props }: React_2.ComponentProps<typeof MenubarPrimitive.Root>): JSX.Element;
2409
2445
 
2410
2446
  export declare function MenubarCheckboxItem({ className, children, checked, ...props }: React_2.ComponentProps<typeof MenubarPrimitive.CheckboxItem>): JSX.Element;
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { $getRoot as O, $createLineBreakNode as D, $createTextNode as y, $isElementNode as I, $isDecoratorNode as B, $isParagraphNode as k, $isTextNode as N, $getSelection as J, $isLineBreakNode as V, $createParagraphNode as Y } from "../../lexical/Lexical.prod.js";
2
+ import { $createLineBreakNode as O, $createTextNode as y, $getRoot as D, $isElementNode as I, $isDecoratorNode as B, $isParagraphNode as k, $isTextNode as N, $getSelection as J, $isLineBreakNode as V, $createParagraphNode as Y } from "../../lexical/Lexical.prod.js";
3
3
  import { ListNode as w, ListItemNode as P, $isListNode as $, $createListItemNode as Z, $createListNode as tt, $isListItemNode as j } from "../list/LexicalList.prod.js";
4
4
  import { HeadingNode as et, QuoteNode as nt, $isHeadingNode as ot, $isQuoteNode as L, $createQuoteNode as rt, $createHeadingNode as st } from "../rich-text/LexicalRichText.prod.js";
5
5
  import { $findMatchingParent as it } from "../utils/LexicalUtils.prod.js";
@@ -160,7 +160,7 @@ function xt(t, e = !1) {
160
160
  })(r.textFormat);
161
161
  return (n, f) => {
162
162
  const o = n.split(`
163
- `), a = o.length, u = f || O();
163
+ `), a = o.length, u = f || D();
164
164
  u.clear();
165
165
  for (let i = 0; i < a; i++) {
166
166
  const g = o[i], [l, d] = $t(o, i, r.multilineElement, u);
@@ -223,7 +223,7 @@ function Et(t, e, r, s, n, f) {
223
223
  const i = u.getLastDescendant();
224
224
  c = i == null ? null : it(i, j);
225
225
  }
226
- c != null && c.getTextContentSize() > 0 && (c.splice(c.getChildrenSize(), 0, [D(), ...a.getChildren()]), a.remove());
226
+ c != null && c.getTextContentSize() > 0 && (c.splice(c.getChildrenSize(), 0, [O(), ...a.getChildren()]), a.remove());
227
227
  }
228
228
  }
229
229
  }
@@ -280,7 +280,7 @@ const U = /^(\s*)(\d{1,})\.\s/, z = /^(\s*)[-*+]\s/, Nt = /^(\s*)(?:-\s)?\s?(\[(
280
280
  }, regExp: Q, replace: (t, e, r, s) => {
281
281
  if (s) {
282
282
  const f = t.getPreviousSibling();
283
- if (L(f)) return f.splice(f.getChildrenSize(), 0, [D(), ...e]), void t.remove();
283
+ if (L(f)) return f.splice(f.getChildrenSize(), 0, [O(), ...e]), void t.remove();
284
284
  }
285
285
  const n = rt();
286
286
  n.append(...e), t.replace(n), s || n.select(0, 0);
@@ -330,7 +330,7 @@ function Jt(t = q, e, r = !1) {
330
330
  return (function(n, f = !1) {
331
331
  const o = H(n), a = [...o.multilineElement, ...o.element], u = !f, c = o.textFormat.filter(((i) => i.format.length === 1)).sort(((i, g) => Number(i.format.includes("code")) - Number(g.format.includes("code"))));
332
332
  return (i) => {
333
- const g = [], l = (i || O()).getChildren();
333
+ const g = [], l = (i || D()).getChildren();
334
334
  for (let d = 0; d < l.length; d++) {
335
335
  const p = l[d], m = mt(p, a, c, o.textMatch);
336
336
  m != null && g.push(u && d > 0 && !b(p) && !b(l[d - 1]) ? `
@@ -0,0 +1,220 @@
1
+ "use client";
2
+ import { useLexicalComposerContext as $ } from "./LexicalComposerContext.prod.js";
3
+ import { $getSelection as Y, $isRangeSelection as F, $isTextNode as te, getDOMSelection as ne, COMMAND_PRIORITY_LOW as J, createCommand as oe, KEY_ENTER_COMMAND as re, KEY_TAB_COMMAND as le, KEY_ESCAPE_COMMAND as ie, KEY_ARROW_UP_COMMAND as se, KEY_ARROW_DOWN_COMMAND as ue } from "../../lexical/Lexical.prod.js";
4
+ import Q, { useCallback as P, useState as Z, useRef as ce, useEffect as I, useLayoutEffect as ae, useMemo as de } from "react";
5
+ import { mergeRegister as V } from "../utils/LexicalUtils.prod.js";
6
+ import { jsx as fe } from "react/jsx-runtime";
7
+ const z = "startTransition", k = typeof window < "u" && window.document !== void 0 && window.document.createElement !== void 0, ge = k ? ae : I;
8
+ class Ce {
9
+ constructor(e) {
10
+ this.key = e, this.ref = { current: null }, this.setRefElement = this.setRefElement.bind(this);
11
+ }
12
+ setRefElement(e) {
13
+ this.ref = { current: e };
14
+ }
15
+ }
16
+ const X = (i) => {
17
+ const e = document.getElementById("typeahead-menu");
18
+ if (!e) return;
19
+ const a = e.getBoundingClientRect();
20
+ a.top + a.height > window.innerHeight && e.scrollIntoView({ block: "center" }), a.top < 0 && e.scrollIntoView({ block: "center" }), i.scrollIntoView({ block: "nearest" });
21
+ };
22
+ function j(i, e) {
23
+ const a = i.getBoundingClientRect(), s = e.getBoundingClientRect();
24
+ return a.top > s.top && a.top < s.bottom;
25
+ }
26
+ function pe(i, e, a, s) {
27
+ const [t] = $();
28
+ I((() => {
29
+ if (e != null && i != null) {
30
+ const T = t.getRootElement(), w = T != null ? (function(y, m) {
31
+ let c = getComputedStyle(y);
32
+ const O = c.position === "absolute", r = /(auto|scroll)/;
33
+ if (c.position === "fixed") return document.body;
34
+ for (let o = y; o = o.parentElement; ) if (c = getComputedStyle(o), (!O || c.position !== "static") && r.test(c.overflow + c.overflowY + c.overflowX)) return o;
35
+ return document.body;
36
+ })(T) : document.body;
37
+ let x = !1, g = j(e, w);
38
+ const A = function() {
39
+ x || (window.requestAnimationFrame((function() {
40
+ a(), x = !1;
41
+ })), x = !0);
42
+ const y = j(e, w);
43
+ y !== g && (g = y, s?.(y));
44
+ }, u = new ResizeObserver(a);
45
+ return window.addEventListener("resize", a), document.addEventListener("scroll", A, { capture: !0, passive: !0 }), u.observe(e), () => {
46
+ u.unobserve(e), window.removeEventListener("resize", a), document.removeEventListener("scroll", A, !0);
47
+ };
48
+ }
49
+ }), [e, t, s, a, i]);
50
+ }
51
+ const q = oe("SCROLL_TYPEAHEAD_OPTION_INTO_VIEW_COMMAND");
52
+ function me({ close: i, editor: e, anchorElementRef: a, resolution: s, options: t, menuRenderFn: T, onSelectOption: w, shouldSplitNodeWithQuery: x = !1, commandPriority: g = J, preselectFirstItem: A = !0 }) {
53
+ const [u, y] = Z(null), m = s.match && s.match.matchingString;
54
+ I((() => {
55
+ A && y(0);
56
+ }), [m, A]);
57
+ const c = P(((r) => {
58
+ e.update((() => {
59
+ const o = s.match != null && x ? (function(C) {
60
+ const l = Y();
61
+ if (!F(l) || !l.isCollapsed()) return null;
62
+ const N = l.anchor;
63
+ if (N.type !== "text") return null;
64
+ const v = N.getNode();
65
+ if (!v.isSimpleText()) return null;
66
+ const E = N.offset, M = v.getTextContent().slice(0, E), R = C.replaceableString.length, d = E - (function(S, h, f) {
67
+ let n = f;
68
+ for (let p = n; p <= h.length; p++) S.slice(-p) === h.substring(0, p) && (n = p);
69
+ return n;
70
+ })(M, C.matchingString, R);
71
+ if (d < 0) return null;
72
+ let b;
73
+ return d === 0 ? [b] = v.splitText(E) : [, b] = v.splitText(d, E), b;
74
+ })(s.match) : null;
75
+ w(r, o, i, s.match ? s.match.matchingString : "");
76
+ }));
77
+ }), [e, x, s.match, w, i]), O = P(((r) => {
78
+ const o = e.getRootElement();
79
+ o !== null && (o.setAttribute("aria-activedescendant", "typeahead-item-" + r), y(r));
80
+ }), [e]);
81
+ return I((() => () => {
82
+ const r = e.getRootElement();
83
+ r !== null && r.removeAttribute("aria-activedescendant");
84
+ }), [e]), ge((() => {
85
+ t === null ? y(null) : u === null && A && O(0);
86
+ }), [t, u, O, A]), I((() => V(e.registerCommand(q, (({ option: r }) => !(!r.ref || r.ref.current == null) && (X(r.ref.current), !0)), g))), [e, O, g]), I((() => V(e.registerCommand(ue, ((r) => {
87
+ const o = r;
88
+ if (t !== null && t.length) {
89
+ const C = u === null ? 0 : u !== t.length - 1 ? u + 1 : 0;
90
+ O(C);
91
+ const l = t[C];
92
+ l.ref != null && l.ref.current && e.dispatchCommand(q, { index: C, option: l }), o.preventDefault(), o.stopImmediatePropagation();
93
+ }
94
+ return !0;
95
+ }), g), e.registerCommand(se, ((r) => {
96
+ const o = r;
97
+ if (t !== null && t.length) {
98
+ const C = u === null ? t.length - 1 : u !== 0 ? u - 1 : t.length - 1;
99
+ O(C);
100
+ const l = t[C];
101
+ l.ref != null && l.ref.current && X(l.ref.current), o.preventDefault(), o.stopImmediatePropagation();
102
+ }
103
+ return !0;
104
+ }), g), e.registerCommand(ie, ((r) => {
105
+ const o = r;
106
+ return o.preventDefault(), o.stopImmediatePropagation(), i(), !0;
107
+ }), g), e.registerCommand(le, ((r) => {
108
+ const o = r;
109
+ return t !== null && u !== null && t[u] != null && (o.preventDefault(), o.stopImmediatePropagation(), c(t[u]), !0);
110
+ }), g), e.registerCommand(re, ((r) => t !== null && u !== null && t[u] != null && (r !== null && (r.preventDefault(), r.stopImmediatePropagation()), c(t[u]), !0)), g))), [c, i, e, t, u, O, g]), T(a, de((() => ({ options: t, selectOptionAndCleanUp: c, selectedIndex: u, setHighlightedIndex: y })), [c, u, t]), s.match ? s.match.matchingString : "");
111
+ }
112
+ function G(i, e) {
113
+ e != null && (i.className = e), i.setAttribute("aria-label", "Typeahead menu"), i.setAttribute("role", "listbox"), i.style.display = "block", i.style.position = "absolute";
114
+ }
115
+ const he = `\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'"~=<>_:;`;
116
+ function ve(i, { minLength: e = 1, maxLength: a = 75, punctuation: s = he, allowWhitespace: t = !1 }) {
117
+ return P(((T) => {
118
+ const w = new RegExp("(^|\\s|\\()([" + i + "]((?:" + ("[^" + i + s + (t ? "" : "\\s") + "]") + "){0," + a + "}))$").exec(T);
119
+ if (w !== null) {
120
+ const x = w[1], g = w[3];
121
+ if (g.length >= e) return { leadOffset: w.index + x.length, matchingString: g, replaceableString: w[2] };
122
+ }
123
+ return null;
124
+ }), [t, i, s, a, e]);
125
+ }
126
+ function be({ options: i, onQueryChange: e, onSelectOption: a, onOpen: s, onClose: t, menuRenderFn: T, triggerFn: w, anchorClassName: x, commandPriority: g = J, parent: A, preselectFirstItem: u = !0, ignoreEntityBoundary: y = !1 }) {
127
+ const [m] = $(), [c, O] = Z(null), r = (function(l, N, v, E = k ? document.body : void 0, M = !0) {
128
+ const [R] = $(), d = ce(k ? document.createElement("div") : null), b = P((() => {
129
+ if (d.current === null || E === void 0) return;
130
+ d.current.style.top = d.current.style.bottom;
131
+ const f = R.getRootElement(), n = d.current, p = n.firstChild;
132
+ if (f !== null && l !== null) {
133
+ const { left: D, top: _, width: H, height: W } = l.getRect(), ee = d.current.offsetHeight;
134
+ if (n.style.top = `${_ + ee + 3 + (M ? window.pageYOffset : 0)}px`, n.style.left = `${D + window.pageXOffset}px`, n.style.height = `${W}px`, n.style.width = `${H}px`, p !== null) {
135
+ p.style.top = `${_}`;
136
+ const K = p.getBoundingClientRect(), L = K.height, U = K.width, B = f.getBoundingClientRect();
137
+ D + U > B.right && (n.style.left = `${B.right - U + window.pageXOffset}px`), (_ + L > window.innerHeight || _ + L > B.bottom) && _ - B.top > L + W && (n.style.top = `${_ - L - W + (M ? window.pageYOffset : 0)}px`);
138
+ }
139
+ n.isConnected || (G(n, v), E.append(n)), n.setAttribute("id", "typeahead-menu"), d.current = n, f.setAttribute("aria-controls", "typeahead-menu");
140
+ }
141
+ }), [R, l, M, v, E]);
142
+ I((() => {
143
+ const f = R.getRootElement();
144
+ return l !== null && b(), () => {
145
+ f !== null && f.removeAttribute("aria-controls");
146
+ const n = d.current;
147
+ n !== null && n.isConnected && (n.remove(), n.removeAttribute("id"));
148
+ };
149
+ }), [R, b, l]);
150
+ const S = P(((f) => {
151
+ l !== null && (f || N(null));
152
+ }), [l, N]);
153
+ pe(l, d.current, b, S);
154
+ const h = d.current;
155
+ return h != null && (G(h, v), E?.append(h)), d;
156
+ })(c, O, x, A), o = P((() => {
157
+ O(null), t != null && c !== null && t();
158
+ }), [t, c]), C = P(((l) => {
159
+ O(l), s != null && c === null && s(l);
160
+ }), [s, c]);
161
+ return I((() => {
162
+ const l = m.registerUpdateListener((() => {
163
+ m.getEditorState().read((() => {
164
+ if (!m.isEditable()) return void o();
165
+ const N = m._window || window, v = N.document.createRange(), E = Y(), M = (function(b) {
166
+ let S = null;
167
+ return b.getEditorState().read((() => {
168
+ const h = Y();
169
+ F(h) && (S = (function(f) {
170
+ const n = f.anchor;
171
+ if (n.type !== "text") return null;
172
+ const p = n.getNode();
173
+ if (!p.isSimpleText()) return null;
174
+ const D = n.offset;
175
+ return p.getTextContent().slice(0, D);
176
+ })(h));
177
+ })), S;
178
+ })(m);
179
+ if (!F(E) || !E.isCollapsed() || M === null || v === null) return void o();
180
+ const R = w(M, m);
181
+ if (e(R ? R.matchingString : null), R !== null && (y || !(function(b, S) {
182
+ return S === 0 && b.getEditorState().read((() => {
183
+ const h = Y();
184
+ if (F(h)) {
185
+ const f = h.anchor.getNode().getPreviousSibling();
186
+ return te(f) && f.isTextEntity();
187
+ }
188
+ return !1;
189
+ }));
190
+ })(m, R.leadOffset)) && (function(S, h, f) {
191
+ const n = ne(f);
192
+ if (n === null || !n.isCollapsed) return !1;
193
+ const p = n.anchorNode, D = S, _ = n.anchorOffset;
194
+ if (p == null || _ == null) return !1;
195
+ try {
196
+ h.setStart(p, D), h.setEnd(p, _);
197
+ } catch {
198
+ return !1;
199
+ }
200
+ return !0;
201
+ })(R.leadOffset, v, N) !== null)
202
+ return d = () => C({ getRect: () => v.getBoundingClientRect(), match: R }), void (z in Q ? Q[z](d) : d());
203
+ var d;
204
+ o();
205
+ }));
206
+ }));
207
+ return () => {
208
+ l();
209
+ };
210
+ }), [m, w, e, c, o, C, y]), I((() => m.registerEditableListener(((l) => {
211
+ l || o();
212
+ }))), [m, o]), c === null || m === null || r.current === null ? null : fe(me, { close: o, resolution: c, editor: m, anchorElementRef: r, options: i, menuRenderFn: T, shouldSplitNodeWithQuery: !0, onSelectOption: a, commandPriority: g, preselectFirstItem: u });
213
+ }
214
+ export {
215
+ be as LexicalTypeaheadMenuPlugin,
216
+ Ce as MenuOption,
217
+ he as PUNCTUATION,
218
+ ve as useBasicTypeaheadTriggerMatch,
219
+ pe as useDynamicPositioning
220
+ };