@lattice-php/lattice 0.24.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/dist/action/components/action-form.js +37 -5
  2. package/dist/action/components/action-form.js.map +1 -1
  3. package/dist/action/components/action-group.js +1 -1
  4. package/dist/action/components/action-group.js.map +1 -1
  5. package/dist/action/components/action.js +3 -2
  6. package/dist/action/components/action.js.map +1 -1
  7. package/dist/action/hooks/use-action.js +2 -1
  8. package/dist/action/hooks/use-action.js.map +1 -1
  9. package/dist/appearance/index.d.ts +1 -1
  10. package/dist/appearance/index.js +8 -8
  11. package/dist/appearance/index.js.map +1 -1
  12. package/dist/chat/components/prompt-input.js +1 -2
  13. package/dist/chat/components/prompt-input.js.map +1 -1
  14. package/dist/create-app.js +2 -2
  15. package/dist/create-app.js.map +1 -1
  16. package/dist/form/components/base/submit-button.d.ts +4 -3
  17. package/dist/form/components/base/submit-button.js +2 -1
  18. package/dist/form/components/base/submit-button.js.map +1 -1
  19. package/dist/form/components/fields/date-picker-field.js +3 -3
  20. package/dist/form/components/fields/date-picker-field.js.map +1 -1
  21. package/dist/form/components/fields/number-input.js +1 -1
  22. package/dist/form/components/fields/number-input.js.map +1 -1
  23. package/dist/form/components/fields/rich-editor-field.js +1 -1
  24. package/dist/form/components/fields/rich-editor-field.js.map +1 -1
  25. package/dist/form/components/fields/row-action-menu.js +3 -3
  26. package/dist/form/components/fields/row-action-menu.js.map +1 -1
  27. package/dist/form/components/fields/row-actions.d.ts +1 -1
  28. package/dist/form/components/fields/row-actions.js +4 -4
  29. package/dist/form/components/fields/row-actions.js.map +1 -1
  30. package/dist/form/components/fields/toggle.js +1 -1
  31. package/dist/form/components/fields/toggle.js.map +1 -1
  32. package/dist/form/components/form.js +15 -5
  33. package/dist/form/components/form.js.map +1 -1
  34. package/dist/form/components/index.d.ts +1 -0
  35. package/dist/form/components/index.js +2 -1
  36. package/dist/form/components/wizard.d.ts +3 -0
  37. package/dist/form/components/wizard.js +148 -0
  38. package/dist/form/components/wizard.js.map +1 -0
  39. package/dist/form/embed.d.ts +1 -1
  40. package/dist/form/embed.js +2 -2
  41. package/dist/form/hooks/context.d.ts +7 -2
  42. package/dist/form/hooks/context.js +4 -1
  43. package/dist/form/hooks/context.js.map +1 -1
  44. package/dist/form/index.js +2 -1
  45. package/dist/form/lib/field-errors.d.ts +2 -0
  46. package/dist/form/lib/field-errors.js +5 -1
  47. package/dist/form/lib/field-errors.js.map +1 -1
  48. package/dist/form/lib/field-props.d.ts +6 -0
  49. package/dist/form/lib/field-props.js +7 -1
  50. package/dist/form/lib/field-props.js.map +1 -1
  51. package/dist/form/lib/prefill-targets.js +2 -3
  52. package/dist/form/lib/prefill-targets.js.map +1 -1
  53. package/dist/form/lib/wizard-steps.d.ts +5 -0
  54. package/dist/form/lib/wizard-steps.js +44 -0
  55. package/dist/form/lib/wizard-steps.js.map +1 -0
  56. package/dist/form/plugin.js +4 -1
  57. package/dist/form/plugin.js.map +1 -1
  58. package/dist/i18n/translatable.d.ts +1 -0
  59. package/dist/i18n/translatable.js +4 -1
  60. package/dist/i18n/translatable.js.map +1 -1
  61. package/dist/index.d.ts +2 -2
  62. package/dist/index.js +2 -2
  63. package/dist/lattice.css +183 -115
  64. package/dist/layout/components/callouts.js +3 -2
  65. package/dist/layout/components/callouts.js.map +1 -1
  66. package/dist/notifications/components/notification-item.js +10 -5
  67. package/dist/notifications/components/notification-item.js.map +1 -1
  68. package/dist/notifications/components/notifications.js +2 -4
  69. package/dist/notifications/components/notifications.js.map +1 -1
  70. package/dist/table/components/bulk-bar.js +2 -0
  71. package/dist/table/components/bulk-bar.js.map +1 -1
  72. package/dist/table/components/cells/badge-cell.js +3 -6
  73. package/dist/table/components/cells/badge-cell.js.map +1 -1
  74. package/dist/table/components/cells/text-cell.js +6 -9
  75. package/dist/table/components/cells/text-cell.js.map +1 -1
  76. package/dist/table/components/column-filter-control.js +2 -2
  77. package/dist/table/components/column-filter-control.js.map +1 -1
  78. package/dist/table/components/filter-bar.js +1 -1
  79. package/dist/table/components/filter-bar.js.map +1 -1
  80. package/dist/table/components/filter-controls.js +4 -1
  81. package/dist/table/components/filter-controls.js.map +1 -1
  82. package/dist/table/components/pagination.js +6 -6
  83. package/dist/table/components/pagination.js.map +1 -1
  84. package/dist/table/lib/bulk.d.ts +3 -2
  85. package/dist/table/lib/bulk.js +2 -1
  86. package/dist/table/lib/bulk.js.map +1 -1
  87. package/dist/toast/callout.js +6 -3
  88. package/dist/toast/callout.js.map +1 -1
  89. package/dist/toast/toast.js +3 -1
  90. package/dist/toast/toast.js.map +1 -1
  91. package/dist/toast/toaster.js +2 -2
  92. package/dist/toast/toaster.js.map +1 -1
  93. package/dist/toast/variant-styles.js +15 -1
  94. package/dist/toast/variant-styles.js.map +1 -1
  95. package/dist/types/generated.d.ts +31 -16
  96. package/dist/ui/action-menu-context.d.ts +1 -1
  97. package/dist/ui/action-menu-context.js +1 -1
  98. package/dist/ui/action-menu-context.js.map +1 -1
  99. package/dist/ui/affix-group.js +1 -1
  100. package/dist/ui/affix-group.js.map +1 -1
  101. package/dist/ui/badge.d.ts +4 -7
  102. package/dist/ui/badge.js +11 -17
  103. package/dist/ui/badge.js.map +1 -1
  104. package/dist/ui/button.d.ts +6 -5
  105. package/dist/ui/button.js +154 -15
  106. package/dist/ui/button.js.map +1 -1
  107. package/dist/ui/chart-view.js +9 -7
  108. package/dist/ui/chart-view.js.map +1 -1
  109. package/dist/ui/checkbox.js +1 -1
  110. package/dist/ui/checkbox.js.map +1 -1
  111. package/dist/ui/confirm-dialog.d.ts +4 -3
  112. package/dist/ui/confirm-dialog.js +3 -2
  113. package/dist/ui/confirm-dialog.js.map +1 -1
  114. package/dist/ui/control.d.ts +1 -1
  115. package/dist/ui/control.js +1 -1
  116. package/dist/ui/control.js.map +1 -1
  117. package/dist/ui/dialog.js +1 -1
  118. package/dist/ui/dialog.js.map +1 -1
  119. package/dist/ui/dropdown-menu.d.ts +2 -2
  120. package/dist/ui/dropdown-menu.js +2 -2
  121. package/dist/ui/dropdown-menu.js.map +1 -1
  122. package/dist/ui/icon-button.d.ts +3 -3
  123. package/dist/ui/icon-button.js +6 -6
  124. package/dist/ui/icon-button.js.map +1 -1
  125. package/dist/ui/image-preview.js +1 -1
  126. package/dist/ui/image-preview.js.map +1 -1
  127. package/dist/ui/index.d.ts +2 -2
  128. package/dist/ui/index.js +2 -2
  129. package/dist/ui/info-tooltip.js +1 -1
  130. package/dist/ui/info-tooltip.js.map +1 -1
  131. package/dist/ui/input-otp.js +1 -1
  132. package/dist/ui/input-otp.js.map +1 -1
  133. package/dist/ui/label.js +1 -1
  134. package/dist/ui/label.js.map +1 -1
  135. package/dist/ui/password-input.js +1 -1
  136. package/dist/ui/password-input.js.map +1 -1
  137. package/dist/ui/progress.js +2 -2
  138. package/dist/ui/progress.js.map +1 -1
  139. package/dist/ui/text.js +1 -1
  140. package/dist/ui/tooltip.js +1 -1
  141. package/dist/ui/tooltip.js.map +1 -1
  142. package/dist/vite-typescript-refresh.d.ts +9 -0
  143. package/dist/vite-typescript-refresh.js +47 -0
  144. package/dist/vite-typescript-refresh.js.map +1 -0
  145. package/dist/vite.d.ts +22 -1
  146. package/dist/vite.js +60 -7
  147. package/dist/vite.js.map +1 -1
  148. package/dist-standalone/chunks/{chart-view-DEwGTt9d.js → chart-view-8xEKTUJV.js} +1 -1
  149. package/dist-standalone/chunks/{date-picker-field-CCQ9nWx0.js → date-picker-field-cdhxtVSG.js} +1 -1
  150. package/dist-standalone/chunks/{rich-editor-field-B9Nv1qia.js → rich-editor-field-47ov3Bny.js} +1 -1
  151. package/dist-standalone/lattice.css +1 -1
  152. package/dist-standalone/lattice.js +15 -15
  153. package/dist-standalone/manifest.json +5 -5
  154. package/package.json +1 -1
