@verbb/plugin-kit-react 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/components/EditableTable.d.ts +4 -2
  3. package/dist/components/EditableTable.d.ts.map +1 -1
  4. package/dist/components/EditableTable.js +2 -1
  5. package/dist/components/EditableTable.js.map +1 -1
  6. package/dist/components/SelectInput.js +1 -1
  7. package/dist/components/SelectInput.js.map +1 -1
  8. package/dist/components/TiptapEditor.d.ts +4 -2
  9. package/dist/components/TiptapEditor.d.ts.map +1 -1
  10. package/dist/components/TiptapEditor.js +27 -9
  11. package/dist/components/TiptapEditor.js.map +1 -1
  12. package/dist/components/TiptapInput.d.ts +18 -13
  13. package/dist/components/TiptapInput.d.ts.map +1 -1
  14. package/dist/components/TiptapInput.js +3 -1
  15. package/dist/components/TiptapInput.js.map +1 -1
  16. package/dist/components/editable-table/RowDataCells.d.ts.map +1 -1
  17. package/dist/components/editable-table/RowDataCells.js +6 -6
  18. package/dist/components/editable-table/RowDataCells.js.map +1 -1
  19. package/dist/components/editable-table/TableRow.d.ts.map +1 -1
  20. package/dist/components/editable-table/TableRow.js +6 -3
  21. package/dist/components/editable-table/TableRow.js.map +1 -1
  22. package/dist/components/editable-table/types.d.ts +13 -1
  23. package/dist/components/editable-table/types.d.ts.map +1 -1
  24. package/dist/components/tiptap/VariableDropdown.d.ts +7 -0
  25. package/dist/components/tiptap/VariableDropdown.d.ts.map +1 -1
  26. package/dist/components/tiptap/VariableDropdown.js.map +1 -1
  27. package/dist/components/tiptap/VariablePickerContext.d.ts +22 -2
  28. package/dist/components/tiptap/VariablePickerContext.d.ts.map +1 -1
  29. package/dist/components/tiptap/VariablePickerContext.js +7 -3
  30. package/dist/components/tiptap/VariablePickerContext.js.map +1 -1
  31. package/dist/components/tiptap/VariableTagView.d.ts.map +1 -1
  32. package/dist/components/tiptap/VariableTagView.js +160 -21
  33. package/dist/components/tiptap/VariableTagView.js.map +1 -1
  34. package/dist/components/tiptap/variableSerialization.d.ts +4 -0
  35. package/dist/components/tiptap/variableSerialization.d.ts.map +1 -1
  36. package/dist/components/tiptap/variableSerialization.js +71 -30
  37. package/dist/components/tiptap/variableSerialization.js.map +1 -1
  38. package/dist/forms/contexts/VariableCategoriesContext.d.ts +3 -1
  39. package/dist/forms/contexts/VariableCategoriesContext.d.ts.map +1 -1
  40. package/dist/forms/contexts/VariableCategoriesContext.js +3 -1
  41. package/dist/forms/contexts/VariableCategoriesContext.js.map +1 -1
  42. package/dist/forms/fields/RichTextField.d.ts.map +1 -1
  43. package/dist/forms/fields/RichTextField.js +3 -1
  44. package/dist/forms/fields/RichTextField.js.map +1 -1
  45. package/dist/forms/fields/SelectField.js +1 -1
  46. package/dist/forms/fields/SelectField.js.map +1 -1
  47. package/dist/forms/fields/VariablePickerField.d.ts.map +1 -1
  48. package/dist/forms/fields/VariablePickerField.js +3 -1
  49. package/dist/forms/fields/VariablePickerField.js.map +1 -1
  50. package/package.json +1 -1
@@ -2,7 +2,7 @@ import { cn } from "../../utils/classes.js";
2
2
  import "../../utils/index.js";
3
3
  import { useTranslation } from "../../hooks/useTranslation.js";
4
4
  import "../../hooks/index.js";
5
- import { buildVariableTagAttrs, parseTokenWithDefault } from "./variableSerialization.js";
5
+ import { buildVariableTagAttrs, getReferenceBaseToken, parseTokenWithDefault, resolveVariableTagLabel } from "./variableSerialization.js";
6
6
  import { VariableCommandList } from "./VariableCommandList.js";
7
7
  import { useVariablePicker } from "./useVariablePicker.js";
8
8
  import { Input } from "../Input.js";
@@ -34,43 +34,70 @@ var VariableTagView_default = (props) => {
34
34
  return acc;
35
35
  }, {});
36
36
  });
37
+ const [pendingTokenValue, setPendingTokenValue] = useState(String(node?.attrs?.value ?? ""));
38
+ const pendingTokenValueRef = useRef(String(node?.attrs?.value ?? ""));
39
+ const configureStateRef = useRef(null);
40
+ const prepareSaveRef = useRef(null);
41
+ const onPendingTokenChangeRef = useRef(() => {});
42
+ const originalTagAttrsRef = useRef(null);
43
+ const [configureSessionKey, setConfigureSessionKey] = useState(0);
37
44
  const openOnInsertHandled = useRef(false);
38
45
  const popoverContentRef = useRef(null);
39
46
  const pickerContext = useVariablePickerContext();
