@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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.2 - 2026-06-07
4
+
5
+ ### Added
6
+ - Added `modifyRow` to `EditableTable`, a row-level companion to `modifyColumn`. Host apps can return optional `cellClassName` and `title` values based on row data; these are applied to all data cells in the row and the actions cell when present.
7
+ - Added support for `cellClassName` and `title` return values from `modifyColumn`, applied to individual table cell wrappers alongside existing column overrides.
8
+
9
+ ## 1.0.1 - 2026-06-07
10
+
11
+ ### Added
12
+ - Added variable tag extension points for custom configure sections and label resolution.
13
+ - Added support for preserving custom reference metadata in variable tokens.
14
+ - Added support for resolving scoped variable token variants against their base variable option.
15
+
16
+ ### Changed
17
+ - Improved Tiptap variable tag configuration so pending token changes preview immediately and are reverted when the popover is dismissed without saving.
18
+ - Kept variable token parsing generic so host applications can define their own reference semantics without plugin-kit knowing about them.
19
+
20
+ ### Fixed
21
+ - Fixed variable tags showing raw token values instead of matched option labels in some reference-token cases.
22
+ - Fixed configured variable tags losing reference metadata when saved with fallback values or transforms.
23
+
3
24
  ## 1.0.0
4
25
 
5
26
  - Initial public release.
@@ -1,5 +1,6 @@
1
1
  import { default as React } from 'react';