@@ -14,7 +14,7 @@ var NumberInputComponent = ({ node }) => {
14
14
  className: "flex items-center gap-3",
15
15
  children: [/* @__PURE__ */ jsx("input", {
16
16
  "aria-label": props.label ?? "",
17
- className: "h-2 w-full cursor-pointer appearance-none rounded-lt-sm bg-lt-muted accent-lt-primary disabled:cursor-not-allowed disabled:opacity-50",
17
+ className: "h-2 w-full cursor-pointer appearance-none rounded-lt-sm bg-lt-muted accent-lt-primary disabled:cursor-not-allowed disabled:accent-lt-disabled",
18
18
  "data-test": testId,
19
19
  disabled: disabled || readOnly,
20
20
  id: name,
@@ -1 +1 @@
1
- {"version":3,"file":"number-input.js","names":[],"sources":["../../../../resources/js/form/components/fields/number-input.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { AffixGroup } from \"@lattice-php/lattice/ui/affix-group\";\nimport { Input } from \"@lattice-php/lattice/ui/input\";\nimport { SimpleField } from \"./simple-field\";\n\nexport const NumberInputComponent: RendererComponent<\"field.number-input\"> = ({ node }) => {\n const props = node.props;\n\n return (\n <SimpleField node={node} label={props.label ?? \"\"}>\n {({ name, testId, value, readOnly, disabled, commit }) => {\n const onChange = (event: React.ChangeEvent<HTMLInputElement>): void =>\n commit(event.target.value);\n\n return props.slider ? (\n <div className=\"flex items-center gap-3\">\n <input\n aria-label={props.label ?? \"\"}\n className=\"h-2 w-full cursor-pointer appearance-none rounded-lt-sm bg-lt-muted accent-lt-primary disabled:cursor-not-allowed disabled:opacity-50\"\n data-test={testId}\n disabled={disabled || readOnly}\n id={name}\n max={props.max ?? undefined}\n min={props.min ?? undefined}\n name={name}\n onChange={onChange}\n step={props.step ?? undefined}\n tabIndex={props.tabIndex ?? undefined}\n type=\"range\"\n value={value}\n />\n <output className=\"w-10 shrink-0 text-right text-sm tabular-nums text-lt-fg\">\n {value}\n </output>\n </div>\n ) : (\n <AffixGroup prefix={props.prefix} suffix={props.suffix}>\n {(controlClassName) => (\n <Input\n autoFocus={props.autoFocus ?? false}\n className={controlClassName}\n data-test={testId}\n disabled={disabled}\n id={name}\n max={props.max ?? undefined}\n min={props.min ?? undefined}\n name={name}\n onChange={onChange}\n placeholder={props.placeholder ?? \"\"}\n readOnly={readOnly}\n step={props.step ?? undefined}\n tabIndex={props.tabIndex ?? undefined}\n type=\"number\"\n value={value}\n />\n )}\n </AffixGroup>\n );\n }}\n </SimpleField>\n );\n};\n"],"mappings":";;;;;AAKA,IAAa,wBAAiE,EAAE,WAAW;CACzF,MAAM,QAAQ,KAAK;CAEnB,OACE,oBAAC,aAAD;EAAmB;EAAM,OAAO,MAAM,SAAS;aAC3C,EAAE,MAAM,QAAQ,OAAO,UAAU,UAAU,aAAa;GACxD,MAAM,YAAY,UAChB,OAAO,MAAM,OAAO,KAAK;GAE3B,OAAO,MAAM,SACX,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,SAAD;KACE,cAAY,MAAM,SAAS;KAC3B,WAAU;KACV,aAAW;KACX,UAAU,YAAY;KACtB,IAAI;KACJ,KAAK,MAAM,OAAO,KAAA;KAClB,KAAK,MAAM,OAAO,KAAA;KACZ;KACI;KACV,MAAM,MAAM,QAAQ,KAAA;KACpB,UAAU,MAAM,YAAY,KAAA;KAC5B,MAAK;KACE;IACR,CAAA,GACD,oBAAC,UAAD;KAAQ,WAAU;eACf;IACK,CAAA,CACL;QAEL,oBAAC,YAAD;IAAY,QAAQ,MAAM;IAAQ,QAAQ,MAAM;eAC5C,qBACA,oBAAC,OAAD;KACE,WAAW,MAAM,aAAa;KAC9B,WAAW;KACX,aAAW;KACD;KACV,IAAI;KACJ,KAAK,MAAM,OAAO,KAAA;KAClB,KAAK,MAAM,OAAO,KAAA;KACZ;KACI;KACV,aAAa,MAAM,eAAe;KACxB;KACV,MAAM,MAAM,QAAQ,KAAA;KACpB,UAAU,MAAM,YAAY,KAAA;KAC5B,MAAK;KACE;IACR,CAAA;GAEO,CAAA;EAEhB;CACW,CAAA;AAEjB"}
1
+ {"version":3,"file":"number-input.js","names":[],"sources":["../../../../resources/js/form/components/fields/number-input.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { AffixGroup } from \"@lattice-php/lattice/ui/affix-group\";\nimport { Input } from \"@lattice-php/lattice/ui/input\";\nimport { SimpleField } from \"./simple-field\";\n\nexport const NumberInputComponent: RendererComponent<\"field.number-input\"> = ({ node }) => {\n const props = node.props;\n\n return (\n <SimpleField node={node} label={props.label ?? \"\"}>\n {({ name, testId, value, readOnly, disabled, commit }) => {\n const onChange = (event: React.ChangeEvent<HTMLInputElement>): void =>\n commit(event.target.value);\n\n return props.slider ? (\n <div className=\"flex items-center gap-3\">\n <input\n aria-label={props.label ?? \"\"}\n className=\"h-2 w-full cursor-pointer appearance-none rounded-lt-sm bg-lt-muted accent-lt-primary disabled:cursor-not-allowed disabled:accent-lt-disabled\"\n data-test={testId}\n disabled={disabled || readOnly}\n id={name}\n max={props.max ?? undefined}\n min={props.min ?? undefined}\n name={name}\n onChange={onChange}\n step={props.step ?? undefined}\n tabIndex={props.tabIndex ?? undefined}\n type=\"range\"\n value={value}\n />\n <output className=\"w-10 shrink-0 text-right text-sm tabular-nums text-lt-fg\">\n {value}\n </output>\n </div>\n ) : (\n <AffixGroup prefix={props.prefix} suffix={props.suffix}>\n {(controlClassName) => (\n <Input\n autoFocus={props.autoFocus ?? false}\n className={controlClassName}\n data-test={testId}\n disabled={disabled}\n id={name}\n max={props.max ?? undefined}\n min={props.min ?? undefined}\n name={name}\n onChange={onChange}\n placeholder={props.placeholder ?? \"\"}\n readOnly={readOnly}\n step={props.step ?? undefined}\n tabIndex={props.tabIndex ?? undefined}\n type=\"number\"\n value={value}\n />\n )}\n </AffixGroup>\n );\n }}\n </SimpleField>\n );\n};\n"],"mappings":";;;;;AAKA,IAAa,wBAAiE,EAAE,WAAW;CACzF,MAAM,QAAQ,KAAK;CAEnB,OACE,oBAAC,aAAD;EAAmB;EAAM,OAAO,MAAM,SAAS;aAC3C,EAAE,MAAM,QAAQ,OAAO,UAAU,UAAU,aAAa;GACxD,MAAM,YAAY,UAChB,OAAO,MAAM,OAAO,KAAK;GAE3B,OAAO,MAAM,SACX,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,SAAD;KACE,cAAY,MAAM,SAAS;KAC3B,WAAU;KACV,aAAW;KACX,UAAU,YAAY;KACtB,IAAI;KACJ,KAAK,MAAM,OAAO,KAAA;KAClB,KAAK,MAAM,OAAO,KAAA;KACZ;KACI;KACV,MAAM,MAAM,QAAQ,KAAA;KACpB,UAAU,MAAM,YAAY,KAAA;KAC5B,MAAK;KACE;IACR,CAAA,GACD,oBAAC,UAAD;KAAQ,WAAU;eACf;IACK,CAAA,CACL;QAEL,oBAAC,YAAD;IAAY,QAAQ,MAAM;IAAQ,QAAQ,MAAM;eAC5C,qBACA,oBAAC,OAAD;KACE,WAAW,MAAM,aAAa;KAC9B,WAAW;KACX,aAAW;KACD;KACV,IAAI;KACJ,KAAK,MAAM,OAAO,KAAA;KAClB,KAAK,MAAM,OAAO,KAAA;KACZ;KACI;KACV,aAAa,MAAM,eAAe;KACxB;KACV,MAAM,MAAM,QAAQ,KAAA;KACpB,UAAU,MAAM,YAAY,KAAA;KAC5B,MAAK;KACE;IACR,CAAA;GAEO,CAAA;EAEhB;CACW,CAAA;AAEjB"}
@@ -83,7 +83,7 @@ var RichEditorField = ({ node }) => {
83
83
  name: domName,
84
84
  required,
85
85
  children: [/* @__PURE__ */ jsxs("div", {
86
- className: cn("overflow-hidden rounded-lt-sm border border-lt-input bg-transparent shadow-lt-xs focus-within:border-lt-ring focus-within:ring-[3px] focus-within:ring-lt-ring/50", locked && "opacity-60"),
86
+ className: cn("overflow-hidden rounded-lt-sm border border-lt-input bg-transparent shadow-lt-xs focus-within:border-lt-ring focus-within:ring-[length:var(--lt-ring-width)] focus-within:ring-lt-ring/50", locked && "opacity-60"),
87
87
  children: [editor && !locked && toolbar.length > 0 && /* @__PURE__ */ jsx(Toolbar, {
88
88
  editor,
89
89
  items: toolbar
@@ -1 +1 @@
1
- {"version":3,"file":"rich-editor-field.js","names":[],"sources":["../../../../resources/js/form/components/fields/rich-editor-field.tsx"],"sourcesContent":["import { Placeholder } from \"@tiptap/extensions\";\nimport { type Editor, EditorContent, useEditor } from \"@tiptap/react\";\nimport { StarterKit } from \"@tiptap/starter-kit\";\nimport { useEffect, useMemo } from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { FormFieldFrame } from \"@lattice-php/lattice/form/components/base/field\";\nimport { useFormContext } from \"@lattice-php/lattice/form/hooks/context\";\nimport { useFieldScope } from \"@lattice-php/lattice/form/hooks/field-scope\";\nimport { useDependentField } from \"@lattice-php/lattice/form/hooks/use-dependent-field\";\nimport { useFieldCommit } from \"@lattice-php/lattice/form/hooks/use-field-commit\";\nimport { useFormValue } from \"@lattice-php/lattice/form/hooks/values\";\nimport { registerBuiltinRichEditorExtensions } from \"@lattice-php/lattice/form/rich-editor/builtins\";\nimport {\n assembleStarterKitOptions,\n assembleTiptapExtensions,\n assembleToolbar,\n resolveRichEditorExtensions,\n type ToolbarEntry,\n} from \"@lattice-php/lattice/form/rich-editor/registry\";\nimport { ToolbarIconButton } from \"@lattice-php/lattice/form/rich-editor/toolbar-button\";\n\nregisterBuiltinRichEditorExtensions();\n\nfunction Toolbar({ editor, items }: { editor: Editor; items: ToolbarEntry[] }) {\n const { t } = useT(\"lattice\");\n\n return (\n <div className=\"flex flex-wrap items-center gap-0.5 border-b border-lt-border p-1\">\n {items.map((item, index) => {\n if (item === \"separator\") {\n // eslint-disable-next-line react/no-array-index-key\n return <span key={`sep-${index}`} className=\"mx-1 h-5 w-px bg-lt-border\" />;\n }\n\n if (\"component\" in item) {\n const Control = item.component;\n\n return <Control editor={editor} key={item.key} />;\n }\n\n const label = t(`form.editor.${item.key}`, item.label);\n\n return (\n <ToolbarIconButton\n active={item.isActive(editor)}\n disabled={item.isDisabled?.(editor) ?? false}\n icon={item.icon}\n key={item.key}\n label={label}\n onClick={() => item.run(editor)}\n testId={`editor-${item.key}`}\n />\n );\n })}\n </div>\n );\n}\n\nconst RichEditorField: RendererComponent<\"field.rich-editor\"> = ({ node }) => {\n const { errors } = useFormContext();\n const { hidden, required, readOnly, disabled } = useDependentField(node);\n const { change, blur } = useFieldCommit();\n const name = node.props.name;\n const scope = useFieldScope();\n const globalValue = useFormValue(name);\n const storedValue = scope ? scope.getValue(name) : globalValue;\n const domName = scope ? scope.scopedName(name) : name;\n const errorKey = scope ? scope.errorKey(name) : name;\n const locked = readOnly || disabled;\n const initialContent =\n typeof storedValue === \"object\" && storedValue !== null\n ? (storedValue as object)\n : ((node.props.value as object | undefined) ?? \"\");\n\n const resolved = useMemo(\n () => resolveRichEditorExtensions(node.props.extensions),\n [node.props.extensions],\n );\n const toolbar = useMemo(() => assembleToolbar(resolved), [resolved]);\n const extensions = useMemo(\n () => [\n StarterKit.configure(assembleStarterKitOptions(resolved)),\n Placeholder.configure({ placeholder: node.props.placeholder ?? \"\" }),\n ...assembleTiptapExtensions(resolved),\n ],\n [resolved, node.props.placeholder],\n );\n\n const editor = useEditor({\n extensions,\n content: initialContent,\n editable: !locked,\n immediatelyRender: false,\n // Tiptap v3 stops re-rendering per transaction by default, but the toolbar\n // reads isActive/isDisabled during render — without this, selection-only\n // transactions leave those states stale.\n shouldRerenderOnTransaction: true,\n editorProps: {\n attributes: {\n class: \"lattice-prose min-h-32 px-3 py-2 outline-none\",\n },\n },\n onUpdate: ({ editor: instance }) => {\n change(name, instance.isEmpty ? null : instance.getJSON());\n },\n onBlur: () => {\n blur(name);\n },\n });\n\n useEffect(() => {\n editor?.setEditable(!locked);\n }, [editor, locked]);\n\n if (hidden) {\n return null;\n }\n\n const submittedValue = storedValue ? JSON.stringify(storedValue) : \"\";\n\n return (\n <FormFieldFrame\n error={errors[errorKey]}\n helperText={node.props.helperText ?? undefined}\n tooltip={node.props.tooltip ?? undefined}\n label={node.props.label ?? \"\"}\n name={domName}\n required={required}\n >\n <div\n className={cn(\n \"overflow-hidden rounded-lt-sm border border-lt-input bg-transparent shadow-lt-xs focus-within:border-lt-ring focus-within:ring-[3px] focus-within:ring-lt-ring/50\",\n locked && \"opacity-60\",\n )}\n >\n {editor && !locked && toolbar.length > 0 && <Toolbar editor={editor} items={toolbar} />}\n <EditorContent editor={editor} />\n </div>\n <input name={domName} type=\"hidden\" value={submittedValue} />\n </FormFieldFrame>\n );\n};\n\nexport default RichEditorField;\n"],"mappings":"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"}
1
+ {"version":3,"file":"rich-editor-field.js","names":[],"sources":["../../../../resources/js/form/components/fields/rich-editor-field.tsx"],"sourcesContent":["import { Placeholder } from \"@tiptap/extensions\";\nimport { type Editor, EditorContent, useEditor } from \"@tiptap/react\";\nimport { StarterKit } from \"@tiptap/starter-kit\";\nimport { useEffect, useMemo } from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { FormFieldFrame } from \"@lattice-php/lattice/form/components/base/field\";\nimport { useFormContext } from \"@lattice-php/lattice/form/hooks/context\";\nimport { useFieldScope } from \"@lattice-php/lattice/form/hooks/field-scope\";\nimport { useDependentField } from \"@lattice-php/lattice/form/hooks/use-dependent-field\";\nimport { useFieldCommit } from \"@lattice-php/lattice/form/hooks/use-field-commit\";\nimport { useFormValue } from \"@lattice-php/lattice/form/hooks/values\";\nimport { registerBuiltinRichEditorExtensions } from \"@lattice-php/lattice/form/rich-editor/builtins\";\nimport {\n assembleStarterKitOptions,\n assembleTiptapExtensions,\n assembleToolbar,\n resolveRichEditorExtensions,\n type ToolbarEntry,\n} from \"@lattice-php/lattice/form/rich-editor/registry\";\nimport { ToolbarIconButton } from \"@lattice-php/lattice/form/rich-editor/toolbar-button\";\n\nregisterBuiltinRichEditorExtensions();\n\nfunction Toolbar({ editor, items }: { editor: Editor; items: ToolbarEntry[] }) {\n const { t } = useT(\"lattice\");\n\n return (\n <div className=\"flex flex-wrap items-center gap-0.5 border-b border-lt-border p-1\">\n {items.map((item, index) => {\n if (item === \"separator\") {\n // eslint-disable-next-line react/no-array-index-key\n return <span key={`sep-${index}`} className=\"mx-1 h-5 w-px bg-lt-border\" />;\n }\n\n if (\"component\" in item) {\n const Control = item.component;\n\n return <Control editor={editor} key={item.key} />;\n }\n\n const label = t(`form.editor.${item.key}`, item.label);\n\n return (\n <ToolbarIconButton\n active={item.isActive(editor)}\n disabled={item.isDisabled?.(editor) ?? false}\n icon={item.icon}\n key={item.key}\n label={label}\n onClick={() => item.run(editor)}\n testId={`editor-${item.key}`}\n />\n );\n })}\n </div>\n );\n}\n\nconst RichEditorField: RendererComponent<\"field.rich-editor\"> = ({ node }) => {\n const { errors } = useFormContext();\n const { hidden, required, readOnly, disabled } = useDependentField(node);\n const { change, blur } = useFieldCommit();\n const name = node.props.name;\n const scope = useFieldScope();\n const globalValue = useFormValue(name);\n const storedValue = scope ? scope.getValue(name) : globalValue;\n const domName = scope ? scope.scopedName(name) : name;\n const errorKey = scope ? scope.errorKey(name) : name;\n const locked = readOnly || disabled;\n const initialContent =\n typeof storedValue === \"object\" && storedValue !== null\n ? (storedValue as object)\n : ((node.props.value as object | undefined) ?? \"\");\n\n const resolved = useMemo(\n () => resolveRichEditorExtensions(node.props.extensions),\n [node.props.extensions],\n );\n const toolbar = useMemo(() => assembleToolbar(resolved), [resolved]);\n const extensions = useMemo(\n () => [\n StarterKit.configure(assembleStarterKitOptions(resolved)),\n Placeholder.configure({ placeholder: node.props.placeholder ?? \"\" }),\n ...assembleTiptapExtensions(resolved),\n ],\n [resolved, node.props.placeholder],\n );\n\n const editor = useEditor({\n extensions,\n content: initialContent,\n editable: !locked,\n immediatelyRender: false,\n // Tiptap v3 stops re-rendering per transaction by default, but the toolbar\n // reads isActive/isDisabled during render — without this, selection-only\n // transactions leave those states stale.\n shouldRerenderOnTransaction: true,\n editorProps: {\n attributes: {\n class: \"lattice-prose min-h-32 px-3 py-2 outline-none\",\n },\n },\n onUpdate: ({ editor: instance }) => {\n change(name, instance.isEmpty ? null : instance.getJSON());\n },\n onBlur: () => {\n blur(name);\n },\n });\n\n useEffect(() => {\n editor?.setEditable(!locked);\n }, [editor, locked]);\n\n if (hidden) {\n return null;\n }\n\n const submittedValue = storedValue ? JSON.stringify(storedValue) : \"\";\n\n return (\n <FormFieldFrame\n error={errors[errorKey]}\n helperText={node.props.helperText ?? undefined}\n tooltip={node.props.tooltip ?? undefined}\n label={node.props.label ?? \"\"}\n name={domName}\n required={required}\n >\n <div\n className={cn(\n \"overflow-hidden rounded-lt-sm border border-lt-input bg-transparent shadow-lt-xs focus-within:border-lt-ring focus-within:ring-[length:var(--lt-ring-width)] focus-within:ring-lt-ring/50\",\n locked && \"opacity-60\",\n )}\n >\n {editor && !locked && toolbar.length > 0 && <Toolbar editor={editor} items={toolbar} />}\n <EditorContent editor={editor} />\n </div>\n <input name={domName} type=\"hidden\" value={submittedValue} />\n </FormFieldFrame>\n );\n};\n\nexport default RichEditorField;\n"],"mappings":"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"}
@@ -28,7 +28,7 @@ function defaultActions(removable) {
28
28
  key: "remove",
29
29
  label: null,
30
30
  icon: null,
31
- destructive: true
31
+ danger: true
32
32
  }];
33
33
  }
34
34
  function toClientAction(action, ctx) {
@@ -38,7 +38,7 @@ function toClientAction(action, ctx) {
38
38
  key: action.key,
39
39
  label: action.label ?? ctx.t(builtIn.key, builtIn.fallback),
40
40
  icon: action.icon ?? builtIn.icon,
41
- destructive: action.destructive,
41
+ danger: action.danger,
42
42
  onClick: () => ctx.onDuplicate(ctx.index)
43
43
  };
44
44
  }
@@ -49,7 +49,7 @@ function toClientAction(action, ctx) {
49
49
  key: action.key,
50
50
  label: action.label ?? ctx.t(builtIn.key, builtIn.fallback),
51
51
  icon: action.icon ?? builtIn.icon,
52
- destructive: action.destructive,
52
+ danger: action.danger,
53
53
  onClick: () => ctx.onRemove(ctx.index)
54
54
  };
55
55
  }
@@ -1 +1 @@
1
- {"version":3,"file":"row-action-menu.js","names":[],"sources":["../../../../resources/js/form/components/fields/row-action-menu.ts"],"sourcesContent":["import type { RowAction as WireRowAction } from \"@lattice-php/lattice/types/generated\";\nimport type { RowAction } from \"./row-actions\";\n\ntype RowActionTranslate = (key: string, fallback: string) => string;\n\n/** Translation key + fallback and icon for each built-in; the server sends null labels. */\nconst BUILT_IN: Record<\"duplicate\" | \"remove\", { key: string; fallback: string; icon: string }> = {\n duplicate: { key: \"table.row-actions.duplicate\", fallback: \"Duplicate\", icon: \"copy\" },\n remove: { key: \"table.row-actions.remove\", fallback: \"Remove\", icon: \"trash-2\" },\n};\n\nexport type RowActionContext = {\n index: number;\n removable: boolean;\n onRemove: (index: number) => void;\n onDuplicate: (index: number) => void;\n t: RowActionTranslate;\n};\n\n/**\n * Resolves the declared wire row actions into the click-wired client actions the\n * kebab renders. `null` (undeclared) falls back to the built-in remove; an empty\n * array disables row actions entirely. Remove is dropped while the row is at its\n * minimum, and built-in labels resolve through i18n when the server sends none.\n */\nexport function buildRowActions(\n declared: WireRowAction[] | null,\n ctx: RowActionContext,\n): RowAction[] {\n const source = declared ?? defaultActions(ctx.removable);\n\n return source\n .map((action) => toClientAction(action, ctx))\n .filter((action): action is RowAction => action !== null);\n}\n\nfunction defaultActions(removable: boolean): WireRowAction[] {\n if (!removable) {\n return [];\n }\n\n return [{ type: \"remove\", key: \"remove\", label: null, icon: null, destructive: true }];\n}\n\nfunction toClientAction(action: WireRowAction, ctx: RowActionContext): RowAction | null {\n if (action.type === \"duplicate\") {\n const builtIn = BUILT_IN.duplicate;\n\n return {\n key: action.key,\n label: action.label ?? ctx.t(builtIn.key, builtIn.fallback),\n icon: action.icon ?? builtIn.icon,\n destructive: action.destructive,\n onClick: () => ctx.onDuplicate(ctx.index),\n };\n }\n\n if (action.type === \"remove\") {\n if (!ctx.removable) {\n return null;\n }\n\n const builtIn = BUILT_IN.remove;\n\n return {\n key: action.key,\n label: action.label ?? ctx.t(builtIn.key, builtIn.fallback),\n icon: action.icon ?? builtIn.icon,\n destructive: action.destructive,\n onClick: () => ctx.onRemove(ctx.index),\n };\n }\n\n return null;\n}\n"],"mappings":";;AAMA,IAAM,WAA4F;CAChG,WAAW;EAAE,KAAK;EAA+B,UAAU;EAAa,MAAM;CAAO;CACrF,QAAQ;EAAE,KAAK;EAA4B,UAAU;EAAU,MAAM;CAAU;AACjF;;;;;;;AAgBA,SAAgB,gBACd,UACA,KACa;CAGb,QAFe,YAAY,eAAe,IAAI,SAAS,GAGpD,KAAK,WAAW,eAAe,QAAQ,GAAG,CAAC,EAC3C,QAAQ,WAAgC,WAAW,IAAI;AAC5D;AAEA,SAAS,eAAe,WAAqC;CAC3D,IAAI,CAAC,WACH,OAAO,CAAC;CAGV,OAAO,CAAC;EAAE,MAAM;EAAU,KAAK;EAAU,OAAO;EAAM,MAAM;EAAM,aAAa;CAAK,CAAC;AACvF;AAEA,SAAS,eAAe,QAAuB,KAAyC;CACtF,IAAI,OAAO,SAAS,aAAa;EAC/B,MAAM,UAAU,SAAS;EAEzB,OAAO;GACL,KAAK,OAAO;GACZ,OAAO,OAAO,SAAS,IAAI,EAAE,QAAQ,KAAK,QAAQ,QAAQ;GAC1D,MAAM,OAAO,QAAQ,QAAQ;GAC7B,aAAa,OAAO;GACpB,eAAe,IAAI,YAAY,IAAI,KAAK;EAC1C;CACF;CAEA,IAAI,OAAO,SAAS,UAAU;EAC5B,IAAI,CAAC,IAAI,WACP,OAAO;EAGT,MAAM,UAAU,SAAS;EAEzB,OAAO;GACL,KAAK,OAAO;GACZ,OAAO,OAAO,SAAS,IAAI,EAAE,QAAQ,KAAK,QAAQ,QAAQ;GAC1D,MAAM,OAAO,QAAQ,QAAQ;GAC7B,aAAa,OAAO;GACpB,eAAe,IAAI,SAAS,IAAI,KAAK;EACvC;CACF;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"row-action-menu.js","names":[],"sources":["../../../../resources/js/form/components/fields/row-action-menu.ts"],"sourcesContent":["import type { RowAction as WireRowAction } from \"@lattice-php/lattice/types/generated\";\nimport type { RowAction } from \"./row-actions\";\n\ntype RowActionTranslate = (key: string, fallback: string) => string;\n\n/** Translation key + fallback and icon for each built-in; the server sends null labels. */\nconst BUILT_IN: Record<\"duplicate\" | \"remove\", { key: string; fallback: string; icon: string }> = {\n duplicate: { key: \"table.row-actions.duplicate\", fallback: \"Duplicate\", icon: \"copy\" },\n remove: { key: \"table.row-actions.remove\", fallback: \"Remove\", icon: \"trash-2\" },\n};\n\nexport type RowActionContext = {\n index: number;\n removable: boolean;\n onRemove: (index: number) => void;\n onDuplicate: (index: number) => void;\n t: RowActionTranslate;\n};\n\n/**\n * Resolves the declared wire row actions into the click-wired client actions the\n * kebab renders. `null` (undeclared) falls back to the built-in remove; an empty\n * array disables row actions entirely. Remove is dropped while the row is at its\n * minimum, and built-in labels resolve through i18n when the server sends none.\n */\nexport function buildRowActions(\n declared: WireRowAction[] | null,\n ctx: RowActionContext,\n): RowAction[] {\n const source = declared ?? defaultActions(ctx.removable);\n\n return source\n .map((action) => toClientAction(action, ctx))\n .filter((action): action is RowAction => action !== null);\n}\n\nfunction defaultActions(removable: boolean): WireRowAction[] {\n if (!removable) {\n return [];\n }\n\n return [{ type: \"remove\", key: \"remove\", label: null, icon: null, danger: true }];\n}\n\nfunction toClientAction(action: WireRowAction, ctx: RowActionContext): RowAction | null {\n if (action.type === \"duplicate\") {\n const builtIn = BUILT_IN.duplicate;\n\n return {\n key: action.key,\n label: action.label ?? ctx.t(builtIn.key, builtIn.fallback),\n icon: action.icon ?? builtIn.icon,\n danger: action.danger,\n onClick: () => ctx.onDuplicate(ctx.index),\n };\n }\n\n if (action.type === \"remove\") {\n if (!ctx.removable) {\n return null;\n }\n\n const builtIn = BUILT_IN.remove;\n\n return {\n key: action.key,\n label: action.label ?? ctx.t(builtIn.key, builtIn.fallback),\n icon: action.icon ?? builtIn.icon,\n danger: action.danger,\n onClick: () => ctx.onRemove(ctx.index),\n };\n }\n\n return null;\n}\n"],"mappings":";;AAMA,IAAM,WAA4F;CAChG,WAAW;EAAE,KAAK;EAA+B,UAAU;EAAa,MAAM;CAAO;CACrF,QAAQ;EAAE,KAAK;EAA4B,UAAU;EAAU,MAAM;CAAU;AACjF;;;;;;;AAgBA,SAAgB,gBACd,UACA,KACa;CAGb,QAFe,YAAY,eAAe,IAAI,SAAS,GAGpD,KAAK,WAAW,eAAe,QAAQ,GAAG,CAAC,EAC3C,QAAQ,WAAgC,WAAW,IAAI;AAC5D;AAEA,SAAS,eAAe,WAAqC;CAC3D,IAAI,CAAC,WACH,OAAO,CAAC;CAGV,OAAO,CAAC;EAAE,MAAM;EAAU,KAAK;EAAU,OAAO;EAAM,MAAM;EAAM,QAAQ;CAAK,CAAC;AAClF;AAEA,SAAS,eAAe,QAAuB,KAAyC;CACtF,IAAI,OAAO,SAAS,aAAa;EAC/B,MAAM,UAAU,SAAS;EAEzB,OAAO;GACL,KAAK,OAAO;GACZ,OAAO,OAAO,SAAS,IAAI,EAAE,QAAQ,KAAK,QAAQ,QAAQ;GAC1D,MAAM,OAAO,QAAQ,QAAQ;GAC7B,QAAQ,OAAO;GACf,eAAe,IAAI,YAAY,IAAI,KAAK;EAC1C;CACF;CAEA,IAAI,OAAO,SAAS,UAAU;EAC5B,IAAI,CAAC,IAAI,WACP,OAAO;EAGT,MAAM,UAAU,SAAS;EAEzB,OAAO;GACL,KAAK,OAAO;GACZ,OAAO,OAAO,SAAS,IAAI,EAAE,QAAQ,KAAK,QAAQ,QAAQ;GAC1D,MAAM,OAAO,QAAQ,QAAQ;GAC7B,QAAQ,OAAO;GACf,eAAe,IAAI,SAAS,IAAI,KAAK;EACvC;CACF;CAEA,OAAO;AACT"}
@@ -3,7 +3,7 @@ export type RowAction = {
3
3
  label: string;
4
4
  icon: string;
5
5
  onClick: () => void;
6
- destructive?: boolean;
6
+ danger?: boolean;
7
7
  };
8
8
  export declare function RowActions({ actions }: {
9
9
  actions: RowAction[];
@@ -3,8 +3,8 @@ import { Icon } from "../../../icons/sprite.js";
3
3
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../../../ui/dropdown-menu.js";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region resources/js/form/components/fields/row-actions.tsx
6
- function inlineClass(destructive) {
7
- return destructive ? "text-lt-danger hover:text-lt-danger [&_svg]:size-lt-icon-sm" : "text-lt-muted-fg hover:text-lt-fg [&_svg]:size-lt-icon-sm";
6
+ function inlineClass(danger) {
7
+ return danger ? "text-lt-danger hover:text-lt-danger [&_svg]:size-lt-icon-sm" : "text-lt-muted-fg hover:text-lt-fg [&_svg]:size-lt-icon-sm";
8
8
  }
9
9
  function RowActions({ actions }) {
10
10
  const { t } = useT("lattice");
@@ -15,7 +15,7 @@ function RowActions({ actions }) {
15
15
  type: "button",
16
16
  "aria-label": action.label,
17
17
  "data-test": `row-action-${action.key}`,
18
- className: inlineClass(action.destructive),
18
+ className: inlineClass(action.danger),
19
19
  onClick: action.onClick,
20
20
  children: /* @__PURE__ */ jsx(Icon, { name: action.icon })
21
21
  });
@@ -34,7 +34,7 @@ function RowActions({ actions }) {
34
34
  className: "min-w-[10rem]",
35
35
  children: actions.map((action) => /* @__PURE__ */ jsx(DropdownMenuItem, {
36
36
  "data-test": `row-action-${action.key}`,
37
- destructive: action.destructive,
37
+ danger: action.danger,
38
38
  icon: action.icon,
39
39
  onClick: action.onClick,
40
40
  children: action.label
@@ -1 +1 @@
1
- {"version":3,"file":"row-actions.js","names":[],"sources":["../../../../resources/js/form/components/fields/row-actions.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@lattice-php/lattice/ui/dropdown-menu\";\n\nexport type RowAction = {\n key: string;\n label: string;\n icon: string;\n onClick: () => void;\n destructive?: boolean;\n};\n\nfunction inlineClass(destructive?: boolean): string {\n return destructive\n ? \"text-lt-danger hover:text-lt-danger [&_svg]:size-lt-icon-sm\"\n : \"text-lt-muted-fg hover:text-lt-fg [&_svg]:size-lt-icon-sm\";\n}\n\nexport function RowActions({ actions }: { actions: RowAction[] }) {\n const { t } = useT(\"lattice\");\n if (actions.length === 0) {\n return null;\n }\n\n if (actions.length === 1) {\n const action = actions[0];\n return (\n <button\n type=\"button\"\n aria-label={action.label}\n data-test={`row-action-${action.key}`}\n className={inlineClass(action.destructive)}\n onClick={action.onClick}\n >\n <Icon name={action.icon} />\n </button>\n );\n }\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label={t(\"common.action-group.label\", \"Actions\")}\n data-test=\"row-actions-menu\"\n className=\"text-lt-muted-fg hover:text-lt-fg [&_svg]:size-lt-icon-sm\"\n >\n <Icon name=\"more-horizontal\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"min-w-[10rem]\">\n {actions.map((action) => (\n <DropdownMenuItem\n key={action.key}\n data-test={`row-action-${action.key}`}\n destructive={action.destructive}\n icon={action.icon}\n onClick={action.onClick}\n >\n {action.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":";;;;;AAiBA,SAAS,YAAY,aAA+B;CAClD,OAAO,cACH,gEACA;AACN;AAEA,SAAgB,WAAW,EAAE,WAAqC;CAChE,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,IAAI,QAAQ,WAAW,GAAG;EACxB,MAAM,SAAS,QAAQ;EACvB,OACE,oBAAC,UAAD;GACE,MAAK;GACL,cAAY,OAAO;GACnB,aAAW,cAAc,OAAO;GAChC,WAAW,YAAY,OAAO,WAAW;GACzC,SAAS,OAAO;aAEhB,oBAAC,MAAD,EAAM,MAAM,OAAO,KAAO,CAAA;EACpB,CAAA;CAEZ;CAEA,OACE,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,qBAAD;EAAqB,SAAA;YACnB,oBAAC,UAAD;GACE,MAAK;GACL,cAAY,EAAE,6BAA6B,SAAS;GACpD,aAAU;GACV,WAAU;aAEV,oBAAC,MAAD,EAAM,MAAK,kBAAmB,CAAA;EACxB,CAAA;CACW,CAAA,GACrB,oBAAC,qBAAD;EAAqB,OAAM;EAAM,WAAU;YACxC,QAAQ,KAAK,WACZ,oBAAC,kBAAD;GAEE,aAAW,cAAc,OAAO;GAChC,aAAa,OAAO;GACpB,MAAM,OAAO;GACb,SAAS,OAAO;aAEf,OAAO;EACQ,GAPX,OAAO,GAOI,CACnB;CACkB,CAAA,CACT,EAAA,CAAA;AAElB"}
1
+ {"version":3,"file":"row-actions.js","names":[],"sources":["../../../../resources/js/form/components/fields/row-actions.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@lattice-php/lattice/ui/dropdown-menu\";\n\nexport type RowAction = {\n key: string;\n label: string;\n icon: string;\n onClick: () => void;\n danger?: boolean;\n};\n\nfunction inlineClass(danger?: boolean): string {\n return danger\n ? \"text-lt-danger hover:text-lt-danger [&_svg]:size-lt-icon-sm\"\n : \"text-lt-muted-fg hover:text-lt-fg [&_svg]:size-lt-icon-sm\";\n}\n\nexport function RowActions({ actions }: { actions: RowAction[] }) {\n const { t } = useT(\"lattice\");\n if (actions.length === 0) {\n return null;\n }\n\n if (actions.length === 1) {\n const action = actions[0];\n return (\n <button\n type=\"button\"\n aria-label={action.label}\n data-test={`row-action-${action.key}`}\n className={inlineClass(action.danger)}\n onClick={action.onClick}\n >\n <Icon name={action.icon} />\n </button>\n );\n }\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n aria-label={t(\"common.action-group.label\", \"Actions\")}\n data-test=\"row-actions-menu\"\n className=\"text-lt-muted-fg hover:text-lt-fg [&_svg]:size-lt-icon-sm\"\n >\n <Icon name=\"more-horizontal\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"min-w-[10rem]\">\n {actions.map((action) => (\n <DropdownMenuItem\n key={action.key}\n data-test={`row-action-${action.key}`}\n danger={action.danger}\n icon={action.icon}\n onClick={action.onClick}\n >\n {action.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"],"mappings":";;;;;AAiBA,SAAS,YAAY,QAA0B;CAC7C,OAAO,SACH,gEACA;AACN;AAEA,SAAgB,WAAW,EAAE,WAAqC;CAChE,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,IAAI,QAAQ,WAAW,GACrB,OAAO;CAGT,IAAI,QAAQ,WAAW,GAAG;EACxB,MAAM,SAAS,QAAQ;EACvB,OACE,oBAAC,UAAD;GACE,MAAK;GACL,cAAY,OAAO;GACnB,aAAW,cAAc,OAAO;GAChC,WAAW,YAAY,OAAO,MAAM;GACpC,SAAS,OAAO;aAEhB,oBAAC,MAAD,EAAM,MAAM,OAAO,KAAO,CAAA;EACpB,CAAA;CAEZ;CAEA,OACE,qBAAC,cAAD,EAAA,UAAA,CACE,oBAAC,qBAAD;EAAqB,SAAA;YACnB,oBAAC,UAAD;GACE,MAAK;GACL,cAAY,EAAE,6BAA6B,SAAS;GACpD,aAAU;GACV,WAAU;aAEV,oBAAC,MAAD,EAAM,MAAK,kBAAmB,CAAA;EACxB,CAAA;CACW,CAAA,GACrB,oBAAC,qBAAD;EAAqB,OAAM;EAAM,WAAU;YACxC,QAAQ,KAAK,WACZ,oBAAC,kBAAD;GAEE,aAAW,cAAc,OAAO;GAChC,QAAQ,OAAO;GACf,MAAM,OAAO;GACb,SAAS,OAAO;aAEf,OAAO;EACQ,GAPX,OAAO,GAOI,CACnB;CACkB,CAAA,CACT,EAAA,CAAA;AAElB"}
@@ -43,7 +43,7 @@ var ToggleComponent = ({ node }) => {
43
43
  "aria-checked": checked,
44
44
  "aria-label": props.label ?? localName,
45
45
  autoFocus: props.autoFocus ?? false,
46
- className: cn("inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border border-transparent bg-lt-muted p-0.5 shadow-lt-xs transition-colors outline-none focus-visible:border-lt-ring focus-visible:ring-[3px] focus-visible:ring-lt-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-lt-primary"),
46
+ className: cn("inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border border-transparent bg-lt-muted p-0.5 shadow-lt-xs transition-colors outline-none focus-visible:border-lt-ring focus-visible:ring-[length:var(--lt-ring-width)] focus-visible:ring-lt-ring/50 disabled:cursor-not-allowed disabled:bg-lt-disabled data-[state=checked]:bg-lt-primary disabled:data-[state=checked]:bg-lt-disabled"),
47
47
  "data-state": checked ? "checked" : "unchecked",
48
48
  "data-test": testIdentity(localName),
49
49
  disabled: locked,
@@ -1 +1 @@
1
- {"version":3,"file":"toggle.js","names":[],"sources":["../../../../resources/js/form/components/fields/toggle.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { testIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { FormFieldFrame } from \"@lattice-php/lattice/form/components/base/field\";\nimport { toBoolean } from \"@lattice-php/lattice/form/lib/conditions\";\nimport { useFormContext } from \"@lattice-php/lattice/form/hooks/context\";\nimport { fieldDomName } from \"@lattice-php/lattice/form/lib/field-dom-name\";\nimport { useFieldScope } from \"@lattice-php/lattice/form/hooks/field-scope\";\nimport { useDependentField } from \"@lattice-php/lattice/form/hooks/use-dependent-field\";\nimport { useFieldCommit } from \"@lattice-php/lattice/form/hooks/use-field-commit\";\nimport { useSeedDefault } from \"@lattice-php/lattice/form/hooks/use-seed-default\";\nimport { useFormValue } from \"@lattice-php/lattice/form/hooks/values\";\n\nexport const ToggleComponent: RendererComponent<\"field.toggle\"> = ({ node }) => {\n const { hidden, required, readOnly, disabled } = useDependentField(node);\n const props = node.props;\n const localName = props.name;\n const scope = useFieldScope();\n const { errors, fieldIdPrefix } = useFormContext();\n const name = fieldDomName(scope ? scope.scopedName(localName) : localName, fieldIdPrefix);\n const errorKey = scope ? scope.errorKey(localName) : localName;\n const globalValue = useFormValue(localName);\n const storedValue = scope ? scope.getValue(localName) : globalValue;\n const defaultChecked = toBoolean(props.value);\n const checked = storedValue !== undefined ? toBoolean(storedValue) : defaultChecked;\n const locked = readOnly || disabled;\n const { commit } = useFieldCommit();\n\n useSeedDefault(localName, defaultChecked);\n\n if (hidden) {\n return null;\n }\n\n return (\n <FormFieldFrame\n error={errors[errorKey]}\n helperText={props.helperText ?? undefined}\n tooltip={props.tooltip ?? undefined}\n label={props.label ?? \"\"}\n name={name}\n required={required}\n >\n <input disabled={locked} name={name} type=\"hidden\" value={checked ? \"1\" : \"0\"} />\n <button\n aria-checked={checked}\n aria-label={props.label ?? localName}\n autoFocus={props.autoFocus ?? false}\n className={cn(\n \"inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border border-transparent bg-lt-muted p-0.5 shadow-lt-xs transition-colors outline-none focus-visible:border-lt-ring focus-visible:ring-[3px] focus-visible:ring-lt-ring/50 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-lt-primary\",\n )}\n data-state={checked ? \"checked\" : \"unchecked\"}\n data-test={testIdentity(localName)}\n disabled={locked}\n id={name}\n name={name}\n onClick={() => commit(localName, !checked)}\n role=\"switch\"\n tabIndex={props.tabIndex ?? undefined}\n type=\"button\"\n >\n <span\n className=\"size-5 rounded-full bg-lt-bg shadow-lt-sm transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0\"\n data-state={checked ? \"checked\" : \"unchecked\"}\n />\n </button>\n </FormFieldFrame>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAaA,IAAa,mBAAsD,EAAE,WAAW;CAC9E,MAAM,EAAE,QAAQ,UAAU,UAAU,aAAa,kBAAkB,IAAI;CACvE,MAAM,QAAQ,KAAK;CACnB,MAAM,YAAY,MAAM;CACxB,MAAM,QAAQ,cAAc;CAC5B,MAAM,EAAE,QAAQ,kBAAkB,eAAe;CACjD,MAAM,OAAO,aAAa,QAAQ,MAAM,WAAW,SAAS,IAAI,WAAW,aAAa;CACxF,MAAM,WAAW,QAAQ,MAAM,SAAS,SAAS,IAAI;CACrD,MAAM,cAAc,aAAa,SAAS;CAC1C,MAAM,cAAc,QAAQ,MAAM,SAAS,SAAS,IAAI;CACxD,MAAM,iBAAiB,UAAU,MAAM,KAAK;CAC5C,MAAM,UAAU,gBAAgB,KAAA,IAAY,UAAU,WAAW,IAAI;CACrE,MAAM,SAAS,YAAY;CAC3B,MAAM,EAAE,WAAW,eAAe;CAElC,eAAe,WAAW,cAAc;CAExC,IAAI,QACF,OAAO;CAGT,OACE,qBAAC,gBAAD;EACE,OAAO,OAAO;EACd,YAAY,MAAM,cAAc,KAAA;EAChC,SAAS,MAAM,WAAW,KAAA;EAC1B,OAAO,MAAM,SAAS;EAChB;EACI;YANZ,CAQE,oBAAC,SAAD;GAAO,UAAU;GAAc;GAAM,MAAK;GAAS,OAAO,UAAU,MAAM;EAAM,CAAA,GAChF,oBAAC,UAAD;GACE,gBAAc;GACd,cAAY,MAAM,SAAS;GAC3B,WAAW,MAAM,aAAa;GAC9B,WAAW,GACT,uUACF;GACA,cAAY,UAAU,YAAY;GAClC,aAAW,aAAa,SAAS;GACjC,UAAU;GACV,IAAI;GACE;GACN,eAAe,OAAO,WAAW,CAAC,OAAO;GACzC,MAAK;GACL,UAAU,MAAM,YAAY,KAAA;GAC5B,MAAK;aAEL,oBAAC,QAAD;IACE,WAAU;IACV,cAAY,UAAU,YAAY;GACnC,CAAA;EACK,CAAA,CACM;;AAEpB"}
1
+ {"version":3,"file":"toggle.js","names":[],"sources":["../../../../resources/js/form/components/fields/toggle.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { testIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { FormFieldFrame } from \"@lattice-php/lattice/form/components/base/field\";\nimport { toBoolean } from \"@lattice-php/lattice/form/lib/conditions\";\nimport { useFormContext } from \"@lattice-php/lattice/form/hooks/context\";\nimport { fieldDomName } from \"@lattice-php/lattice/form/lib/field-dom-name\";\nimport { useFieldScope } from \"@lattice-php/lattice/form/hooks/field-scope\";\nimport { useDependentField } from \"@lattice-php/lattice/form/hooks/use-dependent-field\";\nimport { useFieldCommit } from \"@lattice-php/lattice/form/hooks/use-field-commit\";\nimport { useSeedDefault } from \"@lattice-php/lattice/form/hooks/use-seed-default\";\nimport { useFormValue } from \"@lattice-php/lattice/form/hooks/values\";\n\nexport const ToggleComponent: RendererComponent<\"field.toggle\"> = ({ node }) => {\n const { hidden, required, readOnly, disabled } = useDependentField(node);\n const props = node.props;\n const localName = props.name;\n const scope = useFieldScope();\n const { errors, fieldIdPrefix } = useFormContext();\n const name = fieldDomName(scope ? scope.scopedName(localName) : localName, fieldIdPrefix);\n const errorKey = scope ? scope.errorKey(localName) : localName;\n const globalValue = useFormValue(localName);\n const storedValue = scope ? scope.getValue(localName) : globalValue;\n const defaultChecked = toBoolean(props.value);\n const checked = storedValue !== undefined ? toBoolean(storedValue) : defaultChecked;\n const locked = readOnly || disabled;\n const { commit } = useFieldCommit();\n\n useSeedDefault(localName, defaultChecked);\n\n if (hidden) {\n return null;\n }\n\n return (\n <FormFieldFrame\n error={errors[errorKey]}\n helperText={props.helperText ?? undefined}\n tooltip={props.tooltip ?? undefined}\n label={props.label ?? \"\"}\n name={name}\n required={required}\n >\n <input disabled={locked} name={name} type=\"hidden\" value={checked ? \"1\" : \"0\"} />\n <button\n aria-checked={checked}\n aria-label={props.label ?? localName}\n autoFocus={props.autoFocus ?? false}\n className={cn(\n \"inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border border-transparent bg-lt-muted p-0.5 shadow-lt-xs transition-colors outline-none focus-visible:border-lt-ring focus-visible:ring-[length:var(--lt-ring-width)] focus-visible:ring-lt-ring/50 disabled:cursor-not-allowed disabled:bg-lt-disabled data-[state=checked]:bg-lt-primary disabled:data-[state=checked]:bg-lt-disabled\",\n )}\n data-state={checked ? \"checked\" : \"unchecked\"}\n data-test={testIdentity(localName)}\n disabled={locked}\n id={name}\n name={name}\n onClick={() => commit(localName, !checked)}\n role=\"switch\"\n tabIndex={props.tabIndex ?? undefined}\n type=\"button\"\n >\n <span\n className=\"size-5 rounded-full bg-lt-bg shadow-lt-sm transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0\"\n data-state={checked ? \"checked\" : \"unchecked\"}\n />\n </button>\n </FormFieldFrame>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAaA,IAAa,mBAAsD,EAAE,WAAW;CAC9E,MAAM,EAAE,QAAQ,UAAU,UAAU,aAAa,kBAAkB,IAAI;CACvE,MAAM,QAAQ,KAAK;CACnB,MAAM,YAAY,MAAM;CACxB,MAAM,QAAQ,cAAc;CAC5B,MAAM,EAAE,QAAQ,kBAAkB,eAAe;CACjD,MAAM,OAAO,aAAa,QAAQ,MAAM,WAAW,SAAS,IAAI,WAAW,aAAa;CACxF,MAAM,WAAW,QAAQ,MAAM,SAAS,SAAS,IAAI;CACrD,MAAM,cAAc,aAAa,SAAS;CAC1C,MAAM,cAAc,QAAQ,MAAM,SAAS,SAAS,IAAI;CACxD,MAAM,iBAAiB,UAAU,MAAM,KAAK;CAC5C,MAAM,UAAU,gBAAgB,KAAA,IAAY,UAAU,WAAW,IAAI;CACrE,MAAM,SAAS,YAAY;CAC3B,MAAM,EAAE,WAAW,eAAe;CAElC,eAAe,WAAW,cAAc;CAExC,IAAI,QACF,OAAO;CAGT,OACE,qBAAC,gBAAD;EACE,OAAO,OAAO;EACd,YAAY,MAAM,cAAc,KAAA;EAChC,SAAS,MAAM,WAAW,KAAA;EAC1B,OAAO,MAAM,SAAS;EAChB;EACI;YANZ,CAQE,oBAAC,SAAD;GAAO,UAAU;GAAc;GAAM,MAAK;GAAS,OAAO,UAAU,MAAM;EAAM,CAAA,GAChF,oBAAC,UAAD;GACE,gBAAc;GACd,cAAY,MAAM,SAAS;GAC3B,WAAW,MAAM,aAAa;GAC9B,WAAW,GACT,gZACF;GACA,cAAY,UAAU,YAAY;GAClC,aAAW,aAAa,SAAS;GACjC,UAAU;GACV,IAAI;GACE;GACN,eAAe,OAAO,WAAW,CAAC,OAAO;GACzC,MAAK;GACL,UAAU,MAAM,YAAY,KAAA;GAC5B,MAAK;aAEL,oBAAC,QAAD;IACE,WAAU;IACV,cAAY,UAAU,YAAY;GACnC,CAAA;EACK,CAAA,CACM;;AAEpB"}
@@ -30,7 +30,7 @@ function FormResetListener({ componentId, reset }) {
30
30
  });
31
31
  return null;
32
32
  }
33
- function FormBody({ action, children, componentRef, nodes, shouldRenderSubmitButton, submitButtons, submitJustify, submitLabel, submitVariant, summaryLabel }) {
33
+ function FormBody({ action, children, componentRef, nodes, shouldRenderSubmitButton, submitButtons, submitEmphasis, submitJustify, submitLabel, submitVariant, summaryLabel }) {
34
34
  const { nodes: resolvedNodes, markUserEdit } = useFormResolver(action, componentRef, nodes);
35
35
  return /* @__PURE__ */ jsx(PrefillProvider, {
36
36
  value: { markUserEdit },
@@ -41,13 +41,15 @@ function FormBody({ action, children, componentRef, nodes, shouldRenderSubmitBut
41
41
  children: [children, shouldRenderSubmitButton && /* @__PURE__ */ jsx("div", {
42
42
  className: `flex gap-3 ${JUSTIFY_CLASS[submitJustify ?? "end"]}`,
43
43
  children: submitButtons?.length ? submitButtons.map((button, index) => button.props.buttonType === "submit" ? /* @__PURE__ */ jsx(FormSubmitButton, {
44
+ emphasis: button.props.emphasis ?? submitEmphasis,
44
45
  label: button.props.label ?? submitLabel,
45
46
  summaryLabel,
46
- variant: button.props.variant ?? submitVariant ?? "default"
47
+ variant: button.props.variant ?? submitVariant
47
48
  }, nodeKey(button, index)) : /* @__PURE__ */ jsx(RenderNode, { node: button }, nodeKey(button, index))) : /* @__PURE__ */ jsx(FormSubmitButton, {
49
+ emphasis: submitEmphasis,
48
50
  label: submitLabel,
49
51
  summaryLabel,
50
- variant: submitVariant ?? "default"
52
+ variant: submitVariant
51
53
  })
52
54
  })]
53
55
  })
@@ -75,6 +77,7 @@ var FormComponent = ({ children, node }) => {
75
77
  const submitJustify = props.submitJustify ?? void 0;
76
78
  const submitLabel = props.submitLabel ?? t("form.submit", "Submit");
77
79
  const submitVariant = props.submitVariant ?? void 0;
80
+ const submitEmphasis = props.submitEmphasis ?? void 0;
78
81
  const summaryLabel = props.validationSummaryLabel;
79
82
  const validationTimeout = props.validationTimeout ?? void 0;
80
83
  return /* @__PURE__ */ jsx(Form, {
@@ -88,7 +91,7 @@ var FormComponent = ({ children, node }) => {
88
91
  validationTimeout: precognitive ? validationTimeout : void 0,
89
92
  headers: withHeaders(componentRef),
90
93
  className: "mx-auto flex w-full max-w-2xl flex-col gap-6",
91
- children: ({ clearErrors, errors, processing, reset, validate }) => /* @__PURE__ */ jsxs(FormProvider, {
94
+ children: ({ clearErrors, errors, processing, reset, touch, validate, validating }) => /* @__PURE__ */ jsxs(FormProvider, {
92
95
  value: {
93
96
  action,
94
97
  clearErrors: (field) => clearErrors(field),
@@ -98,7 +101,13 @@ var FormComponent = ({ children, node }) => {
98
101
  fieldLabels,
99
102
  precognitive,
100
103
  processing,
101
- validate: (field) => validate(field)
104
+ touch: (fields) => touch(...fields),
105
+ validate: (field) => validate(field),
106
+ validateFields: (fields, options) => validate({
107
+ only: fields,
108
+ ...options
109
+ }),
110
+ validating
102
111
  },
103
112
  children: [
104
113
  /* @__PURE__ */ jsx(FormResetListener, {
@@ -117,6 +126,7 @@ var FormComponent = ({ children, node }) => {
117
126
  nodes: node.schema,
118
127
  shouldRenderSubmitButton,
119
128
  submitButtons,
129
+ submitEmphasis,
120
130
  submitJustify,
121
131
  submitLabel,
122
132
  submitVariant,
@@ -1 +1 @@
1
- {"version":3,"file":"form.js","names":[],"sources":["../../../resources/js/form/components/form.tsx"],"sourcesContent":["import { Form as InertiaForm } from \"@inertiajs/react\";\nimport { withHeaders } from \"@lattice-php/lattice/core/headers\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\nimport { useWindowEvent } from \"@lattice-php/lattice/core/hooks/use-window-event\";\nimport { nodeKey } from \"@lattice-php/lattice/core/nodes\";\nimport { RenderNode } from \"@lattice-php/lattice/core/renderer\";\nimport type { Node, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { ButtonVariant, Justify } from \"@lattice-php/lattice/types/generated\";\nimport { useMemo } from \"react\";\nimport { FormSubmitButton } from \"./base/submit-button\";\nimport { FormProvider } from \"@lattice-php/lattice/form/hooks/context\";\nimport { collectFields } from \"@lattice-php/lattice/form/lib/collect-fields\";\nimport { PrefillProvider } from \"@lattice-php/lattice/form/hooks/prefill-context\";\nimport { ResolvedNodesProvider } from \"@lattice-php/lattice/form/hooks/resolved-nodes\";\nimport { useFormResolver } from \"@lattice-php/lattice/form/hooks/use-form-resolver\";\nimport { FormValuesProvider } from \"@lattice-php/lattice/form/hooks/values\";\n\nconst JUSTIFY_CLASS: Record<Justify, string> = {\n start: \"justify-start\",\n center: \"justify-center\",\n end: \"justify-end\",\n between: \"justify-between\",\n around: \"justify-around\",\n evenly: \"justify-evenly\",\n};\n\nfunction FormResetListener({\n componentId,\n reset,\n}: {\n componentId?: string;\n reset: (...fields: string[]) => void;\n}) {\n useWindowEvent(LATTICE_EVENT.resetForm, (event) => {\n const detail = (event as CustomEvent<{ form: string | null }>).detail;\n\n if (!detail?.form || detail.form === componentId) {\n reset();\n }\n });\n\n return null;\n}\n\nfunction FormBody({\n action,\n children,\n componentRef,\n nodes,\n shouldRenderSubmitButton,\n submitButtons,\n submitJustify,\n submitLabel,\n submitVariant,\n summaryLabel,\n}: {\n action: string;\n children: React.ReactNode;\n componentRef: string;\n nodes: Node[] | undefined;\n shouldRenderSubmitButton: boolean;\n submitButtons: Node<\"button\">[] | undefined;\n submitJustify: Justify | undefined;\n submitLabel: string;\n submitVariant: ButtonVariant | undefined;\n summaryLabel: string;\n}) {\n const { nodes: resolvedNodes, markUserEdit } = useFormResolver(action, componentRef, nodes);\n\n return (\n <PrefillProvider value={{ markUserEdit }}>\n <ResolvedNodesProvider nodes={resolvedNodes}>\n <div className=\"flex flex-col gap-6\">\n {children}\n\n {shouldRenderSubmitButton && (\n <div className={`flex gap-3 ${JUSTIFY_CLASS[submitJustify ?? \"end\"]}`}>\n {submitButtons?.length ? (\n submitButtons.map((button, index) =>\n button.props.buttonType === \"submit\" ? (\n <FormSubmitButton\n key={nodeKey(button, index)}\n label={button.props.label ?? submitLabel}\n summaryLabel={summaryLabel}\n variant={button.props.variant ?? submitVariant ?? \"default\"}\n />\n ) : (\n <RenderNode key={nodeKey(button, index)} node={button} />\n ),\n )\n ) : (\n <FormSubmitButton\n label={submitLabel}\n summaryLabel={summaryLabel}\n variant={submitVariant ?? \"default\"}\n />\n )}\n </div>\n )}\n </div>\n </ResolvedNodesProvider>\n </PrefillProvider>\n );\n}\n\nexport const FormComponent: RendererComponent<\"form\"> = ({ children, node }) => {\n const { t } = useT(\"lattice\");\n const props = node.props;\n const action = props.action ?? \"#\";\n const errorBag = props.errorBag;\n const componentRef = props.ref ?? \"\";\n const method = props.method ?? \"post\";\n const precognitive = props.precognitive;\n const resetOnError = props.resetOnError ?? false;\n const resetOnSuccess = props.resetOnSuccess ?? [];\n const state = props.state;\n const { labels: fieldLabels, values: fieldValues } = useMemo(\n () => collectFields(node.schema),\n [node.schema],\n );\n const initialValues = useMemo(() => ({ ...fieldValues, ...state }), [fieldValues, state]);\n const shouldRenderSubmitButton = props.submitButton;\n const submitButtons = props.submitButtons ?? undefined;\n const submitJustify = props.submitJustify ?? undefined;\n const submitLabel = props.submitLabel ?? t(\"form.submit\", \"Submit\");\n const submitVariant = props.submitVariant ?? undefined;\n const summaryLabel = props.validationSummaryLabel;\n const validationTimeout = props.validationTimeout ?? undefined;\n\n return (\n <InertiaForm\n action={action}\n data-slot=\"form\"\n data-lattice-component={node.id}\n errorBag={errorBag}\n method={method}\n resetOnError={resetOnError}\n resetOnSuccess={resetOnSuccess}\n validationTimeout={precognitive ? validationTimeout : undefined}\n headers={withHeaders(componentRef)}\n className=\"mx-auto flex w-full max-w-2xl flex-col gap-6\"\n >\n {({ clearErrors, errors, processing, reset, validate }) => (\n <FormProvider\n value={{\n action,\n clearErrors: (field) => clearErrors(field),\n componentId: node.id,\n componentRef,\n errors: errors as Record<string, string | undefined>,\n fieldLabels,\n precognitive,\n processing,\n validate: (field) => validate(field),\n }}\n >\n <FormResetListener componentId={node.id} reset={reset} />\n\n {props.status && (\n <div className=\"text-center text-sm font-medium text-lt-success\">{props.status}</div>\n )}\n\n <FormValuesProvider initial={initialValues}>\n <FormBody\n action={action}\n componentRef={componentRef}\n nodes={node.schema}\n shouldRenderSubmitButton={shouldRenderSubmitButton}\n submitButtons={submitButtons}\n submitJustify={submitJustify}\n submitLabel={submitLabel}\n submitVariant={submitVariant}\n summaryLabel={summaryLabel}\n >\n {children}\n </FormBody>\n </FormValuesProvider>\n </FormProvider>\n )}\n </InertiaForm>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"form.js","names":[],"sources":["../../../resources/js/form/components/form.tsx"],"sourcesContent":["import { Form as InertiaForm } from \"@inertiajs/react\";\nimport { withHeaders } from \"@lattice-php/lattice/core/headers\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\nimport { useWindowEvent } from \"@lattice-php/lattice/core/hooks/use-window-event\";\nimport { nodeKey } from \"@lattice-php/lattice/core/nodes\";\nimport { RenderNode } from \"@lattice-php/lattice/core/renderer\";\nimport type { Node, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { Emphasis, Justify, Variant } from \"@lattice-php/lattice/types/generated\";\nimport { useMemo } from \"react\";\nimport { FormSubmitButton } from \"./base/submit-button\";\nimport { FormProvider } from \"@lattice-php/lattice/form/hooks/context\";\nimport { collectFields } from \"@lattice-php/lattice/form/lib/collect-fields\";\nimport { PrefillProvider } from \"@lattice-php/lattice/form/hooks/prefill-context\";\nimport { ResolvedNodesProvider } from \"@lattice-php/lattice/form/hooks/resolved-nodes\";\nimport { useFormResolver } from \"@lattice-php/lattice/form/hooks/use-form-resolver\";\nimport { FormValuesProvider } from \"@lattice-php/lattice/form/hooks/values\";\n\nconst JUSTIFY_CLASS: Record<Justify, string> = {\n start: \"justify-start\",\n center: \"justify-center\",\n end: \"justify-end\",\n between: \"justify-between\",\n around: \"justify-around\",\n evenly: \"justify-evenly\",\n};\n\nfunction FormResetListener({\n componentId,\n reset,\n}: {\n componentId?: string;\n reset: (...fields: string[]) => void;\n}) {\n useWindowEvent(LATTICE_EVENT.resetForm, (event) => {\n const detail = (event as CustomEvent<{ form: string | null }>).detail;\n\n if (!detail?.form || detail.form === componentId) {\n reset();\n }\n });\n\n return null;\n}\n\nfunction FormBody({\n action,\n children,\n componentRef,\n nodes,\n shouldRenderSubmitButton,\n submitButtons,\n submitEmphasis,\n submitJustify,\n submitLabel,\n submitVariant,\n summaryLabel,\n}: {\n action: string;\n children: React.ReactNode;\n componentRef: string;\n nodes: Node[] | undefined;\n shouldRenderSubmitButton: boolean;\n submitButtons: Node<\"button\">[] | undefined;\n submitEmphasis: Emphasis | undefined;\n submitJustify: Justify | undefined;\n submitLabel: string;\n submitVariant: Variant | undefined;\n summaryLabel: string;\n}) {\n const { nodes: resolvedNodes, markUserEdit } = useFormResolver(action, componentRef, nodes);\n\n return (\n <PrefillProvider value={{ markUserEdit }}>\n <ResolvedNodesProvider nodes={resolvedNodes}>\n <div className=\"flex flex-col gap-6\">\n {children}\n\n {shouldRenderSubmitButton && (\n <div className={`flex gap-3 ${JUSTIFY_CLASS[submitJustify ?? \"end\"]}`}>\n {submitButtons?.length ? (\n submitButtons.map((button, index) =>\n button.props.buttonType === \"submit\" ? (\n <FormSubmitButton\n key={nodeKey(button, index)}\n emphasis={button.props.emphasis ?? submitEmphasis}\n label={button.props.label ?? submitLabel}\n summaryLabel={summaryLabel}\n variant={button.props.variant ?? submitVariant}\n />\n ) : (\n <RenderNode key={nodeKey(button, index)} node={button} />\n ),\n )\n ) : (\n <FormSubmitButton\n emphasis={submitEmphasis}\n label={submitLabel}\n summaryLabel={summaryLabel}\n variant={submitVariant}\n />\n )}\n </div>\n )}\n </div>\n </ResolvedNodesProvider>\n </PrefillProvider>\n );\n}\n\nexport const FormComponent: RendererComponent<\"form\"> = ({ children, node }) => {\n const { t } = useT(\"lattice\");\n const props = node.props;\n const action = props.action ?? \"#\";\n const errorBag = props.errorBag;\n const componentRef = props.ref ?? \"\";\n const method = props.method ?? \"post\";\n const precognitive = props.precognitive;\n const resetOnError = props.resetOnError ?? false;\n const resetOnSuccess = props.resetOnSuccess ?? [];\n const state = props.state;\n const { labels: fieldLabels, values: fieldValues } = useMemo(\n () => collectFields(node.schema),\n [node.schema],\n );\n const initialValues = useMemo(() => ({ ...fieldValues, ...state }), [fieldValues, state]);\n const shouldRenderSubmitButton = props.submitButton;\n const submitButtons = props.submitButtons ?? undefined;\n const submitJustify = props.submitJustify ?? undefined;\n const submitLabel = props.submitLabel ?? t(\"form.submit\", \"Submit\");\n const submitVariant = props.submitVariant ?? undefined;\n const submitEmphasis = props.submitEmphasis ?? undefined;\n const summaryLabel = props.validationSummaryLabel;\n const validationTimeout = props.validationTimeout ?? undefined;\n\n return (\n <InertiaForm\n action={action}\n data-slot=\"form\"\n data-lattice-component={node.id}\n errorBag={errorBag}\n method={method}\n resetOnError={resetOnError}\n resetOnSuccess={resetOnSuccess}\n validationTimeout={precognitive ? validationTimeout : undefined}\n headers={withHeaders(componentRef)}\n className=\"mx-auto flex w-full max-w-2xl flex-col gap-6\"\n >\n {({ clearErrors, errors, processing, reset, touch, validate, validating }) => (\n <FormProvider\n value={{\n action,\n clearErrors: (field) => clearErrors(field),\n componentId: node.id,\n componentRef,\n errors: errors as Record<string, string | undefined>,\n fieldLabels,\n precognitive,\n processing,\n touch: (fields) => touch(...fields),\n validate: (field) => validate(field),\n validateFields: (fields, options) => validate({ only: fields, ...options }),\n validating,\n }}\n >\n <FormResetListener componentId={node.id} reset={reset} />\n\n {props.status && (\n <div className=\"text-center text-sm font-medium text-lt-success\">{props.status}</div>\n )}\n\n <FormValuesProvider initial={initialValues}>\n <FormBody\n action={action}\n componentRef={componentRef}\n nodes={node.schema}\n shouldRenderSubmitButton={shouldRenderSubmitButton}\n submitButtons={submitButtons}\n submitEmphasis={submitEmphasis}\n submitJustify={submitJustify}\n submitLabel={submitLabel}\n submitVariant={submitVariant}\n summaryLabel={summaryLabel}\n >\n {children}\n </FormBody>\n </FormValuesProvider>\n </FormProvider>\n )}\n </InertiaForm>\n );\n};\n"],"mappings":"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"}
@@ -16,3 +16,4 @@ export { TextareaComponent } from './fields/textarea.js';
16
16
  export { TextInputComponent } from './fields/text-input.js';
17
17
  export { TimeInputComponent } from './fields/time-input.js';
18
18
  export { ToggleComponent } from './fields/toggle.js';
19
+ export { WizardComponent, WizardStepComponent } from './wizard.js';
@@ -16,4 +16,5 @@ import { TextareaComponent } from "./fields/textarea.js";
16
16
  import { TextInputComponent } from "./fields/text-input.js";
17
17
  import { TimeInputComponent } from "./fields/time-input.js";
18
18
  import { ToggleComponent } from "./fields/toggle.js";
19
- export { BuilderComponent, CheckboxComponent, ChoiceComponent, ColorPickerFieldComponent, DateInputComponent, DateTimeInputComponent, FileUploadComponent, FormComponent, HiddenInputComponent, NumberInputComponent, OtpInputComponent, PasswordInputComponent, RepeaterComponent, SelectComponent, TextInputComponent, TextareaComponent, TimeInputComponent, ToggleComponent };
19
+ import { WizardComponent, WizardStepComponent } from "./wizard.js";
20
+ export { BuilderComponent, CheckboxComponent, ChoiceComponent, ColorPickerFieldComponent, DateInputComponent, DateTimeInputComponent, FileUploadComponent, FormComponent, HiddenInputComponent, NumberInputComponent, OtpInputComponent, PasswordInputComponent, RepeaterComponent, SelectComponent, TextInputComponent, TextareaComponent, TimeInputComponent, ToggleComponent, WizardComponent, WizardStepComponent };
@@ -0,0 +1,3 @@
1
+ import { RendererComponent } from '../../core/types.js';
2
+ export declare const WizardComponent: RendererComponent<"wizard">;
3
+ export declare const WizardStepComponent: RendererComponent<"wizard-step">;
@@ -0,0 +1,148 @@
1
+ import { useT } from "../../i18n/instance.js";
2
+ import { cn } from "../../lib/utils.js";
3
+ import { Icon } from "../../icons/sprite.js";
4
+ import { Button } from "../../ui/button.js";
5
+ import { Spinner } from "../../ui/spinner.js";
6
+ import { useFormContext } from "../hooks/context.js";
7
+ import { firstErroredStep, stepFieldNames, stepValidationPaths, stepsWithErrors } from "../lib/wizard-steps.js";
8
+ import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ //#region resources/js/form/components/wizard.tsx
11
+ var WizardContext = createContext({ activeName: "" });
12
+ function getSteps(node) {
13
+ const nodes = (node.schema ?? []).filter((child) => child.type === "wizard-step");
14
+ return {
15
+ items: nodes.map((child) => child.props),
16
+ nodes
17
+ };
18
+ }
19
+ var WizardComponent = ({ children, node }) => {
20
+ const { t } = useT("lattice");
21
+ const { errors, processing, touch, validateFields, validating } = useFormContext();
22
+ const { items, nodes } = useMemo(() => getSteps(node), [node]);
23
+ const stepNames = useMemo(() => nodes.map((step) => stepFieldNames(step)), [nodes]);
24
+ const isVertical = node.props.orientation === "vertical";
25
+ const [activeIndex, setActiveIndex] = useState(0);
26
+ const [visited, setVisited] = useState(() => new Set([0]));
27
+ const [completed, setCompleted] = useState(() => /* @__PURE__ */ new Set());
28
+ const erroredSteps = useMemo(() => stepsWithErrors(stepNames, errors), [stepNames, errors]);
29
+ const isLast = activeIndex === items.length - 1;
30
+ const goTo = (index) => {
31
+ setActiveIndex(index);
32
+ setVisited((previous) => new Set(previous).add(index));
33
+ };
34
+ const advance = () => {
35
+ setCompleted((previous) => new Set(previous).add(activeIndex));
36
+ if (!isLast) goTo(activeIndex + 1);
37
+ };
38
+ const onNext = () => {
39
+ const step = nodes[activeIndex];
40
+ const paths = step ? stepValidationPaths(step) : [];
41
+ if (paths.length === 0) {
42
+ advance();
43
+ return;
44
+ }
45
+ touch(paths);
46
+ validateFields(paths, { onSuccess: advance });
47
+ };
48
+ const wasProcessing = useRef(false);
49
+ useEffect(() => {
50
+ if (wasProcessing.current && !processing) {
51
+ const target = firstErroredStep(stepNames, errors);
52
+ if (target !== null && target !== activeIndex) goTo(target);
53
+ }
54
+ wasProcessing.current = processing;
55
+ }, [
56
+ processing,
57
+ errors,
58
+ stepNames,
59
+ activeIndex
60
+ ]);
61
+ const contextValue = useMemo(() => ({ activeName: items[activeIndex]?.name ?? "" }), [items, activeIndex]);
62
+ return /* @__PURE__ */ jsx(WizardContext.Provider, {
63
+ value: contextValue,
64
+ children: /* @__PURE__ */ jsxs("div", {
65
+ className: cn("gap-6", isVertical ? "flex" : "grid"),
66
+ "data-slot": "wizard",
67
+ children: [/* @__PURE__ */ jsx("ol", {
68
+ "aria-label": t("form.wizard.steps", "Steps"),
69
+ className: cn("gap-1", isVertical ? "flex w-56 shrink-0 flex-col" : "flex flex-wrap"),
70
+ children: items.map((step, index) => {
71
+ const isActive = index === activeIndex;
72
+ const isDone = completed.has(index);
73
+ const hasError = erroredSteps.has(index);
74
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("button", {
75
+ "aria-current": isActive ? "step" : void 0,
76
+ className: cn("flex w-full items-center gap-2 rounded-lt px-3 py-2 text-left text-sm", isActive ? "bg-lt-muted font-medium text-lt-fg" : "text-lt-muted-fg", !visited.has(index) && "cursor-not-allowed opacity-60"),
77
+ "data-error": hasError || void 0,
78
+ "data-test": `wizard-rail-${step.name}`,
79
+ disabled: !visited.has(index),
80
+ id: `wizard-step-${step.name}-trigger`,
81
+ onClick: () => goTo(index),
82
+ type: "button",
83
+ children: [/* @__PURE__ */ jsx("span", {
84
+ className: cn("flex size-5 shrink-0 items-center justify-center rounded-full border text-xs", hasError ? "border-lt-danger text-lt-danger" : isDone ? "border-lt-primary bg-lt-primary text-lt-primary-fg" : "border-lt-border"),
85
+ children: isDone && !hasError ? /* @__PURE__ */ jsx(Icon, {
86
+ className: "size-lt-icon-sm",
87
+ name: "check"
88
+ }) : index + 1
89
+ }), /* @__PURE__ */ jsxs("span", {
90
+ className: "min-w-0",
91
+ children: [/* @__PURE__ */ jsx("span", {
92
+ className: "block truncate",
93
+ children: step.label
94
+ }), isVertical && step.description && /* @__PURE__ */ jsx("span", {
95
+ className: "block truncate text-xs text-lt-muted-fg",
96
+ children: step.description
97
+ })]
98
+ })]
99
+ }) }, step.name);
100
+ })
101
+ }), /* @__PURE__ */ jsxs("div", {
102
+ className: "min-w-0 flex-1 space-y-6",
103
+ children: [children, /* @__PURE__ */ jsxs("div", {
104
+ className: "flex items-center justify-between gap-3",
105
+ children: [/* @__PURE__ */ jsx(Button, {
106
+ "data-test": "wizard-back",
107
+ disabled: activeIndex === 0 || processing,
108
+ onClick: () => goTo(activeIndex - 1),
109
+ type: "button",
110
+ emphasis: "outline",
111
+ children: t("form.wizard.back", "Back")
112
+ }), isLast ? /* @__PURE__ */ jsxs(Button, {
113
+ "data-test": "wizard-finish",
114
+ disabled: processing,
115
+ type: "submit",
116
+ children: [processing && /* @__PURE__ */ jsx(Spinner, {}), t("form.wizard.finish", "Finish")]
117
+ }) : /* @__PURE__ */ jsxs(Button, {
118
+ "data-test": "wizard-next",
119
+ disabled: processing || validating,
120
+ onClick: onNext,
121
+ type: "button",
122
+ children: [validating && /* @__PURE__ */ jsx(Spinner, {}), t("form.wizard.next", "Next")]
123
+ })]
124
+ })]
125
+ })]
126
+ })
127
+ });
128
+ };
129
+ var WizardStepComponent = ({ children, node }) => {
130
+ const { activeName } = useContext(WizardContext);
131
+ const name = node.props.name;
132
+ const isActive = activeName === name;
133
+ const [hasOpened, setHasOpened] = useState(isActive);
134
+ useEffect(() => {
135
+ if (isActive) setHasOpened(true);
136
+ }, [isActive]);
137
+ return /* @__PURE__ */ jsx("section", {
138
+ "aria-labelledby": `wizard-step-${name}-trigger`,
139
+ className: cn("space-y-8", !isActive && "hidden"),
140
+ hidden: !isActive,
141
+ id: `wizard-step-${name}-panel`,
142
+ children: hasOpened ? children : null
143
+ });
144
+ };
145
+ //#endregion
146
+ export { WizardComponent, WizardStepComponent };
147
+
148
+ //# sourceMappingURL=wizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard.js","names":[],"sources":["../../../resources/js/form/components/wizard.tsx"],"sourcesContent":["import { createContext, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { Node, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport type { WizardStep } from \"@lattice-php/lattice/types/generated\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { Button } from \"@lattice-php/lattice/ui/button\";\nimport { Spinner } from \"@lattice-php/lattice/ui/spinner\";\nimport { useFormContext } from \"@lattice-php/lattice/form/hooks/context\";\nimport {\n firstErroredStep,\n stepFieldNames,\n stepsWithErrors,\n stepValidationPaths,\n} from \"@lattice-php/lattice/form/lib/wizard-steps\";\n\ntype WizardContextValue = { activeName: string };\n\nconst WizardContext = createContext<WizardContextValue>({ activeName: \"\" });\n\nfunction getSteps(node: Node<\"wizard\">): { items: WizardStep[]; nodes: Node[] } {\n const nodes = (node.schema ?? []).filter((child) => child.type === \"wizard-step\");\n const items = nodes.map((child) => child.props as unknown as WizardStep);\n\n return { items, nodes };\n}\n\nexport const WizardComponent: RendererComponent<\"wizard\"> = ({ children, node }) => {\n const { t } = useT(\"lattice\");\n const { errors, processing, touch, validateFields, validating } = useFormContext();\n const { items, nodes } = useMemo(() => getSteps(node), [node]);\n const stepNames = useMemo(() => nodes.map((step) => stepFieldNames(step)), [nodes]);\n const isVertical = node.props.orientation === \"vertical\";\n\n const [activeIndex, setActiveIndex] = useState(0);\n const [visited, setVisited] = useState<Set<number>>(() => new Set([0]));\n const [completed, setCompleted] = useState<Set<number>>(() => new Set());\n const erroredSteps = useMemo(() => stepsWithErrors(stepNames, errors), [stepNames, errors]);\n const isLast = activeIndex === items.length - 1;\n\n const goTo = (index: number): void => {\n setActiveIndex(index);\n setVisited((previous) => new Set(previous).add(index));\n };\n\n const advance = (): void => {\n setCompleted((previous) => new Set(previous).add(activeIndex));\n\n if (!isLast) {\n goTo(activeIndex + 1);\n }\n };\n\n const onNext = (): void => {\n const step = nodes[activeIndex];\n const paths = step ? stepValidationPaths(step) : [];\n\n if (paths.length === 0) {\n advance();\n\n return;\n }\n\n touch(paths);\n validateFields(paths, { onSuccess: advance });\n };\n\n const wasProcessing = useRef(false);\n useEffect(() => {\n if (wasProcessing.current && !processing) {\n const target = firstErroredStep(stepNames, errors);\n\n if (target !== null && target !== activeIndex) {\n goTo(target);\n }\n }\n\n wasProcessing.current = processing;\n }, [processing, errors, stepNames, activeIndex]);\n\n const contextValue = useMemo(\n () => ({ activeName: items[activeIndex]?.name ?? \"\" }),\n [items, activeIndex],\n );\n\n return (\n <WizardContext.Provider value={contextValue}>\n <div className={cn(\"gap-6\", isVertical ? \"flex\" : \"grid\")} data-slot=\"wizard\">\n <ol\n aria-label={t(\"form.wizard.steps\", \"Steps\")}\n className={cn(\"gap-1\", isVertical ? \"flex w-56 shrink-0 flex-col\" : \"flex flex-wrap\")}\n >\n {items.map((step, index) => {\n const isActive = index === activeIndex;\n const isDone = completed.has(index);\n const hasError = erroredSteps.has(index);\n\n return (\n <li key={step.name}>\n <button\n aria-current={isActive ? \"step\" : undefined}\n className={cn(\n \"flex w-full items-center gap-2 rounded-lt px-3 py-2 text-left text-sm\",\n isActive ? \"bg-lt-muted font-medium text-lt-fg\" : \"text-lt-muted-fg\",\n !visited.has(index) && \"cursor-not-allowed opacity-60\",\n )}\n data-error={hasError || undefined}\n data-test={`wizard-rail-${step.name}`}\n disabled={!visited.has(index)}\n id={`wizard-step-${step.name}-trigger`}\n onClick={() => goTo(index)}\n type=\"button\"\n >\n <span\n className={cn(\n \"flex size-5 shrink-0 items-center justify-center rounded-full border text-xs\",\n hasError\n ? \"border-lt-danger text-lt-danger\"\n : isDone\n ? \"border-lt-primary bg-lt-primary text-lt-primary-fg\"\n : \"border-lt-border\",\n )}\n >\n {isDone && !hasError ? (\n <Icon className=\"size-lt-icon-sm\" name=\"check\" />\n ) : (\n index + 1\n )}\n </span>\n <span className=\"min-w-0\">\n <span className=\"block truncate\">{step.label}</span>\n {isVertical && step.description && (\n <span className=\"block truncate text-xs text-lt-muted-fg\">\n {step.description}\n </span>\n )}\n </span>\n </button>\n </li>\n );\n })}\n </ol>\n\n <div className=\"min-w-0 flex-1 space-y-6\">\n {children}\n\n <div className=\"flex items-center justify-between gap-3\">\n <Button\n data-test=\"wizard-back\"\n disabled={activeIndex === 0 || processing}\n onClick={() => goTo(activeIndex - 1)}\n type=\"button\"\n emphasis=\"outline\"\n >\n {t(\"form.wizard.back\", \"Back\")}\n </Button>\n\n {isLast ? (\n <Button data-test=\"wizard-finish\" disabled={processing} type=\"submit\">\n {processing && <Spinner />}\n {t(\"form.wizard.finish\", \"Finish\")}\n </Button>\n ) : (\n <Button\n data-test=\"wizard-next\"\n disabled={processing || validating}\n onClick={onNext}\n type=\"button\"\n >\n {validating && <Spinner />}\n {t(\"form.wizard.next\", \"Next\")}\n </Button>\n )}\n </div>\n </div>\n </div>\n </WizardContext.Provider>\n );\n};\n\nexport const WizardStepComponent: RendererComponent<\"wizard-step\"> = ({ children, node }) => {\n const { activeName } = useContext(WizardContext);\n const name = node.props.name;\n const isActive = activeName === name;\n const [hasOpened, setHasOpened] = useState(isActive);\n\n useEffect(() => {\n if (isActive) {\n setHasOpened(true);\n }\n }, [isActive]);\n\n return (\n <section\n aria-labelledby={`wizard-step-${name}-trigger`}\n className={cn(\"space-y-8\", !isActive && \"hidden\")}\n hidden={!isActive}\n id={`wizard-step-${name}-panel`}\n >\n {hasOpened ? (children as ReactNode) : null}\n </section>\n );\n};\n"],"mappings":"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"}
@@ -16,7 +16,7 @@ export { FormValuesProvider, useFormValues, useSetFormValue } from './hooks/valu
16
16
  export { walkFields } from './lib/field-props.js';
17
17
  export { collectFields } from './lib/collect-fields.js';
18
18
  export type { CollectedFields } from './lib/collect-fields.js';
19
- export { firstErrors } from './lib/field-errors.js';
19
+ export { errorKeyBelongsTo, firstErrors } from './lib/field-errors.js';
20
20
  export type { FieldErrors } from './lib/field-errors.js';
21
21
  export { appendPath, getPath, setPath } from './lib/form-path.js';
22
22
  export { FORM_DEBOUNCE_MS } from './lib/form-transport.js';
@@ -9,5 +9,5 @@ import { TableCellProvider } from "./hooks/row-layout-context.js";
9
9
  import { FORM_DEBOUNCE_MS } from "./lib/form-transport.js";
10
10
  import { useFormResolver } from "./hooks/use-form-resolver.js";
11
11
  import { collectFields } from "./lib/collect-fields.js";
12
- import { firstErrors } from "./lib/field-errors.js";
13
- export { FORM_DEBOUNCE_MS, FieldCommitOverrideProvider, FormProvider, FormValuesProvider, PrefillProvider, ResolvedNodesProvider, TableCellProvider, appendPath, collectFields, firstErrors, getPath, setPath, useFormResolver, useFormValues, useSetFormValue, walkFields };
12
+ import { errorKeyBelongsTo, firstErrors } from "./lib/field-errors.js";
13
+ export { FORM_DEBOUNCE_MS, FieldCommitOverrideProvider, FormProvider, FormValuesProvider, PrefillProvider, ResolvedNodesProvider, TableCellProvider, appendPath, collectFields, errorKeyBelongsTo, firstErrors, getPath, setPath, useFormResolver, useFormValues, useSetFormValue, walkFields };
@@ -1,5 +1,5 @@
1
1
  import { Option } from '../../core/types.js';
2
- type FormContextValue = {
2
+ export type FormContextValue = {
3
3
  action: string;
4
4
  clearErrors: (field: string) => void;
5
5
  componentId?: string;
@@ -10,11 +10,16 @@ type FormContextValue = {
10
10
  precognitive: boolean;
11
11
  processing: boolean;
12
12
  searchOptions?: (field: string, query: string, values: Record<string, unknown>, signal: AbortSignal) => Promise<Option[]>;
13
+ touch: (fields: string[]) => void;
13
14
  validate: (field: string) => void;
15
+ validateFields: (fields: string[], options?: {
16
+ onSuccess?: () => void;
17
+ onValidationError?: () => void;
18
+ }) => void;
19
+ validating: boolean;
14
20
  };
15
21
  export declare function FormProvider({ children, value, }: {
16
22
  children: React.ReactNode;
17
23
  value: FormContextValue;
18
24
  }): import("react").JSX.Element;
19
25
  export declare function useFormContext(): FormContextValue;
20
- export {};
@@ -11,7 +11,10 @@ var FormContext = createContext({
11
11
  fieldLabels: {},
12
12
  precognitive: false,
13
13
  processing: false,
14
- validate: () => {}
14
+ touch: () => {},
15
+ validate: () => {},
16
+ validateFields: () => {},
17
+ validating: false
15
18
  });
16
19
  function FormProvider({ children, value }) {
17
20
  return /* @__PURE__ */ jsx(FormContext.Provider, {
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":[],"sources":["../../../resources/js/form/hooks/context.tsx"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { Option } from \"@lattice-php/lattice/core/types\";\n\ntype FormContextValue = {\n action: string;\n clearErrors: (field: string) => void;\n componentId?: string;\n componentRef: string;\n errors: Record<string, string | undefined>;\n fieldIdPrefix?: string;\n fieldLabels: Record<string, string>;\n precognitive: boolean;\n processing: boolean;\n searchOptions?: (\n field: string,\n query: string,\n values: Record<string, unknown>,\n signal: AbortSignal,\n ) => Promise<Option[]>;\n validate: (field: string) => void;\n};\n\nconst FormContext = createContext<FormContextValue>({\n action: \"#\",\n clearErrors: () => {},\n componentId: undefined,\n componentRef: \"\",\n errors: {},\n fieldIdPrefix: undefined,\n fieldLabels: {},\n precognitive: false,\n processing: false,\n validate: () => {},\n});\n\nexport function FormProvider({\n children,\n value,\n}: {\n children: React.ReactNode;\n value: FormContextValue;\n}) {\n return <FormContext.Provider value={value}>{children}</FormContext.Provider>;\n}\n\nexport function useFormContext() {\n return useContext(FormContext);\n}\n"],"mappings":";;;AAsBA,IAAM,cAAc,cAAgC;CAClD,QAAQ;CACR,mBAAmB,CAAC;CACpB,aAAa,KAAA;CACb,cAAc;CACd,QAAQ,CAAC;CACT,eAAe,KAAA;CACf,aAAa,CAAC;CACd,cAAc;CACd,YAAY;CACZ,gBAAgB,CAAC;AACnB,CAAC;AAED,SAAgB,aAAa,EAC3B,UACA,SAIC;CACD,OAAO,oBAAC,YAAY,UAAb;EAA6B;EAAQ;CAA+B,CAAA;AAC7E;AAEA,SAAgB,iBAAiB;CAC/B,OAAO,WAAW,WAAW;AAC/B"}
1
+ {"version":3,"file":"context.js","names":[],"sources":["../../../resources/js/form/hooks/context.tsx"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { Option } from \"@lattice-php/lattice/core/types\";\n\nexport type FormContextValue = {\n action: string;\n clearErrors: (field: string) => void;\n componentId?: string;\n componentRef: string;\n errors: Record<string, string | undefined>;\n fieldIdPrefix?: string;\n fieldLabels: Record<string, string>;\n precognitive: boolean;\n processing: boolean;\n searchOptions?: (\n field: string,\n query: string,\n values: Record<string, unknown>,\n signal: AbortSignal,\n ) => Promise<Option[]>;\n touch: (fields: string[]) => void;\n validate: (field: string) => void;\n validateFields: (\n fields: string[],\n options?: { onSuccess?: () => void; onValidationError?: () => void },\n ) => void;\n validating: boolean;\n};\n\nconst FormContext = createContext<FormContextValue>({\n action: \"#\",\n clearErrors: () => {},\n componentId: undefined,\n componentRef: \"\",\n errors: {},\n fieldIdPrefix: undefined,\n fieldLabels: {},\n precognitive: false,\n processing: false,\n touch: () => {},\n validate: () => {},\n validateFields: () => {},\n validating: false,\n});\n\nexport function FormProvider({\n children,\n value,\n}: {\n children: React.ReactNode;\n value: FormContextValue;\n}) {\n return <FormContext.Provider value={value}>{children}</FormContext.Provider>;\n}\n\nexport function useFormContext() {\n return useContext(FormContext);\n}\n"],"mappings":";;;AA4BA,IAAM,cAAc,cAAgC;CAClD,QAAQ;CACR,mBAAmB,CAAC;CACpB,aAAa,KAAA;CACb,cAAc;CACd,QAAQ,CAAC;CACT,eAAe,KAAA;CACf,aAAa,CAAC;CACd,cAAc;CACd,YAAY;CACZ,aAAa,CAAC;CACd,gBAAgB,CAAC;CACjB,sBAAsB,CAAC;CACvB,YAAY;AACd,CAAC;AAED,SAAgB,aAAa,EAC3B,UACA,SAIC;CACD,OAAO,oBAAC,YAAY,UAAb;EAA6B;EAAQ;CAA+B,CAAA;AAC7E;AAEA,SAAgB,iBAAiB;CAC/B,OAAO,WAAW,WAAW;AAC/B"}