@lattice-php/lattice 0.14.0 → 0.15.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 (52) hide show
  1. package/dist/action/components/action-group.js +1 -1
  2. package/dist/action/components/action-group.js.map +1 -1
  3. package/dist/action/components/action-menu-context.d.ts +1 -1
  4. package/dist/action/components/action-menu-context.js +1 -1
  5. package/dist/action/components/action-menu-context.js.map +1 -1
  6. package/dist/core/components/card.js +4 -4
  7. package/dist/core/components/card.js.map +1 -1
  8. package/dist/core/components/collapsible.js +1 -0
  9. package/dist/core/components/collapsible.js.map +1 -1
  10. package/dist/core/components/dialog.d.ts +1 -1
  11. package/dist/core/components/dialog.js +2 -2
  12. package/dist/core/components/dialog.js.map +1 -1
  13. package/dist/core/components/floating-panel.js +2 -2
  14. package/dist/core/components/floating-panel.js.map +1 -1
  15. package/dist/core/components/grid.js +1 -0
  16. package/dist/core/components/grid.js.map +1 -1
  17. package/dist/core/components/link.js +61 -3
  18. package/dist/core/components/link.js.map +1 -1
  19. package/dist/core/components/popover.d.ts +1 -1
  20. package/dist/core/components/popover.js +1 -1
  21. package/dist/core/components/popover.js.map +1 -1
  22. package/dist/core/components/section.js +4 -3
  23. package/dist/core/components/section.js.map +1 -1
  24. package/dist/core/components/stack.js +1 -0
  25. package/dist/core/components/stack.js.map +1 -1
  26. package/dist/form/components/base/submit-button.js +1 -1
  27. package/dist/form/components/base/submit-button.js.map +1 -1
  28. package/dist/form/components/fields/date-picker-control.js +2 -2
  29. package/dist/form/components/fields/date-picker-control.js.map +1 -1
  30. package/dist/form/components/fields/rich-editor.js +1 -1
  31. package/dist/form/components/fields/rich-editor.js.map +1 -1
  32. package/dist/form/components/form.js +2 -1
  33. package/dist/form/components/form.js.map +1 -1
  34. package/dist/lattice.css +68 -36
  35. package/dist/layout/menu-item.js +1 -1
  36. package/dist/layout/menu-item.js.map +1 -1
  37. package/dist/layout/sidebar.js +2 -2
  38. package/dist/layout/sidebar.js.map +1 -1
  39. package/dist/layout/topbar.js +1 -1
  40. package/dist/layout/topbar.js.map +1 -1
  41. package/dist/table/components/column-filter-control.js +2 -2
  42. package/dist/table/components/column-filter-control.js.map +1 -1
  43. package/dist/table/components/filter-controls.js +2 -2
  44. package/dist/table/components/filter-controls.js.map +1 -1
  45. package/dist/table/components/pagination.js +7 -6
  46. package/dist/table/components/pagination.js.map +1 -1
  47. package/dist/table/components/table.js +9 -3
  48. package/dist/table/components/table.js.map +1 -1
  49. package/dist/toast/toaster.js +1 -1
  50. package/dist/toast/toaster.js.map +1 -1
  51. package/dist/types/generated.d.ts +3 -0
  52. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"date-picker-control.js","names":[],"sources":["../../../../resources/js/form/components/fields/date-picker-control.tsx"],"sourcesContent":["import type { DateValue } from \"@internationalized/date\";\nimport * as datePicker from \"@zag-js/date-picker\";\nimport { normalizeProps, useMachine } from \"@zag-js/react\";\nimport { useId, useMemo } from \"react\";\nimport { Button } from \"@lattice-php/lattice/core/components/button\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { useLocale } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { Input } from \"../base/input\";\nimport {\n formatDateDisplayValue,\n formatDateTimeDisplayValue,\n formatDateTimeValue,\n formatDateValue,\n formatTimeInputValue,\n parseDateDisplayValue,\n parseDateTimeDisplayValue,\n parseDateTimeValue,\n parseDateValue,\n} from \"./date-picker-value\";\n\nexport type DatePickerControlProps = {\n mode: \"date\" | \"date-time\";\n label: string;\n name: string;\n testId: string;\n value: unknown;\n min?: string | null;\n max?: string | null;\n step?: number | null;\n disabled: boolean;\n readOnly: boolean;\n autoFocus?: boolean;\n tabIndex?: number | null;\n timezone?: string;\n onChange: (value: string) => void;\n onBlur?: () => void;\n};\n\nexport function DatePickerControl({\n mode,\n label,\n name,\n testId,\n value,\n min,\n max,\n step,\n disabled,\n readOnly,\n autoFocus = false,\n tabIndex,\n timezone = \"UTC\",\n onChange,\n onBlur,\n}: DatePickerControlProps) {\n const id = useId();\n const { locale } = useLocale();\n const selected = useMemo(\n () =>\n [mode === \"date\" ? parseDateValue(value) : parseDateTimeValue(value, timezone)].filter(\n Boolean,\n ) as DateValue[],\n [mode, timezone, value],\n );\n const service = useMachine(datePicker.machine, {\n id,\n name,\n value: selected.length > 0 ? selected : undefined,\n min: min ? parseDateValue(min) : undefined,\n max: max ? parseDateValue(max) : undefined,\n disabled,\n readOnly,\n locale,\n selectionMode: \"single\",\n timeZone: timezone,\n closeOnSelect: mode === \"date\",\n format(date) {\n return mode === \"date\"\n ? formatDateDisplayValue(date, locale)\n : formatDateTimeDisplayValue(date, locale, timezone);\n },\n parse(text) {\n return mode === \"date\"\n ? parseDateDisplayValue(text, locale)\n : parseDateTimeDisplayValue(text, locale, timezone);\n },\n onValueChange(details) {\n const next = details.value[0];\n\n onChange(mode === \"date\" ? formatDateValue(next) : formatDateTimeValue(next, timezone));\n },\n onOpenChange(details) {\n if (!details.open) {\n onBlur?.();\n }\n },\n });\n const api = datePicker.connect(service, normalizeProps);\n const { name: _inputName, onInput, ...inputProps } = api.getInputProps();\n const submittedValue =\n mode === \"date\" ? formatDateValue(selected[0]) : formatDateTimeValue(selected[0], timezone);\n\n return (\n <div {...api.getRootProps()} className={cn(\"relative\", api.open && \"z-[var(--lt-z-popover)]\")}>\n <input type=\"hidden\" name={name} value={submittedValue} data-test={`${testId}-value`} />\n <div {...api.getControlProps()} className=\"flex gap-2\">\n <Input\n {...inputProps}\n aria-label={label}\n autoFocus={autoFocus}\n data-test={testId}\n disabled={disabled}\n id={name}\n onInput={(event) => {\n onInput?.(event);\n\n if (mode !== \"date\") {\n return;\n }\n\n const normalized = normalizeDateInputValue(event.currentTarget.value);\n\n if (!normalized) {\n return;\n }\n\n const next = parseDateValue(normalized);\n\n if (!next) {\n return;\n }\n\n event.currentTarget.value = normalized;\n api.setValue([next]);\n event.currentTarget.value = formatDateDisplayValue(next, locale);\n onChange(formatDateValue(next));\n }}\n readOnly={readOnly}\n tabIndex={tabIndex ?? undefined}\n />\n <Button\n {...api.getTriggerProps()}\n aria-label={`Open ${label || name} calendar`}\n disabled={disabled || readOnly}\n size=\"icon\"\n type=\"button\"\n variant=\"secondary\"\n >\n <Icon name=\"calendar\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n </div>\n {api.open ? (\n <div\n {...api.getPositionerProps()}\n className=\"absolute z-[var(--lt-z-popover)] mt-2 rounded-lt-sm border border-lt-border bg-lt-popover p-3 text-lt-popover-fg shadow-lt-md\"\n >\n <div {...api.getContentProps()} className=\"grid gap-3\">\n <div className=\"flex items-center justify-between gap-2\">\n <Button {...api.getPrevTriggerProps()} size=\"icon\" type=\"button\" variant=\"ghost\">\n <Icon name=\"chevron-left\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n <div {...api.getRangeTextProps()} className=\"text-sm font-medium text-lt-fg\" />\n <Button {...api.getNextTriggerProps()} size=\"icon\" type=\"button\" variant=\"ghost\">\n <Icon name=\"chevron-right\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n </div>\n <table {...api.getTableProps()} className=\"w-full border-collapse text-sm\">\n <thead {...api.getTableHeadProps()}>\n <tr {...api.getTableRowProps()}>\n {api.weekDays.map((day) => (\n <th\n {...api.getTableHeaderProps()}\n aria-label={day.long}\n key={day.value.toString()}\n className=\"size-8 text-center text-xs font-medium text-lt-muted-fg\"\n >\n {day.narrow}\n </th>\n ))}\n </tr>\n </thead>\n <tbody {...api.getTableBodyProps()}>\n {api.weeks.map((week, weekIndex) => (\n <tr {...api.getTableRowProps()} key={weekIndex}>\n {week.map((day) => {\n const state = api.getDayTableCellState({ value: day });\n\n return (\n <td\n {...api.getDayTableCellProps({ value: day })}\n key={day.toString()}\n className=\"p-0 text-center\"\n >\n <button\n {...api.getDayTableCellTriggerProps({ value: day })}\n type=\"button\"\n className={cn(\n \"size-8 rounded-lt-sm text-sm text-lt-fg hover:bg-lt-muted\",\n state.selected && \"bg-lt-primary text-lt-primary-fg\",\n state.outsideRange && \"text-lt-muted-fg\",\n state.disabled && \"cursor-not-allowed opacity-40\",\n )}\n >\n {day.day}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n {mode === \"date-time\" ? (\n <Input\n aria-label={`${label || name} time`}\n disabled={disabled}\n onChange={(event) => {\n const [hour = \"0\", minute = \"0\", second = \"0\"] = event.target.value.split(\":\");\n\n api.setTime({\n hour: Number(hour),\n minute: Number(minute),\n second: Number(second),\n });\n }}\n readOnly={readOnly}\n step={step ?? undefined}\n type=\"time\"\n value={formatTimeInputValue(selected[0], timezone)}\n />\n ) : null}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction normalizeDateInputValue(value: string): string | undefined {\n const compact = value.replace(/\\D/g, \"\");\n\n if (compact.length !== 8) {\n return undefined;\n }\n\n return `${compact.slice(0, 4)}-${compact.slice(4, 6)}-${compact.slice(6, 8)}`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"date-picker-control.js","names":[],"sources":["../../../../resources/js/form/components/fields/date-picker-control.tsx"],"sourcesContent":["import type { DateValue } from \"@internationalized/date\";\nimport * as datePicker from \"@zag-js/date-picker\";\nimport { normalizeProps, useMachine } from \"@zag-js/react\";\nimport { useId, useMemo } from \"react\";\nimport { Button } from \"@lattice-php/lattice/core/components/button\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { useLocale } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { Input } from \"../base/input\";\nimport {\n formatDateDisplayValue,\n formatDateTimeDisplayValue,\n formatDateTimeValue,\n formatDateValue,\n formatTimeInputValue,\n parseDateDisplayValue,\n parseDateTimeDisplayValue,\n parseDateTimeValue,\n parseDateValue,\n} from \"./date-picker-value\";\n\nexport type DatePickerControlProps = {\n mode: \"date\" | \"date-time\";\n label: string;\n name: string;\n testId: string;\n value: unknown;\n min?: string | null;\n max?: string | null;\n step?: number | null;\n disabled: boolean;\n readOnly: boolean;\n autoFocus?: boolean;\n tabIndex?: number | null;\n timezone?: string;\n onChange: (value: string) => void;\n onBlur?: () => void;\n};\n\nexport function DatePickerControl({\n mode,\n label,\n name,\n testId,\n value,\n min,\n max,\n step,\n disabled,\n readOnly,\n autoFocus = false,\n tabIndex,\n timezone = \"UTC\",\n onChange,\n onBlur,\n}: DatePickerControlProps) {\n const id = useId();\n const { locale } = useLocale();\n const selected = useMemo(\n () =>\n [mode === \"date\" ? parseDateValue(value) : parseDateTimeValue(value, timezone)].filter(\n Boolean,\n ) as DateValue[],\n [mode, timezone, value],\n );\n const service = useMachine(datePicker.machine, {\n id,\n name,\n value: selected.length > 0 ? selected : undefined,\n min: min ? parseDateValue(min) : undefined,\n max: max ? parseDateValue(max) : undefined,\n disabled,\n readOnly,\n locale,\n selectionMode: \"single\",\n timeZone: timezone,\n closeOnSelect: mode === \"date\",\n format(date) {\n return mode === \"date\"\n ? formatDateDisplayValue(date, locale)\n : formatDateTimeDisplayValue(date, locale, timezone);\n },\n parse(text) {\n return mode === \"date\"\n ? parseDateDisplayValue(text, locale)\n : parseDateTimeDisplayValue(text, locale, timezone);\n },\n onValueChange(details) {\n const next = details.value[0];\n\n onChange(mode === \"date\" ? formatDateValue(next) : formatDateTimeValue(next, timezone));\n },\n onOpenChange(details) {\n if (!details.open) {\n onBlur?.();\n }\n },\n });\n const api = datePicker.connect(service, normalizeProps);\n const { name: _inputName, onInput, ...inputProps } = api.getInputProps();\n const submittedValue =\n mode === \"date\" ? formatDateValue(selected[0]) : formatDateTimeValue(selected[0], timezone);\n\n return (\n <div {...api.getRootProps()} className={cn(\"relative\", api.open && \"z-lt-popover\")}>\n <input type=\"hidden\" name={name} value={submittedValue} data-test={`${testId}-value`} />\n <div {...api.getControlProps()} className=\"flex gap-2\">\n <Input\n {...inputProps}\n aria-label={label}\n autoFocus={autoFocus}\n data-test={testId}\n disabled={disabled}\n id={name}\n onInput={(event) => {\n onInput?.(event);\n\n if (mode !== \"date\") {\n return;\n }\n\n const normalized = normalizeDateInputValue(event.currentTarget.value);\n\n if (!normalized) {\n return;\n }\n\n const next = parseDateValue(normalized);\n\n if (!next) {\n return;\n }\n\n event.currentTarget.value = normalized;\n api.setValue([next]);\n event.currentTarget.value = formatDateDisplayValue(next, locale);\n onChange(formatDateValue(next));\n }}\n readOnly={readOnly}\n tabIndex={tabIndex ?? undefined}\n />\n <Button\n {...api.getTriggerProps()}\n aria-label={`Open ${label || name} calendar`}\n disabled={disabled || readOnly}\n size=\"icon\"\n type=\"button\"\n variant=\"secondary\"\n >\n <Icon name=\"calendar\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n </div>\n {api.open ? (\n <div\n {...api.getPositionerProps()}\n className=\"absolute z-lt-popover mt-2 rounded-lt-sm border border-lt-border bg-lt-popover p-3 text-lt-popover-fg shadow-lt-md\"\n >\n <div {...api.getContentProps()} className=\"grid gap-3\">\n <div className=\"flex items-center justify-between gap-2\">\n <Button {...api.getPrevTriggerProps()} size=\"icon\" type=\"button\" variant=\"ghost\">\n <Icon name=\"chevron-left\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n <div {...api.getRangeTextProps()} className=\"text-sm font-medium text-lt-fg\" />\n <Button {...api.getNextTriggerProps()} size=\"icon\" type=\"button\" variant=\"ghost\">\n <Icon name=\"chevron-right\" className=\"size-lt-icon-md\" aria-hidden=\"true\" />\n </Button>\n </div>\n <table {...api.getTableProps()} className=\"w-full border-collapse text-sm\">\n <thead {...api.getTableHeadProps()}>\n <tr {...api.getTableRowProps()}>\n {api.weekDays.map((day) => (\n <th\n {...api.getTableHeaderProps()}\n aria-label={day.long}\n key={day.value.toString()}\n className=\"size-8 text-center text-xs font-medium text-lt-muted-fg\"\n >\n {day.narrow}\n </th>\n ))}\n </tr>\n </thead>\n <tbody {...api.getTableBodyProps()}>\n {api.weeks.map((week, weekIndex) => (\n <tr {...api.getTableRowProps()} key={weekIndex}>\n {week.map((day) => {\n const state = api.getDayTableCellState({ value: day });\n\n return (\n <td\n {...api.getDayTableCellProps({ value: day })}\n key={day.toString()}\n className=\"p-0 text-center\"\n >\n <button\n {...api.getDayTableCellTriggerProps({ value: day })}\n type=\"button\"\n className={cn(\n \"size-8 rounded-lt-sm text-sm text-lt-fg hover:bg-lt-muted\",\n state.selected && \"bg-lt-primary text-lt-primary-fg\",\n state.outsideRange && \"text-lt-muted-fg\",\n state.disabled && \"cursor-not-allowed opacity-40\",\n )}\n >\n {day.day}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n {mode === \"date-time\" ? (\n <Input\n aria-label={`${label || name} time`}\n disabled={disabled}\n onChange={(event) => {\n const [hour = \"0\", minute = \"0\", second = \"0\"] = event.target.value.split(\":\");\n\n api.setTime({\n hour: Number(hour),\n minute: Number(minute),\n second: Number(second),\n });\n }}\n readOnly={readOnly}\n step={step ?? undefined}\n type=\"time\"\n value={formatTimeInputValue(selected[0], timezone)}\n />\n ) : null}\n </div>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction normalizeDateInputValue(value: string): string | undefined {\n const compact = value.replace(/\\D/g, \"\");\n\n if (compact.length !== 8) {\n return undefined;\n }\n\n return `${compact.slice(0, 4)}-${compact.slice(4, 6)}-${compact.slice(6, 8)}`;\n}\n"],"mappings":"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"}