2
- import { EditableTableColumn, EditableTableModifyColumn, EditableTableOnCellChange, EditableTableRow, EditableTableRowActionArgs } from './editable-table/types';
2
+ import { EditableTableColumn, EditableTableModifyColumn, EditableTableModifyRow, EditableTableOnCellChange, EditableTableRow, EditableTableRowActionArgs } from './editable-table/types';
3
+ export type { EditableTableColumn, EditableTableModifyColumn, EditableTableModifyColumnResult, EditableTableModifyRow, EditableTableOnCellChange, EditableTableRow, EditableTableRowActionArgs, } from './editable-table/types';
3
4
  export type EditableTableProps = {
4
5
  columns: EditableTableColumn[];
5
6
  rows: EditableTableRow[];
@@ -11,6 +12,7 @@ export type EditableTableProps = {
11
12
  allowDelete?: boolean;
12
13
  className?: string;
13
14
  modifyColumn?: EditableTableModifyColumn;
15
+ modifyRow?: EditableTableModifyRow;
14
16
  fieldName?: string;
15
17
  cellErrors?: Record<string, unknown>;
16
18
  newRowDefaults?: Record<string, unknown>;
@@ -24,5 +26,5 @@ export type EditableTableProps = {
24
26
  renderRowMenuItemsAfterCore?: (args: EditableTableRowActionArgs) => React.ReactNode;
25
27
  renderRowMenuItems?: (args: EditableTableRowActionArgs) => React.ReactNode;
26
28
  };
27
- export declare function EditableTable({ columns, rows, onChange, onCellChange, addRowLabel, allowReorder, allowAdd, allowDelete, className, modifyColumn, fieldName, cellErrors, newRowDefaults, renderActions, renderRowActions, renderRowMenuItemsBeforeCore, renderRowMenuItemsAfterCore, renderRowMenuItems, }: EditableTableProps): import("react/jsx-runtime").JSX.Element;
29
+ export declare function EditableTable({ columns, rows, onChange, onCellChange, addRowLabel, allowReorder, allowAdd, allowDelete, className, modifyColumn, modifyRow, fieldName, cellErrors, newRowDefaults, renderActions, renderRowActions, renderRowMenuItemsBeforeCore, renderRowMenuItemsAfterCore, renderRowMenuItems, }: EditableTableProps): import("react/jsx-runtime").JSX.Element;
28
30
  //# sourceMappingURL=EditableTable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EditableTable.d.ts","sourceRoot":"","sources":["../../src/components/EditableTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+B,MAAM,OAAO,CAAC;AAoBpD,OAAO,KAAK,EACR,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,0BAA0B,EAC7B,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,kBAAkB,GAAG;IAC7B,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,QAAQ,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,yBAAyB,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,yBAAyB,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAC;IACjH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,KAAK,CAAC,SAAS,CAAC;IACzE,4BAA4B,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,KAAK,CAAC,SAAS,CAAC;IACrF,2BAA2B,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,KAAK,CAAC,SAAS,CAAC;IACpF,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,KAAK,CAAC,SAAS,CAAC;CAC9E,CAAC;AAwBF,wBAAgB,aAAa,CAAC,EAC1B,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,YAAwB,EACxB,WAAW,EACX,YAAmB,EACnB,QAAe,EACf,WAAkB,EAClB,SAAc,EACd,YAAwB,EACxB,SAAqB,EACrB,UAAe,EACf,cAAmB,EACnB,aAAyB,EACzB,gBAA4B,EAC5B,4BAAwC,EACxC,2BAAuC,EACvC,kBAA8B,GACjC,EAAE,kBAAkB,2CA8KpB"}
1
+ {"version":3,"file":"EditableTable.d.ts","sourceRoot":"","sources":["../../src/components/EditableTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+B,MAAM,OAAO,CAAC;AAoBpD,OAAO,KAAK,EACR,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,yBAAyB,EACzB,gBAAgB,EAChB,0BAA0B,EAC7B,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACR,mBAAmB,EACnB,yBAAyB,EACzB,+BAA+B,EAC/B,sBAAsB,EACtB,yBAAyB,EACzB,gBAAgB,EAChB,0BAA0B,GAC7B,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,kBAAkB,GAAG;IAC7B,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,QAAQ,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,yBAAyB,CAAC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,yBAAyB,CAAC;IACzC,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAC;IACjH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,KAAK,CAAC,SAAS,CAAC;IACzE,4BAA4B,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,KAAK,CAAC,SAAS,CAAC;IACrF,2BAA2B,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,KAAK,CAAC,SAAS,CAAC;IACpF,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,KAAK,CAAC,SAAS,CAAC;CAC9E,CAAC;AAyBF,wBAAgB,aAAa,CAAC,EAC1B,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,YAAwB,EACxB,WAAW,EACX,YAAmB,EACnB,QAAe,EACf,WAAkB,EAClB,SAAc,EACd,YAAwB,EACxB,SAAqB,EACrB,SAAqB,EACrB,UAAe,EACf,cAAmB,EACnB,aAAyB,EACzB,gBAA4B,EAC5B,4BAAwC,EACxC,2BAAuC,EACvC,kBAA8B,GACjC,EAAE,kBAAkB,2CA+KpB"}
@@ -17,7 +17,7 @@ import { faPlus } from "@fortawesome/pro-solid-svg-icons";
17
17
  import { DragDropProvider } from "@dnd-kit/react";
18
18
  import { AutoScroller } from "@dnd-kit/dom";
19
19
  //#region src/components/EditableTable.tsx
20
- function EditableTable({ columns, rows, onChange, onCellChange = void 0, addRowLabel, allowReorder = true, allowAdd = true, allowDelete = true, className = "", modifyColumn = void 0, fieldName = void 0, cellErrors = {}, newRowDefaults = {}, renderActions = void 0, renderRowActions = void 0, renderRowMenuItemsBeforeCore = void 0, renderRowMenuItemsAfterCore = void 0, renderRowMenuItems = void 0 }) {
20
+ function EditableTable({ columns, rows, onChange, onCellChange = void 0, addRowLabel, allowReorder = true, allowAdd = true, allowDelete = true, className = "", modifyColumn = void 0, modifyRow = void 0, fieldName = void 0, cellErrors = {}, newRowDefaults = {}, renderActions = void 0, renderRowActions = void 0, renderRowMenuItemsBeforeCore = void 0, renderRowMenuItemsAfterCore = void 0, renderRowMenuItems = void 0 }) {
21
21
  const TableRowComponent = TableRow;
22
22
  const t = useTranslation();
23
23
  const normalizedColumns = useMemo(() => {
@@ -114,6 +114,7 @@ function EditableTable({ columns, rows, onChange, onCellChange = void 0, addRowL
114
114
  showReorderControls: allowReorder,
115
115
  allowDelete,
116
116
  modifyColumn,
117
+ modifyRow,
117
118
  getCellErrors,
118
119
  onUpdateCell: handleCellValueChange,
119
120
  moveRow,
@@ -1 +1 @@
1
- {"version":3,"file":"EditableTable.js","names":[],"sources":["../../src/components/EditableTable.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from 'react';\nimport { DragDropProvider } from '@dnd-kit/react';\nimport { AutoScroller } from '@dnd-kit/dom';\nimport {\n Button,\n Table,\n TableHeader,\n TableBody,\n TableRow as UITableRow,\n TableHead,\n} from '@verbb/plugin-kit-react/components';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faPlus } from '@fortawesome/pro-solid-svg-icons';\nimport { useTranslation } from '@verbb/plugin-kit-react/hooks';\nimport { cn } from '@verbb/plugin-kit-react/utils';\nimport { TableRow } from './editable-table/TableRow';\nimport { isGeneratedColumn, isThinColumn } from './editable-table/helpers';\nimport { useEditableTableRows } from './editable-table/useEditableTableRows';\nimport { useEditableTableDnd } from './editable-table/useEditableTableDnd';\nimport { useEditableTableCellChange } from './editable-table/useEditableTableCellChange';\nimport type {\n EditableTableColumn,\n EditableTableModifyColumn,\n EditableTableOnCellChange,\n EditableTableRow,\n EditableTableRowActionArgs,\n} from './editable-table/types';\n\nexport type EditableTableProps = {\n columns: EditableTableColumn[];\n rows: EditableTableRow[];\n onChange: (rows: EditableTableRow[]) => void;\n onCellChange?: EditableTableOnCellChange;\n addRowLabel?: string;\n allowReorder?: boolean;\n allowAdd?: boolean;\n allowDelete?: boolean;\n className?: string;\n modifyColumn?: EditableTableModifyColumn;\n fieldName?: string;\n cellErrors?: Record<string, unknown>;\n newRowDefaults?: Record<string, unknown>;\n renderActions?: (args: { rows: EditableTableRow[]; addRow: () => void; isDragging: boolean }) => React.ReactNode;\n renderRowActions?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItemsBeforeCore?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItemsAfterCore?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItems?: (args: EditableTableRowActionArgs) => React.ReactNode;\n};\n\ntype TableRowComponentProps = {\n row: EditableTableRow;\n rowIndex: number;\n rowCount: number;\n columns: EditableTableColumn[];\n columnsSignature: string;\n useDnd: boolean;\n allowReorder: boolean;\n showReorderControls: boolean;\n allowDelete: boolean;\n modifyColumn?: EditableTableModifyColumn;\n getCellErrors: (rowIndex: number, columnName: string) => unknown[];\n onUpdateCell: (rowIndex: number, row: EditableTableRow, column: EditableTableColumn, newValue: unknown) => void;\n moveRow: (row: EditableTableRow, direction: number) => void;\n removeRow: (row: EditableTableRow) => void;\n t: (key: string) => string;\n renderRowActions?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItemsBeforeCore?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItemsAfterCore?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItems?: (args: EditableTableRowActionArgs) => React.ReactNode;\n};\n\nexport function EditableTable({\n columns,\n rows,\n onChange,\n onCellChange = undefined,\n addRowLabel,\n allowReorder = true,\n allowAdd = true,\n allowDelete = true,\n className = '',\n modifyColumn = undefined,\n fieldName = undefined,\n cellErrors = {},\n newRowDefaults = {},\n renderActions = undefined,\n renderRowActions = undefined,\n renderRowMenuItemsBeforeCore = undefined,\n renderRowMenuItemsAfterCore = undefined,\n renderRowMenuItems = undefined,\n}: EditableTableProps) {\n const TableRowComponent = TableRow as React.ComponentType<TableRowComponentProps>;\n const t = useTranslation();\n const normalizedColumns = useMemo(() => {\n const sourceColumns = Array.isArray(columns) ? columns : [];\n const validColumns = sourceColumns.filter((column) => {\n return typeof column?.name === 'string' && column.name.trim() !== '';\n });\n\n if (validColumns.length !== sourceColumns.length) {\n const invalidColumns = sourceColumns.filter((column) => {\n return !(typeof column?.name === 'string' && column.name.trim() !== '');\n });\n\n console.error(\n 'EditableTable: column definitions must include a non-empty `name`.',\n { invalidColumns, columns: sourceColumns },\n );\n }\n\n return validColumns;\n }, [columns]);\n\n const generatedColumns = useMemo(() => {\n return normalizedColumns.filter(isGeneratedColumn);\n }, [normalizedColumns]);\n\n const columnsSignature = useMemo(() => {\n return JSON.stringify(normalizedColumns.map((column) => {\n return {\n name: column.name,\n type: column.type,\n label: column.label,\n required: column.required,\n placeholder: column.placeholder,\n options: column.options,\n };\n }));\n }, [normalizedColumns]);\n\n const {\n internalData,\n setInternalData,\n internalDataRef,\n skipNextRowsSyncRef,\n handleChange,\n addRow,\n removeRow,\n updateRow,\n moveRow,\n } = useEditableTableRows({\n rows,\n onChange,\n newRowDefaults,\n });\n\n const {\n isDragging,\n isDndHydrated,\n effectiveAllowReorder,\n handleDragStart,\n handleDragEnd,\n } = useEditableTableDnd({\n allowReorder,\n internalData,\n handleChange,\n });\n\n const {\n handleCellValueChange,\n } = useEditableTableCellChange({\n internalData,\n internalDataRef,\n setInternalData,\n skipNextRowsSyncRef,\n generatedColumns,\n onCellChange,\n updateRow,\n handleChange,\n });\n\n const getCellErrors = useCallback((rowIndex: number, columnName: string) => {\n if (!fieldName) {\n return [];\n }\n\n const key = `${fieldName}.${rowIndex}.${columnName}`;\n const errors = cellErrors?.[key];\n if (!errors) {\n return [];\n }\n\n return Array.isArray(errors) ? errors : [errors];\n }, [cellErrors, fieldName]);\n\n const actions = typeof renderActions === 'function'\n ? renderActions({\n rows: internalData,\n addRow,\n isDragging,\n })\n : null;\n\n const dragDropPlugins = useCallback((defaults) => {\n return defaults.filter((plugin) => { return plugin !== AutoScroller; });\n }, []);\n\n return (\n <div className={className}>\n {actions}\n\n <DragDropProvider\n plugins={dragDropPlugins}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n >\n <Table>\n <TableHeader>\n <UITableRow>\n {normalizedColumns.map((column) => {\n return (\n <TableHead key={column.name} className={cn(column.className, isThinColumn(column) && 'w-[1%] whitespace-nowrap')}>\n {column.label}\n {column.required && <span className=\"text-error ml-1\">*</span>}\n </TableHead>\n );\n })}\n {(allowReorder || allowDelete) && <TableHead className=\"p-0 w-0\"></TableHead>}\n </UITableRow>\n </TableHeader>\n <TableBody>\n {internalData.map((row, rowIndex) => {\n return (\n <TableRowComponent\n key={row._id}\n row={row}\n rowIndex={rowIndex}\n rowCount={internalData.length}\n columns={normalizedColumns}\n columnsSignature={columnsSignature}\n useDnd={allowReorder && isDndHydrated}\n allowReorder={effectiveAllowReorder && isDndHydrated}\n showReorderControls={allowReorder}\n allowDelete={allowDelete}\n modifyColumn={modifyColumn}\n getCellErrors={getCellErrors}\n onUpdateCell={handleCellValueChange}\n moveRow={moveRow}\n removeRow={removeRow}\n t={t}\n renderRowActions={renderRowActions}\n renderRowMenuItemsBeforeCore={renderRowMenuItemsBeforeCore}\n renderRowMenuItemsAfterCore={renderRowMenuItemsAfterCore}\n renderRowMenuItems={renderRowMenuItems}\n />\n );\n })}\n </TableBody>\n </Table>\n </DragDropProvider>\n\n {allowAdd && (\n <Button\n type=\"button\"\n variant=\"dashed\"\n onClick={addRow}\n className={cn('w-full rounded-t-none! border-t-0!', isDragging && 'pointer-events-none')}\n >\n <FontAwesomeIcon icon={faPlus} className=\"size-3 mr-1\" />\n {addRowLabel || t('Add row')}\n </Button>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EditableTable.js","names":[],"sources":["../../src/components/EditableTable.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from 'react';\nimport { DragDropProvider } from '@dnd-kit/react';\nimport { AutoScroller } from '@dnd-kit/dom';\nimport {\n Button,\n Table,\n TableHeader,\n TableBody,\n TableRow as UITableRow,\n TableHead,\n} from '@verbb/plugin-kit-react/components';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faPlus } from '@fortawesome/pro-solid-svg-icons';\nimport { useTranslation } from '@verbb/plugin-kit-react/hooks';\nimport { cn } from '@verbb/plugin-kit-react/utils';\nimport { TableRow } from './editable-table/TableRow';\nimport { isGeneratedColumn, isThinColumn } from './editable-table/helpers';\nimport { useEditableTableRows } from './editable-table/useEditableTableRows';\nimport { useEditableTableDnd } from './editable-table/useEditableTableDnd';\nimport { useEditableTableCellChange } from './editable-table/useEditableTableCellChange';\nimport type {\n EditableTableColumn,\n EditableTableModifyColumn,\n EditableTableModifyRow,\n EditableTableOnCellChange,\n EditableTableRow,\n EditableTableRowActionArgs,\n} from './editable-table/types';\n\nexport type {\n EditableTableColumn,\n EditableTableModifyColumn,\n EditableTableModifyColumnResult,\n EditableTableModifyRow,\n EditableTableOnCellChange,\n EditableTableRow,\n EditableTableRowActionArgs,\n} from './editable-table/types';\n\nexport type EditableTableProps = {\n columns: EditableTableColumn[];\n rows: EditableTableRow[];\n onChange: (rows: EditableTableRow[]) => void;\n onCellChange?: EditableTableOnCellChange;\n addRowLabel?: string;\n allowReorder?: boolean;\n allowAdd?: boolean;\n allowDelete?: boolean;\n className?: string;\n modifyColumn?: EditableTableModifyColumn;\n modifyRow?: EditableTableModifyRow;\n fieldName?: string;\n cellErrors?: Record<string, unknown>;\n newRowDefaults?: Record<string, unknown>;\n renderActions?: (args: { rows: EditableTableRow[]; addRow: () => void; isDragging: boolean }) => React.ReactNode;\n renderRowActions?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItemsBeforeCore?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItemsAfterCore?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItems?: (args: EditableTableRowActionArgs) => React.ReactNode;\n};\n\ntype TableRowComponentProps = {\n row: EditableTableRow;\n rowIndex: number;\n rowCount: number;\n columns: EditableTableColumn[];\n columnsSignature: string;\n useDnd: boolean;\n allowReorder: boolean;\n showReorderControls: boolean;\n allowDelete: boolean;\n modifyColumn?: EditableTableModifyColumn;\n modifyRow?: EditableTableModifyRow;\n getCellErrors: (rowIndex: number, columnName: string) => unknown[];\n onUpdateCell: (rowIndex: number, row: EditableTableRow, column: EditableTableColumn, newValue: unknown) => void;\n moveRow: (row: EditableTableRow, direction: number) => void;\n removeRow: (row: EditableTableRow) => void;\n t: (key: string) => string;\n renderRowActions?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItemsBeforeCore?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItemsAfterCore?: (args: EditableTableRowActionArgs) => React.ReactNode;\n renderRowMenuItems?: (args: EditableTableRowActionArgs) => React.ReactNode;\n};\n\nexport function EditableTable({\n columns,\n rows,\n onChange,\n onCellChange = undefined,\n addRowLabel,\n allowReorder = true,\n allowAdd = true,\n allowDelete = true,\n className = '',\n modifyColumn = undefined,\n modifyRow = undefined,\n fieldName = undefined,\n cellErrors = {},\n newRowDefaults = {},\n renderActions = undefined,\n renderRowActions = undefined,\n renderRowMenuItemsBeforeCore = undefined,\n renderRowMenuItemsAfterCore = undefined,\n renderRowMenuItems = undefined,\n}: EditableTableProps) {\n const TableRowComponent = TableRow as React.ComponentType<TableRowComponentProps>;\n const t = useTranslation();\n const normalizedColumns = useMemo(() => {\n const sourceColumns = Array.isArray(columns) ? columns : [];\n const validColumns = sourceColumns.filter((column) => {\n return typeof column?.name === 'string' && column.name.trim() !== '';\n });\n\n if (validColumns.length !== sourceColumns.length) {\n const invalidColumns = sourceColumns.filter((column) => {\n return !(typeof column?.name === 'string' && column.name.trim() !== '');\n });\n\n console.error(\n 'EditableTable: column definitions must include a non-empty `name`.',\n { invalidColumns, columns: sourceColumns },\n );\n }\n\n return validColumns;\n }, [columns]);\n\n const generatedColumns = useMemo(() => {\n return normalizedColumns.filter(isGeneratedColumn);\n }, [normalizedColumns]);\n\n const columnsSignature = useMemo(() => {\n return JSON.stringify(normalizedColumns.map((column) => {\n return {\n name: column.name,\n type: column.type,\n label: column.label,\n required: column.required,\n placeholder: column.placeholder,\n options: column.options,\n };\n }));\n }, [normalizedColumns]);\n\n const {\n internalData,\n setInternalData,\n internalDataRef,\n skipNextRowsSyncRef,\n handleChange,\n addRow,\n removeRow,\n updateRow,\n moveRow,\n } = useEditableTableRows({\n rows,\n onChange,\n newRowDefaults,\n });\n\n const {\n isDragging,\n isDndHydrated,\n effectiveAllowReorder,\n handleDragStart,\n handleDragEnd,\n } = useEditableTableDnd({\n allowReorder,\n internalData,\n handleChange,\n });\n\n const {\n handleCellValueChange,\n } = useEditableTableCellChange({\n internalData,\n internalDataRef,\n setInternalData,\n skipNextRowsSyncRef,\n generatedColumns,\n onCellChange,\n updateRow,\n handleChange,\n });\n\n const getCellErrors = useCallback((rowIndex: number, columnName: string) => {\n if (!fieldName) {\n return [];\n }\n\n const key = `${fieldName}.${rowIndex}.${columnName}`;\n const errors = cellErrors?.[key];\n if (!errors) {\n return [];\n }\n\n return Array.isArray(errors) ? errors : [errors];\n }, [cellErrors, fieldName]);\n\n const actions = typeof renderActions === 'function'\n ? renderActions({\n rows: internalData,\n addRow,\n isDragging,\n })\n : null;\n\n const dragDropPlugins = useCallback((defaults) => {\n return defaults.filter((plugin) => { return plugin !== AutoScroller; });\n }, []);\n\n return (\n <div className={className}>\n {actions}\n\n <DragDropProvider\n plugins={dragDropPlugins}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n >\n <Table>\n <TableHeader>\n <UITableRow>\n {normalizedColumns.map((column) => {\n return (\n <TableHead key={column.name} className={cn(column.className, isThinColumn(column) && 'w-[1%] whitespace-nowrap')}>\n {column.label}\n {column.required && <span className=\"text-error ml-1\">*</span>}\n </TableHead>\n );\n })}\n {(allowReorder || allowDelete) && <TableHead className=\"p-0 w-0\"></TableHead>}\n </UITableRow>\n </TableHeader>\n <TableBody>\n {internalData.map((row, rowIndex) => {\n return (\n <TableRowComponent\n key={row._id}\n row={row}\n rowIndex={rowIndex}\n rowCount={internalData.length}\n columns={normalizedColumns}\n columnsSignature={columnsSignature}\n useDnd={allowReorder && isDndHydrated}\n allowReorder={effectiveAllowReorder && isDndHydrated}\n showReorderControls={allowReorder}\n allowDelete={allowDelete}\n modifyColumn={modifyColumn}\n modifyRow={modifyRow}\n getCellErrors={getCellErrors}\n onUpdateCell={handleCellValueChange}\n moveRow={moveRow}\n removeRow={removeRow}\n t={t}\n renderRowActions={renderRowActions}\n renderRowMenuItemsBeforeCore={renderRowMenuItemsBeforeCore}\n renderRowMenuItemsAfterCore={renderRowMenuItemsAfterCore}\n renderRowMenuItems={renderRowMenuItems}\n />\n );\n })}\n </TableBody>\n </Table>\n </DragDropProvider>\n\n {allowAdd && (\n <Button\n type=\"button\"\n variant=\"dashed\"\n onClick={addRow}\n className={cn('w-full rounded-t-none! border-t-0!', isDragging && 'pointer-events-none')}\n >\n <FontAwesomeIcon icon={faPlus} className=\"size-3 mr-1\" />\n {addRowLabel || t('Add row')}\n </Button>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -26,7 +26,7 @@ var SelectInput = forwardRef(({ options, placeholder, size, onChange, value, tri
26
26
  return [option];
27
27
  });
28
28
  const selectedOption = flatOptions.find((option) => {
29
- return option.value === value;
29
+ return String(option.value) === String(value);
30
30
  });
31
31
  const resolvedPlaceholder = placeholder || "";
32
32
  const resolvedIsInvalid = Boolean(isInvalid || ariaInvalid === true || ariaInvalid === "true");
@@ -1 +1 @@
1
- {"version":3,"file":"SelectInput.js","names":[],"sources":["../../src/components/SelectInput.tsx"],"sourcesContent":["import {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n SelectLabel,\n} from '@verbb/plugin-kit-react/components';\n\nimport type React from 'react';\nimport { ComponentProps, forwardRef } from 'react';\nimport { Status } from '@verbb/plugin-kit-react/components/Status';\nimport { cn } from '@verbb/plugin-kit-react/utils';\n\n\nexport interface Option<T = unknown> {\n value: T;\n label: string;\n disabled?: boolean;\n status?: string;\n}\n\ntype OptionGroup<T = unknown> = {\n group: string;\n options: Option<T>[];\n};\n\n// const valueToString = (val: Option['value']) => {\n// if (val === null) { return '__null__'; }\n// if (val === undefined) {\n// console.error('option value cannot be undefined');\n// return '__undefined__';\n// }\n// if (val === Infinity) { return '__Infinity__'; }\n// if (val === -Infinity) { return '__-Infinity__'; }\n// if (Number.isNaN(val)) { return '__NaN__'; }\n// if (typeof val === 'symbol') { return `__symbol__${val.description}`; }\n// // console.log(JSON.stringify(val));\n// return JSON.stringify(val);\n// };\n\n// const stringToValue = (str: string) => {\n// switch (str) {\n// case '__null__':\n// return null;\n// case '__undefined__':\n// return undefined;\n// case '__Infinity__':\n// return Infinity;\n// case '__-Infinity__':\n// return -Infinity;\n// case '__NaN__':\n// return NaN;\n// default:\n// if (str.startsWith('__symbol__')) {\n// return Symbol(str.slice(10));\n// }\n// return JSON.parse(str);\n// }\n// };\n\ntype SelectBaseProps = ComponentProps<typeof Select>;\n\ninterface SelectProps<T = unknown>\n extends Omit<SelectBaseProps, 'children' | 'value' | 'defaultValue' | 'onValueChange'> {\n options: Array<Option<T> | OptionGroup<T>>;\n placeholder?: string;\n onChange?: (value: T) => void;\n value?: T;\n isInvalid?: boolean;\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n triggerClassName?: string;\n contentClassName?: string;\n id?: string;\n 'aria-invalid'?: boolean | 'true' | 'false';\n 'aria-describedby'?: string;\n 'aria-errormessage'?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\nexport const SelectInput = forwardRef<HTMLButtonElement, SelectProps>(({\n options,\n placeholder,\n size,\n onChange,\n value,\n triggerClassName,\n contentClassName,\n isInvalid,\n id,\n 'aria-invalid': ariaInvalid,\n 'aria-describedby': ariaDescribedBy,\n 'aria-errormessage': ariaErrorMessage,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...selectProps\n}, ref) => {\n const handleValueChange = (nextValue: SelectProps['value']) => {\n if (onChange) {\n onChange(nextValue);\n }\n };\n\n // const hasEmptyOption = options?.find((option) => { return option.value === ''; });\n\n // let defaultValue = undefined;\n\n // // Only show placeholder when value is initially undefined,\n // // or when the value is an empty string and there's an empty option\n // if (value === undefined || value === '') {\n // if (hasEmptyOption) {\n // defaultValue = valueToString('');\n // } else {\n // defaultValue = undefined;\n // }\n // } else {\n // defaultValue = valueToString(value);\n // }\n\n const hasGroup = (option: Option<unknown> | OptionGroup<unknown>): option is OptionGroup<unknown> => {\n return typeof option === 'object' && option !== null && 'group' in option;\n };\n\n const groupedOptions = options.map((option, index) => {\n if (hasGroup(option)) {\n return option;\n }\n\n return {\n group: null,\n options: [option],\n _key: `ungrouped-${index}`,\n };\n });\n\n const flatOptions = options.flatMap((option) => {\n if (hasGroup(option)) {\n return option.options;\n }\n\n return [option];\n });\n\n const selectedOption = flatOptions.find((option) => {\n return option.value === value;\n });\n const resolvedPlaceholder = placeholder || '';\n const resolvedIsInvalid = Boolean(isInvalid || ariaInvalid === true || ariaInvalid === 'true');\n\n return (\n <Select\n value={value}\n onValueChange={handleValueChange}\n size={size}\n items={flatOptions as ComponentProps<typeof Select>['items']}\n {...selectProps}\n >\n <SelectTrigger\n ref={ref}\n id={id}\n aria-invalid={resolvedIsInvalid}\n aria-describedby={ariaDescribedBy}\n aria-errormessage={ariaErrorMessage}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n className={cn(\n selectedOption?.status && 'relative [&_[data-slot=select-value]]:pl-5',\n '[&_[data-slot=select-value]]:overflow-hidden [&_[data-slot=select-value]>span]:block [&_[data-slot=select-value]>span]:min-w-0 [&_[data-slot=select-value]>span]:max-w-full [&_[data-slot=select-value]>span]:truncate',\n triggerClassName,\n )}\n >\n {selectedOption?.status && (\n <Status\n status={selectedOption.status}\n className=\"absolute left-2.5 top-1/2 -translate-y-1/2\"\n />\n )}\n <SelectValue placeholder={placeholder}>\n {selectedOption ? (\n <span className=\"block min-w-0 max-w-full truncate\" title={selectedOption.label}>\n {selectedOption.label}\n </span>\n ) : (\n <span className=\"block min-w-0 max-w-full truncate text-slate-500\" title={resolvedPlaceholder}>\n {resolvedPlaceholder}\n </span>\n )}\n </SelectValue>\n </SelectTrigger>\n\n {options?.length > 0 && (\n <SelectContent className={contentClassName}>\n {groupedOptions.map((group) => {\n return (\n <SelectGroup key={group.group ?? group._key}>\n {group.group && <SelectLabel>{group.group}</SelectLabel>}\n\n {group.options?.map((option) => {\n return (\n <SelectItem\n key={String(option.value)}\n value={option.value}\n disabled={option.disabled}\n >\n {option.status && (\n <Status status={option.status} />\n )}\n <span className=\"block min-w-0 flex-1 truncate\" title={option.label}>\n {option.label}\n </span>\n </SelectItem>\n );\n })}\n </SelectGroup>\n );\n })}\n </SelectContent>\n )}\n </Select>\n );\n});\n\nexport default Select;\nexport type { SelectProps };\n"],"mappings":";;;;;;;;AAkFA,IAAa,cAAc,YAA4C,EACnE,SACA,aACA,MACA,UACA,OACA,kBACA,kBACA,WACA,IACA,gBAAgB,aAChB,oBAAoB,iBACpB,qBAAqB,kBACrB,cAAc,WACd,mBAAmB,gBACnB,GAAG,eACJ,QAAQ;CACP,MAAM,qBAAqB,cAAoC;AAC3D,MAAI,SACA,UAAS,UAAU;;CAoB3B,MAAM,YAAY,WAAmF;AACjG,SAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,WAAW;;CAGvE,MAAM,iBAAiB,QAAQ,KAAK,QAAQ,UAAU;AAClD,MAAI,SAAS,OAAO,CAChB,QAAO;AAGX,SAAO;GACH,OAAO;GACP,SAAS,CAAC,OAAO;GACjB,MAAM,aAAa;GACtB;GACH;CAEF,MAAM,cAAc,QAAQ,SAAS,WAAW;AAC5C,MAAI,SAAS,OAAO,CAChB,QAAO,OAAO;AAGlB,SAAO,CAAC,OAAO;GACjB;CAEF,MAAM,iBAAiB,YAAY,MAAM,WAAW;AAChD,SAAO,OAAO,UAAU;GAC1B;CACF,MAAM,sBAAsB,eAAe;CAC3C,MAAM,oBAAoB,QAAQ,aAAa,gBAAgB,QAAQ,gBAAgB,OAAO;AAE9F,QACI,qBAAC,QAAD;EACW;EACP,eAAe;EACT;EACN,OAAO;EACP,GAAI;YALR,CAOI,qBAAC,eAAD;GACS;GACD;GACJ,gBAAc;GACd,oBAAkB;GAClB,qBAAmB;GACnB,cAAY;GACZ,mBAAiB;GACjB,WAAW,GACP,gBAAgB,UAAU,8CAC1B,0NACA,iBACH;aAZL,CAcK,gBAAgB,UACb,oBAAC,QAAD;IACI,QAAQ,eAAe;IACvB,WAAU;IACZ,CAAA,EAEN,oBAAC,aAAD;IAA0B;cACrB,iBACG,oBAAC,QAAD;KAAM,WAAU;KAAoC,OAAO,eAAe;eACrE,eAAe;KACb,CAAA,GAEP,oBAAC,QAAD;KAAM,WAAU;KAAmD,OAAO;eACrE;KACE,CAAA;IAED,CAAA,CACF;MAEf,SAAS,SAAS,KACf,oBAAC,eAAD;GAAe,WAAW;aACrB,eAAe,KAAK,UAAU;AAC3B,WACI,qBAAC,aAAD,EAAA,UAAA,CACK,MAAM,SAAS,oBAAC,aAAD,EAAA,UAAc,MAAM,OAAoB,CAAA,EAEvD,MAAM,SAAS,KAAK,WAAW;AAC5B,YACI,qBAAC,YAAD;MAEI,OAAO,OAAO;MACd,UAAU,OAAO;gBAHrB,CAKK,OAAO,UACJ,oBAAC,QAAD,EAAQ,QAAQ,OAAO,QAAU,CAAA,EAErC,oBAAC,QAAD;OAAM,WAAU;OAAgC,OAAO,OAAO;iBACzD,OAAO;OACL,CAAA,CACE;QAVJ,OAAO,OAAO,MAAM,CAUhB;MAEnB,CACQ,EAAA,EAnBI,MAAM,SAAS,MAAM,KAmBzB;KAEpB;GACU,CAAA,CAEf;;EAEf;AAEF,IAAA,sBAAe"}
1
+ {"version":3,"file":"SelectInput.js","names":[],"sources":["../../src/components/SelectInput.tsx"],"sourcesContent":["import {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n SelectLabel,\n} from '@verbb/plugin-kit-react/components';\n\nimport type React from 'react';\nimport { ComponentProps, forwardRef } from 'react';\nimport { Status } from '@verbb/plugin-kit-react/components/Status';\nimport { cn } from '@verbb/plugin-kit-react/utils';\n\n\nexport interface Option<T = unknown> {\n value: T;\n label: string;\n disabled?: boolean;\n status?: string;\n}\n\ntype OptionGroup<T = unknown> = {\n group: string;\n options: Option<T>[];\n};\n\n// const valueToString = (val: Option['value']) => {\n// if (val === null) { return '__null__'; }\n// if (val === undefined) {\n// console.error('option value cannot be undefined');\n// return '__undefined__';\n// }\n// if (val === Infinity) { return '__Infinity__'; }\n// if (val === -Infinity) { return '__-Infinity__'; }\n// if (Number.isNaN(val)) { return '__NaN__'; }\n// if (typeof val === 'symbol') { return `__symbol__${val.description}`; }\n// // console.log(JSON.stringify(val));\n// return JSON.stringify(val);\n// };\n\n// const stringToValue = (str: string) => {\n// switch (str) {\n// case '__null__':\n// return null;\n// case '__undefined__':\n// return undefined;\n// case '__Infinity__':\n// return Infinity;\n// case '__-Infinity__':\n// return -Infinity;\n// case '__NaN__':\n// return NaN;\n// default:\n// if (str.startsWith('__symbol__')) {\n// return Symbol(str.slice(10));\n// }\n// return JSON.parse(str);\n// }\n// };\n\ntype SelectBaseProps = ComponentProps<typeof Select>;\n\ninterface SelectProps<T = unknown>\n extends Omit<SelectBaseProps, 'children' | 'value' | 'defaultValue' | 'onValueChange'> {\n options: Array<Option<T> | OptionGroup<T>>;\n placeholder?: string;\n onChange?: (value: T) => void;\n value?: T;\n isInvalid?: boolean;\n onBlur?: React.FocusEventHandler<HTMLButtonElement>;\n triggerClassName?: string;\n contentClassName?: string;\n id?: string;\n 'aria-invalid'?: boolean | 'true' | 'false';\n 'aria-describedby'?: string;\n 'aria-errormessage'?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n}\n\nexport const SelectInput = forwardRef<HTMLButtonElement, SelectProps>(({\n options,\n placeholder,\n size,\n onChange,\n value,\n triggerClassName,\n contentClassName,\n isInvalid,\n id,\n 'aria-invalid': ariaInvalid,\n 'aria-describedby': ariaDescribedBy,\n 'aria-errormessage': ariaErrorMessage,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n ...selectProps\n}, ref) => {\n const handleValueChange = (nextValue: SelectProps['value']) => {\n if (onChange) {\n onChange(nextValue);\n }\n };\n\n // const hasEmptyOption = options?.find((option) => { return option.value === ''; });\n\n // let defaultValue = undefined;\n\n // // Only show placeholder when value is initially undefined,\n // // or when the value is an empty string and there's an empty option\n // if (value === undefined || value === '') {\n // if (hasEmptyOption) {\n // defaultValue = valueToString('');\n // } else {\n // defaultValue = undefined;\n // }\n // } else {\n // defaultValue = valueToString(value);\n // }\n\n const hasGroup = (option: Option<unknown> | OptionGroup<unknown>): option is OptionGroup<unknown> => {\n return typeof option === 'object' && option !== null && 'group' in option;\n };\n\n const groupedOptions = options.map((option, index) => {\n if (hasGroup(option)) {\n return option;\n }\n\n return {\n group: null,\n options: [option],\n _key: `ungrouped-${index}`,\n };\n });\n\n const flatOptions = options.flatMap((option) => {\n if (hasGroup(option)) {\n return option.options;\n }\n\n return [option];\n });\n\n const selectedOption = flatOptions.find((option) => {\n return String(option.value) === String(value);\n });\n const resolvedPlaceholder = placeholder || '';\n const resolvedIsInvalid = Boolean(isInvalid || ariaInvalid === true || ariaInvalid === 'true');\n\n return (\n <Select\n value={value}\n onValueChange={handleValueChange}\n size={size}\n items={flatOptions as ComponentProps<typeof Select>['items']}\n {...selectProps}\n >\n <SelectTrigger\n ref={ref}\n id={id}\n aria-invalid={resolvedIsInvalid}\n aria-describedby={ariaDescribedBy}\n aria-errormessage={ariaErrorMessage}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n className={cn(\n selectedOption?.status && 'relative [&_[data-slot=select-value]]:pl-5',\n '[&_[data-slot=select-value]]:overflow-hidden [&_[data-slot=select-value]>span]:block [&_[data-slot=select-value]>span]:min-w-0 [&_[data-slot=select-value]>span]:max-w-full [&_[data-slot=select-value]>span]:truncate',\n triggerClassName,\n )}\n >\n {selectedOption?.status && (\n <Status\n status={selectedOption.status}\n className=\"absolute left-2.5 top-1/2 -translate-y-1/2\"\n />\n )}\n <SelectValue placeholder={placeholder}>\n {selectedOption ? (\n <span className=\"block min-w-0 max-w-full truncate\" title={selectedOption.label}>\n {selectedOption.label}\n </span>\n ) : (\n <span className=\"block min-w-0 max-w-full truncate text-slate-500\" title={resolvedPlaceholder}>\n {resolvedPlaceholder}\n </span>\n )}\n </SelectValue>\n </SelectTrigger>\n\n {options?.length > 0 && (\n <SelectContent className={contentClassName}>\n {groupedOptions.map((group) => {\n return (\n <SelectGroup key={group.group ?? group._key}>\n {group.group && <SelectLabel>{group.group}</SelectLabel>}\n\n {group.options?.map((option) => {\n return (\n <SelectItem\n key={String(option.value)}\n value={option.value}\n disabled={option.disabled}\n >\n {option.status && (\n <Status status={option.status} />\n )}\n <span className=\"block min-w-0 flex-1 truncate\" title={option.label}>\n {option.label}\n </span>\n </SelectItem>\n );\n })}\n </SelectGroup>\n );\n })}\n </SelectContent>\n )}\n </Select>\n );\n});\n\nexport default Select;\nexport type { SelectProps };\n"],"mappings":";;;;;;;;AAkFA,IAAa,cAAc,YAA4C,EACnE,SACA,aACA,MACA,UACA,OACA,kBACA,kBACA,WACA,IACA,gBAAgB,aAChB,oBAAoB,iBACpB,qBAAqB,kBACrB,cAAc,WACd,mBAAmB,gBACnB,GAAG,eACJ,QAAQ;CACP,MAAM,qBAAqB,cAAoC;AAC3D,MAAI,SACA,UAAS,UAAU;;CAoB3B,MAAM,YAAY,WAAmF;AACjG,SAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,WAAW;;CAGvE,MAAM,iBAAiB,QAAQ,KAAK,QAAQ,UAAU;AAClD,MAAI,SAAS,OAAO,CAChB,QAAO;AAGX,SAAO;GACH,OAAO;GACP,SAAS,CAAC,OAAO;GACjB,MAAM,aAAa;GACtB;GACH;CAEF,MAAM,cAAc,QAAQ,SAAS,WAAW;AAC5C,MAAI,SAAS,OAAO,CAChB,QAAO,OAAO;AAGlB,SAAO,CAAC,OAAO;GACjB;CAEF,MAAM,iBAAiB,YAAY,MAAM,WAAW;AAChD,SAAO,OAAO,OAAO,MAAM,KAAK,OAAO,MAAM;GAC/C;CACF,MAAM,sBAAsB,eAAe;CAC3C,MAAM,oBAAoB,QAAQ,aAAa,gBAAgB,QAAQ,gBAAgB,OAAO;AAE9F,QACI,qBAAC,QAAD;EACW;EACP,eAAe;EACT;EACN,OAAO;EACP,GAAI;YALR,CAOI,qBAAC,eAAD;GACS;GACD;GACJ,gBAAc;GACd,oBAAkB;GAClB,qBAAmB;GACnB,cAAY;GACZ,mBAAiB;GACjB,WAAW,GACP,gBAAgB,UAAU,8CAC1B,0NACA,iBACH;aAZL,CAcK,gBAAgB,UACb,oBAAC,QAAD;IACI,QAAQ,eAAe;IACvB,WAAU;IACZ,CAAA,EAEN,oBAAC,aAAD;IAA0B;cACrB,iBACG,oBAAC,QAAD;KAAM,WAAU;KAAoC,OAAO,eAAe;eACrE,eAAe;KACb,CAAA,GAEP,oBAAC,QAAD;KAAM,WAAU;KAAmD,OAAO;eACrE;KACE,CAAA;IAED,CAAA,CACF;MAEf,SAAS,SAAS,KACf,oBAAC,eAAD;GAAe,WAAW;aACrB,eAAe,KAAK,UAAU;AAC3B,WACI,qBAAC,aAAD,EAAA,UAAA,CACK,MAAM,SAAS,oBAAC,aAAD,EAAA,UAAc,MAAM,OAAoB,CAAA,EAEvD,MAAM,SAAS,KAAK,WAAW;AAC5B,YACI,qBAAC,YAAD;MAEI,OAAO,OAAO;MACd,UAAU,OAAO;gBAHrB,CAKK,OAAO,UACJ,oBAAC,QAAD,EAAQ,QAAQ,OAAO,QAAU,CAAA,EAErC,oBAAC,QAAD;OAAM,WAAU;OAAgC,OAAO,OAAO;iBACzD,OAAO;OACL,CAAA,CACE;QAVJ,OAAO,OAAO,MAAM,CAUhB;MAEnB,CACQ,EAAA,EAnBI,MAAM,SAAS,MAAM,KAmBzB;KAEpB;GACU,CAAA,CAEf;;EAEf;AAEF,IAAA,sBAAe"}
@@ -2,7 +2,7 @@ import { ReactNode } from 'react';
2
2
  import { Editor as TiptapEditorInstance } from '@tiptap/core';
3
3
  import { LinkOptions, LinkOptionsInput } from './tiptap/LinkDropdown';
4
4
  import { VariableOption, VariableCategories } from './tiptap/VariableDropdown';
5
- import { VariableTransformerRegistry } from './tiptap/VariablePickerContext';
5
+ import { VariableTransformerRegistry, VariableConfigureSectionProps, VariableTagLabelResolver } from './tiptap/VariablePickerContext';
6
6
  export type { LinkOptions, LinkOptionsInput, VariableOption, VariableCategories, };
7
7
  type TiptapEditorProps = {
8
8
  value?: unknown;
@@ -21,6 +21,8 @@ type TiptapEditorProps = {
21
21
  variableCategoryOrder?: string[];
22
22
  variableTransformerRegistry?: VariableTransformerRegistry;
23
23
  variablePickerTriggerCharacters?: string[];
24
+ renderVariableConfigureSection?: (props: VariableConfigureSectionProps) => ReactNode;
25
+ resolveVariableTagLabel?: VariableTagLabelResolver;
24
26
  toolbarContent?: (params: {
25
27
  editor: TiptapEditorInstance | null;
26
28
  variableCategories: VariableCategories;
@@ -37,5 +39,5 @@ type TiptapEditorProps = {
37
39
  invalidContentMessage?: string;
38
40
  [key: string]: unknown;
39
41
  };
40
- export declare const TiptapEditor: ({ value, onChange, buttons, tableOptions, linkOptions, linkSelectorStorageKeyPrefix, variableCategories, variableCategoryLabels, variableCategoryOrder, variableTransformerRegistry, variablePickerTriggerCharacters, toolbarContent, rows, className, isInvalid, disabled, readOnly, invalidContentMessage, ...props }: TiptapEditorProps) => import("react/jsx-runtime").JSX.Element;
42
+ export declare const TiptapEditor: ({ value, onChange, buttons, tableOptions, linkOptions, linkSelectorStorageKeyPrefix, variableCategories, variableCategoryLabels, variableCategoryOrder, variableTransformerRegistry, variablePickerTriggerCharacters, renderVariableConfigureSection, resolveVariableTagLabel, toolbarContent, rows, className, isInvalid, disabled, readOnly, invalidContentMessage, ...props }: TiptapEditorProps) => import("react/jsx-runtime").JSX.Element;
41
43
  //# sourceMappingURL=TiptapEditor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TiptapEditor.d.ts","sourceRoot":"","sources":["../../src/components/TiptapEditor.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAgB,KAAK,MAAM,IAAI,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAIjF,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAKlF,YAAY,EACR,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,kBAAkB,GACpE,CAAC;AAqWF,KAAK,iBAAiB,GAAG;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAChF,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D,+BAA+B,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3C,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE;QACtB,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC;QACpC,kBAAkB,EAAE,kBAAkB,CAAC;QACvC,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChD,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;QACjC,kBAAkB,EAAE,OAAO,CAAC;QAC5B,0BAA0B,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;KACvD,KAAK,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,yTAoB1B,iBAAiB,4CA+QnB,CAAC"}
1
+ {"version":3,"file":"TiptapEditor.d.ts","sourceRoot":"","sources":["../../src/components/TiptapEditor.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAgB,KAAK,MAAM,IAAI,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAIjF,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,KAAK,EAAE,2BAA2B,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAK3I,YAAY,EACR,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,kBAAkB,GACpE,CAAC;AAqWF,KAAK,iBAAiB,GAAG;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAChF,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D,+BAA+B,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3C,8BAA8B,CAAC,EAAE,CAAC,KAAK,EAAE,6BAA6B,KAAK,SAAS,CAAC;IACrF,uBAAuB,CAAC,EAAE,wBAAwB,CAAC;IACnD,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE;QACtB,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC;QACpC,kBAAkB,EAAE,kBAAkB,CAAC;QACvC,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChD,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;QACjC,kBAAkB,EAAE,OAAO,CAAC;QAC5B,0BAA0B,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;KACvD,KAAK,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,kXAsB1B,iBAAiB,4CAoTnB,CAAC"}
@@ -345,10 +345,11 @@ var MenuBar = ({ editor, buttons = ["bold", "italic"], linkOptions, linkSelector
345
345
  children: renderedButtons
346
346
  });
347
347
  };
348
- var TiptapEditor = ({ value = "", onChange, buttons = ["bold", "italic"], tableOptions = [], linkOptions, linkSelectorStorageKeyPrefix, variableCategories = {}, variableCategoryLabels, variableCategoryOrder, variableTransformerRegistry, variablePickerTriggerCharacters = ["@"], toolbarContent, rows, className, isInvalid, disabled = false, readOnly = false, invalidContentMessage, ...props }) => {
348
+ var TiptapEditor = ({ value = "", onChange, buttons = ["bold", "italic"], tableOptions = [], linkOptions, linkSelectorStorageKeyPrefix, variableCategories = {}, variableCategoryLabels, variableCategoryOrder, variableTransformerRegistry, variablePickerTriggerCharacters = ["@"], renderVariableConfigureSection, resolveVariableTagLabel, toolbarContent, rows, className, isInvalid, disabled = false, readOnly = false, invalidContentMessage, ...props }) => {
349
349
  useTranslation();
350
350
  const wrapperRef = useRef(null);
351
351
  const handleKeyDownRef = useRef(null);
352
+ const lastEmittedContentRef = useRef(null);
352
353
  const extensions = useMemo(() => {
353
354
  return createTiptapExtensions({ trailingCursorText: "⁠" });
354
355
  }, []);
@@ -368,6 +369,9 @@ var TiptapEditor = ({ value = "", onChange, buttons = ["bold", "italic"], tableO
368
369
  const serializeContent = (content) => {
369
370
  return normalizeContentArray(content);
370
371
  };
372
+ const serializeEditorDocument = useCallback((editorInstance) => {
373
+ return JSON.stringify(serializeContent(editorInstance.getJSON().content));
374
+ }, []);
371
375
  const editor = useEditor({
372
376
  extensions,
373
377
  content: contentError ? null : editorContent,
@@ -375,8 +379,10 @@ var TiptapEditor = ({ value = "", onChange, buttons = ["bold", "italic"], tableO
375
379
  editorProps: { handleKeyDown: (view, event) => {
376
380
  return handleKeyDownRef.current?.(view, event) ?? false;
377
381
  } },
378
- onUpdate: ({ editor }) => {
379
- if (onChange) onChange(serializeContent(editor.getJSON().content));
382
+ onUpdate: ({ editor: editorInstance }) => {
383
+ const serialized = serializeContent(editorInstance.getJSON().content);
384
+ lastEmittedContentRef.current = JSON.stringify(serialized);
385
+ if (onChange) onChange(serialized);
380
386
  }
381
387
  });
382
388
  const inlinePicker = useInlineVariablePicker(editor, {
@@ -438,15 +444,25 @@ var TiptapEditor = ({ value = "", onChange, buttons = ["bold", "italic"], tableO
438
444
  }
439
445
  }, [editor]);
440
446
  useEffect(() => {
441
- if (editor) {
442
- const newContent = contentError ? null : editorContent;
443
- const currentContent = editor.getJSON();
444
- if (JSON.stringify(newContent) !== JSON.stringify(currentContent)) editor.commands.setContent(newContent);
445
- }
447
+ if (!editor) return;
448
+ const incomingContent = contentError ? null : editorContent;
449
+ const incomingSerialized = JSON.stringify(incomingContent?.content ?? []);
450
+ const currentSerialized = serializeEditorDocument(editor);
451
+ const isVariableConfigActive = Boolean(document.activeElement?.closest("[data-variable-config-popover]"));
452
+ if (incomingSerialized === currentSerialized) return;
453
+ if (lastEmittedContentRef.current === incomingSerialized) return;
454
+ if (!readOnly && (editor.isFocused || isVariableConfigActive || lastEmittedContentRef.current && currentSerialized === lastEmittedContentRef.current && incomingSerialized !== lastEmittedContentRef.current)) return;
455
+ editor.commands.setContent(incomingContent ?? {
456
+ type: "doc",
457
+ content: []
458
+ });
459
+ lastEmittedContentRef.current = incomingSerialized;
446
460
  }, [
447
461
  contentError,
448
462
  editor,
449
- editorContent
463
+ editorContent,
464
+ readOnly,
465
+ serializeEditorDocument
450
466
  ]);
451
467
  const handleLinkBubbleEdit = useCallback(() => {
452
468
  if (!editor) return;
@@ -470,6 +486,8 @@ var TiptapEditor = ({ value = "", onChange, buttons = ["bold", "italic"], tableO
470
486
  variableCategoryLabels,
471
487
  variableCategoryOrder,
472
488
  variableTransformerRegistry,
489
+ renderVariableConfigureSection,
490
+ resolveVariableTagLabel,
473
491
  children: [/* @__PURE__ */ jsxs(EditorContext.Provider, {
474
492
  value: { editor },
475
493
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"TiptapEditor.js","names":[],"sources":["../../src/components/TiptapEditor.tsx"],"sourcesContent":["import {\n useEffect, useCallback, useMemo, useRef, useState,\n} from 'react';\nimport type { ReactNode } from 'react';\nimport { useEditor, EditorContent, EditorContext } from '@tiptap/react';\nimport { getMarkRange, type Editor as TiptapEditorInstance } from '@tiptap/core';\n\nimport { Button } from '@verbb/plugin-kit-react/components';\nimport { LinkDropdown } from './tiptap/LinkDropdown';\nimport type { LinkOptions, LinkOptionsInput } from './tiptap/LinkDropdown';\nimport { VariableDropdown } from './tiptap/VariableDropdown';\nimport type { VariableOption, VariableCategories } from './tiptap/VariableDropdown';\nimport type { VariableTransformerRegistry } from './tiptap/VariablePickerContext';\nimport { VariablePickerProvider } from './tiptap/VariablePickerContext';\nimport { InlineVariablePickerPopover } from './tiptap/InlineVariablePickerPopover';\nimport { useInlineVariablePicker } from './tiptap/useInlineVariablePicker';\n\nexport type {\n LinkOptions, LinkOptionsInput, VariableOption, VariableCategories,\n};\nimport { LinkBubbleMenu } from './tiptap/LinkBubbleMenu';\nimport { InsertLinkDialog } from './tiptap/InsertLinkDialog';\n\nimport {\n createTiptapExtensions,\n getFatalTiptapContentError,\n normalizeContentArray,\n valueToContent,\n} from './tiptap/editorConfig';\n\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\n\nimport {\n faAlignCenter,\n faAlignJustify,\n faAlignLeft,\n faAlignRight,\n faArrowRotateLeft,\n faArrowRotateRight,\n faBold,\n faBracketsCurly,\n faCode,\n faH1,\n faH2,\n faH3,\n faH4,\n faH5,\n faH6,\n faHighlighter,\n faItalic,\n faListOl,\n faListUl,\n faMinus,\n faQuoteRight,\n faStrikethrough,\n faSubscript,\n faSuperscript,\n faTriangleExclamation,\n\n faUnderline,\n faTextSlash,\n} from '@fortawesome/pro-solid-svg-icons';\n\nimport {\n faFileDashedLine,\n faTable,\n} from '@fortawesome/pro-regular-svg-icons';\n\nimport { cn } from '@verbb/plugin-kit-react/utils';\nimport { useTranslation } from '@verbb/plugin-kit-react/hooks';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@verbb/plugin-kit-react/components/Tooltip';\n\nconst MenuBar = ({\n editor,\n buttons = ['bold', 'italic'],\n linkOptions,\n linkSelectorStorageKeyPrefix,\n variableCategories = {},\n variableCategoryLabels,\n variableCategoryOrder,\n variablePickerOpen,\n onVariablePickerOpenChange,\n openInsertLinkDialog,\n}: {\n editor: TiptapEditorInstance | null | undefined;\n buttons?: string[];\n linkOptions?: LinkOptionsInput;\n linkSelectorStorageKeyPrefix?: string;\n variableCategories?: VariableCategories;\n variableCategoryLabels?: Record<string, string>;\n variableCategoryOrder?: string[];\n variablePickerOpen?: boolean;\n onVariablePickerOpenChange?: (open: boolean) => void;\n openInsertLinkDialog?: (initial?: { url?: string; text?: string; from?: number; to?: number }) => void;\n}) => {\n const t = useTranslation();\n\n if (!editor) {\n return null;\n }\n\n const hasAnyVariables = Object.values(variableCategories ?? {}).some(\n items => {\n return Array.isArray(items) && items.length > 0;\n },\n );\n\n const visibleButtons = buttons.filter((buttonName) => {\n if (buttonName === 'variableTag') {\n return hasAnyVariables;\n }\n\n return true;\n });\n\n const buttonConfig = {\n bold: {\n icon: FontAwesomeIcon,\n iconProp: faBold,\n title: t('Bold'),\n action: () => { return editor.chain().focus().toggleBold().run(); },\n isActive: () => { return editor.isActive('bold'); },\n },\n italic: {\n icon: FontAwesomeIcon,\n iconProp: faItalic,\n title: t('Italic'),\n action: () => { return editor.chain().focus().toggleItalic().run(); },\n isActive: () => { return editor.isActive('italic'); },\n },\n underline: {\n icon: FontAwesomeIcon,\n iconProp: faUnderline,\n title: t('Underline'),\n action: () => { return editor.chain().focus().toggleUnderline().run(); },\n isActive: () => { return editor.isActive('underline'); },\n },\n strikethrough: {\n icon: FontAwesomeIcon,\n iconProp: faStrikethrough,\n title: t('Strikethrough'),\n action: () => { return editor.chain().focus().toggleStrike().run(); },\n isActive: () => { return editor.isActive('strike'); },\n },\n subscript: {\n icon: FontAwesomeIcon,\n iconProp: faSubscript,\n title: t('Subscript'),\n action: () => { return editor.chain().focus().toggleSubscript().run(); },\n isActive: () => { return editor.isActive('subscript'); },\n },\n superscript: {\n icon: FontAwesomeIcon,\n iconProp: faSuperscript,\n title: t('Superscript'),\n action: () => { return editor.chain().focus().toggleSuperscript().run(); },\n isActive: () => { return editor.isActive('superscript'); },\n },\n 'unordered-list': {\n icon: FontAwesomeIcon,\n iconProp: faListUl,\n title: t('Bullet List'),\n action: () => { return editor.chain().focus().toggleBulletList().run(); },\n isActive: () => { return editor.isActive('bulletList'); },\n },\n 'ordered-list': {\n icon: FontAwesomeIcon,\n iconProp: faListOl,\n title: t('Ordered List'),\n action: () => { return editor.chain().focus().toggleOrderedList().run(); },\n isActive: () => { return editor.isActive('orderedList'); },\n },\n blockquote: {\n icon: FontAwesomeIcon,\n iconProp: faQuoteRight,\n title: t('Blockquote'),\n action: () => { return editor.chain().focus().toggleBlockquote().run(); },\n isActive: () => { return editor.isActive('blockquote'); },\n },\n highlight: {\n icon: FontAwesomeIcon,\n iconProp: faHighlighter,\n title: t('Highlight'),\n action: () => { return editor.chain().focus().toggleHighlight().run(); },\n isActive: () => { return editor.isActive('highlight'); },\n },\n code: {\n icon: FontAwesomeIcon,\n iconProp: faBracketsCurly,\n title: t('Inline Code'),\n action: () => { return editor.chain().focus().toggleCode().run(); },\n isActive: () => { return editor.isActive('code'); },\n },\n 'code-block': {\n icon: FontAwesomeIcon,\n iconProp: faCode,\n title: t('Code Block'),\n action: () => { return editor.chain().focus().toggleCodeBlock().run(); },\n isActive: () => { return editor.isActive('codeBlock'); },\n },\n hr: {\n icon: FontAwesomeIcon,\n iconProp: faMinus,\n title: t('Horizontal Rule'),\n action: () => { return editor.chain().focus().setHorizontalRule().run(); },\n },\n 'line-break': {\n icon: FontAwesomeIcon,\n iconProp: faFileDashedLine,\n title: t('Line Break'),\n action: () => { return editor.chain().focus().setHardBreak().run(); },\n },\n 'align-left': {\n icon: FontAwesomeIcon,\n iconProp: faAlignLeft,\n title: t('Align Left'),\n action: () => { return editor.chain().focus().setTextAlign('left').run(); },\n isActive: () => { return editor.isActive({ textAlign: 'left' }); },\n },\n 'align-center': {\n icon: FontAwesomeIcon,\n iconProp: faAlignCenter,\n title: t('Align Center'),\n action: () => { return editor.chain().focus().setTextAlign('center').run(); },\n isActive: () => { return editor.isActive({ textAlign: 'center' }); },\n },\n 'align-right': {\n icon: FontAwesomeIcon,\n iconProp: faAlignRight,\n title: t('Align Right'),\n action: () => { return editor.chain().focus().setTextAlign('right').run(); },\n isActive: () => { return editor.isActive({ textAlign: 'right' }); },\n },\n 'align-justify': {\n icon: FontAwesomeIcon,\n iconProp: faAlignJustify,\n title: t('Justify'),\n action: () => { return editor.chain().focus().setTextAlign('justify').run(); },\n isActive: () => { return editor.isActive({ textAlign: 'justify' }); },\n },\n 'clear-format': {\n icon: FontAwesomeIcon,\n iconProp: faTextSlash,\n title: t('Clear Format'),\n action: () => { return editor.chain().focus().clearNodes().unsetAllMarks().run(); },\n },\n undo: {\n icon: FontAwesomeIcon,\n iconProp: faArrowRotateLeft,\n title: t('Undo'),\n action: () => { return editor.chain().focus().undo().run(); },\n },\n redo: {\n icon: FontAwesomeIcon,\n iconProp: faArrowRotateRight,\n title: t('Redo'),\n action: () => { return editor.chain().focus().redo().run(); },\n },\n link: {\n title: t('Link'),\n isActive: () => { return editor.isActive('link'); },\n isDropdown: true,\n },\n table: {\n icon: FontAwesomeIcon,\n iconProp: faTable,\n title: t('Insert Table'),\n action: () => { return editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(); },\n },\n variableTag: {\n title: t('Insert Variable'),\n isActive: () => { return editor.isActive('variableTag'); },\n isDropdown: true,\n },\n };\n\n // Add heading levels h1–h6\n [1, 2, 3, 4, 5, 6].forEach((level) => {\n buttonConfig[`h${level}`] = {\n icon: FontAwesomeIcon,\n iconProp: {\n 1: faH1,\n 2: faH2,\n 3: faH3,\n 4: faH4,\n 5: faH5,\n 6: faH6,\n }[level],\n title: t('Heading {level}', { level: String(level) }),\n action: () => { return editor.chain().focus().toggleHeading({ level }).run(); },\n isActive: () => { return editor.isActive('heading', { level }); },\n };\n });\n\n const resolveIsActive = (config) => {\n if (!config.isActive) {\n return false;\n }\n return typeof config.isActive === 'function' ? config.isActive() : config.isActive;\n };\n\n const renderedButtons = visibleButtons\n .map((buttonName) => {\n const config = buttonConfig[buttonName];\n\n if (!config) { return null; }\n\n if (config.isDropdown && buttonName === 'link') {\n return (\n <LinkDropdown\n key={buttonName}\n editor={editor}\n linkOptions={linkOptions}\n linkSelectorStorageKeyPrefix={linkSelectorStorageKeyPrefix}\n openInsertLinkDialog={openInsertLinkDialog!}\n title={config.title}\n />\n );\n }\n\n if (config.isDropdown && buttonName === 'variableTag') {\n return (\n <VariableDropdown\n key={buttonName}\n editor={editor}\n variableCategories={variableCategories}\n variableCategoryLabels={variableCategoryLabels}\n variableCategoryOrder={variableCategoryOrder}\n title={config.title}\n open={variablePickerOpen}\n onOpenChange={onVariablePickerOpenChange}\n />\n );\n }\n\n const Icon = config.icon;\n\n return (\n <Tooltip key={buttonName}>\n <TooltipTrigger\n render={\n <Button\n variant=\"transparent\"\n onClick={config.action}\n className={cn(\n 'w-[32px] h-[32px]',\n 'text-[#1c2e36]',\n 'hover:bg-slate-100!',\n resolveIsActive(config) && 'bg-slate-250! hover:bg-slate-250!',\n )}\n >\n <Icon icon={config.iconProp} className=\"size-4\" />\n </Button>\n }\n />\n <TooltipContent sideOffset={4}>{config.title}</TooltipContent>\n </Tooltip>\n );\n })\n .filter(Boolean);\n\n if (renderedButtons.length === 0) {\n return null;\n }\n\n return (\n <div className={cn(\n 'flex flex-wrap relative z-10 gap-1 px-[8px] py-[4px]',\n 'border-b border-[rgba(96,125,159,0.4)] bg-white',\n 'shadow-[0_2px_3px_rgba(49,49,93,.07)]',\n )}>\n {renderedButtons}\n </div>\n );\n};\n\ntype TiptapEditorProps = {\n value?: unknown;\n onChange?: (value: unknown) => void;\n placeholder?: string;\n buttons?: string[];\n tableOptions?: Array<{ rows?: number; cols?: number; withHeaderRow?: boolean }>;\n linkOptions?: LinkOptionsInput;\n linkSelectorStorageKeyPrefix?: string;\n variableCategories?: VariableCategories;\n variableCategoryLabels?: Record<string, string>;\n variableCategoryOrder?: string[];\n variableTransformerRegistry?: VariableTransformerRegistry;\n variablePickerTriggerCharacters?: string[];\n toolbarContent?: (params: {\n editor: TiptapEditorInstance | null;\n variableCategories: VariableCategories;\n variableCategoryLabels?: Record<string, string>;\n variableCategoryOrder?: string[];\n variablePickerOpen: boolean;\n onVariablePickerOpenChange: (open: boolean) => void;\n }) => ReactNode;\n rows?: number;\n className?: string;\n isInvalid?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n invalidContentMessage?: string;\n [key: string]: unknown;\n};\n\nexport const TiptapEditor = ({\n value = '',\n onChange,\n buttons = ['bold', 'italic'],\n tableOptions = [],\n linkOptions,\n linkSelectorStorageKeyPrefix,\n variableCategories = {},\n variableCategoryLabels,\n variableCategoryOrder,\n variableTransformerRegistry,\n variablePickerTriggerCharacters = ['@'],\n toolbarContent,\n rows,\n className,\n isInvalid,\n disabled = false,\n readOnly = false,\n invalidContentMessage,\n ...props\n}: TiptapEditorProps) => {\n // Ensure value is a string and handle null/undefined\n // const safeValue = value || '';\n const t = useTranslation();\n\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const handleKeyDownRef = useRef<import('./tiptap/useInlineVariablePicker').InlineVariablePickerHandleKeyDown | null>(null);\n\n const extensions = useMemo(() => {\n return createTiptapExtensions({ trailingCursorText: '\\u2060' });\n }, []);\n const [isVariablePickerOpen, setIsVariablePickerOpen] = useState(false);\n const hasAnyVariables = useMemo(() => {\n return Object.values(variableCategories || {}).some((variables) => {\n return Array.isArray(variables) && variables.length > 0;\n });\n }, [variableCategories]);\n const editorContent = useMemo(() => {\n return valueToContent(value, { trailingCursorText: '\\u2060' });\n }, [value]);\n const contentError = useMemo(() => {\n const detectedError = getFatalTiptapContentError(value);\n return detectedError ? (invalidContentMessage || detectedError) : '';\n }, [invalidContentMessage, value]);\n\n const serializeContent = (content: unknown) => {\n return normalizeContentArray(content);\n };\n\n const editor = useEditor({\n extensions,\n content: contentError ? null : editorContent,\n editable: !disabled && !readOnly,\n editorProps: {\n handleKeyDown: (view, event) => {\n return handleKeyDownRef.current?.(view, event) ?? false;\n },\n },\n onUpdate: ({ editor }) => {\n if (onChange) {\n onChange(serializeContent(editor.getJSON().content));\n }\n },\n });\n\n const inlinePicker = useInlineVariablePicker(editor, {\n variableCategories,\n variableCategoryLabels,\n variableCategoryOrder,\n variablePickerTriggerCharacters,\n disabled,\n readOnly,\n wrapperRef,\n onOpenDropdown: () => {\n return setIsVariablePickerOpen(true);\n },\n });\n\n useEffect(() => {\n handleKeyDownRef.current = inlinePicker.handleKeyDown;\n }, [inlinePicker.handleKeyDown]);\n\n const [insertLinkDialogOpen, setInsertLinkDialogOpen] = useState(false);\n const [insertLinkInitialValues, setInsertLinkInitialValues] = useState<{ url?: string; text?: string; openInNewTab?: boolean; from?: number; to?: number } | undefined>();\n const editorMinHeight = useMemo(() => {\n const normalizedRows = Math.max(1, Number(rows || 0));\n const lineHeight = 24;\n const verticalPadding = 32;\n\n return `${(normalizedRows * lineHeight) + verticalPadding}px`;\n }, [rows]);\n\n useEffect(() => {\n if (!editor?.view?.dom) {\n return;\n }\n\n editor.view.dom.style.minHeight = editorMinHeight;\n }, [editor, editorMinHeight]);\n\n const openInsertLinkDialog = useCallback((initial?: { url?: string; text?: string; from?: number; to?: number }) => {\n if (initial) {\n const openInNewTab = editor?.isActive('link') ? editor.getAttributes('link').target === '_blank' : false;\n setInsertLinkInitialValues({ ...initial, openInNewTab });\n } else {\n setInsertLinkInitialValues(undefined);\n }\n setInsertLinkDialogOpen(true);\n }, [editor]);\n\n const insertLink = useCallback(\n (params: { url: string; text: string; openInNewTab: boolean; from?: number; to?: number }) => {\n if (!editor) { return; }\n const {\n url, text, openInNewTab, from: fromParam, to: toParam,\n } = params;\n const chain = editor.chain().focus();\n const linkAttrs: { href: string; target?: string | null } = { href: url };\n if (openInNewTab) {\n linkAttrs.target = '_blank';\n }\n\n const content = {\n type: 'text',\n text: text.trim() || url,\n marks: [{ type: 'link', attrs: linkAttrs }],\n };\n\n if (typeof fromParam === 'number' && typeof toParam === 'number' && fromParam !== toParam) {\n chain.insertContentAt({ from: fromParam, to: toParam }, [content]).run();\n } else {\n const { from, to } = editor.state.selection;\n const selectedText = editor.state.doc.textBetween(from, to, ' ');\n if (selectedText) {\n chain.extendMarkRange('link').setLink(linkAttrs).run();\n } else {\n chain.insertContent([content]).run();\n }\n }\n },\n [editor],\n );\n\n // Watch for value changes and update editor content\n useEffect(() => {\n if (editor) {\n const newContent = contentError ? null : editorContent;\n const currentContent = editor.getJSON();\n\n // Only update if content has actually changed\n if (JSON.stringify(newContent) !== JSON.stringify(currentContent)) {\n editor.commands.setContent(newContent);\n }\n }\n }, [contentError, editor, editorContent]);\n\n const handleLinkBubbleEdit = useCallback(() => {\n if (!editor) { return; }\n const { href } = editor.getAttributes('link');\n const { state } = editor;\n const linkType = state.schema.marks.link;\n const range = getMarkRange(state.selection.$from, linkType);\n const from = range?.from ?? state.selection.from;\n const to = range?.to ?? state.selection.to;\n const text = editor.state.doc.textBetween(from, to, ' ');\n openInsertLinkDialog({\n url: href, text, from, to,\n });\n }, [editor, openInsertLinkDialog]);\n\n return (\n <div className={cn(\n 'border border-[rgba(96,125,159,0.4)] rounded-sm overflow-hidden',\n isInvalid && [\n 'border-rose-600!',\n '[focus-visible:shadow-[0_0_0_1px_var(--color-rose-600),0_0_4px_0_hsl(from_var(--color-rose-600)_h_s_l/0.7)]!',\n ],\n className,\n )}>\n <VariablePickerProvider\n variableCategories={variableCategories}\n variableCategoryLabels={variableCategoryLabels}\n variableCategoryOrder={variableCategoryOrder}\n variableTransformerRegistry={variableTransformerRegistry}\n >\n <EditorContext.Provider value={{ editor }}>\n {toolbarContent ? (\n toolbarContent({\n editor,\n variableCategories,\n variableCategoryLabels,\n variableCategoryOrder,\n variablePickerOpen: isVariablePickerOpen,\n onVariablePickerOpenChange: setIsVariablePickerOpen,\n })\n ) : (\n <MenuBar\n editor={editor}\n buttons={buttons}\n tableOptions={tableOptions}\n linkOptions={linkOptions}\n linkSelectorStorageKeyPrefix={linkSelectorStorageKeyPrefix}\n variableCategories={variableCategories}\n variableCategoryLabels={variableCategoryLabels}\n variableCategoryOrder={variableCategoryOrder}\n variablePickerOpen={isVariablePickerOpen}\n onVariablePickerOpenChange={setIsVariablePickerOpen}\n openInsertLinkDialog={openInsertLinkDialog}\n />\n )}\n\n <div ref={wrapperRef} className=\"relative\">\n {contentError && (\n <div className=\"flex items-start gap-2 border-b border-rose-200 bg-rose-50 px-4 py-2 text-sm text-rose-800\">\n <FontAwesomeIcon icon={faTriangleExclamation} className=\"mt-0.5 size-3.5 shrink-0\" />\n <p>{contentError}</p>\n </div>\n )}\n\n <EditorContent\n editor={editor}\n className={cn(\n '[&_.ProseMirror]:outline-none',\n '[&_.ProseMirror]:min-h-8',\n '[&_.ProseMirror]:p-4',\n '[&_.ProseMirror]:bg-[#fbfcfe]',\n '[&_.ProseMirror]:shadow-none',\n '[&_.ProseMirror]:whitespace-pre-wrap',\n '[&_.ProseMirror_p]:m-0 [&_.ProseMirror_p]:mb-2',\n '[&_.ProseMirror_p:last-child]:mb-0',\n '[&_.ProseMirror_h1]:text-xl [&_.ProseMirror_h1]:font-bold [&_.ProseMirror_h1]:mb-2',\n '[&_.ProseMirror_h2]:text-lg [&_.ProseMirror_h2]:font-semibold [&_.ProseMirror_h2]:mb-2',\n '[&_.ProseMirror_ul]:list-disc [&_.ProseMirror_ul]:pl-5 [&_.ProseMirror_ul]:mb-2',\n '[&_.ProseMirror_ol]:list-decimal [&_.ProseMirror_ol]:pl-5 [&_.ProseMirror_ol]:mb-2',\n '[&_.ProseMirror_li]:mb-1',\n '[&_.ProseMirror_hr]:border-slate-300 [&_.ProseMirror_hr]:my-4',\n '[&_.ProseMirror_code]:bg-slate-100 [&_.ProseMirror_code]:px-1 [&_.ProseMirror_code]:py-0.5 [&_.ProseMirror_code]:rounded [&_.ProseMirror_code]:text-sm',\n '[&_.ProseMirror_pre]:bg-slate-100 [&_.ProseMirror_pre]:p-3 [&_.ProseMirror_pre]:rounded [&_.ProseMirror_pre]:overflow-x-auto [&_.ProseMirror_pre]:mb-2',\n '[&_.ProseMirror_blockquote]:border-l-4 [&_.ProseMirror_blockquote]:border-slate-300 [&_.ProseMirror_blockquote]:pl-4 [&_.ProseMirror_blockquote]:italic [&_.ProseMirror_blockquote]:text-slate-600 [&_.ProseMirror_blockquote]:mb-2',\n '[&_.ProseMirror_table]:border-collapse [&_.ProseMirror_table]:w-full [&_.ProseMirror_table]:mb-2',\n '[&_.ProseMirror_th]:border [&_.ProseMirror_th]:border-slate-300 [&_.ProseMirror_th]:px-3 [&_.ProseMirror_th]:py-2 [&_.ProseMirror_th]:bg-slate-100 [&_.ProseMirror_th]:text-left',\n '[&_.ProseMirror_td]:border [&_.ProseMirror_td]:border-slate-300 [&_.ProseMirror_td]:px-3 [&_.ProseMirror_td]:py-2',\n '[&_.ProseMirror_a]:text-blue-600 [&_.ProseMirror_a]:underline [&_.ProseMirror_a]:cursor-pointer',\n )}\n {...props}\n />\n\n {hasAnyVariables && !readOnly && (\n <InlineVariablePickerPopover\n open={inlinePicker.state.open}\n onOpenChange={(open) => {\n if (!open) {\n inlinePicker.closePicker();\n }\n }}\n position={{ top: inlinePicker.state.top, left: inlinePicker.state.left }}\n isChildMode={inlinePicker.filteredVariables.isChildMode}\n query={inlinePicker.state.query}\n onQueryChange={inlinePicker.setQuery}\n filteredVariables={inlinePicker.filteredVariables}\n onSelect={inlinePicker.handleSelect}\n onBack={inlinePicker.goBack}\n />\n )}\n </div>\n\n {buttons.includes('link') && editor && (\n <LinkBubbleMenu\n editor={editor}\n onEdit={handleLinkBubbleEdit}\n dialogOpen={insertLinkDialogOpen}\n />\n )}\n </EditorContext.Provider>\n\n <InsertLinkDialog\n open={insertLinkDialogOpen}\n onOpenChange={setInsertLinkDialogOpen}\n initialValues={insertLinkInitialValues}\n onInsert={(values) => {\n insertLink({\n ...values,\n from: insertLinkInitialValues?.from,\n to: insertLinkInitialValues?.to,\n });\n setInsertLinkDialogOpen(false);\n }}\n />\n </VariablePickerProvider>\n </div >\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"TiptapEditor.js","names":[],"sources":["../../src/components/TiptapEditor.tsx"],"sourcesContent":["import {\n useEffect, useCallback, useMemo, useRef, useState,\n} from 'react';\nimport type { ReactNode } from 'react';\nimport { useEditor, EditorContent, EditorContext } from '@tiptap/react';\nimport { getMarkRange, type Editor as TiptapEditorInstance } from '@tiptap/core';\n\nimport { Button } from '@verbb/plugin-kit-react/components';\nimport { LinkDropdown } from './tiptap/LinkDropdown';\nimport type { LinkOptions, LinkOptionsInput } from './tiptap/LinkDropdown';\nimport { VariableDropdown } from './tiptap/VariableDropdown';\nimport type { VariableOption, VariableCategories } from './tiptap/VariableDropdown';\nimport type { VariableTransformerRegistry, VariableConfigureSectionProps, VariableTagLabelResolver } from './tiptap/VariablePickerContext';\nimport { VariablePickerProvider } from './tiptap/VariablePickerContext';\nimport { InlineVariablePickerPopover } from './tiptap/InlineVariablePickerPopover';\nimport { useInlineVariablePicker } from './tiptap/useInlineVariablePicker';\n\nexport type {\n LinkOptions, LinkOptionsInput, VariableOption, VariableCategories,\n};\nimport { LinkBubbleMenu } from './tiptap/LinkBubbleMenu';\nimport { InsertLinkDialog } from './tiptap/InsertLinkDialog';\n\nimport {\n createTiptapExtensions,\n getFatalTiptapContentError,\n normalizeContentArray,\n valueToContent,\n} from './tiptap/editorConfig';\n\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\n\nimport {\n faAlignCenter,\n faAlignJustify,\n faAlignLeft,\n faAlignRight,\n faArrowRotateLeft,\n faArrowRotateRight,\n faBold,\n faBracketsCurly,\n faCode,\n faH1,\n faH2,\n faH3,\n faH4,\n faH5,\n faH6,\n faHighlighter,\n faItalic,\n faListOl,\n faListUl,\n faMinus,\n faQuoteRight,\n faStrikethrough,\n faSubscript,\n faSuperscript,\n faTriangleExclamation,\n\n faUnderline,\n faTextSlash,\n} from '@fortawesome/pro-solid-svg-icons';\n\nimport {\n faFileDashedLine,\n faTable,\n} from '@fortawesome/pro-regular-svg-icons';\n\nimport { cn } from '@verbb/plugin-kit-react/utils';\nimport { useTranslation } from '@verbb/plugin-kit-react/hooks';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@verbb/plugin-kit-react/components/Tooltip';\n\nconst MenuBar = ({\n editor,\n buttons = ['bold', 'italic'],\n linkOptions,\n linkSelectorStorageKeyPrefix,\n variableCategories = {},\n variableCategoryLabels,\n variableCategoryOrder,\n variablePickerOpen,\n onVariablePickerOpenChange,\n openInsertLinkDialog,\n}: {\n editor: TiptapEditorInstance | null | undefined;\n buttons?: string[];\n linkOptions?: LinkOptionsInput;\n linkSelectorStorageKeyPrefix?: string;\n variableCategories?: VariableCategories;\n variableCategoryLabels?: Record<string, string>;\n variableCategoryOrder?: string[];\n variablePickerOpen?: boolean;\n onVariablePickerOpenChange?: (open: boolean) => void;\n openInsertLinkDialog?: (initial?: { url?: string; text?: string; from?: number; to?: number }) => void;\n}) => {\n const t = useTranslation();\n\n if (!editor) {\n return null;\n }\n\n const hasAnyVariables = Object.values(variableCategories ?? {}).some(\n items => {\n return Array.isArray(items) && items.length > 0;\n },\n );\n\n const visibleButtons = buttons.filter((buttonName) => {\n if (buttonName === 'variableTag') {\n return hasAnyVariables;\n }\n\n return true;\n });\n\n const buttonConfig = {\n bold: {\n icon: FontAwesomeIcon,\n iconProp: faBold,\n title: t('Bold'),\n action: () => { return editor.chain().focus().toggleBold().run(); },\n isActive: () => { return editor.isActive('bold'); },\n },\n italic: {\n icon: FontAwesomeIcon,\n iconProp: faItalic,\n title: t('Italic'),\n action: () => { return editor.chain().focus().toggleItalic().run(); },\n isActive: () => { return editor.isActive('italic'); },\n },\n underline: {\n icon: FontAwesomeIcon,\n iconProp: faUnderline,\n title: t('Underline'),\n action: () => { return editor.chain().focus().toggleUnderline().run(); },\n isActive: () => { return editor.isActive('underline'); },\n },\n strikethrough: {\n icon: FontAwesomeIcon,\n iconProp: faStrikethrough,\n title: t('Strikethrough'),\n action: () => { return editor.chain().focus().toggleStrike().run(); },\n isActive: () => { return editor.isActive('strike'); },\n },\n subscript: {\n icon: FontAwesomeIcon,\n iconProp: faSubscript,\n title: t('Subscript'),\n action: () => { return editor.chain().focus().toggleSubscript().run(); },\n isActive: () => { return editor.isActive('subscript'); },\n },\n superscript: {\n icon: FontAwesomeIcon,\n iconProp: faSuperscript,\n title: t('Superscript'),\n action: () => { return editor.chain().focus().toggleSuperscript().run(); },\n isActive: () => { return editor.isActive('superscript'); },\n },\n 'unordered-list': {\n icon: FontAwesomeIcon,\n iconProp: faListUl,\n title: t('Bullet List'),\n action: () => { return editor.chain().focus().toggleBulletList().run(); },\n isActive: () => { return editor.isActive('bulletList'); },\n },\n 'ordered-list': {\n icon: FontAwesomeIcon,\n iconProp: faListOl,\n title: t('Ordered List'),\n action: () => { return editor.chain().focus().toggleOrderedList().run(); },\n isActive: () => { return editor.isActive('orderedList'); },\n },\n blockquote: {\n icon: FontAwesomeIcon,\n iconProp: faQuoteRight,\n title: t('Blockquote'),\n action: () => { return editor.chain().focus().toggleBlockquote().run(); },\n isActive: () => { return editor.isActive('blockquote'); },\n },\n highlight: {\n icon: FontAwesomeIcon,\n iconProp: faHighlighter,\n title: t('Highlight'),\n action: () => { return editor.chain().focus().toggleHighlight().run(); },\n isActive: () => { return editor.isActive('highlight'); },\n },\n code: {\n icon: FontAwesomeIcon,\n iconProp: faBracketsCurly,\n title: t('Inline Code'),\n action: () => { return editor.chain().focus().toggleCode().run(); },\n isActive: () => { return editor.isActive('code'); },\n },\n 'code-block': {\n icon: FontAwesomeIcon,\n iconProp: faCode,\n title: t('Code Block'),\n action: () => { return editor.chain().focus().toggleCodeBlock().run(); },\n isActive: () => { return editor.isActive('codeBlock'); },\n },\n hr: {\n icon: FontAwesomeIcon,\n iconProp: faMinus,\n title: t('Horizontal Rule'),\n action: () => { return editor.chain().focus().setHorizontalRule().run(); },\n },\n 'line-break': {\n icon: FontAwesomeIcon,\n iconProp: faFileDashedLine,\n title: t('Line Break'),\n action: () => { return editor.chain().focus().setHardBreak().run(); },\n },\n 'align-left': {\n icon: FontAwesomeIcon,\n iconProp: faAlignLeft,\n title: t('Align Left'),\n action: () => { return editor.chain().focus().setTextAlign('left').run(); },\n isActive: () => { return editor.isActive({ textAlign: 'left' }); },\n },\n 'align-center': {\n icon: FontAwesomeIcon,\n iconProp: faAlignCenter,\n title: t('Align Center'),\n action: () => { return editor.chain().focus().setTextAlign('center').run(); },\n isActive: () => { return editor.isActive({ textAlign: 'center' }); },\n },\n 'align-right': {\n icon: FontAwesomeIcon,\n iconProp: faAlignRight,\n title: t('Align Right'),\n action: () => { return editor.chain().focus().setTextAlign('right').run(); },\n isActive: () => { return editor.isActive({ textAlign: 'right' }); },\n },\n 'align-justify': {\n icon: FontAwesomeIcon,\n iconProp: faAlignJustify,\n title: t('Justify'),\n action: () => { return editor.chain().focus().setTextAlign('justify').run(); },\n isActive: () => { return editor.isActive({ textAlign: 'justify' }); },\n },\n 'clear-format': {\n icon: FontAwesomeIcon,\n iconProp: faTextSlash,\n title: t('Clear Format'),\n action: () => { return editor.chain().focus().clearNodes().unsetAllMarks().run(); },\n },\n undo: {\n icon: FontAwesomeIcon,\n iconProp: faArrowRotateLeft,\n title: t('Undo'),\n action: () => { return editor.chain().focus().undo().run(); },\n },\n redo: {\n icon: FontAwesomeIcon,\n iconProp: faArrowRotateRight,\n title: t('Redo'),\n action: () => { return editor.chain().focus().redo().run(); },\n },\n link: {\n title: t('Link'),\n isActive: () => { return editor.isActive('link'); },\n isDropdown: true,\n },\n table: {\n icon: FontAwesomeIcon,\n iconProp: faTable,\n title: t('Insert Table'),\n action: () => { return editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(); },\n },\n variableTag: {\n title: t('Insert Variable'),\n isActive: () => { return editor.isActive('variableTag'); },\n isDropdown: true,\n },\n };\n\n // Add heading levels h1–h6\n [1, 2, 3, 4, 5, 6].forEach((level) => {\n buttonConfig[`h${level}`] = {\n icon: FontAwesomeIcon,\n iconProp: {\n 1: faH1,\n 2: faH2,\n 3: faH3,\n 4: faH4,\n 5: faH5,\n 6: faH6,\n }[level],\n title: t('Heading {level}', { level: String(level) }),\n action: () => { return editor.chain().focus().toggleHeading({ level }).run(); },\n isActive: () => { return editor.isActive('heading', { level }); },\n };\n });\n\n const resolveIsActive = (config) => {\n if (!config.isActive) {\n return false;\n }\n return typeof config.isActive === 'function' ? config.isActive() : config.isActive;\n };\n\n const renderedButtons = visibleButtons\n .map((buttonName) => {\n const config = buttonConfig[buttonName];\n\n if (!config) { return null; }\n\n if (config.isDropdown && buttonName === 'link') {\n return (\n <LinkDropdown\n key={buttonName}\n editor={editor}\n linkOptions={linkOptions}\n linkSelectorStorageKeyPrefix={linkSelectorStorageKeyPrefix}\n openInsertLinkDialog={openInsertLinkDialog!}\n title={config.title}\n />\n );\n }\n\n if (config.isDropdown && buttonName === 'variableTag') {\n return (\n <VariableDropdown\n key={buttonName}\n editor={editor}\n variableCategories={variableCategories}\n variableCategoryLabels={variableCategoryLabels}\n variableCategoryOrder={variableCategoryOrder}\n title={config.title}\n open={variablePickerOpen}\n onOpenChange={onVariablePickerOpenChange}\n />\n );\n }\n\n const Icon = config.icon;\n\n return (\n <Tooltip key={buttonName}>\n <TooltipTrigger\n render={\n <Button\n variant=\"transparent\"\n onClick={config.action}\n className={cn(\n 'w-[32px] h-[32px]',\n 'text-[#1c2e36]',\n 'hover:bg-slate-100!',\n resolveIsActive(config) && 'bg-slate-250! hover:bg-slate-250!',\n )}\n >\n <Icon icon={config.iconProp} className=\"size-4\" />\n </Button>\n }\n />\n <TooltipContent sideOffset={4}>{config.title}</TooltipContent>\n </Tooltip>\n );\n })\n .filter(Boolean);\n\n if (renderedButtons.length === 0) {\n return null;\n }\n\n return (\n <div className={cn(\n 'flex flex-wrap relative z-10 gap-1 px-[8px] py-[4px]',\n 'border-b border-[rgba(96,125,159,0.4)] bg-white',\n 'shadow-[0_2px_3px_rgba(49,49,93,.07)]',\n )}>\n {renderedButtons}\n </div>\n );\n};\n\ntype TiptapEditorProps = {\n value?: unknown;\n onChange?: (value: unknown) => void;\n placeholder?: string;\n buttons?: string[];\n tableOptions?: Array<{ rows?: number; cols?: number; withHeaderRow?: boolean }>;\n linkOptions?: LinkOptionsInput;\n linkSelectorStorageKeyPrefix?: string;\n variableCategories?: VariableCategories;\n variableCategoryLabels?: Record<string, string>;\n variableCategoryOrder?: string[];\n variableTransformerRegistry?: VariableTransformerRegistry;\n variablePickerTriggerCharacters?: string[];\n renderVariableConfigureSection?: (props: VariableConfigureSectionProps) => ReactNode;\n resolveVariableTagLabel?: VariableTagLabelResolver;\n toolbarContent?: (params: {\n editor: TiptapEditorInstance | null;\n variableCategories: VariableCategories;\n variableCategoryLabels?: Record<string, string>;\n variableCategoryOrder?: string[];\n variablePickerOpen: boolean;\n onVariablePickerOpenChange: (open: boolean) => void;\n }) => ReactNode;\n rows?: number;\n className?: string;\n isInvalid?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n invalidContentMessage?: string;\n [key: string]: unknown;\n};\n\nexport const TiptapEditor = ({\n value = '',\n onChange,\n buttons = ['bold', 'italic'],\n tableOptions = [],\n linkOptions,\n linkSelectorStorageKeyPrefix,\n variableCategories = {},\n variableCategoryLabels,\n variableCategoryOrder,\n variableTransformerRegistry,\n variablePickerTriggerCharacters = ['@'],\n renderVariableConfigureSection,\n resolveVariableTagLabel,\n toolbarContent,\n rows,\n className,\n isInvalid,\n disabled = false,\n readOnly = false,\n invalidContentMessage,\n ...props\n}: TiptapEditorProps) => {\n // Ensure value is a string and handle null/undefined\n // const safeValue = value || '';\n const t = useTranslation();\n\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const handleKeyDownRef = useRef<import('./tiptap/useInlineVariablePicker').InlineVariablePickerHandleKeyDown | null>(null);\n const lastEmittedContentRef = useRef<string | null>(null);\n\n const extensions = useMemo(() => {\n return createTiptapExtensions({ trailingCursorText: '\\u2060' });\n }, []);\n const [isVariablePickerOpen, setIsVariablePickerOpen] = useState(false);\n const hasAnyVariables = useMemo(() => {\n return Object.values(variableCategories || {}).some((variables) => {\n return Array.isArray(variables) && variables.length > 0;\n });\n }, [variableCategories]);\n const editorContent = useMemo(() => {\n return valueToContent(value, { trailingCursorText: '\\u2060' });\n }, [value]);\n const contentError = useMemo(() => {\n const detectedError = getFatalTiptapContentError(value);\n return detectedError ? (invalidContentMessage || detectedError) : '';\n }, [invalidContentMessage, value]);\n\n const serializeContent = (content: unknown) => {\n return normalizeContentArray(content);\n };\n\n const serializeEditorDocument = useCallback((editorInstance: NonNullable<ReturnType<typeof useEditor>>) => {\n return JSON.stringify(serializeContent(editorInstance.getJSON().content));\n }, []);\n\n const editor = useEditor({\n extensions,\n content: contentError ? null : editorContent,\n editable: !disabled && !readOnly,\n editorProps: {\n handleKeyDown: (view, event) => {\n return handleKeyDownRef.current?.(view, event) ?? false;\n },\n },\n onUpdate: ({ editor: editorInstance }) => {\n const serialized = serializeContent(editorInstance.getJSON().content);\n lastEmittedContentRef.current = JSON.stringify(serialized);\n\n if (onChange) {\n onChange(serialized);\n }\n },\n });\n\n const inlinePicker = useInlineVariablePicker(editor, {\n variableCategories,\n variableCategoryLabels,\n variableCategoryOrder,\n variablePickerTriggerCharacters,\n disabled,\n readOnly,\n wrapperRef,\n onOpenDropdown: () => {\n return setIsVariablePickerOpen(true);\n },\n });\n\n useEffect(() => {\n handleKeyDownRef.current = inlinePicker.handleKeyDown;\n }, [inlinePicker.handleKeyDown]);\n\n const [insertLinkDialogOpen, setInsertLinkDialogOpen] = useState(false);\n const [insertLinkInitialValues, setInsertLinkInitialValues] = useState<{ url?: string; text?: string; openInNewTab?: boolean; from?: number; to?: number } | undefined>();\n const editorMinHeight = useMemo(() => {\n const normalizedRows = Math.max(1, Number(rows || 0));\n const lineHeight = 24;\n const verticalPadding = 32;\n\n return `${(normalizedRows * lineHeight) + verticalPadding}px`;\n }, [rows]);\n\n useEffect(() => {\n if (!editor?.view?.dom) {\n return;\n }\n\n editor.view.dom.style.minHeight = editorMinHeight;\n }, [editor, editorMinHeight]);\n\n const openInsertLinkDialog = useCallback((initial?: { url?: string; text?: string; from?: number; to?: number }) => {\n if (initial) {\n const openInNewTab = editor?.isActive('link') ? editor.getAttributes('link').target === '_blank' : false;\n setInsertLinkInitialValues({ ...initial, openInNewTab });\n } else {\n setInsertLinkInitialValues(undefined);\n }\n setInsertLinkDialogOpen(true);\n }, [editor]);\n\n const insertLink = useCallback(\n (params: { url: string; text: string; openInNewTab: boolean; from?: number; to?: number }) => {\n if (!editor) { return; }\n const {\n url, text, openInNewTab, from: fromParam, to: toParam,\n } = params;\n const chain = editor.chain().focus();\n const linkAttrs: { href: string; target?: string | null } = { href: url };\n if (openInNewTab) {\n linkAttrs.target = '_blank';\n }\n\n const content = {\n type: 'text',\n text: text.trim() || url,\n marks: [{ type: 'link', attrs: linkAttrs }],\n };\n\n if (typeof fromParam === 'number' && typeof toParam === 'number' && fromParam !== toParam) {\n chain.insertContentAt({ from: fromParam, to: toParam }, [content]).run();\n } else {\n const { from, to } = editor.state.selection;\n const selectedText = editor.state.doc.textBetween(from, to, ' ');\n if (selectedText) {\n chain.extendMarkRange('link').setLink(linkAttrs).run();\n } else {\n chain.insertContent([content]).run();\n }\n }\n },\n [editor],\n );\n\n // Watch for value changes and update editor content\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const incomingContent = contentError ? null : editorContent;\n const incomingSerialized = JSON.stringify(incomingContent?.content ?? []);\n const currentSerialized = serializeEditorDocument(editor);\n const isVariableConfigActive = Boolean(\n document.activeElement?.closest('[data-variable-config-popover]'),\n );\n\n if (incomingSerialized === currentSerialized) {\n return;\n }\n\n if (lastEmittedContentRef.current === incomingSerialized) {\n return;\n }\n\n if (\n !readOnly\n && (\n editor.isFocused\n || isVariableConfigActive\n || (\n lastEmittedContentRef.current\n && currentSerialized === lastEmittedContentRef.current\n && incomingSerialized !== lastEmittedContentRef.current\n )\n )\n ) {\n return;\n }\n\n editor.commands.setContent(incomingContent ?? { type: 'doc', content: [] });\n lastEmittedContentRef.current = incomingSerialized;\n }, [contentError, editor, editorContent, readOnly, serializeEditorDocument]);\n\n const handleLinkBubbleEdit = useCallback(() => {\n if (!editor) { return; }\n const { href } = editor.getAttributes('link');\n const { state } = editor;\n const linkType = state.schema.marks.link;\n const range = getMarkRange(state.selection.$from, linkType);\n const from = range?.from ?? state.selection.from;\n const to = range?.to ?? state.selection.to;\n const text = editor.state.doc.textBetween(from, to, ' ');\n openInsertLinkDialog({\n url: href, text, from, to,\n });\n }, [editor, openInsertLinkDialog]);\n\n return (\n <div className={cn(\n 'border border-[rgba(96,125,159,0.4)] rounded-sm overflow-hidden',\n isInvalid && [\n 'border-rose-600!',\n '[focus-visible:shadow-[0_0_0_1px_var(--color-rose-600),0_0_4px_0_hsl(from_var(--color-rose-600)_h_s_l/0.7)]!',\n ],\n className,\n )}>\n <VariablePickerProvider\n variableCategories={variableCategories}\n variableCategoryLabels={variableCategoryLabels}\n variableCategoryOrder={variableCategoryOrder}\n variableTransformerRegistry={variableTransformerRegistry}\n renderVariableConfigureSection={renderVariableConfigureSection}\n resolveVariableTagLabel={resolveVariableTagLabel}\n >\n <EditorContext.Provider value={{ editor }}>\n {toolbarContent ? (\n toolbarContent({\n editor,\n variableCategories,\n variableCategoryLabels,\n variableCategoryOrder,\n variablePickerOpen: isVariablePickerOpen,\n onVariablePickerOpenChange: setIsVariablePickerOpen,\n })\n ) : (\n <MenuBar\n editor={editor}\n buttons={buttons}\n tableOptions={tableOptions}\n linkOptions={linkOptions}\n linkSelectorStorageKeyPrefix={linkSelectorStorageKeyPrefix}\n variableCategories={variableCategories}\n variableCategoryLabels={variableCategoryLabels}\n variableCategoryOrder={variableCategoryOrder}\n variablePickerOpen={isVariablePickerOpen}\n onVariablePickerOpenChange={setIsVariablePickerOpen}\n openInsertLinkDialog={openInsertLinkDialog}\n />\n )}\n\n <div ref={wrapperRef} className=\"relative\">\n {contentError && (\n <div className=\"flex items-start gap-2 border-b border-rose-200 bg-rose-50 px-4 py-2 text-sm text-rose-800\">\n <FontAwesomeIcon icon={faTriangleExclamation} className=\"mt-0.5 size-3.5 shrink-0\" />\n <p>{contentError}</p>\n </div>\n )}\n\n <EditorContent\n editor={editor}\n className={cn(\n '[&_.ProseMirror]:outline-none',\n '[&_.ProseMirror]:min-h-8',\n '[&_.ProseMirror]:p-4',\n '[&_.ProseMirror]:bg-[#fbfcfe]',\n '[&_.ProseMirror]:shadow-none',\n '[&_.ProseMirror]:whitespace-pre-wrap',\n '[&_.ProseMirror_p]:m-0 [&_.ProseMirror_p]:mb-2',\n '[&_.ProseMirror_p:last-child]:mb-0',\n '[&_.ProseMirror_h1]:text-xl [&_.ProseMirror_h1]:font-bold [&_.ProseMirror_h1]:mb-2',\n '[&_.ProseMirror_h2]:text-lg [&_.ProseMirror_h2]:font-semibold [&_.ProseMirror_h2]:mb-2',\n '[&_.ProseMirror_ul]:list-disc [&_.ProseMirror_ul]:pl-5 [&_.ProseMirror_ul]:mb-2',\n '[&_.ProseMirror_ol]:list-decimal [&_.ProseMirror_ol]:pl-5 [&_.ProseMirror_ol]:mb-2',\n '[&_.ProseMirror_li]:mb-1',\n '[&_.ProseMirror_hr]:border-slate-300 [&_.ProseMirror_hr]:my-4',\n '[&_.ProseMirror_code]:bg-slate-100 [&_.ProseMirror_code]:px-1 [&_.ProseMirror_code]:py-0.5 [&_.ProseMirror_code]:rounded [&_.ProseMirror_code]:text-sm',\n '[&_.ProseMirror_pre]:bg-slate-100 [&_.ProseMirror_pre]:p-3 [&_.ProseMirror_pre]:rounded [&_.ProseMirror_pre]:overflow-x-auto [&_.ProseMirror_pre]:mb-2',\n '[&_.ProseMirror_blockquote]:border-l-4 [&_.ProseMirror_blockquote]:border-slate-300 [&_.ProseMirror_blockquote]:pl-4 [&_.ProseMirror_blockquote]:italic [&_.ProseMirror_blockquote]:text-slate-600 [&_.ProseMirror_blockquote]:mb-2',\n '[&_.ProseMirror_table]:border-collapse [&_.ProseMirror_table]:w-full [&_.ProseMirror_table]:mb-2',\n '[&_.ProseMirror_th]:border [&_.ProseMirror_th]:border-slate-300 [&_.ProseMirror_th]:px-3 [&_.ProseMirror_th]:py-2 [&_.ProseMirror_th]:bg-slate-100 [&_.ProseMirror_th]:text-left',\n '[&_.ProseMirror_td]:border [&_.ProseMirror_td]:border-slate-300 [&_.ProseMirror_td]:px-3 [&_.ProseMirror_td]:py-2',\n '[&_.ProseMirror_a]:text-blue-600 [&_.ProseMirror_a]:underline [&_.ProseMirror_a]:cursor-pointer',\n )}\n {...props}\n />\n\n {hasAnyVariables && !readOnly && (\n <InlineVariablePickerPopover\n open={inlinePicker.state.open}\n onOpenChange={(open) => {\n if (!open) {\n inlinePicker.closePicker();\n }\n }}\n position={{ top: inlinePicker.state.top, left: inlinePicker.state.left }}\n isChildMode={inlinePicker.filteredVariables.isChildMode}\n query={inlinePicker.state.query}\n onQueryChange={inlinePicker.setQuery}\n filteredVariables={inlinePicker.filteredVariables}\n onSelect={inlinePicker.handleSelect}\n onBack={inlinePicker.goBack}\n />\n )}\n </div>\n\n {buttons.includes('link') && editor && (\n <LinkBubbleMenu\n editor={editor}\n onEdit={handleLinkBubbleEdit}\n dialogOpen={insertLinkDialogOpen}\n />\n )}\n </EditorContext.Provider>\n\n <InsertLinkDialog\n open={insertLinkDialogOpen}\n onOpenChange={setInsertLinkDialogOpen}\n initialValues={insertLinkInitialValues}\n onInsert={(values) => {\n insertLink({\n ...values,\n from: insertLinkInitialValues?.from,\n to: insertLinkInitialValues?.to,\n });\n setInsertLinkDialogOpen(false);\n }}\n />\n </VariablePickerProvider>\n </div >\n );\n};\n"],"mappings":"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"}
@@ -1,15 +1,20 @@
1
- export declare const TiptapInput: ({ value, onChange, className, isInvalid, disabled, readOnly, variableCategories, variableCategoryLabels, variableCategoryOrder, variableTransformerRegistry, variablePickerTriggerCharacters, ...props }: {
2
- [x: string]: any;
3
- value?: string | undefined;
4
- onChange: any;
5
- className: any;
6
- isInvalid: any;
7
- disabled?: boolean | undefined;
8
- readOnly?: boolean | undefined;
9
- variableCategories?: {} | undefined;
10
- variableCategoryLabels: any;
11
- variableCategoryOrder: any;
12
- variableTransformerRegistry: any;
13
- variablePickerTriggerCharacters?: string[] | undefined;
1
+ import { ReactNode } from 'react';
2
+ import { VariableCategories } from './tiptap/VariableDropdown';
3
+ import { VariableConfigureSectionProps, VariableTransformerRegistry, VariableTagLabelResolver } from './tiptap/VariablePickerContext';
4
+ export declare const TiptapInput: ({ value, onChange, className, isInvalid, disabled, readOnly, variableCategories, variableCategoryLabels, variableCategoryOrder, variableTransformerRegistry, variablePickerTriggerCharacters, renderVariableConfigureSection, resolveVariableTagLabel, ...props }: {
5
+ value?: string;
6
+ onChange?: (value: string) => void;
7
+ className?: string;
8
+ isInvalid?: boolean;
9
+ disabled?: boolean;
10
+ readOnly?: boolean;
11
+ variableCategories?: VariableCategories;
12
+ variableCategoryLabels?: Record<string, string>;
13
+ variableCategoryOrder?: string[];
14
+ variableTransformerRegistry?: VariableTransformerRegistry;
15
+ variablePickerTriggerCharacters?: string[];
16
+ renderVariableConfigureSection?: (props: VariableConfigureSectionProps) => ReactNode;
17
+ resolveVariableTagLabel?: VariableTagLabelResolver;
18
+ [key: string]: unknown;
14
19
  }) => import("react/jsx-runtime").JSX.Element;
15
20
  //# sourceMappingURL=TiptapInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TiptapInput.d.ts","sourceRoot":"","sources":["../../src/components/TiptapInput.tsx"],"names":[],"mappings":"AAyBA,eAAO,MAAM,WAAW,GAAI;;;;;;;;;;;;;CAa3B,4CAgJA,CAAC"}
1
+ {"version":3,"file":"TiptapInput.d.ts","sourceRoot":"","sources":["../../src/components/TiptapInput.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4DAA4D,CAAC;AACrG,OAAO,KAAK,EAAE,6BAA6B,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,MAAM,iEAAiE,CAAC;AAiB5K,eAAO,MAAM,WAAW,GAAI,mQAezB;IACC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D,+BAA+B,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3C,8BAA8B,CAAC,EAAE,CAAC,KAAK,EAAE,6BAA6B,KAAK,SAAS,CAAC;IACrF,uBAAuB,CAAC,EAAE,wBAAwB,CAAC;IACnD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B,4CAkJA,CAAC"}
@@ -13,7 +13,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
13
13
  import { EditorContent, useEditor } from "@tiptap/react";
14
14
  //#region src/components/TiptapInput.tsx
15
15
  var OneLinerDocument = Document.extend({ content: "inline*" });
16
- var TiptapInput = ({ value = "", onChange, className, isInvalid, disabled = false, readOnly = false, variableCategories = {}, variableCategoryLabels, variableCategoryOrder, variableTransformerRegistry, variablePickerTriggerCharacters = ["@"], ...props }) => {
16
+ var TiptapInput = ({ value = "", onChange, className, isInvalid, disabled = false, readOnly = false, variableCategories = {}, variableCategoryLabels, variableCategoryOrder, variableTransformerRegistry, variablePickerTriggerCharacters = ["@"], renderVariableConfigureSection, resolveVariableTagLabel, ...props }) => {
17
17
  const wrapperRef = useRef(null);
18
18
  const [isVariablePickerOpen, setIsVariablePickerOpen] = useState(false);
19
19
  const handleKeyDownRef = useRef(null);
@@ -82,6 +82,8 @@ var TiptapInput = ({ value = "", onChange, className, isInvalid, disabled = fals
82
82
  variableCategoryLabels,
83
83
  variableCategoryOrder,
84
84
  variableTransformerRegistry,
85
+ renderVariableConfigureSection,
86
+ resolveVariableTagLabel,
85
87
  children: /* @__PURE__ */ jsxs("div", {
86
88
  ref: wrapperRef,
87
89
  className: cn("relative", className),