40
- const selectedVariableMeta = useMemo(() => {
41
- const [token] = parseTokenWithDefault(String(node?.attrs?.value ?? ""));
47
+ const resolveVariableMetaForToken = useCallback((lookupValue = "") => {
48
+ const [token] = parseTokenWithDefault(String(lookupValue || ""));
49
+ const tokenBase = getReferenceBaseToken(token);
42
50
  const groups = Object.values(pickerContext?.variableCategories ?? {});
43
51
  const visit = (items) => {
52
+ let fallbackMatch = null;
44
53
  for (const item of items) {
45
- if (item?.value === token) return item;
46
- const childMatch = (Array.isArray(item?.children) ? item.children : []).find((child) => {
47
- return child?.value === token;
48
- });
49
- if (childMatch) return childMatch;
54
+ const children = Array.isArray(item?.children) ? item.children : [];
55
+ const itemValue = String(item?.value ?? "");
56
+ if (itemValue === token) return item;
57
+ if (children.length) {
58
+ const childMatch = visit(children);
59
+ if (childMatch?.value === token) return childMatch;
60
+ if (childMatch && !fallbackMatch) fallbackMatch = childMatch;
61
+ }
62
+ if (getReferenceBaseToken(itemValue) === tokenBase) {
63
+ if (!fallbackMatch) fallbackMatch = item;
64
+ }
50
65
  }
51
- return null;
66
+ return fallbackMatch;
52
67
  };
53
68
  for (const groupItems of groups) {
54
69
  const match = visit(Array.isArray(groupItems) ? groupItems : []);
55
70
  if (match) return match;
56
71
  }
57
72
  return null;
58
- }, [pickerContext?.variableCategories, node?.attrs?.value]);
73
+ }, [pickerContext?.variableCategories]);
74
+ const selectedVariableMeta = useMemo(() => {
75
+ return resolveVariableMetaForToken(isConfigOpen ? String(pendingTokenValueRef.current || node?.attrs?.value || "") : String(node?.attrs?.value ?? ""));
76
+ }, [
77
+ isConfigOpen,
78
+ node?.attrs?.value,
79
+ pendingTokenValue,
80
+ resolveVariableMetaForToken
81
+ ]);
59
82
  const transformOptions = useMemo(() => {
83
+ if (selectedVariableMeta?.allowTransforms === false) return [];
60
84
  const registry = pickerContext?.variableTransformerRegistry ?? {};
61
85
  const compatibleWith = Array.isArray(selectedVariableMeta?.compatibleWith) ? selectedVariableMeta.compatibleWith : [];
86
+ const sourceTypes = Array.isArray(selectedVariableMeta?.types) ? selectedVariableMeta.types : [];
62
87
  const allowedTypes = /* @__PURE__ */ new Set();
63
88
  const hasCompatibilityHints = compatibleWith.length > 0;
64
- (Array.isArray(selectedVariableMeta?.transformValueTypes) ? selectedVariableMeta.transformValueTypes : []).forEach((type) => {
89
+ const hasExplicitTransformTypes = Object.prototype.hasOwnProperty.call(selectedVariableMeta ?? {}, "transformValueTypes");
90
+ (hasExplicitTransformTypes && Array.isArray(selectedVariableMeta?.transformValueTypes) ? selectedVariableMeta.transformValueTypes : sourceTypes).forEach((type) => {
65
91
  if (typeof type === "string" && type.trim() !== "") allowedTypes.add(type);
66
92
  });
67
- const hasTransformHints = hasCompatibilityHints || allowedTypes.size > 0;
93
+ const hasTransformHints = hasCompatibilityHints || hasExplicitTransformTypes || sourceTypes.length > 0;
68
94
  if (compatibleWith.includes("plainText") || compatibleWith.includes("email")) allowedTypes.add("text");
69
95
  if (compatibleWith.includes("number") || compatibleWith.includes("calculations")) allowedTypes.add("number");
70
96
  if (compatibleWith.includes("url")) allowedTypes.add("url");
71
97
  if (compatibleWith.includes("date")) allowedTypes.add("date");
72
98
  if (compatibleWith.includes("boolean")) allowedTypes.add("boolean");
73
99
  if (compatibleWith.includes("array")) allowedTypes.add("array");
100
+ if (hasTransformHints && allowedTypes.size === 0) return [];
74
101
  const byId = /* @__PURE__ */ new Map();
75
102
  Object.entries(registry).forEach(([valueType, transformers]) => {
76
103
  if (hasTransformHints && allowedTypes.size > 0 && !allowedTypes.has(valueType)) return;
@@ -148,15 +175,63 @@ var VariableTagView_default = (props) => {
148
175
  useEffect(() => {
149
176
  if (!openOnInsert || openOnInsertHandled.current) return;
150
177
  openOnInsertHandled.current = true;
178
+ originalTagAttrsRef.current = {
179
+ value: node?.attrs?.value ?? null,
180
+ label: node?.attrs?.label ?? null,
181
+ default: node?.attrs?.default ?? null,
182
+ transformerId: node?.attrs?.transformerId ?? null,
183
+ transformerParams: node?.attrs?.transformerParams ?? null
184
+ };
151
185
  setIsConfigOpen(true);
152
186
  queueMicrotask(() => {
153
187
  updateAttributes?.({ openOnInsert: false });
154
188
  });
155
- }, [openOnInsert, updateAttributes]);
189
+ }, [
190
+ node?.attrs?.default,
191
+ node?.attrs?.label,
192
+ node?.attrs?.transformerId,
193
+ node?.attrs?.transformerParams,
194
+ node?.attrs?.value,
195
+ openOnInsert,
196
+ updateAttributes
197
+ ]);
156
198
  const handleDelete = () => {
157
199
  if (!isReadOnly) deleteNode();
158
200
  };
159
- function closeConfig() {
201
+ const commitPendingToken = useCallback((nextToken) => {
202
+ const normalizedToken = String(nextToken || "");
203
+ const meta = resolveVariableMetaForToken(normalizedToken);
204
+ const defaultLabel = resolveVariableTagLabel(normalizedToken, meta);
205
+ const label = pickerContext?.resolveVariableTagLabel?.({
206
+ tokenValue: normalizedToken,
207
+ variableOption: meta,
208
+ defaultLabel,
209
+ storedLabel: String(node?.attrs?.label ?? "")
210
+ }) || defaultLabel;
211
+ pendingTokenValueRef.current = normalizedToken;
212
+ setPendingTokenValue(normalizedToken);
213
+ updateAttributes?.({
214
+ value: normalizedToken,
215
+ label,
216
+ default: node?.attrs?.default ?? null,
217
+ transformerId: node?.attrs?.transformerId ?? null,
218
+ transformerParams: node?.attrs?.transformerParams ?? null
219
+ });
220
+ }, [
221
+ node?.attrs?.default,
222
+ node?.attrs?.label,
223
+ node?.attrs?.transformerId,
224
+ node?.attrs?.transformerParams,
225
+ pickerContext,
226
+ resolveVariableMetaForToken,
227
+ updateAttributes
228
+ ]);
229
+ function closeConfig(preservedValue = null) {
230
+ const nextValue = preservedValue != null ? String(preservedValue) : String(node?.attrs?.value ?? "");
231
+ pendingTokenValueRef.current = nextValue;
232
+ setPendingTokenValue(nextValue);
233
+ if (preservedValue == null && originalTagAttrsRef.current) updateAttributes?.(originalTagAttrsRef.current);
234
+ originalTagAttrsRef.current = null;
160
235
  setIsConfigOpen(false);
161
236
  setIsPickerMode(false);
162
237
  picker.reset();
@@ -166,8 +241,26 @@ var VariableTagView_default = (props) => {
166
241
  }, []);
167
242
  const handleOpenConfig = useCallback(() => {
168
243
  if (!isConfigurable) return;
244
+ const nextValue = String(node?.attrs?.value ?? "");
245
+ originalTagAttrsRef.current = {
246
+ value: node?.attrs?.value ?? null,
247
+ label: node?.attrs?.label ?? null,
248
+ default: node?.attrs?.default ?? null,
249
+ transformerId: node?.attrs?.transformerId ?? null,
250
+ transformerParams: node?.attrs?.transformerParams ?? null
251
+ };
252
+ pendingTokenValueRef.current = nextValue;
253
+ setPendingTokenValue(nextValue);
254
+ setConfigureSessionKey((current) => current + 1);
169
255
  setIsConfigOpen(true);
170
- }, [isConfigurable]);
256
+ }, [
257
+ isConfigurable,
258
+ node?.attrs?.default,
259
+ node?.attrs?.label,
260
+ node?.attrs?.transformerId,
261
+ node?.attrs?.transformerParams,
262
+ node?.attrs?.value
263
+ ]);
171
264
  useEffect(() => {
172
265
  const editorDom = editor?.view?.dom;
173
266
  if (!editorDom || !isActive || !isConfigurable) return;
@@ -192,6 +285,7 @@ var VariableTagView_default = (props) => {
192
285
  handleOpenConfig
193
286
  ]);
194
287
  const handleSaveOptions = () => {
288
+ prepareSaveRef.current?.();
195
289
  const trimmedDefault = defaultIfEmpty.trim();
196
290
  const trimmedTransformerId = transformerId.trim();
197
291
  const normalizedParams = trimmedTransformerId ? Object.entries(transformerParams).reduce((acc, [key, value]) => {
@@ -199,17 +293,31 @@ var VariableTagView_default = (props) => {
199
293
  if (trimmed !== "") acc[key] = trimmed;
200
294
  return acc;
201
295
  }, {}) : null;
296
+ const savedValue = pendingTokenValueRef.current || String(node?.attrs?.value ?? "");
297
+ const savedMeta = resolveVariableMetaForToken(savedValue);
298
+ const defaultSavedLabel = resolveVariableTagLabel(savedValue, savedMeta);
299
+ const savedLabel = pickerContext?.resolveVariableTagLabel?.({
300
+ tokenValue: savedValue,
301
+ variableOption: savedMeta,
302
+ defaultLabel: defaultSavedLabel,
303
+ storedLabel: String(node?.attrs?.label ?? "")
304
+ }) || defaultSavedLabel;
202
305
  updateAttributes?.({
306
+ value: savedValue,
307
+ label: savedLabel,
203
308
  default: trimmedDefault || null,
204
309
  transformerId: trimmedTransformerId || null,
205
310
  transformerParams: trimmedTransformerId ? normalizedParams : null
206
311
  });
207
- closeConfig();
312
+ closeConfig(savedValue);
208
313
  };
209
314
  const handleConfigOpenChange = (nextOpen) => {
210
- setIsConfigOpen(nextOpen);
211
- setIsPickerMode(false);
212
- if (!nextOpen) picker.reset();
315
+ if (nextOpen) {
316
+ setIsConfigOpen(true);
317
+ setIsPickerMode(false);
318
+ return;
319
+ }
320
+ closeConfig();
213
321
  };
214
322
  const handleTagKeyDown = (event) => {
215
323
  if (!isConfigurable) return;
@@ -220,6 +328,7 @@ var VariableTagView_default = (props) => {
220
328
  }
221
329
  };
222
330
  useEffect(() => {
331
+ if (!isConfigOpen) return;
223
332
  setDefaultIfEmpty(node?.attrs?.default ?? "");
224
333
  setTransformerId(node?.attrs?.transformerId ?? "");
225
334
  const raw = node?.attrs?.transformerParams;
@@ -273,9 +382,37 @@ var VariableTagView_default = (props) => {
273
382
  let transformPreview = "";
274
383
  if (appliedTransformer?.label) transformPreview = appliedTransformer.label;
275
384
  else if (appliedTransformerId) transformPreview = appliedTransformerId;
276
- const tokenValue = String(node?.attrs?.value ?? "");
277
- const tagLabel = selectedVariableMeta?.label ?? node?.attrs?.label ?? "";
385
+ const tokenValue = String(isConfigOpen ? pendingTokenValueRef.current || pendingTokenValue || node?.attrs?.value || "" : node?.attrs?.value || pendingTokenValue || "");
386
+ const tagLabel = useMemo(() => {
387
+ const resolvedMeta = selectedVariableMeta || resolveVariableMetaForToken(tokenValue);
388
+ const defaultLabel = resolveVariableTagLabel(tokenValue, resolvedMeta);
389
+ return pickerContext?.resolveVariableTagLabel?.({
390
+ tokenValue,
391
+ variableOption: resolvedMeta,
392
+ defaultLabel,
393
+ storedLabel: String(node?.attrs?.label ?? "")
394
+ }) || defaultLabel;
395
+ }, [
396
+ node?.attrs?.label,
397
+ pickerContext,
398
+ resolveVariableMetaForToken,
399
+ selectedVariableMeta,
400
+ tokenValue
401
+ ]);
278
402
  const tagTitle = tagLabel;
403
+ const configureResetKey = isConfigOpen ? String(configureSessionKey) : "closed";
404
+ onPendingTokenChangeRef.current = commitPendingToken;
405
+ const configureSection = pickerContext?.renderVariableConfigureSection?.({
406
+ tokenValue,
407
+ variableOption: selectedVariableMeta,
408
+ configureResetKey,
409
+ configureStateRef,
410
+ prepareSaveRef,
411
+ getPendingTokenValue: () => pendingTokenValueRef.current || String(node?.attrs?.value ?? ""),
412
+ onPendingTokenChange: (nextToken) => {
413
+ onPendingTokenChangeRef.current(nextToken);
414
+ }
415
+ });
279
416
  return /* @__PURE__ */ jsx(NodeViewWrapper, {
280
417
  as: "span",
281
418
  className: cn("relative inline-block leading-none mx-[1px] cursor-default"),
@@ -317,6 +454,7 @@ var VariableTagView_default = (props) => {
317
454
  })
318
455
  }) }), /* @__PURE__ */ jsx(PopoverContent, {
319
456
  ref: popoverContentRef,
457
+ "data-variable-config-popover": "",
320
458
  align: "start",
321
459
  side: "bottom",
322
460
  sideOffset: 6,
@@ -345,6 +483,7 @@ var VariableTagView_default = (props) => {
345
483
  }) : /* @__PURE__ */ jsxs("div", {
346
484
  className: "p-2",
347
485
  children: [
486
+ configureSection,
348
487
  /* @__PURE__ */ jsx("label", {
349
488
  className: "text-[11px] text-gray-500 block mb-1",
350
489
  children: t("Default if empty (optional)")
@@ -1 +1 @@
1
- {"version":3,"file":"VariableTagView.js","names":[],"sources":["../../../src/components/tiptap/VariableTagView.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { NodeViewWrapper } from '@tiptap/react';\nimport { cn } from '@verbb/plugin-kit-react/utils';\nimport { Popover, PopoverContent, PopoverTrigger } from '@verbb/plugin-kit-react/components';\nimport { useTranslation } from '@verbb/plugin-kit-react/hooks';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faXmark } from '@fortawesome/pro-solid-svg-icons';\nimport { Button } from '@verbb/plugin-kit-react/components/Button';\nimport { Input } from '@verbb/plugin-kit-react/components/Input';\nimport type { VariableOption } from './VariableDropdown';\nimport { VariableCommandList } from './VariableCommandList';\nimport { useVariablePickerContext } from './VariablePickerContext';\nimport { VariableTransformControls } from './VariableTransformControls';\nimport { useVariablePicker } from './useVariablePicker';\nimport { buildVariableTagAttrs } from './variableSerialization';\nimport { parseTokenWithDefault } from './variableSerialization';\n\ntype VariableMeta = VariableOption & {\n compatibleWith?: string[];\n transformValueTypes?: string[];\n};\n\nexport default (props) => {\n const t = useTranslation();\n const {\n editor,\n node,\n updateAttributes,\n deleteNode,\n selected: isActive,\n } = props;\n const isReadOnly = !editor?.isEditable || false;\n const openOnInsert = Boolean(node?.attrs?.openOnInsert);\n const [isConfigOpen, setIsConfigOpen] = useState(openOnInsert);\n const [isPickerMode, setIsPickerMode] = useState(false);\n const [defaultIfEmpty, setDefaultIfEmpty] = useState(node?.attrs?.default ?? '');\n const [transformerId, setTransformerId] = useState(node?.attrs?.transformerId ?? '');\n const [transformerParams, setTransformerParams] = useState<Record<string, string>>(() => {\n const raw = node?.attrs?.transformerParams;\n if (!raw || typeof raw !== 'object') {\n return {};\n }\n\n return Object.entries(raw).reduce((acc, [key, value]) => {\n acc[key] = value == null ? '' : String(value);\n return acc;\n }, {} as Record<string, string>);\n });\n const openOnInsertHandled = useRef(false);\n const popoverContentRef = useRef<HTMLDivElement | null>(null);\n const pickerContext = useVariablePickerContext();\n\n const selectedVariableMeta = useMemo(() => {\n const [token] = parseTokenWithDefault(String(node?.attrs?.value ?? ''));\n const groups = Object.values(pickerContext?.variableCategories ?? {});\n\n const visit = (items: VariableOption[]): VariableMeta | null => {\n for (const item of items) {\n if (item?.value === token) {\n return item as VariableMeta;\n }\n\n const children = Array.isArray(item?.children) ? item.children : [];\n const childMatch = children.find((child) => {\n return child?.value === token;\n });\n if (childMatch) {\n return childMatch as VariableMeta;\n }\n }\n\n return null;\n };\n\n for (const groupItems of groups) {\n const match = visit(Array.isArray(groupItems) ? groupItems : []);\n if (match) {\n return match;\n }\n }\n\n return null;\n }, [pickerContext?.variableCategories, node?.attrs?.value]);\n\n const transformOptions = useMemo(() => {\n const registry = pickerContext?.variableTransformerRegistry ?? {};\n const compatibleWith = Array.isArray(selectedVariableMeta?.compatibleWith)\n ? selectedVariableMeta.compatibleWith\n : [];\n\n const allowedTypes = new Set<string>();\n const hasCompatibilityHints = compatibleWith.length > 0;\n const explicitTransformTypes = Array.isArray(selectedVariableMeta?.transformValueTypes)\n ? selectedVariableMeta.transformValueTypes\n : [];\n explicitTransformTypes.forEach((type) => {\n if (typeof type === 'string' && type.trim() !== '') {\n allowedTypes.add(type);\n }\n });\n const hasTransformHints = hasCompatibilityHints || allowedTypes.size > 0;\n if (compatibleWith.includes('plainText') || compatibleWith.includes('email')) {\n allowedTypes.add('text');\n }\n if (compatibleWith.includes('number') || compatibleWith.includes('calculations')) {\n allowedTypes.add('number');\n }\n if (compatibleWith.includes('url')) {\n allowedTypes.add('url');\n }\n if (compatibleWith.includes('date')) {\n allowedTypes.add('date');\n }\n if (compatibleWith.includes('boolean')) {\n allowedTypes.add('boolean');\n }\n if (compatibleWith.includes('array')) {\n allowedTypes.add('array');\n }\n\n const byId = new Map();\n\n Object.entries(registry).forEach(([valueType, transformers]) => {\n if (hasTransformHints && allowedTypes.size > 0 && !allowedTypes.has(valueType)) {\n return;\n }\n\n (Array.isArray(transformers) ? transformers : []).forEach((transformer) => {\n const appliesTo = Array.isArray(transformer.appliesTo) && transformer.appliesTo.length\n ? transformer.appliesTo\n : [valueType];\n\n if (hasTransformHints && allowedTypes.size > 0 && !appliesTo.some((type) => {\n return allowedTypes.has(type);\n })) {\n return;\n }\n\n if (!byId.has(transformer.id)) {\n byId.set(transformer.id, {\n value: transformer.id,\n label: transformer.label,\n description: transformer.description,\n params: Array.isArray(transformer.params) ? transformer.params : [],\n appliesTo,\n });\n }\n });\n });\n\n return Array.from(byId.values());\n }, [pickerContext?.variableTransformerRegistry, selectedVariableMeta]);\n\n const selectedTransformer = useMemo(() => {\n return transformOptions.find((option) => {\n return option.value === transformerId;\n }) ?? null;\n }, [transformOptions, transformerId]);\n const hasIncompatibleTransformerSelection = useMemo(() => {\n const current = transformerId.trim();\n return current !== '' && !selectedTransformer;\n }, [transformerId, selectedTransformer]);\n\n const initialPage = useMemo((): VariableOption | null => {\n const currentValue = node?.attrs?.value;\n if (!currentValue || !pickerContext?.variableCategories) {\n return null;\n }\n const findParentWithChild = (items: VariableOption[]): VariableOption | null => {\n for (const item of items) {\n const children = Array.isArray(item?.children) ? item.children : [];\n if (children.some((c) => {\n return c?.value === currentValue;\n })) {\n return item;\n }\n const nested = findParentWithChild(children);\n if (nested) {\n return nested;\n }\n }\n return null;\n };\n const allItems = Object.values(pickerContext.variableCategories).flatMap((items) => {\n return items ?? [];\n });\n return findParentWithChild(allItems);\n }, [node?.attrs?.value, pickerContext?.variableCategories]);\n\n const picker = useVariablePicker({\n variableCategories: pickerContext?.variableCategories ?? {},\n variableCategoryLabels: pickerContext?.variableCategoryLabels,\n variableCategoryOrder: pickerContext?.variableCategoryOrder,\n isOpen: isConfigOpen,\n initialPage,\n getDefaultIfEmpty: () => {\n return defaultIfEmpty;\n },\n onApply: (baseVariable, variable, defaultText) => {\n const attrs = buildVariableTagAttrs(baseVariable, variable, {\n defaultIfEmpty: defaultText,\n });\n updateAttributes?.(attrs);\n setDefaultIfEmpty('');\n setTransformerId('');\n setTransformerParams({});\n setIsConfigOpen(false);\n setIsPickerMode(false);\n picker.reset();\n },\n });\n\n const hasFullPicker = pickerContext && Object.values(pickerContext.variableCategories ?? {}).some((items) => {\n return Array.isArray(items) && items.length > 0;\n });\n\n const isConfigurable = !isReadOnly;\n const canChangeVariable = !!hasFullPicker;\n\n useEffect(() => {\n if (!openOnInsert) {\n return;\n }\n openOnInsertHandled.current = false;\n }, [openOnInsert]);\n\n useEffect(() => {\n if (!openOnInsert || openOnInsertHandled.current) {\n return;\n }\n openOnInsertHandled.current = true;\n setIsConfigOpen(true);\n queueMicrotask(() => {\n updateAttributes?.({ openOnInsert: false });\n });\n }, [openOnInsert, updateAttributes]);\n\n const handleDelete = () => {\n if (!isReadOnly) {\n deleteNode();\n }\n };\n\n function closeConfig() {\n setIsConfigOpen(false);\n setIsPickerMode(false);\n picker.reset();\n }\n\n const exitPickerMode = useCallback(() => {\n setIsPickerMode(false);\n }, []);\n\n const handleOpenConfig = useCallback(() => {\n if (!isConfigurable) {\n return;\n }\n\n setIsConfigOpen(true);\n }, [isConfigurable]);\n\n useEffect(() => {\n const editorDom = editor?.view?.dom;\n\n if (!editorDom || !isActive || !isConfigurable) {\n return;\n }\n\n const handleEditorKeyDown = (event: KeyboardEvent) => {\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) {\n return;\n }\n\n const target = event.target as HTMLElement | null;\n const tagName = target?.tagName;\n const isFocusableInput = tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT';\n\n if (isFocusableInput) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n event.stopPropagation();\n handleOpenConfig();\n }\n };\n\n editorDom.addEventListener('keydown', handleEditorKeyDown, true);\n\n return () => {\n editorDom.removeEventListener('keydown', handleEditorKeyDown, true);\n };\n }, [editor, isActive, isConfigurable, handleOpenConfig]);\n\n const handleSaveOptions = () => {\n const trimmedDefault = defaultIfEmpty.trim();\n const trimmedTransformerId = transformerId.trim();\n const normalizedParams = trimmedTransformerId\n ? Object.entries(transformerParams).reduce((acc, [key, value]) => {\n const trimmed = String(value ?? '').trim();\n if (trimmed !== '') {\n acc[key] = trimmed;\n }\n return acc;\n }, {} as Record<string, string>)\n : null;\n\n updateAttributes?.({\n default: trimmedDefault || null,\n transformerId: trimmedTransformerId || null,\n transformerParams: trimmedTransformerId ? normalizedParams : null,\n });\n closeConfig();\n };\n\n const handleConfigOpenChange = (nextOpen: boolean) => {\n setIsConfigOpen(nextOpen);\n\n // Always reopen on the options view.\n setIsPickerMode(false);\n\n if (!nextOpen) {\n picker.reset();\n }\n };\n\n const handleTagKeyDown = (event) => {\n if (!isConfigurable) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n event.stopPropagation();\n handleOpenConfig();\n }\n };\n\n useEffect(() => {\n setDefaultIfEmpty(node?.attrs?.default ?? '');\n setTransformerId(node?.attrs?.transformerId ?? '');\n const raw = node?.attrs?.transformerParams;\n if (raw && typeof raw === 'object') {\n setTransformerParams(Object.entries(raw).reduce((acc, [key, value]) => {\n acc[key] = value == null ? '' : String(value);\n return acc;\n }, {} as Record<string, string>));\n } else {\n setTransformerParams({});\n }\n }, [isConfigOpen, node?.attrs?.default, node?.attrs?.transformerId, node?.attrs?.transformerParams]);\n\n useEffect(() => {\n if (!selectedTransformer) {\n return;\n }\n\n setTransformerParams((current) => {\n const next = { ...current };\n (selectedTransformer.params ?? []).forEach((param) => {\n if (next[param.name] == null || next[param.name] === '') {\n next[param.name] = param.default == null ? '' : String(param.default);\n }\n });\n\n return next;\n });\n }, [selectedTransformer]);\n\n useEffect(() => {\n if (!isConfigOpen || !isPickerMode) {\n return;\n }\n\n let frame = 0;\n let cancelled = false;\n\n const focusSearch = (attempt = 0) => {\n if (cancelled) {\n return;\n }\n\n const input = popoverContentRef.current?.querySelector<HTMLInputElement>('[data-slot=\"command-input\"]');\n\n if (input) {\n input.focus();\n return;\n }\n\n if (attempt < 8) {\n frame = requestAnimationFrame(() => {\n focusSearch(attempt + 1);\n });\n }\n };\n\n focusSearch();\n\n return () => {\n cancelled = true;\n\n if (frame) {\n cancelAnimationFrame(frame);\n }\n };\n }, [isConfigOpen, isPickerMode]);\n\n const fallbackPreview = String(props.node?.attrs?.default ?? '').trim();\n const appliedTransformerId = String(props.node?.attrs?.transformerId ?? '').trim();\n const appliedTransformer = transformOptions.find((option) => {\n return option.value === appliedTransformerId;\n }) ?? null;\n let transformPreview = '';\n if (appliedTransformer?.label) {\n transformPreview = appliedTransformer.label;\n } else if (appliedTransformerId) {\n transformPreview = appliedTransformerId;\n }\n const tokenValue = String(node?.attrs?.value ?? '');\n const tagLabel = selectedVariableMeta?.label ?? (node?.attrs?.label ?? '');\n const tagTitle = tagLabel;\n const useCornerBadge = true;\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={cn(\n 'relative inline-block leading-none mx-[1px] cursor-default',\n )}\n tabIndex={isConfigurable ? 0 : undefined}\n onKeyDown={handleTagKeyDown}\n data-drag-handle\n data-variable-value={tokenValue}\n >\n <span className={cn(\n 'relative inline-flex items-stretch whitespace-nowrap gap-0 overflow-hidden',\n '-mt-[3px] text-[11px] font-normal! leading-none align-middle',\n 'bg-[#5C6BC0] text-white rounded-[2px]',\n\n isReadOnly && 'inline-flex flex-1 px-[5px] py-[4px]',\n\n isActive && !isReadOnly && 'outline-none shadow-[0_0_0_2px_rgba(123,140,232,0.5)]',\n\n isReadOnly && isActive && 'shadow-none',\n )}>\n {fallbackPreview && useCornerBadge && (\n <span\n className=\"pointer-events-none absolute top-0 left-0 h-0 w-0 border-t-[8px] border-r-[8px] border-t-orange-400 border-r-transparent\"\n aria-label={t('Has fallback value')}\n />\n )}\n {isConfigurable ? (\n <Popover open={isConfigOpen} onOpenChange={handleConfigOpenChange}>\n <PopoverTrigger\n render={\n <button\n type=\"button\"\n className=\"inline-flex flex-1 min-w-0 self-stretch items-center cursor-pointer bg-transparent border-0 px-[5px] py-[4px] m-0 text-left text-inherit focus:outline-none\"\n title={tagTitle}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n handleOpenConfig();\n }}\n >\n <span className=\"block truncate max-w-[220px]\">\n {tagLabel}\n {(transformPreview) && (\n <span\n className=\"ml-1 inline-flex items-center rounded bg-white/20 px-1 py-[1px] text-[9px] leading-none text-white/95 align-middle\"\n title={t('Transform: {transform}', { transform: transformPreview })}\n aria-label={t('Transform: {transform}', { transform: transformPreview })}\n >\n {transformPreview}\n </span>\n )}\n {fallbackPreview && !useCornerBadge && (\n <span\n className=\"ml-1 inline-block size-[5px] rounded-full bg-white/75 align-middle\"\n aria-label={t('Has fallback value')}\n />\n )}\n </span>\n </button>\n }\n />\n\n <PopoverContent\n ref={popoverContentRef}\n align=\"start\"\n side=\"bottom\"\n sideOffset={6}\n className={hasFullPicker ? 'min-w-[260px] max-w-[360px] p-0' : 'w-[260px] p-0'}\n onMouseDown={(event) => {\n const target = event.target as HTMLElement | null;\n const tagName = target?.tagName;\n const isFocusableInput = tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT';\n const isSelectControl = Boolean(target?.closest('[data-slot=\"select-trigger\"]'));\n\n // Keep editor selection stable for picker clicks, but allow typing in fallback input.\n if (isFocusableInput || isSelectControl) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n }}\n >\n {isPickerMode ? (\n canChangeVariable && (\n <VariableCommandList\n search={picker.search}\n onSearchChange={picker.setSearch}\n groups={picker.groups}\n options={picker.options}\n selectedValue={node?.attrs?.value}\n onSelect={picker.handleSelect}\n placeholder={t('Search variables')}\n showSearch\n shouldFilter={false}\n onBack={picker.page ? picker.handleBack : exitPickerMode}\n isChildMode={!!picker.page}\n />\n )\n ) : (\n <div className=\"p-2\">\n <label className=\"text-[11px] text-gray-500 block mb-1\">\n {t('Default if empty (optional)')}\n </label>\n <Input\n type=\"text\"\n value={defaultIfEmpty}\n onChange={(event) => {\n setDefaultIfEmpty(event.target.value);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n handleSaveOptions();\n }\n }}\n />\n <VariableTransformControls\n transformerId={transformerId}\n onTransformerIdChange={(nextId) => {\n setTransformerId(nextId);\n if (!nextId) {\n setTransformerParams({});\n }\n }}\n transformOptions={transformOptions}\n hasIncompatibleTransformerSelection={hasIncompatibleTransformerSelection}\n selectedTransformer={selectedTransformer}\n transformerParams={transformerParams}\n onTransformerParamChange={(paramName, nextValue) => {\n setTransformerParams((current) => {\n return {\n ...current,\n [paramName]: nextValue,\n };\n });\n }}\n />\n <div className=\"mt-3 -mx-2 -mb-2 border-t border-slate-200 bg-[#f3f7fd] px-2 py-2 flex items-center justify-between gap-2\">\n {canChangeVariable ? (\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"sm\"\n className=\"text-[11px]\"\n onClick={() => {\n setIsPickerMode(true);\n }}\n >\n {t('Change variable')}\n </Button>\n ) : <span className=\"inline-block\" />}\n <Button\n type=\"button\"\n variant=\"primary\"\n size=\"sm\"\n className=\"text-[11px]\"\n onClick={handleSaveOptions}\n >\n {t('Save')}\n </Button>\n </div>\n </div>\n )}\n </PopoverContent>\n </Popover>\n ) : (\n <span className=\"block truncate max-w-[220px]\" title={tagTitle}>\n {tagLabel}\n {(transformPreview && !isReadOnly) && (\n <span\n className=\"ml-1 inline-flex items-center rounded bg-white/20 px-1 py-[1px] text-[9px] leading-none text-white/95 align-middle\"\n title={t('Transform: {transform}', { transform: transformPreview })}\n aria-label={t('Transform: {transform}', { transform: transformPreview })}\n >\n {transformPreview}\n </span>\n )}\n {fallbackPreview && !useCornerBadge && (\n <span\n className=\"ml-1 inline-block size-[5px] rounded-full bg-white/75 align-middle\"\n aria-label={t('Has fallback value')}\n />\n )}\n </span>\n )}\n\n <span\n className={cn(\n 'inline-flex items-center justify-center cursor-pointer',\n 'px-1 pr-[5px] py-[4px] self-stretch',\n isReadOnly && 'hidden',\n )}\n onMouseDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n handleDelete();\n }}\n >\n <FontAwesomeIcon icon={faXmark} className=\"size-[10px]\" />\n </span>\n </span>\n\n </NodeViewWrapper>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"VariableTagView.js","names":[],"sources":["../../../src/components/tiptap/VariableTagView.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { NodeViewWrapper } from '@tiptap/react';\nimport { cn } from '@verbb/plugin-kit-react/utils';\nimport { Popover, PopoverContent, PopoverTrigger } from '@verbb/plugin-kit-react/components';\nimport { useTranslation } from '@verbb/plugin-kit-react/hooks';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faXmark } from '@fortawesome/pro-solid-svg-icons';\nimport { Button } from '@verbb/plugin-kit-react/components/Button';\nimport { Input } from '@verbb/plugin-kit-react/components/Input';\nimport type { VariableOption } from './VariableDropdown';\nimport { VariableCommandList } from './VariableCommandList';\nimport { useVariablePickerContext } from './VariablePickerContext';\nimport { VariableTransformControls } from './VariableTransformControls';\nimport { useVariablePicker } from './useVariablePicker';\nimport { buildVariableTagAttrs, getReferenceBaseToken, resolveVariableTagLabel } from './variableSerialization';\nimport { parseTokenWithDefault } from './variableSerialization';\n\ntype VariableMeta = VariableOption & {\n compatibleWith?: string[];\n types?: string[];\n transformValueTypes?: string[];\n allowTransforms?: boolean;\n};\n\nexport default (props) => {\n const t = useTranslation();\n const {\n editor,\n node,\n updateAttributes,\n deleteNode,\n selected: isActive,\n } = props;\n const isReadOnly = !editor?.isEditable || false;\n const openOnInsert = Boolean(node?.attrs?.openOnInsert);\n const [isConfigOpen, setIsConfigOpen] = useState(openOnInsert);\n const [isPickerMode, setIsPickerMode] = useState(false);\n const [defaultIfEmpty, setDefaultIfEmpty] = useState(node?.attrs?.default ?? '');\n const [transformerId, setTransformerId] = useState(node?.attrs?.transformerId ?? '');\n const [transformerParams, setTransformerParams] = useState<Record<string, string>>(() => {\n const raw = node?.attrs?.transformerParams;\n if (!raw || typeof raw !== 'object') {\n return {};\n }\n\n return Object.entries(raw).reduce((acc, [key, value]) => {\n acc[key] = value == null ? '' : String(value);\n return acc;\n }, {} as Record<string, string>);\n });\n const [pendingTokenValue, setPendingTokenValue] = useState(String(node?.attrs?.value ?? ''));\n const pendingTokenValueRef = useRef(String(node?.attrs?.value ?? ''));\n const configureStateRef = useRef(null);\n const prepareSaveRef = useRef(null);\n const onPendingTokenChangeRef = useRef<(token: string) => void>(() => {});\n const originalTagAttrsRef = useRef<Record<string, unknown> | null>(null);\n const [configureSessionKey, setConfigureSessionKey] = useState(0);\n const openOnInsertHandled = useRef(false);\n const popoverContentRef = useRef<HTMLDivElement | null>(null);\n const pickerContext = useVariablePickerContext();\n\n const resolveVariableMetaForToken = useCallback((lookupValue = '') => {\n const [token] = parseTokenWithDefault(String(lookupValue || ''));\n const tokenBase = getReferenceBaseToken(token);\n const groups = Object.values(pickerContext?.variableCategories ?? {});\n\n const visit = (items: VariableOption[]): VariableMeta | null => {\n let fallbackMatch: VariableMeta | null = null;\n\n for (const item of items) {\n const children = Array.isArray(item?.children) ? item.children : [];\n const itemValue = String(item?.value ?? '');\n\n if (itemValue === token) {\n return item as VariableMeta;\n }\n\n if (children.length) {\n const childMatch = visit(children);\n if (childMatch?.value === token) {\n return childMatch;\n }\n\n if (childMatch && !fallbackMatch) {\n fallbackMatch = childMatch;\n }\n }\n\n if (getReferenceBaseToken(itemValue) === tokenBase) {\n if (!fallbackMatch) {\n fallbackMatch = item as VariableMeta;\n }\n }\n }\n\n return fallbackMatch;\n };\n\n for (const groupItems of groups) {\n const match = visit(Array.isArray(groupItems) ? groupItems : []);\n if (match) {\n return match;\n }\n }\n\n return null;\n }, [pickerContext?.variableCategories]);\n\n const selectedVariableMeta = useMemo(() => {\n const lookupValue = isConfigOpen\n ? String(pendingTokenValueRef.current || node?.attrs?.value || '')\n : String(node?.attrs?.value ?? '');\n\n return resolveVariableMetaForToken(lookupValue);\n }, [isConfigOpen, node?.attrs?.value, pendingTokenValue, resolveVariableMetaForToken]);\n\n const transformOptions = useMemo(() => {\n if (selectedVariableMeta?.allowTransforms === false) {\n return [];\n }\n\n const registry = pickerContext?.variableTransformerRegistry ?? {};\n const compatibleWith = Array.isArray(selectedVariableMeta?.compatibleWith)\n ? selectedVariableMeta.compatibleWith\n : [];\n const sourceTypes = Array.isArray(selectedVariableMeta?.types)\n ? selectedVariableMeta.types\n : [];\n\n const allowedTypes = new Set<string>();\n const hasCompatibilityHints = compatibleWith.length > 0;\n const hasExplicitTransformTypes = Object.prototype.hasOwnProperty.call(selectedVariableMeta ?? {}, 'transformValueTypes');\n const explicitTransformTypes = hasExplicitTransformTypes && Array.isArray(selectedVariableMeta?.transformValueTypes)\n ? selectedVariableMeta.transformValueTypes\n : sourceTypes;\n explicitTransformTypes.forEach((type) => {\n if (typeof type === 'string' && type.trim() !== '') {\n allowedTypes.add(type);\n }\n });\n const hasTransformHints = hasCompatibilityHints || hasExplicitTransformTypes || sourceTypes.length > 0;\n if (compatibleWith.includes('plainText') || compatibleWith.includes('email')) {\n allowedTypes.add('text');\n }\n if (compatibleWith.includes('number') || compatibleWith.includes('calculations')) {\n allowedTypes.add('number');\n }\n if (compatibleWith.includes('url')) {\n allowedTypes.add('url');\n }\n if (compatibleWith.includes('date')) {\n allowedTypes.add('date');\n }\n if (compatibleWith.includes('boolean')) {\n allowedTypes.add('boolean');\n }\n if (compatibleWith.includes('array')) {\n allowedTypes.add('array');\n }\n\n if (hasTransformHints && allowedTypes.size === 0) {\n return [];\n }\n\n const byId = new Map();\n\n Object.entries(registry).forEach(([valueType, transformers]) => {\n if (hasTransformHints && allowedTypes.size > 0 && !allowedTypes.has(valueType)) {\n return;\n }\n\n (Array.isArray(transformers) ? transformers : []).forEach((transformer) => {\n const appliesTo = Array.isArray(transformer.appliesTo) && transformer.appliesTo.length\n ? transformer.appliesTo\n : [valueType];\n\n if (hasTransformHints && allowedTypes.size > 0 && !appliesTo.some((type) => {\n return allowedTypes.has(type);\n })) {\n return;\n }\n\n if (!byId.has(transformer.id)) {\n byId.set(transformer.id, {\n value: transformer.id,\n label: transformer.label,\n description: transformer.description,\n params: Array.isArray(transformer.params) ? transformer.params : [],\n appliesTo,\n });\n }\n });\n });\n\n return Array.from(byId.values());\n }, [pickerContext?.variableTransformerRegistry, selectedVariableMeta]);\n\n const selectedTransformer = useMemo(() => {\n return transformOptions.find((option) => {\n return option.value === transformerId;\n }) ?? null;\n }, [transformOptions, transformerId]);\n const hasIncompatibleTransformerSelection = useMemo(() => {\n const current = transformerId.trim();\n return current !== '' && !selectedTransformer;\n }, [transformerId, selectedTransformer]);\n\n const initialPage = useMemo((): VariableOption | null => {\n const currentValue = node?.attrs?.value;\n if (!currentValue || !pickerContext?.variableCategories) {\n return null;\n }\n const findParentWithChild = (items: VariableOption[]): VariableOption | null => {\n for (const item of items) {\n const children = Array.isArray(item?.children) ? item.children : [];\n if (children.some((c) => {\n return c?.value === currentValue;\n })) {\n return item;\n }\n const nested = findParentWithChild(children);\n if (nested) {\n return nested;\n }\n }\n return null;\n };\n const allItems = Object.values(pickerContext.variableCategories).flatMap((items) => {\n return items ?? [];\n });\n return findParentWithChild(allItems);\n }, [node?.attrs?.value, pickerContext?.variableCategories]);\n\n const picker = useVariablePicker({\n variableCategories: pickerContext?.variableCategories ?? {},\n variableCategoryLabels: pickerContext?.variableCategoryLabels,\n variableCategoryOrder: pickerContext?.variableCategoryOrder,\n isOpen: isConfigOpen,\n initialPage,\n getDefaultIfEmpty: () => {\n return defaultIfEmpty;\n },\n onApply: (baseVariable, variable, defaultText) => {\n const attrs = buildVariableTagAttrs(baseVariable, variable, {\n defaultIfEmpty: defaultText,\n });\n updateAttributes?.(attrs);\n setDefaultIfEmpty('');\n setTransformerId('');\n setTransformerParams({});\n setIsConfigOpen(false);\n setIsPickerMode(false);\n picker.reset();\n },\n });\n\n const hasFullPicker = pickerContext && Object.values(pickerContext.variableCategories ?? {}).some((items) => {\n return Array.isArray(items) && items.length > 0;\n });\n\n const isConfigurable = !isReadOnly;\n const canChangeVariable = !!hasFullPicker;\n\n useEffect(() => {\n if (!openOnInsert) {\n return;\n }\n openOnInsertHandled.current = false;\n }, [openOnInsert]);\n\n useEffect(() => {\n if (!openOnInsert || openOnInsertHandled.current) {\n return;\n }\n openOnInsertHandled.current = true;\n originalTagAttrsRef.current = {\n value: node?.attrs?.value ?? null,\n label: node?.attrs?.label ?? null,\n default: node?.attrs?.default ?? null,\n transformerId: node?.attrs?.transformerId ?? null,\n transformerParams: node?.attrs?.transformerParams ?? null,\n };\n setIsConfigOpen(true);\n queueMicrotask(() => {\n updateAttributes?.({ openOnInsert: false });\n });\n }, [\n node?.attrs?.default,\n node?.attrs?.label,\n node?.attrs?.transformerId,\n node?.attrs?.transformerParams,\n node?.attrs?.value,\n openOnInsert,\n updateAttributes,\n ]);\n\n const handleDelete = () => {\n if (!isReadOnly) {\n deleteNode();\n }\n };\n\n const commitPendingToken = useCallback((nextToken: string) => {\n const normalizedToken = String(nextToken || '');\n const meta = resolveVariableMetaForToken(normalizedToken);\n const defaultLabel = resolveVariableTagLabel(normalizedToken, meta);\n const label = pickerContext?.resolveVariableTagLabel?.({\n tokenValue: normalizedToken,\n variableOption: meta,\n defaultLabel,\n storedLabel: String(node?.attrs?.label ?? ''),\n }) || defaultLabel;\n\n pendingTokenValueRef.current = normalizedToken;\n setPendingTokenValue(normalizedToken);\n\n updateAttributes?.({\n value: normalizedToken,\n label,\n default: node?.attrs?.default ?? null,\n transformerId: node?.attrs?.transformerId ?? null,\n transformerParams: node?.attrs?.transformerParams ?? null,\n });\n }, [\n node?.attrs?.default,\n node?.attrs?.label,\n node?.attrs?.transformerId,\n node?.attrs?.transformerParams,\n pickerContext,\n resolveVariableMetaForToken,\n updateAttributes,\n ]);\n\n function closeConfig(preservedValue: string | null = null) {\n const nextValue = preservedValue != null\n ? String(preservedValue)\n : String(node?.attrs?.value ?? '');\n\n pendingTokenValueRef.current = nextValue;\n setPendingTokenValue(nextValue);\n\n if (preservedValue == null && originalTagAttrsRef.current) {\n updateAttributes?.(originalTagAttrsRef.current);\n }\n\n originalTagAttrsRef.current = null;\n setIsConfigOpen(false);\n setIsPickerMode(false);\n picker.reset();\n }\n\n const exitPickerMode = useCallback(() => {\n setIsPickerMode(false);\n }, []);\n\n const handleOpenConfig = useCallback(() => {\n if (!isConfigurable) {\n return;\n }\n\n const attrValue = String(node?.attrs?.value ?? '');\n const nextValue = attrValue;\n originalTagAttrsRef.current = {\n value: node?.attrs?.value ?? null,\n label: node?.attrs?.label ?? null,\n default: node?.attrs?.default ?? null,\n transformerId: node?.attrs?.transformerId ?? null,\n transformerParams: node?.attrs?.transformerParams ?? null,\n };\n pendingTokenValueRef.current = nextValue;\n setPendingTokenValue(nextValue);\n setConfigureSessionKey((current) => current + 1);\n setIsConfigOpen(true);\n }, [\n isConfigurable,\n node?.attrs?.default,\n node?.attrs?.label,\n node?.attrs?.transformerId,\n node?.attrs?.transformerParams,\n node?.attrs?.value,\n ]);\n\n useEffect(() => {\n const editorDom = editor?.view?.dom;\n\n if (!editorDom || !isActive || !isConfigurable) {\n return;\n }\n\n const handleEditorKeyDown = (event: KeyboardEvent) => {\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey) {\n return;\n }\n\n const target = event.target as HTMLElement | null;\n const tagName = target?.tagName;\n const isFocusableInput = tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT';\n\n if (isFocusableInput) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ' || event.key === 'Spacebar') {\n event.preventDefault();\n event.stopPropagation();\n handleOpenConfig();\n }\n };\n\n editorDom.addEventListener('keydown', handleEditorKeyDown, true);\n\n return () => {\n editorDom.removeEventListener('keydown', handleEditorKeyDown, true);\n };\n }, [editor, isActive, isConfigurable, handleOpenConfig]);\n\n const handleSaveOptions = () => {\n prepareSaveRef.current?.();\n\n const trimmedDefault = defaultIfEmpty.trim();\n const trimmedTransformerId = transformerId.trim();\n const normalizedParams = trimmedTransformerId\n ? Object.entries(transformerParams).reduce((acc, [key, value]) => {\n const trimmed = String(value ?? '').trim();\n if (trimmed !== '') {\n acc[key] = trimmed;\n }\n return acc;\n }, {} as Record<string, string>)\n : null;\n const savedValue = pendingTokenValueRef.current || String(node?.attrs?.value ?? '');\n const savedMeta = resolveVariableMetaForToken(savedValue);\n const defaultSavedLabel = resolveVariableTagLabel(savedValue, savedMeta);\n const savedLabel = pickerContext?.resolveVariableTagLabel?.({\n tokenValue: savedValue,\n variableOption: savedMeta,\n defaultLabel: defaultSavedLabel,\n storedLabel: String(node?.attrs?.label ?? ''),\n }) || defaultSavedLabel;\n\n updateAttributes?.({\n value: savedValue,\n label: savedLabel,\n default: trimmedDefault || null,\n transformerId: trimmedTransformerId || null,\n transformerParams: trimmedTransformerId ? normalizedParams : null,\n });\n closeConfig(savedValue);\n };\n\n const handleConfigOpenChange = (nextOpen: boolean) => {\n if (nextOpen) {\n setIsConfigOpen(true);\n setIsPickerMode(false);\n return;\n }\n\n closeConfig();\n };\n\n const handleTagKeyDown = (event) => {\n if (!isConfigurable) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n event.stopPropagation();\n handleOpenConfig();\n }\n };\n\n useEffect(() => {\n if (!isConfigOpen) {\n return;\n }\n\n setDefaultIfEmpty(node?.attrs?.default ?? '');\n setTransformerId(node?.attrs?.transformerId ?? '');\n const raw = node?.attrs?.transformerParams;\n if (raw && typeof raw === 'object') {\n setTransformerParams(Object.entries(raw).reduce((acc, [key, value]) => {\n acc[key] = value == null ? '' : String(value);\n return acc;\n }, {} as Record<string, string>));\n } else {\n setTransformerParams({});\n }\n }, [isConfigOpen, node?.attrs?.default, node?.attrs?.transformerId, node?.attrs?.transformerParams]);\n\n useEffect(() => {\n if (!selectedTransformer) {\n return;\n }\n\n setTransformerParams((current) => {\n const next = { ...current };\n (selectedTransformer.params ?? []).forEach((param) => {\n if (next[param.name] == null || next[param.name] === '') {\n next[param.name] = param.default == null ? '' : String(param.default);\n }\n });\n\n return next;\n });\n }, [selectedTransformer]);\n\n useEffect(() => {\n if (!isConfigOpen || !isPickerMode) {\n return;\n }\n\n let frame = 0;\n let cancelled = false;\n\n const focusSearch = (attempt = 0) => {\n if (cancelled) {\n return;\n }\n\n const input = popoverContentRef.current?.querySelector<HTMLInputElement>('[data-slot=\"command-input\"]');\n\n if (input) {\n input.focus();\n return;\n }\n\n if (attempt < 8) {\n frame = requestAnimationFrame(() => {\n focusSearch(attempt + 1);\n });\n }\n };\n\n focusSearch();\n\n return () => {\n cancelled = true;\n\n if (frame) {\n cancelAnimationFrame(frame);\n }\n };\n }, [isConfigOpen, isPickerMode]);\n\n const fallbackPreview = String(props.node?.attrs?.default ?? '').trim();\n const appliedTransformerId = String(props.node?.attrs?.transformerId ?? '').trim();\n const appliedTransformer = transformOptions.find((option) => {\n return option.value === appliedTransformerId;\n }) ?? null;\n let transformPreview = '';\n if (appliedTransformer?.label) {\n transformPreview = appliedTransformer.label;\n } else if (appliedTransformerId) {\n transformPreview = appliedTransformerId;\n }\n const tokenValue = String(\n isConfigOpen\n ? (pendingTokenValueRef.current || pendingTokenValue || node?.attrs?.value || '')\n : (node?.attrs?.value || pendingTokenValue || ''),\n );\n const tagLabel = useMemo(() => {\n const resolvedMeta = selectedVariableMeta || resolveVariableMetaForToken(tokenValue);\n const defaultLabel = resolveVariableTagLabel(tokenValue, resolvedMeta);\n\n return pickerContext?.resolveVariableTagLabel?.({\n tokenValue,\n variableOption: resolvedMeta,\n defaultLabel,\n storedLabel: String(node?.attrs?.label ?? ''),\n }) || defaultLabel;\n }, [node?.attrs?.label, pickerContext, resolveVariableMetaForToken, selectedVariableMeta, tokenValue]);\n const tagTitle = tagLabel;\n const configureResetKey = isConfigOpen ? String(configureSessionKey) : 'closed';\n\n onPendingTokenChangeRef.current = commitPendingToken;\n\n const configureSection = pickerContext?.renderVariableConfigureSection?.({\n tokenValue,\n variableOption: selectedVariableMeta,\n configureResetKey,\n configureStateRef,\n prepareSaveRef,\n getPendingTokenValue: () => pendingTokenValueRef.current || String(node?.attrs?.value ?? ''),\n onPendingTokenChange: (nextToken) => {\n onPendingTokenChangeRef.current(nextToken);\n },\n });\n const useCornerBadge = true;\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={cn(\n 'relative inline-block leading-none mx-[1px] cursor-default',\n )}\n tabIndex={isConfigurable ? 0 : undefined}\n onKeyDown={handleTagKeyDown}\n data-drag-handle\n data-variable-value={tokenValue}\n >\n <span className={cn(\n 'relative inline-flex items-stretch whitespace-nowrap gap-0 overflow-hidden',\n '-mt-[3px] text-[11px] font-normal! leading-none align-middle',\n 'bg-[#5C6BC0] text-white rounded-[2px]',\n\n isReadOnly && 'inline-flex flex-1 px-[5px] py-[4px]',\n\n isActive && !isReadOnly && 'outline-none shadow-[0_0_0_2px_rgba(123,140,232,0.5)]',\n\n isReadOnly && isActive && 'shadow-none',\n )}>\n {fallbackPreview && useCornerBadge && (\n <span\n className=\"pointer-events-none absolute top-0 left-0 h-0 w-0 border-t-[8px] border-r-[8px] border-t-orange-400 border-r-transparent\"\n aria-label={t('Has fallback value')}\n />\n )}\n {isConfigurable ? (\n <Popover open={isConfigOpen} onOpenChange={handleConfigOpenChange}>\n <PopoverTrigger\n render={\n <button\n type=\"button\"\n className=\"inline-flex flex-1 min-w-0 self-stretch items-center cursor-pointer bg-transparent border-0 px-[5px] py-[4px] m-0 text-left text-inherit focus:outline-none\"\n title={tagTitle}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n handleOpenConfig();\n }}\n >\n <span className=\"block truncate max-w-[220px]\">\n {tagLabel}\n {(transformPreview) && (\n <span\n className=\"ml-1 inline-flex items-center rounded bg-white/20 px-1 py-[1px] text-[9px] leading-none text-white/95 align-middle\"\n title={t('Transform: {transform}', { transform: transformPreview })}\n aria-label={t('Transform: {transform}', { transform: transformPreview })}\n >\n {transformPreview}\n </span>\n )}\n {fallbackPreview && !useCornerBadge && (\n <span\n className=\"ml-1 inline-block size-[5px] rounded-full bg-white/75 align-middle\"\n aria-label={t('Has fallback value')}\n />\n )}\n </span>\n </button>\n }\n />\n\n <PopoverContent\n ref={popoverContentRef}\n data-variable-config-popover=\"\"\n align=\"start\"\n side=\"bottom\"\n sideOffset={6}\n className={hasFullPicker ? 'min-w-[260px] max-w-[360px] p-0' : 'w-[260px] p-0'}\n onMouseDown={(event) => {\n const target = event.target as HTMLElement | null;\n const tagName = target?.tagName;\n const isFocusableInput = tagName === 'INPUT' || tagName === 'TEXTAREA' || tagName === 'SELECT';\n const isSelectControl = Boolean(target?.closest('[data-slot=\"select-trigger\"]'));\n\n // Keep editor selection stable for picker clicks, but allow typing in fallback input.\n if (isFocusableInput || isSelectControl) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n }}\n >\n {isPickerMode ? (\n canChangeVariable && (\n <VariableCommandList\n search={picker.search}\n onSearchChange={picker.setSearch}\n groups={picker.groups}\n options={picker.options}\n selectedValue={node?.attrs?.value}\n onSelect={picker.handleSelect}\n placeholder={t('Search variables')}\n showSearch\n shouldFilter={false}\n onBack={picker.page ? picker.handleBack : exitPickerMode}\n isChildMode={!!picker.page}\n />\n )\n ) : (\n <div className=\"p-2\">\n {configureSection}\n <label className=\"text-[11px] text-gray-500 block mb-1\">\n {t('Default if empty (optional)')}\n </label>\n <Input\n type=\"text\"\n value={defaultIfEmpty}\n onChange={(event) => {\n setDefaultIfEmpty(event.target.value);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n handleSaveOptions();\n }\n }}\n />\n <VariableTransformControls\n transformerId={transformerId}\n onTransformerIdChange={(nextId) => {\n setTransformerId(nextId);\n if (!nextId) {\n setTransformerParams({});\n }\n }}\n transformOptions={transformOptions}\n hasIncompatibleTransformerSelection={hasIncompatibleTransformerSelection}\n selectedTransformer={selectedTransformer}\n transformerParams={transformerParams}\n onTransformerParamChange={(paramName, nextValue) => {\n setTransformerParams((current) => {\n return {\n ...current,\n [paramName]: nextValue,\n };\n });\n }}\n />\n <div className=\"mt-3 -mx-2 -mb-2 border-t border-slate-200 bg-[#f3f7fd] px-2 py-2 flex items-center justify-between gap-2\">\n {canChangeVariable ? (\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"sm\"\n className=\"text-[11px]\"\n onClick={() => {\n setIsPickerMode(true);\n }}\n >\n {t('Change variable')}\n </Button>\n ) : <span className=\"inline-block\" />}\n <Button\n type=\"button\"\n variant=\"primary\"\n size=\"sm\"\n className=\"text-[11px]\"\n onClick={handleSaveOptions}\n >\n {t('Save')}\n </Button>\n </div>\n </div>\n )}\n </PopoverContent>\n </Popover>\n ) : (\n <span className=\"block truncate max-w-[220px]\" title={tagTitle}>\n {tagLabel}\n {(transformPreview && !isReadOnly) && (\n <span\n className=\"ml-1 inline-flex items-center rounded bg-white/20 px-1 py-[1px] text-[9px] leading-none text-white/95 align-middle\"\n title={t('Transform: {transform}', { transform: transformPreview })}\n aria-label={t('Transform: {transform}', { transform: transformPreview })}\n >\n {transformPreview}\n </span>\n )}\n {fallbackPreview && !useCornerBadge && (\n <span\n className=\"ml-1 inline-block size-[5px] rounded-full bg-white/75 align-middle\"\n aria-label={t('Has fallback value')}\n />\n )}\n </span>\n )}\n\n <span\n className={cn(\n 'inline-flex items-center justify-center cursor-pointer',\n 'px-1 pr-[5px] py-[4px] self-stretch',\n isReadOnly && 'hidden',\n )}\n onMouseDown={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n handleDelete();\n }}\n >\n <FontAwesomeIcon icon={faXmark} className=\"size-[10px]\" />\n </span>\n </span>\n\n </NodeViewWrapper>\n );\n};\n"],"mappings":"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"}
@@ -22,12 +22,16 @@ export declare function buildVariableTagAttrs(baseVariable: VariableOption, sele
22
22
  defaultIfEmpty?: string;
23
23
  transformerId?: string;
24
24
  transformerParams?: Record<string, unknown>;
25
+ label?: string;
26
+ value?: string;
25
27
  }): VariableTagAttrs;
26
28
  /**
27
29
  * Strip optional inline default from token for lookup: {user:firstName|Guest} -> {user:firstName}.
28
30
  * Returns [tokenWithoutDefault, defaultText].
29
31
  */
30
32
  export declare function parseTokenWithDefault(tokenValue: string): [string, string | undefined];
33
+ export declare function getReferenceBaseToken(tokenValue: string): string;
34
+ export declare function resolveVariableTagLabel(tokenValue: string, option: VariableOption | null): string;
31
35
  /**
32
36
  * Resolve variable tag attrs from a token string (e.g. '{form:name}' or '{user:firstName|Guest}').
33
37
  */
@@ -1 +1 @@
1
- {"version":3,"file":"variableSerialization.d.ts","sourceRoot":"","sources":["../../../src/components/tiptap/variableSerialization.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,MAAM,gBAAgB,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/C,CAAC;AA6IF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAe/E;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAehF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACjC,YAAY,EAAE,cAAc,EAC5B,gBAAgB,GAAE,cAA6B,EAC/C,OAAO,GAAE;IACL,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C,GACP,gBAAgB,CAoBlB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAGtF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACrC,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,cAAc,EAAE,EACnC,YAAY,EAAE,cAAc,EAAE,GAC/B,gBAAgB,GAAG,IAAI,CA0DzB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC1B,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,cAAc,EAAE,EACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,kBAAkB,SAAW,GAC9B,WAAW,GAAG,IAAI,CA0BpB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CA4CvD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACX,IAAI,CAqBN"}
1
+ {"version":3,"file":"variableSerialization.d.ts","sourceRoot":"","sources":["../../../src/components/tiptap/variableSerialization.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,MAAM,gBAAgB,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/C,CAAC;AAsKF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAe/E;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAehF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACjC,YAAY,EAAE,cAAc,EAC5B,gBAAgB,GAAE,cAA6B,EAC/C,OAAO,GAAE;IACL,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CACb,GACP,gBAAgB,CAoBlB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAGtF;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAWhE;AAcD,wBAAgB,uBAAuB,CACnC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,GAAG,IAAI,GAC9B,MAAM,CAQR;AAoCD;;GAEG;AACH,wBAAgB,yBAAyB,CACrC,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,cAAc,EAAE,EACnC,YAAY,EAAE,cAAc,EAAE,GAC/B,gBAAgB,GAAG,IAAI,CA6CzB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC1B,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,cAAc,EAAE,EACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,kBAAkB,SAAW,GAC9B,WAAW,GAAG,IAAI,CA0BpB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CA4CvD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,gBAAgB,EACvB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACX,IAAI,CAqBN"}