@@ -238,7 +238,7 @@ function EmojiPicker({ editor }) {
238
238
  type: "button",
239
239
  children: /* @__PURE__ */ jsx(Icon, { name: "smile" })
240
240
  }), open && /* @__PURE__ */ jsx("div", {
241
- className: "absolute z-10 mt-1 grid grid-cols-8 gap-0.5 rounded-lt-sm border border-lt-border bg-lt-bg p-1 shadow-lt-md",
241
+ className: "absolute z-lt-dropdown mt-1 grid grid-cols-8 gap-0.5 rounded-lt-sm border border-lt-border bg-lt-bg p-1 shadow-lt-md",
242
242
  children: emojis.map((emoji) => /* @__PURE__ */ jsx("button", {
243
243
  className: "inline-flex size-7 items-center justify-center rounded-lt-sm text-base hover:bg-lt-accent",
244
244
  onClick: () => {
@@ -1 +1 @@
1
- {"version":3,"file":"rich-editor.js","names":[],"sources":["../../../../resources/js/form/components/fields/rich-editor.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { Details, DetailsContent, DetailsSummary } from \"@tiptap/extension-details\";\nimport { Highlight } from \"@tiptap/extension-highlight\";\nimport { Link } from \"@tiptap/extension-link\";\nimport { TableKit } from \"@tiptap/extension-table\";\nimport { TextAlign } from \"@tiptap/extension-text-align\";\nimport { type Editor, EditorContent, useEditor } from \"@tiptap/react\";\nimport { StarterKit } from \"@tiptap/starter-kit\";\nimport { useEffect, useState } 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 \"../base/field\";\nimport { useFormContext } from \"../context\";\nimport { useFieldScope } from \"../field-scope\";\nimport { useDependentField } from \"../use-dependent-field\";\nimport { useFieldCommit } from \"../use-field-commit\";\nimport { useFormValue } from \"../values\";\n\ntype ToolbarItem =\n | \"separator\"\n | {\n icon: string;\n key: string;\n label: string;\n isActive: (editor: Editor) => boolean;\n isDisabled?: (editor: Editor) => boolean;\n run: (editor: Editor) => void;\n };\n\nconst toolbar: ToolbarItem[] = [\n {\n icon: \"bold\",\n key: \"bold\",\n label: \"Bold\",\n isActive: (e) => e.isActive(\"bold\"),\n run: (e) => e.chain().focus().toggleBold().run(),\n },\n {\n icon: \"italic\",\n key: \"italic\",\n label: \"Italic\",\n isActive: (e) => e.isActive(\"italic\"),\n run: (e) => e.chain().focus().toggleItalic().run(),\n },\n {\n icon: \"strikethrough\",\n key: \"strikethrough\",\n label: \"Strikethrough\",\n isActive: (e) => e.isActive(\"strike\"),\n run: (e) => e.chain().focus().toggleStrike().run(),\n },\n {\n icon: \"underline\",\n key: \"underline\",\n label: \"Underline\",\n isActive: (e) => e.isActive(\"underline\"),\n run: (e) => e.chain().focus().toggleUnderline().run(),\n },\n {\n icon: \"highlighter\",\n key: \"highlight\",\n label: \"Highlight\",\n isActive: (e) => e.isActive(\"highlight\"),\n run: (e) => e.chain().focus().toggleHighlight().run(),\n },\n \"separator\",\n {\n icon: \"heading-1\",\n key: \"heading-1\",\n label: \"Heading 1\",\n isActive: (e) => e.isActive(\"heading\", { level: 1 }),\n run: (e) => e.chain().focus().toggleHeading({ level: 1 }).run(),\n },\n {\n icon: \"heading-2\",\n key: \"heading-2\",\n label: \"Heading 2\",\n isActive: (e) => e.isActive(\"heading\", { level: 2 }),\n run: (e) => e.chain().focus().toggleHeading({ level: 2 }).run(),\n },\n {\n icon: \"heading-3\",\n key: \"heading-3\",\n label: \"Heading 3\",\n isActive: (e) => e.isActive(\"heading\", { level: 3 }),\n run: (e) => e.chain().focus().toggleHeading({ level: 3 }).run(),\n },\n \"separator\",\n {\n icon: \"list\",\n key: \"bullet-list\",\n label: \"Bullet list\",\n isActive: (e) => e.isActive(\"bulletList\"),\n run: (e) => e.chain().focus().toggleBulletList().run(),\n },\n {\n icon: \"list-ordered\",\n key: \"ordered-list\",\n label: \"Ordered list\",\n isActive: (e) => e.isActive(\"orderedList\"),\n run: (e) => e.chain().focus().toggleOrderedList().run(),\n },\n {\n icon: \"quote\",\n key: \"blockquote\",\n label: \"Blockquote\",\n isActive: (e) => e.isActive(\"blockquote\"),\n run: (e) => e.chain().focus().toggleBlockquote().run(),\n },\n {\n icon: \"code\",\n key: \"code-block\",\n label: \"Code block\",\n isActive: (e) => e.isActive(\"codeBlock\"),\n run: (e) => e.chain().focus().toggleCodeBlock().run(),\n },\n {\n icon: \"minus\",\n key: \"horizontal-rule\",\n label: \"Horizontal rule\",\n isActive: () => false,\n run: (e) => e.chain().focus().setHorizontalRule().run(),\n },\n \"separator\",\n {\n icon: \"align-left\",\n key: \"align-left\",\n label: \"Align left\",\n isActive: (e) => e.isActive({ textAlign: \"left\" }),\n run: (e) => e.chain().focus().setTextAlign(\"left\").run(),\n },\n {\n icon: \"align-center\",\n key: \"align-center\",\n label: \"Align center\",\n isActive: (e) => e.isActive({ textAlign: \"center\" }),\n run: (e) => e.chain().focus().setTextAlign(\"center\").run(),\n },\n {\n icon: \"align-right\",\n key: \"align-right\",\n label: \"Align right\",\n isActive: (e) => e.isActive({ textAlign: \"right\" }),\n run: (e) => e.chain().focus().setTextAlign(\"right\").run(),\n },\n {\n icon: \"align-justify\",\n key: \"justify\",\n label: \"Justify\",\n isActive: (e) => e.isActive({ textAlign: \"justify\" }),\n run: (e) => e.chain().focus().setTextAlign(\"justify\").run(),\n },\n \"separator\",\n {\n icon: \"link\",\n key: \"link\",\n label: \"Link\",\n isActive: (e) => e.isActive(\"link\"),\n run: (e) => {\n if (e.isActive(\"link\")) {\n e.chain().focus().unsetLink().run();\n return;\n }\n const url = window.prompt(\"Link URL\");\n if (url) {\n e.chain().focus().extendMarkRange(\"link\").setLink({ href: url }).run();\n }\n },\n },\n \"separator\",\n {\n icon: \"table\",\n key: \"insert-table\",\n label: \"Insert table\",\n isActive: (e) => e.isActive(\"table\"),\n run: (e) => e.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(),\n },\n {\n icon: \"columns-3\",\n key: \"add-column\",\n label: \"Add column\",\n isActive: () => false,\n isDisabled: (e) => !e.can().addColumnAfter(),\n run: (e) => e.chain().focus().addColumnAfter().run(),\n },\n {\n icon: \"rows-3\",\n key: \"add-row\",\n label: \"Add row\",\n isActive: () => false,\n isDisabled: (e) => !e.can().addRowAfter(),\n run: (e) => e.chain().focus().addRowAfter().run(),\n },\n {\n icon: \"trash-2\",\n key: \"delete-table\",\n label: \"Delete table\",\n isActive: () => false,\n isDisabled: (e) => !e.can().deleteTable(),\n run: (e) => e.chain().focus().deleteTable().run(),\n },\n {\n icon: \"chevron-right\",\n key: \"details\",\n label: \"Details\",\n isActive: (e) => e.isActive(\"details\"),\n run: (e) => {\n if (e.isActive(\"details\")) {\n e.chain().focus().unsetDetails().run();\n return;\n }\n e.chain().focus().setDetails().run();\n },\n },\n];\n\nconst emojis = [\n \"😀\",\n \"😅\",\n \"😂\",\n \"🥳\",\n \"😎\",\n \"🤔\",\n \"👍\",\n \"🙏\",\n \"🔥\",\n \"🎉\",\n \"🚀\",\n \"💡\",\n \"✅\",\n \"❌\",\n \"⭐\",\n \"❤️\",\n];\n\nfunction EmojiPicker({ editor }: { editor: Editor }) {\n const { t } = useT(\"lattice\");\n const [open, setOpen] = useState(false);\n\n return (\n <div className=\"relative\">\n <button\n aria-label={t(\"form.editor.insert-emoji\", \"Insert emoji\")}\n data-test=\"editor-emoji\"\n className=\"inline-flex size-7 items-center justify-center rounded-lt-sm text-lt-muted-fg transition-colors hover:bg-lt-accent hover:text-lt-accent-fg [&_svg]:size-lt-icon-md\"\n onClick={() => setOpen((value) => !value)}\n onMouseDown={(event) => event.preventDefault()}\n title={t(\"form.editor.insert-emoji\", \"Insert emoji\")}\n type=\"button\"\n >\n <Icon name=\"smile\" />\n </button>\n {open && (\n <div className=\"absolute z-10 mt-1 grid grid-cols-8 gap-0.5 rounded-lt-sm border border-lt-border bg-lt-bg p-1 shadow-lt-md\">\n {emojis.map((emoji) => (\n <button\n className=\"inline-flex size-7 items-center justify-center rounded-lt-sm text-base hover:bg-lt-accent\"\n key={emoji}\n onClick={() => {\n editor.chain().focus().insertContent(emoji).run();\n setOpen(false);\n }}\n onMouseDown={(event) => event.preventDefault()}\n type=\"button\"\n >\n {emoji}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction Toolbar({ editor }: { editor: Editor }) {\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 {toolbar.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 const label = t(`form.editor.${item.key}`, item.label);\n\n return (\n <button\n aria-label={label}\n aria-pressed={item.isActive(editor)}\n data-test={`editor-${item.key}`}\n className={cn(\n \"inline-flex size-7 items-center justify-center rounded-lt-sm text-lt-muted-fg transition-colors hover:bg-lt-accent hover:text-lt-accent-fg disabled:pointer-events-none disabled:opacity-40 [&_svg]:size-lt-icon-md\",\n item.isActive(editor) && \"bg-lt-accent text-lt-accent-fg\",\n )}\n disabled={item.isDisabled?.(editor) ?? false}\n key={item.key}\n // Keep focus in the editor so toolbar clicks don't blur it (which would\n // otherwise trigger a precognition request).\n onClick={() => item.run(editor)}\n onMouseDown={(event) => event.preventDefault()}\n title={label}\n type=\"button\"\n >\n <Icon name={item.icon} />\n </button>\n );\n })}\n <span className=\"mx-1 h-5 w-px bg-lt-border\" />\n <EmojiPicker editor={editor} />\n </div>\n );\n}\n\nexport const RichEditorComponent: 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 editor = useEditor({\n extensions: [\n StarterKit,\n Highlight,\n TextAlign.configure({ types: [\"heading\", \"paragraph\"] }),\n Link.configure({ openOnClick: false }),\n TableKit.configure({ table: { resizable: false } }),\n Details,\n DetailsSummary,\n DetailsContent,\n ],\n content: initialContent,\n editable: !locked,\n immediatelyRender: false,\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 editor={editor} />}\n <EditorContent editor={editor} />\n </div>\n <input name={domName} type=\"hidden\" value={submittedValue} />\n </FormFieldFrame>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"rich-editor.js","names":[],"sources":["../../../../resources/js/form/components/fields/rich-editor.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { Details, DetailsContent, DetailsSummary } from \"@tiptap/extension-details\";\nimport { Highlight } from \"@tiptap/extension-highlight\";\nimport { Link } from \"@tiptap/extension-link\";\nimport { TableKit } from \"@tiptap/extension-table\";\nimport { TextAlign } from \"@tiptap/extension-text-align\";\nimport { type Editor, EditorContent, useEditor } from \"@tiptap/react\";\nimport { StarterKit } from \"@tiptap/starter-kit\";\nimport { useEffect, useState } 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 \"../base/field\";\nimport { useFormContext } from \"../context\";\nimport { useFieldScope } from \"../field-scope\";\nimport { useDependentField } from \"../use-dependent-field\";\nimport { useFieldCommit } from \"../use-field-commit\";\nimport { useFormValue } from \"../values\";\n\ntype ToolbarItem =\n | \"separator\"\n | {\n icon: string;\n key: string;\n label: string;\n isActive: (editor: Editor) => boolean;\n isDisabled?: (editor: Editor) => boolean;\n run: (editor: Editor) => void;\n };\n\nconst toolbar: ToolbarItem[] = [\n {\n icon: \"bold\",\n key: \"bold\",\n label: \"Bold\",\n isActive: (e) => e.isActive(\"bold\"),\n run: (e) => e.chain().focus().toggleBold().run(),\n },\n {\n icon: \"italic\",\n key: \"italic\",\n label: \"Italic\",\n isActive: (e) => e.isActive(\"italic\"),\n run: (e) => e.chain().focus().toggleItalic().run(),\n },\n {\n icon: \"strikethrough\",\n key: \"strikethrough\",\n label: \"Strikethrough\",\n isActive: (e) => e.isActive(\"strike\"),\n run: (e) => e.chain().focus().toggleStrike().run(),\n },\n {\n icon: \"underline\",\n key: \"underline\",\n label: \"Underline\",\n isActive: (e) => e.isActive(\"underline\"),\n run: (e) => e.chain().focus().toggleUnderline().run(),\n },\n {\n icon: \"highlighter\",\n key: \"highlight\",\n label: \"Highlight\",\n isActive: (e) => e.isActive(\"highlight\"),\n run: (e) => e.chain().focus().toggleHighlight().run(),\n },\n \"separator\",\n {\n icon: \"heading-1\",\n key: \"heading-1\",\n label: \"Heading 1\",\n isActive: (e) => e.isActive(\"heading\", { level: 1 }),\n run: (e) => e.chain().focus().toggleHeading({ level: 1 }).run(),\n },\n {\n icon: \"heading-2\",\n key: \"heading-2\",\n label: \"Heading 2\",\n isActive: (e) => e.isActive(\"heading\", { level: 2 }),\n run: (e) => e.chain().focus().toggleHeading({ level: 2 }).run(),\n },\n {\n icon: \"heading-3\",\n key: \"heading-3\",\n label: \"Heading 3\",\n isActive: (e) => e.isActive(\"heading\", { level: 3 }),\n run: (e) => e.chain().focus().toggleHeading({ level: 3 }).run(),\n },\n \"separator\",\n {\n icon: \"list\",\n key: \"bullet-list\",\n label: \"Bullet list\",\n isActive: (e) => e.isActive(\"bulletList\"),\n run: (e) => e.chain().focus().toggleBulletList().run(),\n },\n {\n icon: \"list-ordered\",\n key: \"ordered-list\",\n label: \"Ordered list\",\n isActive: (e) => e.isActive(\"orderedList\"),\n run: (e) => e.chain().focus().toggleOrderedList().run(),\n },\n {\n icon: \"quote\",\n key: \"blockquote\",\n label: \"Blockquote\",\n isActive: (e) => e.isActive(\"blockquote\"),\n run: (e) => e.chain().focus().toggleBlockquote().run(),\n },\n {\n icon: \"code\",\n key: \"code-block\",\n label: \"Code block\",\n isActive: (e) => e.isActive(\"codeBlock\"),\n run: (e) => e.chain().focus().toggleCodeBlock().run(),\n },\n {\n icon: \"minus\",\n key: \"horizontal-rule\",\n label: \"Horizontal rule\",\n isActive: () => false,\n run: (e) => e.chain().focus().setHorizontalRule().run(),\n },\n \"separator\",\n {\n icon: \"align-left\",\n key: \"align-left\",\n label: \"Align left\",\n isActive: (e) => e.isActive({ textAlign: \"left\" }),\n run: (e) => e.chain().focus().setTextAlign(\"left\").run(),\n },\n {\n icon: \"align-center\",\n key: \"align-center\",\n label: \"Align center\",\n isActive: (e) => e.isActive({ textAlign: \"center\" }),\n run: (e) => e.chain().focus().setTextAlign(\"center\").run(),\n },\n {\n icon: \"align-right\",\n key: \"align-right\",\n label: \"Align right\",\n isActive: (e) => e.isActive({ textAlign: \"right\" }),\n run: (e) => e.chain().focus().setTextAlign(\"right\").run(),\n },\n {\n icon: \"align-justify\",\n key: \"justify\",\n label: \"Justify\",\n isActive: (e) => e.isActive({ textAlign: \"justify\" }),\n run: (e) => e.chain().focus().setTextAlign(\"justify\").run(),\n },\n \"separator\",\n {\n icon: \"link\",\n key: \"link\",\n label: \"Link\",\n isActive: (e) => e.isActive(\"link\"),\n run: (e) => {\n if (e.isActive(\"link\")) {\n e.chain().focus().unsetLink().run();\n return;\n }\n const url = window.prompt(\"Link URL\");\n if (url) {\n e.chain().focus().extendMarkRange(\"link\").setLink({ href: url }).run();\n }\n },\n },\n \"separator\",\n {\n icon: \"table\",\n key: \"insert-table\",\n label: \"Insert table\",\n isActive: (e) => e.isActive(\"table\"),\n run: (e) => e.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(),\n },\n {\n icon: \"columns-3\",\n key: \"add-column\",\n label: \"Add column\",\n isActive: () => false,\n isDisabled: (e) => !e.can().addColumnAfter(),\n run: (e) => e.chain().focus().addColumnAfter().run(),\n },\n {\n icon: \"rows-3\",\n key: \"add-row\",\n label: \"Add row\",\n isActive: () => false,\n isDisabled: (e) => !e.can().addRowAfter(),\n run: (e) => e.chain().focus().addRowAfter().run(),\n },\n {\n icon: \"trash-2\",\n key: \"delete-table\",\n label: \"Delete table\",\n isActive: () => false,\n isDisabled: (e) => !e.can().deleteTable(),\n run: (e) => e.chain().focus().deleteTable().run(),\n },\n {\n icon: \"chevron-right\",\n key: \"details\",\n label: \"Details\",\n isActive: (e) => e.isActive(\"details\"),\n run: (e) => {\n if (e.isActive(\"details\")) {\n e.chain().focus().unsetDetails().run();\n return;\n }\n e.chain().focus().setDetails().run();\n },\n },\n];\n\nconst emojis = [\n \"😀\",\n \"😅\",\n \"😂\",\n \"🥳\",\n \"😎\",\n \"🤔\",\n \"👍\",\n \"🙏\",\n \"🔥\",\n \"🎉\",\n \"🚀\",\n \"💡\",\n \"✅\",\n \"❌\",\n \"⭐\",\n \"❤️\",\n];\n\nfunction EmojiPicker({ editor }: { editor: Editor }) {\n const { t } = useT(\"lattice\");\n const [open, setOpen] = useState(false);\n\n return (\n <div className=\"relative\">\n <button\n aria-label={t(\"form.editor.insert-emoji\", \"Insert emoji\")}\n data-test=\"editor-emoji\"\n className=\"inline-flex size-7 items-center justify-center rounded-lt-sm text-lt-muted-fg transition-colors hover:bg-lt-accent hover:text-lt-accent-fg [&_svg]:size-lt-icon-md\"\n onClick={() => setOpen((value) => !value)}\n onMouseDown={(event) => event.preventDefault()}\n title={t(\"form.editor.insert-emoji\", \"Insert emoji\")}\n type=\"button\"\n >\n <Icon name=\"smile\" />\n </button>\n {open && (\n <div className=\"absolute z-lt-dropdown mt-1 grid grid-cols-8 gap-0.5 rounded-lt-sm border border-lt-border bg-lt-bg p-1 shadow-lt-md\">\n {emojis.map((emoji) => (\n <button\n className=\"inline-flex size-7 items-center justify-center rounded-lt-sm text-base hover:bg-lt-accent\"\n key={emoji}\n onClick={() => {\n editor.chain().focus().insertContent(emoji).run();\n setOpen(false);\n }}\n onMouseDown={(event) => event.preventDefault()}\n type=\"button\"\n >\n {emoji}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction Toolbar({ editor }: { editor: Editor }) {\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 {toolbar.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 const label = t(`form.editor.${item.key}`, item.label);\n\n return (\n <button\n aria-label={label}\n aria-pressed={item.isActive(editor)}\n data-test={`editor-${item.key}`}\n className={cn(\n \"inline-flex size-7 items-center justify-center rounded-lt-sm text-lt-muted-fg transition-colors hover:bg-lt-accent hover:text-lt-accent-fg disabled:pointer-events-none disabled:opacity-40 [&_svg]:size-lt-icon-md\",\n item.isActive(editor) && \"bg-lt-accent text-lt-accent-fg\",\n )}\n disabled={item.isDisabled?.(editor) ?? false}\n key={item.key}\n // Keep focus in the editor so toolbar clicks don't blur it (which would\n // otherwise trigger a precognition request).\n onClick={() => item.run(editor)}\n onMouseDown={(event) => event.preventDefault()}\n title={label}\n type=\"button\"\n >\n <Icon name={item.icon} />\n </button>\n );\n })}\n <span className=\"mx-1 h-5 w-px bg-lt-border\" />\n <EmojiPicker editor={editor} />\n </div>\n );\n}\n\nexport const RichEditorComponent: 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 editor = useEditor({\n extensions: [\n StarterKit,\n Highlight,\n TextAlign.configure({ types: [\"heading\", \"paragraph\"] }),\n Link.configure({ openOnClick: false }),\n TableKit.configure({ table: { resizable: false } }),\n Details,\n DetailsSummary,\n DetailsContent,\n ],\n content: initialContent,\n editable: !locked,\n immediatelyRender: false,\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 editor={editor} />}\n <EditorContent editor={editor} />\n </div>\n <input name={domName} type=\"hidden\" value={submittedValue} />\n </FormFieldFrame>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA8BA,IAAM,UAAyB;CAC7B;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,MAAM;EAClC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI;CACjD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,QAAQ;EACpC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI;CACnD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,QAAQ;EACpC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI;CACnD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,WAAW;EACvC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI;CACtD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,WAAW;EACvC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI;CACtD;CACA;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,WAAW,EAAE,OAAO,EAAE,CAAC;EACnD,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI;CAChE;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,WAAW,EAAE,OAAO,EAAE,CAAC;EACnD,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI;CAChE;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,WAAW,EAAE,OAAO,EAAE,CAAC;EACnD,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI;CAChE;CACA;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,YAAY;EACxC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI;CACvD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,aAAa;EACzC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,IAAI;CACxD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,YAAY;EACxC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI;CACvD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,WAAW;EACvC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI;CACtD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,gBAAgB;EAChB,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,IAAI;CACxD;CACA;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,EAAE,WAAW,OAAO,CAAC;EACjD,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,MAAM,EAAE,IAAI;CACzD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,EAAE,WAAW,SAAS,CAAC;EACnD,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,QAAQ,EAAE,IAAI;CAC3D;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,EAAE,WAAW,QAAQ,CAAC;EAClD,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,OAAO,EAAE,IAAI;CAC1D;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,EAAE,WAAW,UAAU,CAAC;EACpD,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,SAAS,EAAE,IAAI;CAC5D;CACA;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,MAAM;EAClC,MAAM,MAAM;GACV,IAAI,EAAE,SAAS,MAAM,GAAG;IACtB,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI;IAClC;GACF;GACA,MAAM,MAAM,OAAO,OAAO,UAAU;GACpC,IAAI,KACF,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAE,IAAI;EAEzE;CACF;CACA;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,OAAO;EACnC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY;GAAE,MAAM;GAAG,MAAM;GAAG,eAAe;EAAK,CAAC,EAAE,IAAI;CAC3F;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,gBAAgB;EAChB,aAAa,MAAM,CAAC,EAAE,IAAI,EAAE,eAAe;EAC3C,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI;CACrD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,gBAAgB;EAChB,aAAa,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY;EACxC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI;CAClD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,gBAAgB;EAChB,aAAa,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY;EACxC,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI;CAClD;CACA;EACE,MAAM;EACN,KAAK;EACL,OAAO;EACP,WAAW,MAAM,EAAE,SAAS,SAAS;EACrC,MAAM,MAAM;GACV,IAAI,EAAE,SAAS,SAAS,GAAG;IACzB,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI;IACrC;GACF;GACA,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI;EACrC;CACF;AACF;AAEA,IAAM,SAAS;CACb;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAS,YAAY,EAAE,UAA8B;CACnD,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CAEtC,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,UAAD;GACE,cAAY,EAAE,4BAA4B,cAAc;GACxD,aAAU;GACV,WAAU;GACV,eAAe,SAAS,UAAU,CAAC,KAAK;GACxC,cAAc,UAAU,MAAM,eAAe;GAC7C,OAAO,EAAE,4BAA4B,cAAc;GACnD,MAAK;aAEL,oBAAC,MAAD,EAAM,MAAK,QAAS,CAAA;EACd,CAAA,GACP,QACC,oBAAC,OAAD;GAAK,WAAU;aACZ,OAAO,KAAK,UACX,oBAAC,UAAD;IACE,WAAU;IAEV,eAAe;KACb,OAAO,MAAM,EAAE,MAAM,EAAE,cAAc,KAAK,EAAE,IAAI;KAChD,QAAQ,KAAK;IACf;IACA,cAAc,UAAU,MAAM,eAAe;IAC7C,MAAK;cAEJ;GACK,GATD,KASC,CACT;EACE,CAAA,CAEJ;;AAET;AAEA,SAAS,QAAQ,EAAE,UAA8B;CAC/C,MAAM,EAAE,MAAM,KAAK,SAAS;CAE5B,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACG,QAAQ,KAAK,MAAM,UAAU;IAC5B,IAAI,SAAS,aAEX,OAAO,oBAAC,QAAD,EAA2B,WAAU,6BAA8B,GAAxD,OAAO,OAAiD;IAG5E,MAAM,QAAQ,EAAE,eAAe,KAAK,OAAO,KAAK,KAAK;IAErD,OACE,oBAAC,UAAD;KACE,cAAY;KACZ,gBAAc,KAAK,SAAS,MAAM;KAClC,aAAW,UAAU,KAAK;KAC1B,WAAW,GACT,uNACA,KAAK,SAAS,MAAM,KAAK,gCAC3B;KACA,UAAU,KAAK,aAAa,MAAM,KAAK;KAIvC,eAAe,KAAK,IAAI,MAAM;KAC9B,cAAc,UAAU,MAAM,eAAe;KAC7C,OAAO;KACP,MAAK;eAEL,oBAAC,MAAD,EAAM,MAAM,KAAK,KAAO,CAAA;IAClB,GATD,KAAK,GASJ;GAEZ,CAAC;GACD,oBAAC,QAAD,EAAM,WAAU,6BAA8B,CAAA;GAC9C,oBAAC,aAAD,EAAqB,OAAS,CAAA;EAC3B;;AAET;AAEA,IAAa,uBAA+D,EAAE,WAAW;CACvF,MAAM,EAAE,WAAW,eAAe;CAClC,MAAM,EAAE,QAAQ,UAAU,UAAU,aAAa,kBAAkB,IAAI;CACvE,MAAM,EAAE,QAAQ,SAAS,eAAe;CACxC,MAAM,OAAO,KAAK,MAAM;CACxB,MAAM,QAAQ,cAAc;CAC5B,MAAM,cAAc,aAAa,IAAI;CACrC,MAAM,cAAc,QAAQ,MAAM,SAAS,IAAI,IAAI;CACnD,MAAM,UAAU,QAAQ,MAAM,WAAW,IAAI,IAAI;CACjD,MAAM,WAAW,QAAQ,MAAM,SAAS,IAAI,IAAI;CAChD,MAAM,SAAS,YAAY;CAC3B,MAAM,iBACJ,OAAO,gBAAgB,YAAY,gBAAgB,OAC9C,cACC,KAAK,MAAM,SAAgC;CAEnD,MAAM,SAAS,UAAU;EACvB,YAAY;GACV;GACA;GACA,UAAU,UAAU,EAAE,OAAO,CAAC,WAAW,WAAW,EAAE,CAAC;GACvD,KAAK,UAAU,EAAE,aAAa,MAAM,CAAC;GACrC,SAAS,UAAU,EAAE,OAAO,EAAE,WAAW,MAAM,EAAE,CAAC;GAClD;GACA;GACA;EACF;EACA,SAAS;EACT,UAAU,CAAC;EACX,mBAAmB;EACnB,aAAa,EACX,YAAY,EACV,OAAO,gDACT,EACF;EACA,WAAW,EAAE,QAAQ,eAAe;GAClC,OAAO,MAAM,SAAS,UAAU,OAAO,SAAS,QAAQ,CAAC;EAC3D;EACA,cAAc;GACZ,KAAK,IAAI;EACX;CACF,CAAC;CAED,gBAAgB;EACd,QAAQ,YAAY,CAAC,MAAM;CAC7B,GAAG,CAAC,QAAQ,MAAM,CAAC;CAEnB,IAAI,QACF,OAAO;CAGT,MAAM,iBAAiB,cAAc,KAAK,UAAU,WAAW,IAAI;CAEnE,OACE,qBAAC,gBAAD;EACE,OAAO,OAAO;EACd,YAAY,KAAK,MAAM,cAAc,KAAA;EACrC,SAAS,KAAK,MAAM,WAAW,KAAA;EAC/B,OAAO,KAAK,MAAM,SAAS;EAC3B,MAAM;EACI;YANZ,CAQE,qBAAC,OAAD;GACE,WAAW,GACT,qKACA,UAAU,YACZ;aAJF,CAMG,UAAU,CAAC,UAAU,oBAAC,SAAD,EAAiB,OAAS,CAAA,GAChD,oBAAC,eAAD,EAAuB,OAAS,CAAA,CAC7B;MACL,oBAAC,SAAD;GAAO,MAAM;GAAS,MAAK;GAAS,OAAO;EAAiB,CAAA,CAC9C;;AAEpB"}
@@ -43,7 +43,7 @@ function FormBody({ action, children, componentRef, nodes, shouldRenderSubmitBut
43
43
  children: /* @__PURE__ */ jsxs("div", {
44
44
  className: "flex flex-col gap-6",
45
45
  children: [children, shouldRenderSubmitButton && /* @__PURE__ */ jsx("div", {
46
- className: "flex justify-end rounded-lt border border-lt-border bg-lt-surface px-6 py-4 shadow-lt-sm",
46
+ className: "flex justify-end rounded-lt border border-lt-border bg-lt-surface px-lt-gutter py-4 shadow-lt-sm",
47
47
  children: /* @__PURE__ */ jsx(FormSubmitButton, {
48
48
  label: submitLabel,
49
49
  summaryLabel
@@ -74,6 +74,7 @@ var FormComponent = ({ children, node }) => {
74
74
  const validationTimeout = props.validationTimeout ?? void 0;
75
75
  return /* @__PURE__ */ jsx(Form, {
76
76
  action,
77
+ "data-slot": "form",
77
78
  "data-lattice-component": node.id,
78
79
  errorBag,
79
80
  method,
@@ -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/events/event-names\";\nimport type { Node, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useEffect, useMemo } from \"react\";\nimport { FormSubmitButton } from \"./base/submit-button\";\nimport { FormProvider } from \"./context\";\nimport { walkFields } from \"./field-props\";\nimport { PrefillProvider } from \"./prefill-context\";\nimport { ResolvedNodesProvider } from \"./resolved-nodes\";\nimport { useFormResolver } from \"./use-form-resolver\";\nimport { FormValuesProvider } from \"./values\";\n\ntype CollectedFields = {\n labels: Record<string, string>;\n values: Record<string, unknown>;\n};\n\nfunction collectFields(nodes: Node[] | undefined): CollectedFields {\n const collected: CollectedFields = { labels: {}, values: {} };\n\n walkFields(nodes, (props) => {\n if (!props.name) {\n return;\n }\n if (props.label) {\n collected.labels[props.name] = props.label;\n }\n if (props.value !== undefined) {\n collected.values[props.name] = props.value;\n }\n });\n\n return collected;\n}\n\nfunction FormResetListener({\n componentId,\n reset,\n}: {\n componentId?: string;\n reset: (...fields: string[]) => void;\n}) {\n useEffect(() => {\n const handler = (event: 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 window.addEventListener(LATTICE_EVENT.resetForm, handler);\n\n return () => window.removeEventListener(LATTICE_EVENT.resetForm, handler);\n }, [componentId, reset]);\n\n return null;\n}\n\nfunction FormBody({\n action,\n children,\n componentRef,\n nodes,\n shouldRenderSubmitButton,\n submitLabel,\n summaryLabel,\n}: {\n action: string;\n children: React.ReactNode;\n componentRef: string;\n nodes: Node[] | undefined;\n shouldRenderSubmitButton: boolean;\n submitLabel: string;\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 justify-end rounded-lt border border-lt-border bg-lt-surface px-6 py-4 shadow-lt-sm\">\n <FormSubmitButton label={submitLabel} summaryLabel={summaryLabel} />\n </div>\n )}\n </div>\n </ResolvedNodesProvider>\n </PrefillProvider>\n );\n}\n\nexport const FormComponent: RendererComponent<\"form\"> = ({ children, node }) => {\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 submitLabel = props.submitLabel ?? \"Submit\";\n const summaryLabel = props.validationSummaryLabel;\n const validationTimeout = props.validationTimeout ?? undefined;\n\n return (\n <InertiaForm\n action={action}\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 submitLabel={submitLabel}\n summaryLabel={summaryLabel}\n >\n {children}\n </FormBody>\n </FormValuesProvider>\n </FormProvider>\n )}\n </InertiaForm>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAkBA,SAAS,cAAc,OAA4C;CACjE,MAAM,YAA6B;EAAE,QAAQ,CAAC;EAAG,QAAQ,CAAC;CAAE;CAE5D,WAAW,QAAQ,UAAU;EAC3B,IAAI,CAAC,MAAM,MACT;EAEF,IAAI,MAAM,OACR,UAAU,OAAO,MAAM,QAAQ,MAAM;EAEvC,IAAI,MAAM,UAAU,KAAA,GAClB,UAAU,OAAO,MAAM,QAAQ,MAAM;CAEzC,CAAC;CAED,OAAO;AACT;AAEA,SAAS,kBAAkB,EACzB,aACA,SAIC;CACD,gBAAgB;EACd,MAAM,WAAW,UAAiB;GAChC,MAAM,SAAU,MAA+C;GAE/D,IAAI,CAAC,QAAQ,QAAQ,OAAO,SAAS,aACnC,MAAM;EAEV;EAEA,OAAO,iBAAiB,cAAc,WAAW,OAAO;EAExD,aAAa,OAAO,oBAAoB,cAAc,WAAW,OAAO;CAC1E,GAAG,CAAC,aAAa,KAAK,CAAC;CAEvB,OAAO;AACT;AAEA,SAAS,SAAS,EAChB,QACA,UACA,cACA,OACA,0BACA,aACA,gBASC;CACD,MAAM,EAAE,OAAO,eAAe,iBAAiB,gBAAgB,QAAQ,cAAc,KAAK;CAE1F,OACE,oBAAC,iBAAD;EAAiB,OAAO,EAAE,aAAa;YACrC,oBAAC,uBAAD;GAAuB,OAAO;aAC5B,qBAAC,OAAD;IAAK,WAAU;cAAf,CACG,UAEA,4BACC,oBAAC,OAAD;KAAK,WAAU;eACb,oBAAC,kBAAD;MAAkB,OAAO;MAA2B;KAAe,CAAA;IAChE,CAAA,CAEJ;;EACgB,CAAA;CACR,CAAA;AAErB;AAEA,IAAa,iBAA4C,EAAE,UAAU,WAAW;CAC9E,MAAM,QAAQ,KAAK;CACnB,MAAM,SAAS,MAAM,UAAU;CAC/B,MAAM,WAAW,MAAM;CACvB,MAAM,eAAe,MAAM,OAAO;CAClC,MAAM,SAAS,MAAM,UAAU;CAC/B,MAAM,eAAe,MAAM;CAC3B,MAAM,eAAe,MAAM,gBAAgB;CAC3C,MAAM,iBAAiB,MAAM,kBAAkB,CAAC;CAChD,MAAM,QAAQ,MAAM;CACpB,MAAM,EAAE,QAAQ,aAAa,QAAQ,gBAAgB,cAC7C,cAAc,KAAK,MAAM,GAC/B,CAAC,KAAK,MAAM,CACd;CACA,MAAM,gBAAgB,eAAe;EAAE,GAAG;EAAa,GAAG;CAAM,IAAI,CAAC,aAAa,KAAK,CAAC;CACxF,MAAM,2BAA2B,MAAM;CACvC,MAAM,cAAc,MAAM,eAAe;CACzC,MAAM,eAAe,MAAM;CAC3B,MAAM,oBAAoB,MAAM,qBAAqB,KAAA;CAErD,OACE,oBAAC,MAAD;EACU;EACR,0BAAwB,KAAK;EACnB;EACF;EACM;EACE;EAChB,mBAAmB,eAAe,oBAAoB,KAAA;EACtD,SAAS,YAAY,YAAY;EACjC,WAAU;aAER,EAAE,aAAa,QAAQ,YAAY,OAAO,eAC1C,qBAAC,cAAD;GACE,OAAO;IACL;IACA,cAAc,UAAU,YAAY,KAAK;IACzC,aAAa,KAAK;IAClB;IACQ;IACR;IACA;IACA;IACA,WAAW,UAAU,SAAS,KAAK;GACrC;aAXF;IAaE,oBAAC,mBAAD;KAAmB,aAAa,KAAK;KAAW;IAAQ,CAAA;IAEvD,MAAM,UACL,oBAAC,OAAD;KAAK,WAAU;eAAmD,MAAM;IAAY,CAAA;IAGtF,oBAAC,oBAAD;KAAoB,SAAS;eAC3B,oBAAC,UAAD;MACU;MACM;MACd,OAAO,KAAK;MACc;MACb;MACC;MAEb;KACO,CAAA;IACQ,CAAA;GACR;;CAEL,CAAA;AAEjB"}
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/events/event-names\";\nimport type { Node, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useEffect, useMemo } from \"react\";\nimport { FormSubmitButton } from \"./base/submit-button\";\nimport { FormProvider } from \"./context\";\nimport { walkFields } from \"./field-props\";\nimport { PrefillProvider } from \"./prefill-context\";\nimport { ResolvedNodesProvider } from \"./resolved-nodes\";\nimport { useFormResolver } from \"./use-form-resolver\";\nimport { FormValuesProvider } from \"./values\";\n\ntype CollectedFields = {\n labels: Record<string, string>;\n values: Record<string, unknown>;\n};\n\nfunction collectFields(nodes: Node[] | undefined): CollectedFields {\n const collected: CollectedFields = { labels: {}, values: {} };\n\n walkFields(nodes, (props) => {\n if (!props.name) {\n return;\n }\n if (props.label) {\n collected.labels[props.name] = props.label;\n }\n if (props.value !== undefined) {\n collected.values[props.name] = props.value;\n }\n });\n\n return collected;\n}\n\nfunction FormResetListener({\n componentId,\n reset,\n}: {\n componentId?: string;\n reset: (...fields: string[]) => void;\n}) {\n useEffect(() => {\n const handler = (event: 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 window.addEventListener(LATTICE_EVENT.resetForm, handler);\n\n return () => window.removeEventListener(LATTICE_EVENT.resetForm, handler);\n }, [componentId, reset]);\n\n return null;\n}\n\nfunction FormBody({\n action,\n children,\n componentRef,\n nodes,\n shouldRenderSubmitButton,\n submitLabel,\n summaryLabel,\n}: {\n action: string;\n children: React.ReactNode;\n componentRef: string;\n nodes: Node[] | undefined;\n shouldRenderSubmitButton: boolean;\n submitLabel: string;\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 justify-end rounded-lt border border-lt-border bg-lt-surface px-lt-gutter py-4 shadow-lt-sm\">\n <FormSubmitButton label={submitLabel} summaryLabel={summaryLabel} />\n </div>\n )}\n </div>\n </ResolvedNodesProvider>\n </PrefillProvider>\n );\n}\n\nexport const FormComponent: RendererComponent<\"form\"> = ({ children, node }) => {\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 submitLabel = props.submitLabel ?? \"Submit\";\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 submitLabel={submitLabel}\n summaryLabel={summaryLabel}\n >\n {children}\n </FormBody>\n </FormValuesProvider>\n </FormProvider>\n )}\n </InertiaForm>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAkBA,SAAS,cAAc,OAA4C;CACjE,MAAM,YAA6B;EAAE,QAAQ,CAAC;EAAG,QAAQ,CAAC;CAAE;CAE5D,WAAW,QAAQ,UAAU;EAC3B,IAAI,CAAC,MAAM,MACT;EAEF,IAAI,MAAM,OACR,UAAU,OAAO,MAAM,QAAQ,MAAM;EAEvC,IAAI,MAAM,UAAU,KAAA,GAClB,UAAU,OAAO,MAAM,QAAQ,MAAM;CAEzC,CAAC;CAED,OAAO;AACT;AAEA,SAAS,kBAAkB,EACzB,aACA,SAIC;CACD,gBAAgB;EACd,MAAM,WAAW,UAAiB;GAChC,MAAM,SAAU,MAA+C;GAE/D,IAAI,CAAC,QAAQ,QAAQ,OAAO,SAAS,aACnC,MAAM;EAEV;EAEA,OAAO,iBAAiB,cAAc,WAAW,OAAO;EAExD,aAAa,OAAO,oBAAoB,cAAc,WAAW,OAAO;CAC1E,GAAG,CAAC,aAAa,KAAK,CAAC;CAEvB,OAAO;AACT;AAEA,SAAS,SAAS,EAChB,QACA,UACA,cACA,OACA,0BACA,aACA,gBASC;CACD,MAAM,EAAE,OAAO,eAAe,iBAAiB,gBAAgB,QAAQ,cAAc,KAAK;CAE1F,OACE,oBAAC,iBAAD;EAAiB,OAAO,EAAE,aAAa;YACrC,oBAAC,uBAAD;GAAuB,OAAO;aAC5B,qBAAC,OAAD;IAAK,WAAU;cAAf,CACG,UAEA,4BACC,oBAAC,OAAD;KAAK,WAAU;eACb,oBAAC,kBAAD;MAAkB,OAAO;MAA2B;KAAe,CAAA;IAChE,CAAA,CAEJ;;EACgB,CAAA;CACR,CAAA;AAErB;AAEA,IAAa,iBAA4C,EAAE,UAAU,WAAW;CAC9E,MAAM,QAAQ,KAAK;CACnB,MAAM,SAAS,MAAM,UAAU;CAC/B,MAAM,WAAW,MAAM;CACvB,MAAM,eAAe,MAAM,OAAO;CAClC,MAAM,SAAS,MAAM,UAAU;CAC/B,MAAM,eAAe,MAAM;CAC3B,MAAM,eAAe,MAAM,gBAAgB;CAC3C,MAAM,iBAAiB,MAAM,kBAAkB,CAAC;CAChD,MAAM,QAAQ,MAAM;CACpB,MAAM,EAAE,QAAQ,aAAa,QAAQ,gBAAgB,cAC7C,cAAc,KAAK,MAAM,GAC/B,CAAC,KAAK,MAAM,CACd;CACA,MAAM,gBAAgB,eAAe;EAAE,GAAG;EAAa,GAAG;CAAM,IAAI,CAAC,aAAa,KAAK,CAAC;CACxF,MAAM,2BAA2B,MAAM;CACvC,MAAM,cAAc,MAAM,eAAe;CACzC,MAAM,eAAe,MAAM;CAC3B,MAAM,oBAAoB,MAAM,qBAAqB,KAAA;CAErD,OACE,oBAAC,MAAD;EACU;EACR,aAAU;EACV,0BAAwB,KAAK;EACnB;EACF;EACM;EACE;EAChB,mBAAmB,eAAe,oBAAoB,KAAA;EACtD,SAAS,YAAY,YAAY;EACjC,WAAU;aAER,EAAE,aAAa,QAAQ,YAAY,OAAO,eAC1C,qBAAC,cAAD;GACE,OAAO;IACL;IACA,cAAc,UAAU,YAAY,KAAK;IACzC,aAAa,KAAK;IAClB;IACQ;IACR;IACA;IACA;IACA,WAAW,UAAU,SAAS,KAAK;GACrC;aAXF;IAaE,oBAAC,mBAAD;KAAmB,aAAa,KAAK;KAAW;IAAQ,CAAA;IAEvD,MAAM,UACL,oBAAC,OAAD;KAAK,WAAU;eAAmD,MAAM;IAAY,CAAA;IAGtF,oBAAC,oBAAD;KAAoB,SAAS;eAC3B,oBAAC,UAAD;MACU;MACM;MACd,OAAO,KAAK;MACc;MACb;MACC;MAEb;KACO,CAAA;IACQ,CAAA;GACR;;CAEL,CAAA;AAEjB"}
package/dist/lattice.css CHANGED
@@ -61,15 +61,15 @@
61
61
  --lt-control-h-md: 2.25rem;
62
62
  --lt-control-h-lg: 2.5rem;
63
63
 
64
+ /* Table cell padding — table density lever */
65
+ --lt-table-cell-x: calc(var(--spacing) * 4); /* 1rem */
66
+ --lt-table-cell-y: calc(var(--spacing) * 4); /* 1rem */
67
+
64
68
  --lt-font-weight-normal: 400;
65
69
  --lt-font-weight-medium: 500;
66
70
  --lt-font-weight-semibold: 600;
67
71
  --lt-font-weight-bold: 700;
68
72
 
69
- /* Focus-ring size (colour: --lt-ring) */
70
- --lt-ring-width: 0.125rem;
71
- --lt-ring-offset: 0.125rem;
72
-
73
73
  /* Elevation */
74
74
  --lt-shadow-xs: 0 1px 1px 0 oklch(0 0 0 / 0.04);
75
75
  --lt-shadow-sm: 0 1px 2px 0 oklch(0 0 0 / 0.05);
@@ -89,14 +89,15 @@
89
89
  /* Motion */
90
90
  --lt-duration-fast: 120ms;
91
91
  --lt-duration-base: 160ms;
92
- --lt-duration-slow: 240ms;
93
- --lt-ease: cubic-bezier(0.2, 0, 0, 1);
94
92
 
95
93
  /* Layout dimensions */
96
94
  --lt-sidebar-w: 16rem;
97
95
  --lt-sidebar-w-collapsed: 4rem;
98
96
  --lt-container-max: 80rem;
99
97
 
98
+ /* Card / section content inset — the gutter apps can break out of */
99
+ --lt-gutter: calc(var(--spacing) * 6); /* 1.5rem */
100
+
100
101
  color-scheme: light;
101
102
  }
102
103
 
@@ -201,6 +202,13 @@
201
202
  --spacing-lt-control-sm: var(--lt-control-h-sm);
202
203
  --spacing-lt-control-md: var(--lt-control-h-md);
203
204
  --spacing-lt-control-lg: var(--lt-control-h-lg);
205
+ --spacing-lt-gutter: var(--lt-gutter);
206
+ --spacing-lt-cell-x: var(--lt-table-cell-x);
207
+ --spacing-lt-cell-y: var(--lt-table-cell-y);
208
+ --font-weight-lt-normal: var(--lt-font-weight-normal);
209
+ --font-weight-lt-medium: var(--lt-font-weight-medium);
210
+ --font-weight-lt-semibold: var(--lt-font-weight-semibold);
211
+ --font-weight-lt-bold: var(--lt-font-weight-bold);
204
212
  --animate-lt-toast-in: lt-toast-in var(--lt-duration-base) ease-out;
205
213
  --animate-lt-toast-out: lt-toast-out var(--lt-duration-fast) ease-in;
206
214
  }
@@ -238,6 +246,30 @@
238
246
  --text-7xl--line-height: 1;
239
247
  }
240
248
 
249
+ /*
250
+ * Layering utilities backed by the --lt-z-* scale. Tailwind v4 does not expose
251
+ * z-index as a themeable namespace, so these are defined as named utilities
252
+ * (the scale itself stays the single source of truth in the :root block above).
253
+ */
254
+ @utility z-lt-dropdown {
255
+ z-index: var(--lt-z-dropdown);
256
+ }
257
+ @utility z-lt-sticky {
258
+ z-index: var(--lt-z-sticky);
259
+ }
260
+ @utility z-lt-overlay {
261
+ z-index: var(--lt-z-overlay);
262
+ }
263
+ @utility z-lt-modal {
264
+ z-index: var(--lt-z-modal);
265
+ }
266
+ @utility z-lt-popover {
267
+ z-index: var(--lt-z-popover);
268
+ }
269
+ @utility z-lt-toast {
270
+ z-index: var(--lt-z-toast);
271
+ }
272
+
241
273
  @keyframes lt-toast-in {
242
274
  from {
243
275
  opacity: 0;
@@ -346,44 +378,44 @@
346
378
  * `:where()` keeps specificity low so consumers can override freely.
347
379
  */
348
380
  .lattice-prose :where(h1) {
349
- font-size: 1.5rem;
381
+ font-size: var(--text-4xl);
350
382
  line-height: 2rem;
351
- font-weight: 700;
352
- margin: 1rem 0 0.5rem;
383
+ font-weight: var(--lt-font-weight-bold);
384
+ margin: calc(var(--spacing) * 4) 0 calc(var(--spacing) * 2);
353
385
  }
354
386
 
355
387
  .lattice-prose :where(h2) {
356
- font-size: 1.25rem;
388
+ font-size: var(--text-3xl);
357
389
  line-height: 1.75rem;
358
- font-weight: 700;
359
- margin: 1rem 0 0.5rem;
390
+ font-weight: var(--lt-font-weight-bold);
391
+ margin: calc(var(--spacing) * 4) 0 calc(var(--spacing) * 2);
360
392
  }
361
393
 
362
394
  .lattice-prose :where(h3) {
363
- font-size: 1.125rem;
395
+ font-size: var(--text-2xl);
364
396
  line-height: 1.5rem;
365
- font-weight: 600;
366
- margin: 0.75rem 0 0.5rem;
397
+ font-weight: var(--lt-font-weight-semibold);
398
+ margin: calc(var(--spacing) * 3) 0 calc(var(--spacing) * 2);
367
399
  }
368
400
 
369
401
  .lattice-prose :where(p) {
370
- margin: 0.5rem 0;
402
+ margin: calc(var(--spacing) * 2) 0;
371
403
  }
372
404
 
373
405
  .lattice-prose :where(ul) {
374
406
  list-style: disc;
375
- padding-left: 1.5rem;
376
- margin: 0.5rem 0;
407
+ padding-left: calc(var(--spacing) * 6);
408
+ margin: calc(var(--spacing) * 2) 0;
377
409
  }
378
410
 
379
411
  .lattice-prose :where(ol) {
380
412
  list-style: decimal;
381
- padding-left: 1.5rem;
382
- margin: 0.5rem 0;
413
+ padding-left: calc(var(--spacing) * 6);
414
+ margin: calc(var(--spacing) * 2) 0;
383
415
  }
384
416
 
385
417
  .lattice-prose :where(li) {
386
- margin: 0.25rem 0;
418
+ margin: var(--spacing) 0;
387
419
  }
388
420
 
389
421
  .lattice-prose :where(li p) {
@@ -392,14 +424,14 @@
392
424
 
393
425
  .lattice-prose :where(blockquote) {
394
426
  border-left: 3px solid var(--lt-border);
395
- padding-left: 1rem;
396
- margin: 0.75rem 0;
427
+ padding-left: calc(var(--spacing) * 4);
428
+ margin: calc(var(--spacing) * 3) 0;
397
429
  color: var(--lt-muted-fg);
398
430
  font-style: italic;
399
431
  }
400
432
 
401
433
  .lattice-prose :where(strong) {
402
- font-weight: 700;
434
+ font-weight: var(--lt-font-weight-bold);
403
435
  }
404
436
 
405
437
  .lattice-prose :where(em) {
@@ -416,7 +448,7 @@
416
448
  }
417
449
 
418
450
  .lattice-prose :where(mark) {
419
- background: var(--lt-warning, #fef08a);
451
+ background: var(--lt-warning);
420
452
  color: inherit;
421
453
  border-radius: var(--lt-radius-sm);
422
454
  padding: 0.05em 0.15em;
@@ -431,7 +463,7 @@
431
463
  .lattice-prose :where(code) {
432
464
  background: var(--lt-muted);
433
465
  border-radius: var(--lt-radius-sm);
434
- padding: 0.125rem 0.25rem;
466
+ padding: calc(var(--spacing) * 0.5) var(--spacing);
435
467
  font-family: ui-monospace, "SFMono-Regular", "Menlo", monospace;
436
468
  font-size: 0.875em;
437
469
  }
@@ -439,11 +471,11 @@
439
471
  .lattice-prose :where(pre) {
440
472
  background: var(--lt-muted);
441
473
  border-radius: var(--lt-radius-sm);
442
- padding: 0.75rem 1rem;
443
- margin: 0.75rem 0;
474
+ padding: calc(var(--spacing) * 3) calc(var(--spacing) * 4);
475
+ margin: calc(var(--spacing) * 3) 0;
444
476
  overflow-x: auto;
445
477
  font-family: ui-monospace, "SFMono-Regular", "Menlo", monospace;
446
- font-size: 0.875rem;
478
+ font-size: var(--text-lg);
447
479
  }
448
480
 
449
481
  .lattice-prose :where(pre code) {
@@ -455,27 +487,27 @@
455
487
  .lattice-prose :where(hr) {
456
488
  border: none;
457
489
  border-top: 1px solid var(--lt-border);
458
- margin: 1rem 0;
490
+ margin: calc(var(--spacing) * 4) 0;
459
491
  }
460
492
 
461
493
  .lattice-prose :where(table) {
462
494
  border-collapse: collapse;
463
495
  width: 100%;
464
- margin: 0.75rem 0;
496
+ margin: calc(var(--spacing) * 3) 0;
465
497
  table-layout: fixed;
466
498
  overflow: hidden;
467
499
  }
468
500
 
469
501
  .lattice-prose :where(th, td) {
470
502
  border: 1px solid var(--lt-border);
471
- padding: 0.375rem 0.5rem;
503
+ padding: calc(var(--spacing) * 1.5) calc(var(--spacing) * 2);
472
504
  text-align: left;
473
505
  vertical-align: top;
474
506
  }
475
507
 
476
508
  .lattice-prose :where(th) {
477
509
  background: var(--lt-muted);
478
- font-weight: 600;
510
+ font-weight: var(--lt-font-weight-semibold);
479
511
  }
480
512
 
481
513
  .lattice-prose :where(.selectedCell) {
@@ -485,13 +517,13 @@
485
517
  .lattice-prose :where(details) {
486
518
  border: 1px solid var(--lt-border);
487
519
  border-radius: var(--lt-radius-sm);
488
- padding: 0.5rem 0.75rem;
489
- margin: 0.75rem 0;
520
+ padding: calc(var(--spacing) * 2) calc(var(--spacing) * 3);
521
+ margin: calc(var(--spacing) * 3) 0;
490
522
  }
491
523
 
492
524
  .lattice-prose :where(summary) {
493
525
  cursor: pointer;
494
- font-weight: 600;
526
+ font-weight: var(--lt-font-weight-semibold);
495
527
  }
496
528
 
497
529
  .lattice-prose :where(:first-child) {
@@ -40,7 +40,7 @@ var MenuItemComponent = ({ children, node }) => {
40
40
  }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
41
41
  prefix ? /* @__PURE__ */ jsx(MenuAffix, { affix: prefix }) : null,
42
42
  collapsed ? /* @__PURE__ */ jsx("span", {
43
- className: "pointer-events-none absolute top-1/2 left-full z-50 ml-2 hidden -translate-y-1/2 rounded-lt-sm border border-lt-border bg-lt-popover px-2 py-1 text-sm whitespace-nowrap text-lt-popover-fg shadow-lt-md group-hover:block",
43
+ className: "pointer-events-none absolute top-1/2 left-full z-lt-popover ml-2 hidden -translate-y-1/2 rounded-lt-sm border border-lt-border bg-lt-popover px-2 py-1 text-sm whitespace-nowrap text-lt-popover-fg shadow-lt-md group-hover:block",
44
44
  role: "tooltip",
45
45
  children: label
46
46
  }) : /* @__PURE__ */ jsx("span", { children: label }),
@@ -1 +1 @@
1
- {"version":3,"file":"menu-item.js","names":[],"sources":["../../resources/js/layout/menu-item.tsx"],"sourcesContent":["import { Link, usePage } from \"@inertiajs/react\";\nimport { useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { useAction } from \"@lattice-php/lattice/action/use-action\";\nimport { prefixedNodeTestId } from \"@lattice-php/lattice/core/test-id\";\nimport type { Node, RendererComponent, Schema } from \"@lattice-php/lattice/core/types\";\nimport { Icon, IconRenderer } from \"@lattice-php/lattice/icons\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport type { Affix } from \"@lattice-php/lattice/types/generated\";\nimport { useSidebarCollapsed } from \"./context\";\nimport { Popover } from \"./popover\";\n\nconst rowClass =\n \"flex items-center gap-2 rounded-lt-sm px-3 py-2 text-base font-medium text-lt-fg transition-colors hover:bg-lt-muted\";\n\nfunction MenuAffix({ affix, className }: { affix: Affix; className?: string }) {\n if (affix.icon) {\n return <IconRenderer className={cn(\"size-lt-icon-md shrink-0\", className)} icon={affix.icon} />;\n }\n\n return <span className={cn(\"shrink-0 text-sm text-lt-muted-fg\", className)}>{affix.text}</span>;\n}\n\nfunction schemaContainsPath(schema: Schema | undefined, path: string): boolean {\n return (schema ?? []).some(\n (child) => child.props?.href === path || schemaContainsPath(child.schema, path),\n );\n}\n\nconst MenuItemComponent: RendererComponent<\"menu-item\"> = ({ children, node }) => {\n const collapsed = useSidebarCollapsed();\n const icon = node.props.icon;\n const label = node.props.label;\n const prefix = node.props.prefix;\n const suffix = node.props.suffix;\n const iconOnly = Boolean(icon);\n const flyoutIcon = icon ?? prefix?.icon ?? null;\n const href = node.props.href ?? \"\";\n const currentPath = usePage().url.split(\"?\")[0];\n const testId = prefixedNodeTestId(\"menu\", node);\n\n const content = icon ? (\n <IconRenderer className=\"size-lt-icon-md shrink-0\" icon={icon} />\n ) : (\n <>\n {prefix ? <MenuAffix affix={prefix} /> : null}\n {collapsed ? (\n <span\n className=\"pointer-events-none absolute top-1/2 left-full z-50 ml-2 hidden -translate-y-1/2 rounded-lt-sm border border-lt-border bg-lt-popover px-2 py-1 text-sm whitespace-nowrap text-lt-popover-fg shadow-lt-md group-hover:block\"\n role=\"tooltip\"\n >\n {label}\n </span>\n ) : (\n <span>{label}</span>\n )}\n {suffix ? <MenuAffix affix={suffix} className=\"ml-auto\" /> : null}\n </>\n );\n\n const action = node.props.action;\n\n if (action && href === \"\" && !children) {\n return (\n <ActionMenuItem\n action={action as Node<\"action\">}\n className={cn(\n rowClass,\n \"w-full\",\n collapsed && \"group relative justify-center\",\n iconOnly && \"justify-center\",\n )}\n label={collapsed || iconOnly ? label : undefined}\n testId={testId}\n >\n {content}\n </ActionMenuItem>\n );\n }\n\n if (href === \"\") {\n if (!children) {\n return collapsed ? null : (\n <li>\n <span className=\"flex items-center gap-2 px-3 py-2 text-xs font-semibold tracking-wide text-lt-muted-fg uppercase\">\n {content}\n </span>\n </li>\n );\n }\n\n if (collapsed) {\n return (\n <FlyoutGroup icon={flyoutIcon} label={label} testId={testId}>\n {children}\n </FlyoutGroup>\n );\n }\n\n return (\n <CollapsibleItem\n content={content}\n defaultOpen={schemaContainsPath(node.schema, currentPath)}\n testId={testId}\n >\n {children}\n </CollapsibleItem>\n );\n }\n\n const active = currentPath === href;\n const method = node.props.method ?? \"get\";\n\n return (\n <li>\n <Link\n aria-current={active ? \"page\" : undefined}\n aria-label={collapsed || iconOnly ? label : undefined}\n as={method === \"get\" ? undefined : \"button\"}\n className={cn(\n rowClass,\n \"w-full\",\n collapsed && \"group relative justify-center\",\n iconOnly && \"justify-center\",\n active && \"bg-lt-muted font-medium\",\n )}\n data-test={testId}\n href={href}\n method={method}\n >\n {content}\n </Link>\n </li>\n );\n};\n\nfunction CollapsibleItem({\n children,\n content,\n defaultOpen,\n testId,\n}: {\n children: ReactNode;\n content: ReactNode;\n defaultOpen: boolean;\n testId?: string;\n}) {\n const [open, setOpen] = useState(defaultOpen);\n\n return (\n <li>\n <button\n aria-expanded={open}\n className={cn(rowClass, \"w-full\")}\n data-test={testId}\n onClick={() => setOpen((value) => !value)}\n type=\"button\"\n >\n {content}\n <Icon\n name=\"chevron-right\"\n className={cn(\n \"ml-auto size-lt-icon-md shrink-0 transition-transform\",\n open && \"rotate-90\",\n )}\n />\n </button>\n {open ? <ul className=\"mt-1 flex flex-col gap-1 pl-3\">{children}</ul> : null}\n </li>\n );\n}\n\nfunction FlyoutGroup({\n children,\n icon,\n label,\n testId,\n}: {\n children: ReactNode;\n icon?: string | null;\n label: string;\n testId?: string;\n}) {\n return (\n <li>\n <Popover\n className=\"min-w-48\"\n placement=\"right\"\n testId={testId}\n trigger={\n icon ? (\n <IconRenderer className=\"size-lt-icon-md shrink-0\" icon={icon} />\n ) : (\n <span>{label}</span>\n )\n }\n triggerClassName={cn(rowClass, \"justify-center\")}\n triggerLabel={label}\n >\n <ul className=\"flex flex-col gap-1\">\n <li className=\"px-3 py-1.5 text-xs font-semibold tracking-wide text-lt-muted-fg uppercase\">\n {label}\n </li>\n {children}\n </ul>\n </Popover>\n </li>\n );\n}\n\nfunction ActionMenuItem({\n action,\n children,\n className,\n label,\n testId,\n}: {\n action: Node<\"action\">;\n children: ReactNode;\n className: string;\n label?: string;\n testId?: string;\n}) {\n const { processing, requestSubmit, overlays } = useAction(action);\n\n return (\n <li>\n <button\n aria-label={label}\n className={className}\n data-test={testId}\n disabled={processing}\n onClick={requestSubmit}\n type=\"button\"\n >\n {children}\n </button>\n {overlays}\n </li>\n );\n}\n\nexport default MenuItemComponent;\n"],"mappings":";;;;;;;;;;;AAYA,IAAM,WACJ;AAEF,SAAS,UAAU,EAAE,OAAO,aAAmD;CAC7E,IAAI,MAAM,MACR,OAAO,oBAAC,cAAD;EAAc,WAAW,GAAG,4BAA4B,SAAS;EAAG,MAAM,MAAM;CAAO,CAAA;CAGhG,OAAO,oBAAC,QAAD;EAAM,WAAW,GAAG,qCAAqC,SAAS;YAAI,MAAM;CAAW,CAAA;AAChG;AAEA,SAAS,mBAAmB,QAA4B,MAAuB;CAC7E,QAAQ,UAAU,CAAC,GAAG,MACnB,UAAU,MAAM,OAAO,SAAS,QAAQ,mBAAmB,MAAM,QAAQ,IAAI,CAChF;AACF;AAEA,IAAM,qBAAqD,EAAE,UAAU,WAAW;CAChF,MAAM,YAAY,aAAoB;CACtC,MAAM,OAAO,KAAK,MAAM;CACxB,MAAM,QAAQ,KAAK,MAAM;CACzB,MAAM,SAAS,KAAK,MAAM;CAC1B,MAAM,SAAS,KAAK,MAAM;CAC1B,MAAM,WAAW,QAAQ,IAAI;CAC7B,MAAM,aAAa,QAAQ,QAAQ,QAAQ;CAC3C,MAAM,OAAO,KAAK,MAAM,QAAQ;CAChC,MAAM,cAAc,QAAQ,EAAE,IAAI,MAAM,GAAG,EAAE;CAC7C,MAAM,SAAS,mBAAmB,QAAQ,IAAI;CAE9C,MAAM,UAAU,OACd,oBAAC,cAAD;EAAc,WAAU;EAAiC;CAAO,CAAA,IAEhE,qBAAA,YAAA,EAAA,UAAA;EACG,SAAS,oBAAC,WAAD,EAAW,OAAO,OAAS,CAAA,IAAI;EACxC,YACC,oBAAC,QAAD;GACE,WAAU;GACV,MAAK;aAEJ;EACG,CAAA,IAEN,oBAAC,QAAD,EAAA,UAAO,MAAY,CAAA;EAEpB,SAAS,oBAAC,WAAD;GAAW,OAAO;GAAQ,WAAU;EAAW,CAAA,IAAI;CAC7D,EAAA,CAAA;CAGJ,MAAM,SAAS,KAAK,MAAM;CAE1B,IAAI,UAAU,SAAS,MAAM,CAAC,UAC5B,OACE,oBAAC,gBAAD;EACU;EACR,WAAW,GACT,UACA,UACA,aAAa,iCACb,YAAY,gBACd;EACA,OAAO,aAAa,WAAW,QAAQ,KAAA;EAC/B;YAEP;CACa,CAAA;CAIpB,IAAI,SAAS,IAAI;EACf,IAAI,CAAC,UACH,OAAO,YAAY,OACjB,oBAAC,MAAD,EAAA,UACE,oBAAC,QAAD;GAAM,WAAU;aACb;EACG,CAAA,EACJ,CAAA;EAIR,IAAI,WACF,OACE,oBAAC,aAAD;GAAa,MAAM;GAAmB;GAAe;GAClD;EACU,CAAA;EAIjB,OACE,oBAAC,iBAAD;GACW;GACT,aAAa,mBAAmB,KAAK,QAAQ,WAAW;GAChD;GAEP;EACc,CAAA;CAErB;CAEA,MAAM,SAAS,gBAAgB;CAC/B,MAAM,SAAS,KAAK,MAAM,UAAU;CAEpC,OACE,oBAAC,MAAD,EAAA,UACE,oBAAC,MAAD;EACE,gBAAc,SAAS,SAAS,KAAA;EAChC,cAAY,aAAa,WAAW,QAAQ,KAAA;EAC5C,IAAI,WAAW,QAAQ,KAAA,IAAY;EACnC,WAAW,GACT,UACA,UACA,aAAa,iCACb,YAAY,kBACZ,UAAU,yBACZ;EACA,aAAW;EACL;EACE;YAEP;CACG,CAAA,EACJ,CAAA;AAER;AAEA,SAAS,gBAAgB,EACvB,UACA,SACA,aACA,UAMC;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,WAAW;CAE5C,OACE,qBAAC,MAAD,EAAA,UAAA,CACE,qBAAC,UAAD;EACE,iBAAe;EACf,WAAW,GAAG,UAAU,QAAQ;EAChC,aAAW;EACX,eAAe,SAAS,UAAU,CAAC,KAAK;EACxC,MAAK;YALP,CAOG,SACD,oBAAC,MAAD;GACE,MAAK;GACL,WAAW,GACT,yDACA,QAAQ,WACV;EACD,CAAA,CACK;KACP,OAAO,oBAAC,MAAD;EAAI,WAAU;EAAiC;CAAa,CAAA,IAAI,IACtE,EAAA,CAAA;AAER;AAEA,SAAS,YAAY,EACnB,UACA,MACA,OACA,UAMC;CACD,OACE,oBAAC,MAAD,EAAA,UACE,oBAAC,SAAD;EACE,WAAU;EACV,WAAU;EACF;EACR,SACE,OACE,oBAAC,cAAD;GAAc,WAAU;GAAiC;EAAO,CAAA,IAEhE,oBAAC,QAAD,EAAA,UAAO,MAAY,CAAA;EAGvB,kBAAkB,GAAG,UAAU,gBAAgB;EAC/C,cAAc;YAEd,qBAAC,MAAD;GAAI,WAAU;aAAd,CACE,oBAAC,MAAD;IAAI,WAAU;cACX;GACC,CAAA,GACH,QACC;;CACG,CAAA,EACP,CAAA;AAER;AAEA,SAAS,eAAe,EACtB,QACA,UACA,WACA,OACA,UAOC;CACD,MAAM,EAAE,YAAY,eAAe,aAAa,UAAU,MAAM;CAEhE,OACE,qBAAC,MAAD,EAAA,UAAA,CACE,oBAAC,UAAD;EACE,cAAY;EACD;EACX,aAAW;EACX,UAAU;EACV,SAAS;EACT,MAAK;EAEJ;CACK,CAAA,GACP,QACC,EAAA,CAAA;AAER"}
1
+ {"version":3,"file":"menu-item.js","names":[],"sources":["../../resources/js/layout/menu-item.tsx"],"sourcesContent":["import { Link, usePage } from \"@inertiajs/react\";\nimport { useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { useAction } from \"@lattice-php/lattice/action/use-action\";\nimport { prefixedNodeTestId } from \"@lattice-php/lattice/core/test-id\";\nimport type { Node, RendererComponent, Schema } from \"@lattice-php/lattice/core/types\";\nimport { Icon, IconRenderer } from \"@lattice-php/lattice/icons\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport type { Affix } from \"@lattice-php/lattice/types/generated\";\nimport { useSidebarCollapsed } from \"./context\";\nimport { Popover } from \"./popover\";\n\nconst rowClass =\n \"flex items-center gap-2 rounded-lt-sm px-3 py-2 text-base font-medium text-lt-fg transition-colors hover:bg-lt-muted\";\n\nfunction MenuAffix({ affix, className }: { affix: Affix; className?: string }) {\n if (affix.icon) {\n return <IconRenderer className={cn(\"size-lt-icon-md shrink-0\", className)} icon={affix.icon} />;\n }\n\n return <span className={cn(\"shrink-0 text-sm text-lt-muted-fg\", className)}>{affix.text}</span>;\n}\n\nfunction schemaContainsPath(schema: Schema | undefined, path: string): boolean {\n return (schema ?? []).some(\n (child) => child.props?.href === path || schemaContainsPath(child.schema, path),\n );\n}\n\nconst MenuItemComponent: RendererComponent<\"menu-item\"> = ({ children, node }) => {\n const collapsed = useSidebarCollapsed();\n const icon = node.props.icon;\n const label = node.props.label;\n const prefix = node.props.prefix;\n const suffix = node.props.suffix;\n const iconOnly = Boolean(icon);\n const flyoutIcon = icon ?? prefix?.icon ?? null;\n const href = node.props.href ?? \"\";\n const currentPath = usePage().url.split(\"?\")[0];\n const testId = prefixedNodeTestId(\"menu\", node);\n\n const content = icon ? (\n <IconRenderer className=\"size-lt-icon-md shrink-0\" icon={icon} />\n ) : (\n <>\n {prefix ? <MenuAffix affix={prefix} /> : null}\n {collapsed ? (\n <span\n className=\"pointer-events-none absolute top-1/2 left-full z-lt-popover ml-2 hidden -translate-y-1/2 rounded-lt-sm border border-lt-border bg-lt-popover px-2 py-1 text-sm whitespace-nowrap text-lt-popover-fg shadow-lt-md group-hover:block\"\n role=\"tooltip\"\n >\n {label}\n </span>\n ) : (\n <span>{label}</span>\n )}\n {suffix ? <MenuAffix affix={suffix} className=\"ml-auto\" /> : null}\n </>\n );\n\n const action = node.props.action;\n\n if (action && href === \"\" && !children) {\n return (\n <ActionMenuItem\n action={action as Node<\"action\">}\n className={cn(\n rowClass,\n \"w-full\",\n collapsed && \"group relative justify-center\",\n iconOnly && \"justify-center\",\n )}\n label={collapsed || iconOnly ? label : undefined}\n testId={testId}\n >\n {content}\n </ActionMenuItem>\n );\n }\n\n if (href === \"\") {\n if (!children) {\n return collapsed ? null : (\n <li>\n <span className=\"flex items-center gap-2 px-3 py-2 text-xs font-semibold tracking-wide text-lt-muted-fg uppercase\">\n {content}\n </span>\n </li>\n );\n }\n\n if (collapsed) {\n return (\n <FlyoutGroup icon={flyoutIcon} label={label} testId={testId}>\n {children}\n </FlyoutGroup>\n );\n }\n\n return (\n <CollapsibleItem\n content={content}\n defaultOpen={schemaContainsPath(node.schema, currentPath)}\n testId={testId}\n >\n {children}\n </CollapsibleItem>\n );\n }\n\n const active = currentPath === href;\n const method = node.props.method ?? \"get\";\n\n return (\n <li>\n <Link\n aria-current={active ? \"page\" : undefined}\n aria-label={collapsed || iconOnly ? label : undefined}\n as={method === \"get\" ? undefined : \"button\"}\n className={cn(\n rowClass,\n \"w-full\",\n collapsed && \"group relative justify-center\",\n iconOnly && \"justify-center\",\n active && \"bg-lt-muted font-medium\",\n )}\n data-test={testId}\n href={href}\n method={method}\n >\n {content}\n </Link>\n </li>\n );\n};\n\nfunction CollapsibleItem({\n children,\n content,\n defaultOpen,\n testId,\n}: {\n children: ReactNode;\n content: ReactNode;\n defaultOpen: boolean;\n testId?: string;\n}) {\n const [open, setOpen] = useState(defaultOpen);\n\n return (\n <li>\n <button\n aria-expanded={open}\n className={cn(rowClass, \"w-full\")}\n data-test={testId}\n onClick={() => setOpen((value) => !value)}\n type=\"button\"\n >\n {content}\n <Icon\n name=\"chevron-right\"\n className={cn(\n \"ml-auto size-lt-icon-md shrink-0 transition-transform\",\n open && \"rotate-90\",\n )}\n />\n </button>\n {open ? <ul className=\"mt-1 flex flex-col gap-1 pl-3\">{children}</ul> : null}\n </li>\n );\n}\n\nfunction FlyoutGroup({\n children,\n icon,\n label,\n testId,\n}: {\n children: ReactNode;\n icon?: string | null;\n label: string;\n testId?: string;\n}) {\n return (\n <li>\n <Popover\n className=\"min-w-48\"\n placement=\"right\"\n testId={testId}\n trigger={\n icon ? (\n <IconRenderer className=\"size-lt-icon-md shrink-0\" icon={icon} />\n ) : (\n <span>{label}</span>\n )\n }\n triggerClassName={cn(rowClass, \"justify-center\")}\n triggerLabel={label}\n >\n <ul className=\"flex flex-col gap-1\">\n <li className=\"px-3 py-1.5 text-xs font-semibold tracking-wide text-lt-muted-fg uppercase\">\n {label}\n </li>\n {children}\n </ul>\n </Popover>\n </li>\n );\n}\n\nfunction ActionMenuItem({\n action,\n children,\n className,\n label,\n testId,\n}: {\n action: Node<\"action\">;\n children: ReactNode;\n className: string;\n label?: string;\n testId?: string;\n}) {\n const { processing, requestSubmit, overlays } = useAction(action);\n\n return (\n <li>\n <button\n aria-label={label}\n className={className}\n data-test={testId}\n disabled={processing}\n onClick={requestSubmit}\n type=\"button\"\n >\n {children}\n </button>\n {overlays}\n </li>\n );\n}\n\nexport default MenuItemComponent;\n"],"mappings":"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"}
@@ -70,11 +70,11 @@ var SidebarComponent = ({ children, node }) => {
70
70
  value: isCollapsed,
71
71
  children: [mobileOpen ? /* @__PURE__ */ jsx("div", {
72
72
  "aria-hidden": "true",
73
- className: "fixed inset-0 z-30 bg-black/50 md:hidden",
73
+ className: "fixed inset-0 z-lt-overlay bg-lt-overlay md:hidden",
74
74
  "data-test": "sidebar-backdrop",
75
75
  onClick: () => setMobileOpen(false)
76
76
  }) : null, /* @__PURE__ */ jsx("aside", {
77
- className: cn("fixed inset-y-0 left-0 z-40 flex h-svh w-72 max-w-[80vw] shrink-0 flex-col gap-4 border-r border-lt-border bg-lt-bg p-4 transition-transform", "md:sticky md:top-0 md:z-auto md:max-w-none md:translate-x-0 md:transition-[width]", mobileOpen ? "translate-x-0" : "-translate-x-full", isCollapsed ? "md:w-16 md:overflow-visible" : "md:w-64 md:overflow-x-hidden md:overflow-y-auto"),
77
+ className: cn("fixed inset-y-0 left-0 z-lt-modal flex h-svh w-72 max-w-[80vw] shrink-0 flex-col gap-4 border-r border-lt-border bg-lt-bg p-4 transition-transform", "md:sticky md:top-0 md:z-auto md:max-w-none md:translate-x-0 md:transition-[width]", mobileOpen ? "translate-x-0" : "-translate-x-full", isCollapsed ? "md:w-16 md:overflow-visible" : "md:w-64 md:overflow-x-hidden md:overflow-y-auto"),
78
78
  "data-collapsed": isCollapsed ? "true" : "false",
79
79
  "data-lattice-component": identity,
80
80
  "data-test": "sidebar",
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar.js","names":[],"sources":["../../resources/js/layout/sidebar.tsx"],"sourcesContent":["import { router } from \"@inertiajs/react\";\nimport { useEffect, useState } from \"react\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { CollapsedContext } from \"../core/collapsed-context\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/events/event-names\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nconst DESKTOP_QUERY = \"(min-width: 768px)\";\n\nfunction readStored(key: string, remember: boolean): boolean {\n if (!remember || typeof window === \"undefined\") {\n return false;\n }\n\n return window.localStorage.getItem(key) === \"true\";\n}\n\nfunction matchesTarget(event: Event, identity: string | undefined): boolean {\n const target = (event as CustomEvent<{ target?: string }>).detail?.target;\n\n return target == null || target === identity;\n}\n\nfunction useIsDesktop(): boolean {\n const supported = () => typeof window !== \"undefined\" && typeof window.matchMedia === \"function\";\n const [isDesktop, setIsDesktop] = useState(() =>\n supported() ? window.matchMedia(DESKTOP_QUERY).matches : true,\n );\n\n useEffect(() => {\n if (!supported()) {\n return;\n }\n\n const query = window.matchMedia(DESKTOP_QUERY);\n const update = (): void => setIsDesktop(query.matches);\n\n update();\n query.addEventListener(\"change\", update);\n\n return () => query.removeEventListener(\"change\", update);\n }, []);\n\n return isDesktop;\n}\n\nconst SidebarComponent: RendererComponent<\"sidebar\"> = ({ children, node }) => {\n const collapsible = node.props.collapsible;\n const rememberState = node.props.rememberState;\n const identity = nodeIdentity(node);\n const storageKey = `lattice:sidebar:${identity ?? \"default\"}`;\n const isDesktop = useIsDesktop();\n\n const [collapsed, setCollapsed] = useState(() =>\n readStored(storageKey, collapsible && rememberState),\n );\n const [mobileOpen, setMobileOpen] = useState(false);\n\n useEffect(() => {\n function toggle(event: Event): void {\n if (!matchesTarget(event, identity)) {\n return;\n }\n\n if (window.matchMedia?.(DESKTOP_QUERY).matches ?? true) {\n if (!collapsible) {\n return;\n }\n\n setCollapsed((value) => {\n const next = !value;\n\n if (rememberState && typeof window !== \"undefined\") {\n window.localStorage.setItem(storageKey, String(next));\n }\n\n return next;\n });\n } else {\n setMobileOpen((open) => !open);\n }\n }\n\n window.addEventListener(LATTICE_EVENT.toggleSidebar, toggle);\n\n return () => window.removeEventListener(LATTICE_EVENT.toggleSidebar, toggle);\n }, [identity, collapsible, rememberState, storageKey]);\n\n useEffect(() => router.on(\"navigate\", () => setMobileOpen(false)), []);\n\n useEffect(() => {\n if (!mobileOpen) {\n return;\n }\n\n function close(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n setMobileOpen(false);\n }\n }\n\n window.addEventListener(\"keydown\", close);\n\n return () => window.removeEventListener(\"keydown\", close);\n }, [mobileOpen]);\n\n const isCollapsed = collapsible && collapsed && isDesktop;\n\n return (\n <CollapsedContext.Provider value={isCollapsed}>\n {mobileOpen ? (\n <div\n aria-hidden=\"true\"\n className=\"fixed inset-0 z-30 bg-black/50 md:hidden\"\n data-test=\"sidebar-backdrop\"\n onClick={() => setMobileOpen(false)}\n />\n ) : null}\n <aside\n className={cn(\n \"fixed inset-y-0 left-0 z-40 flex h-svh w-72 max-w-[80vw] shrink-0 flex-col gap-4 border-r border-lt-border bg-lt-bg p-4 transition-transform\",\n \"md:sticky md:top-0 md:z-auto md:max-w-none md:translate-x-0 md:transition-[width]\",\n mobileOpen ? \"translate-x-0\" : \"-translate-x-full\",\n isCollapsed\n ? \"md:w-16 md:overflow-visible\"\n : \"md:w-64 md:overflow-x-hidden md:overflow-y-auto\",\n )}\n data-collapsed={isCollapsed ? \"true\" : \"false\"}\n data-lattice-component={identity}\n data-test=\"sidebar\"\n >\n {children}\n </aside>\n </CollapsedContext.Provider>\n );\n};\n\nexport default SidebarComponent;\n"],"mappings":";;;;;;;;AAQA,IAAM,gBAAgB;AAEtB,SAAS,WAAW,KAAa,UAA4B;CAC3D,IAAI,CAAC,YAAY,OAAO,WAAW,aACjC,OAAO;CAGT,OAAO,OAAO,aAAa,QAAQ,GAAG,MAAM;AAC9C;AAEA,SAAS,cAAc,OAAc,UAAuC;CAC1E,MAAM,SAAU,MAA2C,QAAQ;CAEnE,OAAO,UAAU,QAAQ,WAAW;AACtC;AAEA,SAAS,eAAwB;CAC/B,MAAM,kBAAkB,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe;CACtF,MAAM,CAAC,WAAW,gBAAgB,eAChC,UAAU,IAAI,OAAO,WAAW,aAAa,EAAE,UAAU,IAC3D;CAEA,gBAAgB;EACd,IAAI,CAAC,UAAU,GACb;EAGF,MAAM,QAAQ,OAAO,WAAW,aAAa;EAC7C,MAAM,eAAqB,aAAa,MAAM,OAAO;EAErD,OAAO;EACP,MAAM,iBAAiB,UAAU,MAAM;EAEvC,aAAa,MAAM,oBAAoB,UAAU,MAAM;CACzD,GAAG,CAAC,CAAC;CAEL,OAAO;AACT;AAEA,IAAM,oBAAkD,EAAE,UAAU,WAAW;CAC7E,MAAM,cAAc,KAAK,MAAM;CAC/B,MAAM,gBAAgB,KAAK,MAAM;CACjC,MAAM,WAAW,aAAa,IAAI;CAClC,MAAM,aAAa,mBAAmB,YAAY;CAClD,MAAM,YAAY,aAAa;CAE/B,MAAM,CAAC,WAAW,gBAAgB,eAChC,WAAW,YAAY,eAAe,aAAa,CACrD;CACA,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAElD,gBAAgB;EACd,SAAS,OAAO,OAAoB;GAClC,IAAI,CAAC,cAAc,OAAO,QAAQ,GAChC;GAGF,IAAI,OAAO,aAAa,aAAa,EAAE,WAAW,MAAM;IACtD,IAAI,CAAC,aACH;IAGF,cAAc,UAAU;KACtB,MAAM,OAAO,CAAC;KAEd,IAAI,iBAAiB,OAAO,WAAW,aACrC,OAAO,aAAa,QAAQ,YAAY,OAAO,IAAI,CAAC;KAGtD,OAAO;IACT,CAAC;GACH,OACE,eAAe,SAAS,CAAC,IAAI;EAEjC;EAEA,OAAO,iBAAiB,cAAc,eAAe,MAAM;EAE3D,aAAa,OAAO,oBAAoB,cAAc,eAAe,MAAM;CAC7E,GAAG;EAAC;EAAU;EAAa;EAAe;CAAU,CAAC;CAErD,gBAAgB,OAAO,GAAG,kBAAkB,cAAc,KAAK,CAAC,GAAG,CAAC,CAAC;CAErE,gBAAgB;EACd,IAAI,CAAC,YACH;EAGF,SAAS,MAAM,OAA4B;GACzC,IAAI,MAAM,QAAQ,UAChB,cAAc,KAAK;EAEvB;EAEA,OAAO,iBAAiB,WAAW,KAAK;EAExC,aAAa,OAAO,oBAAoB,WAAW,KAAK;CAC1D,GAAG,CAAC,UAAU,CAAC;CAEf,MAAM,cAAc,eAAe,aAAa;CAEhD,OACE,qBAAC,iBAAiB,UAAlB;EAA2B,OAAO;YAAlC,CACG,aACC,oBAAC,OAAD;GACE,eAAY;GACZ,WAAU;GACV,aAAU;GACV,eAAe,cAAc,KAAK;EACnC,CAAA,IACC,MACJ,oBAAC,SAAD;GACE,WAAW,GACT,gJACA,qFACA,aAAa,kBAAkB,qBAC/B,cACI,gCACA,iDACN;GACA,kBAAgB,cAAc,SAAS;GACvC,0BAAwB;GACxB,aAAU;GAET;EACI,CAAA,CACkB;;AAE/B"}
1
+ {"version":3,"file":"sidebar.js","names":[],"sources":["../../resources/js/layout/sidebar.tsx"],"sourcesContent":["import { router } from \"@inertiajs/react\";\nimport { useEffect, useState } from \"react\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { CollapsedContext } from \"../core/collapsed-context\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/events/event-names\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nconst DESKTOP_QUERY = \"(min-width: 768px)\";\n\nfunction readStored(key: string, remember: boolean): boolean {\n if (!remember || typeof window === \"undefined\") {\n return false;\n }\n\n return window.localStorage.getItem(key) === \"true\";\n}\n\nfunction matchesTarget(event: Event, identity: string | undefined): boolean {\n const target = (event as CustomEvent<{ target?: string }>).detail?.target;\n\n return target == null || target === identity;\n}\n\nfunction useIsDesktop(): boolean {\n const supported = () => typeof window !== \"undefined\" && typeof window.matchMedia === \"function\";\n const [isDesktop, setIsDesktop] = useState(() =>\n supported() ? window.matchMedia(DESKTOP_QUERY).matches : true,\n );\n\n useEffect(() => {\n if (!supported()) {\n return;\n }\n\n const query = window.matchMedia(DESKTOP_QUERY);\n const update = (): void => setIsDesktop(query.matches);\n\n update();\n query.addEventListener(\"change\", update);\n\n return () => query.removeEventListener(\"change\", update);\n }, []);\n\n return isDesktop;\n}\n\nconst SidebarComponent: RendererComponent<\"sidebar\"> = ({ children, node }) => {\n const collapsible = node.props.collapsible;\n const rememberState = node.props.rememberState;\n const identity = nodeIdentity(node);\n const storageKey = `lattice:sidebar:${identity ?? \"default\"}`;\n const isDesktop = useIsDesktop();\n\n const [collapsed, setCollapsed] = useState(() =>\n readStored(storageKey, collapsible && rememberState),\n );\n const [mobileOpen, setMobileOpen] = useState(false);\n\n useEffect(() => {\n function toggle(event: Event): void {\n if (!matchesTarget(event, identity)) {\n return;\n }\n\n if (window.matchMedia?.(DESKTOP_QUERY).matches ?? true) {\n if (!collapsible) {\n return;\n }\n\n setCollapsed((value) => {\n const next = !value;\n\n if (rememberState && typeof window !== \"undefined\") {\n window.localStorage.setItem(storageKey, String(next));\n }\n\n return next;\n });\n } else {\n setMobileOpen((open) => !open);\n }\n }\n\n window.addEventListener(LATTICE_EVENT.toggleSidebar, toggle);\n\n return () => window.removeEventListener(LATTICE_EVENT.toggleSidebar, toggle);\n }, [identity, collapsible, rememberState, storageKey]);\n\n useEffect(() => router.on(\"navigate\", () => setMobileOpen(false)), []);\n\n useEffect(() => {\n if (!mobileOpen) {\n return;\n }\n\n function close(event: KeyboardEvent): void {\n if (event.key === \"Escape\") {\n setMobileOpen(false);\n }\n }\n\n window.addEventListener(\"keydown\", close);\n\n return () => window.removeEventListener(\"keydown\", close);\n }, [mobileOpen]);\n\n const isCollapsed = collapsible && collapsed && isDesktop;\n\n return (\n <CollapsedContext.Provider value={isCollapsed}>\n {mobileOpen ? (\n <div\n aria-hidden=\"true\"\n className=\"fixed inset-0 z-lt-overlay bg-lt-overlay md:hidden\"\n data-test=\"sidebar-backdrop\"\n onClick={() => setMobileOpen(false)}\n />\n ) : null}\n <aside\n className={cn(\n \"fixed inset-y-0 left-0 z-lt-modal flex h-svh w-72 max-w-[80vw] shrink-0 flex-col gap-4 border-r border-lt-border bg-lt-bg p-4 transition-transform\",\n \"md:sticky md:top-0 md:z-auto md:max-w-none md:translate-x-0 md:transition-[width]\",\n mobileOpen ? \"translate-x-0\" : \"-translate-x-full\",\n isCollapsed\n ? \"md:w-16 md:overflow-visible\"\n : \"md:w-64 md:overflow-x-hidden md:overflow-y-auto\",\n )}\n data-collapsed={isCollapsed ? \"true\" : \"false\"}\n data-lattice-component={identity}\n data-test=\"sidebar\"\n >\n {children}\n </aside>\n </CollapsedContext.Provider>\n );\n};\n\nexport default SidebarComponent;\n"],"mappings":";;;;;;;;AAQA,IAAM,gBAAgB;AAEtB,SAAS,WAAW,KAAa,UAA4B;CAC3D,IAAI,CAAC,YAAY,OAAO,WAAW,aACjC,OAAO;CAGT,OAAO,OAAO,aAAa,QAAQ,GAAG,MAAM;AAC9C;AAEA,SAAS,cAAc,OAAc,UAAuC;CAC1E,MAAM,SAAU,MAA2C,QAAQ;CAEnE,OAAO,UAAU,QAAQ,WAAW;AACtC;AAEA,SAAS,eAAwB;CAC/B,MAAM,kBAAkB,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe;CACtF,MAAM,CAAC,WAAW,gBAAgB,eAChC,UAAU,IAAI,OAAO,WAAW,aAAa,EAAE,UAAU,IAC3D;CAEA,gBAAgB;EACd,IAAI,CAAC,UAAU,GACb;EAGF,MAAM,QAAQ,OAAO,WAAW,aAAa;EAC7C,MAAM,eAAqB,aAAa,MAAM,OAAO;EAErD,OAAO;EACP,MAAM,iBAAiB,UAAU,MAAM;EAEvC,aAAa,MAAM,oBAAoB,UAAU,MAAM;CACzD,GAAG,CAAC,CAAC;CAEL,OAAO;AACT;AAEA,IAAM,oBAAkD,EAAE,UAAU,WAAW;CAC7E,MAAM,cAAc,KAAK,MAAM;CAC/B,MAAM,gBAAgB,KAAK,MAAM;CACjC,MAAM,WAAW,aAAa,IAAI;CAClC,MAAM,aAAa,mBAAmB,YAAY;CAClD,MAAM,YAAY,aAAa;CAE/B,MAAM,CAAC,WAAW,gBAAgB,eAChC,WAAW,YAAY,eAAe,aAAa,CACrD;CACA,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAElD,gBAAgB;EACd,SAAS,OAAO,OAAoB;GAClC,IAAI,CAAC,cAAc,OAAO,QAAQ,GAChC;GAGF,IAAI,OAAO,aAAa,aAAa,EAAE,WAAW,MAAM;IACtD,IAAI,CAAC,aACH;IAGF,cAAc,UAAU;KACtB,MAAM,OAAO,CAAC;KAEd,IAAI,iBAAiB,OAAO,WAAW,aACrC,OAAO,aAAa,QAAQ,YAAY,OAAO,IAAI,CAAC;KAGtD,OAAO;IACT,CAAC;GACH,OACE,eAAe,SAAS,CAAC,IAAI;EAEjC;EAEA,OAAO,iBAAiB,cAAc,eAAe,MAAM;EAE3D,aAAa,OAAO,oBAAoB,cAAc,eAAe,MAAM;CAC7E,GAAG;EAAC;EAAU;EAAa;EAAe;CAAU,CAAC;CAErD,gBAAgB,OAAO,GAAG,kBAAkB,cAAc,KAAK,CAAC,GAAG,CAAC,CAAC;CAErE,gBAAgB;EACd,IAAI,CAAC,YACH;EAGF,SAAS,MAAM,OAA4B;GACzC,IAAI,MAAM,QAAQ,UAChB,cAAc,KAAK;EAEvB;EAEA,OAAO,iBAAiB,WAAW,KAAK;EAExC,aAAa,OAAO,oBAAoB,WAAW,KAAK;CAC1D,GAAG,CAAC,UAAU,CAAC;CAEf,MAAM,cAAc,eAAe,aAAa;CAEhD,OACE,qBAAC,iBAAiB,UAAlB;EAA2B,OAAO;YAAlC,CACG,aACC,oBAAC,OAAD;GACE,eAAY;GACZ,WAAU;GACV,aAAU;GACV,eAAe,cAAc,KAAK;EACnC,CAAA,IACC,MACJ,oBAAC,SAAD;GACE,WAAW,GACT,sJACA,qFACA,aAAa,kBAAkB,qBAC/B,cACI,gCACA,iDACN;GACA,kBAAgB,cAAc,SAAS;GACvC,0BAAwB;GACxB,aAAU;GAET;EACI,CAAA,CACkB;;AAE/B"}
@@ -6,7 +6,7 @@ var TopbarComponent = ({ children, node }) => {
6
6
  const sticky = node.props.sticky;
7
7
  return /* @__PURE__ */ jsx("header", {
8
8
  "data-lattice-component": nodeIdentity(node),
9
- className: cn("flex h-14 w-full items-center gap-2 border-b border-lt-border bg-lt-bg px-4 text-lt-fg", sticky && "sticky top-0 z-30"),
9
+ className: cn("flex h-14 w-full items-center gap-2 border-b border-lt-border bg-lt-bg px-4 text-lt-fg", sticky && "sticky top-0 z-lt-sticky"),
10
10
  children
11
11
  });
12
12
  };
@@ -1 +1 @@
1
- {"version":3,"file":"topbar.js","names":[],"sources":["../../resources/js/layout/topbar.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nconst TopbarComponent: RendererComponent<\"topbar\"> = ({ children, node }) => {\n const sticky = node.props.sticky;\n\n return (\n <header\n data-lattice-component={nodeIdentity(node)}\n className={cn(\n \"flex h-14 w-full items-center gap-2 border-b border-lt-border bg-lt-bg px-4 text-lt-fg\",\n sticky && \"sticky top-0 z-30\",\n )}\n >\n {children}\n </header>\n );\n};\n\nexport default TopbarComponent;\n"],"mappings":";;;;AAIA,IAAM,mBAAgD,EAAE,UAAU,WAAW;CAC3E,MAAM,SAAS,KAAK,MAAM;CAE1B,OACE,oBAAC,UAAD;EACE,0BAAwB,aAAa,IAAI;EACzC,WAAW,GACT,0FACA,UAAU,mBACZ;EAEC;CACK,CAAA;AAEZ"}
1
+ {"version":3,"file":"topbar.js","names":[],"sources":["../../resources/js/layout/topbar.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nconst TopbarComponent: RendererComponent<\"topbar\"> = ({ children, node }) => {\n const sticky = node.props.sticky;\n\n return (\n <header\n data-lattice-component={nodeIdentity(node)}\n className={cn(\n \"flex h-14 w-full items-center gap-2 border-b border-lt-border bg-lt-bg px-4 text-lt-fg\",\n sticky && \"sticky top-0 z-lt-sticky\",\n )}\n >\n {children}\n </header>\n );\n};\n\nexport default TopbarComponent;\n"],"mappings":";;;;AAIA,IAAM,mBAAgD,EAAE,UAAU,WAAW;CAC3E,MAAM,SAAS,KAAK,MAAM;CAE1B,OACE,oBAAC,UAAD;EACE,0BAAwB,aAAa,IAAI;EACzC,WAAW,GACT,0FACA,UAAU,0BACZ;EAEC;CACK,CAAA;AAEZ"}
@@ -59,7 +59,7 @@ function ColumnFilterControl({ column, clauses, processing, onAdd, onUpdate, onR
59
59
  type: "button",
60
60
  "aria-label": t("table.filter.columnFilters", "{{label}} filters", { label: column.label }),
61
61
  "data-test": `filter-${column.key}`,
62
- className: "relative -ml-px inline-flex size-9 shrink-0 items-center justify-center rounded-r-lt-sm border border-lt-input disabled:opacity-50 data-[state=open]:z-10 data-[state=open]:border-lt-primary",
62
+ className: "relative -ml-px inline-flex size-lt-control-md shrink-0 items-center justify-center rounded-r-lt-sm border border-lt-input disabled:opacity-50 data-[state=open]:z-10 data-[state=open]:border-lt-primary",
63
63
  disabled: processing,
64
64
  children: [/* @__PURE__ */ jsx(Icon, {
65
65
  name: "filter",
@@ -252,7 +252,7 @@ function FilterClauseRow({ column, type, operators, clause, processing, onOperat
252
252
  type: "button",
253
253
  "aria-label": t("table.filter.remove", "Remove {{label}} filter", { label: column.label }),
254
254
  "data-test": `filter-${column.key}-remove`,
255
- className: "inline-flex size-9 items-center justify-center rounded-lt-sm border border-lt-border hover:bg-lt-muted disabled:opacity-50",
255
+ className: "inline-flex size-lt-control-md items-center justify-center rounded-lt-sm border border-lt-border hover:bg-lt-muted disabled:opacity-50",
256
256
  disabled: processing,
257
257
  onClick: onRemove,
258
258
  children: /* @__PURE__ */ jsx(Icon, {