@lattice-php/lattice 0.33.0 → 0.35.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 (78) hide show
  1. package/dist/appearance/index.js +2 -6
  2. package/dist/appearance/index.js.map +1 -1
  3. package/dist/chat/lib/transport.d.ts +2 -2
  4. package/dist/chat/lib/transport.js +22 -23
  5. package/dist/chat/lib/transport.js.map +1 -1
  6. package/dist/core/api.d.ts +0 -1
  7. package/dist/core/api.js +2 -2
  8. package/dist/core/api.js.map +1 -1
  9. package/dist/core/hooks/column-sizing.d.ts +1 -1
  10. package/dist/core/hooks/column-sizing.js +7 -14
  11. package/dist/core/hooks/column-sizing.js.map +1 -1
  12. package/dist/core/hooks/use-column-resizing.js +22 -54
  13. package/dist/core/hooks/use-column-resizing.js.map +1 -1
  14. package/dist/core/index.d.ts +1 -1
  15. package/dist/core/index.js +2 -2
  16. package/dist/core/registry.d.ts +1 -5
  17. package/dist/core/registry.js +1 -2
  18. package/dist/core/registry.js.map +1 -1
  19. package/dist/core/renderer.js +4 -10
  20. package/dist/core/renderer.js.map +1 -1
  21. package/dist/effects/registry.js +1 -4
  22. package/dist/effects/registry.js.map +1 -1
  23. package/dist/event-bridge.d.ts +1 -4
  24. package/dist/event-bridge.js +1 -11
  25. package/dist/event-bridge.js.map +1 -1
  26. package/dist/form/components/fields/choice.js +1 -1
  27. package/dist/form/components/fields/choice.js.map +1 -1
  28. package/dist/form/types.d.ts +1 -4
  29. package/dist/i18n/config.d.ts +1 -1
  30. package/dist/i18n/config.js +5 -21
  31. package/dist/i18n/config.js.map +1 -1
  32. package/dist/i18n/index.d.ts +2 -2
  33. package/dist/i18n/index.js +2 -2
  34. package/dist/i18n/locale-switcher.d.ts +0 -5
  35. package/dist/i18n/locale-switcher.js +1 -5
  36. package/dist/i18n/locale-switcher.js.map +1 -1
  37. package/dist/i18n/locale.js +2 -10
  38. package/dist/i18n/locale.js.map +1 -1
  39. package/dist/i18n/timezone.js +2 -10
  40. package/dist/i18n/timezone.js.map +1 -1
  41. package/dist/icons/icon-renderer.d.ts +1 -2
  42. package/dist/icons/icon-renderer.js +2 -6
  43. package/dist/icons/icon-renderer.js.map +1 -1
  44. package/dist/lattice.css +89 -0
  45. package/dist/lib/listeners.d.ts +5 -0
  46. package/dist/lib/listeners.js +19 -0
  47. package/dist/lib/listeners.js.map +1 -0
  48. package/dist/table/hooks/use-column-visibility.js +4 -12
  49. package/dist/table/hooks/use-column-visibility.js.map +1 -1
  50. package/dist/toast/callout.js +8 -16
  51. package/dist/toast/callout.js.map +1 -1
  52. package/dist/toast/toast.d.ts +2 -0
  53. package/dist/toast/toast.js +16 -10
  54. package/dist/toast/toast.js.map +1 -1
  55. package/dist/types/generated.d.ts +3 -1
  56. package/dist/ui/grid.js +17 -5
  57. package/dist/ui/grid.js.map +1 -1
  58. package/dist/ui/segmented-pills.d.ts +1 -1
  59. package/dist/ui/segmented-pills.js +1 -1
  60. package/dist/ui/segmented-pills.js.map +1 -1
  61. package/dist-standalone/chunks/{chart-view-WqyMTZiX.js → chart-view-CR1X2aGE.js} +1 -1
  62. package/dist-standalone/chunks/{date-picker-field-CCnkf4SC.js → date-picker-field-B4Xzow-A.js} +1 -1
  63. package/dist-standalone/chunks/{dist-CK9gk4iB.js → dist-ci5ng714.js} +1 -1
  64. package/dist-standalone/chunks/{icon-button-D4DKcnhp.js → icon-button-D3AltHNz.js} +1 -1
  65. package/dist-standalone/chunks/{instance-BQeVkUpw.js → instance-C4O1XWa6.js} +1 -1
  66. package/dist-standalone/chunks/locale-GyqtaX1O.js +1 -0
  67. package/dist-standalone/chunks/{page-props-BA5zqTIT.js → page-props-BHNNVkgJ.js} +1 -1
  68. package/dist-standalone/chunks/{rich-editor-field-BeeSr2Zx.js → rich-editor-field-JM3jBEV1.js} +1 -1
  69. package/dist-standalone/chunks/{subscriptions-Cwd1jFs5.js → subscriptions-BV4g0s0U.js} +1 -1
  70. package/dist-standalone/chunks/{time-picker-DSs9fDWe.js → time-picker-kbhOHEPd.js} +1 -1
  71. package/dist-standalone/chunks/timezone-CyoBch3a.js +1 -0
  72. package/dist-standalone/chunks/{use-effect-dispatcher-CiWYRvsF.js → use-effect-dispatcher-CJXFkAv1.js} +2 -2
  73. package/dist-standalone/lattice.css +1 -1
  74. package/dist-standalone/lattice.js +4 -4
  75. package/dist-standalone/manifest.json +1 -27
  76. package/package.json +2 -2
  77. package/dist-standalone/chunks/locale-CgtcxthU.js +0 -1
  78. package/dist-standalone/chunks/timezone-BORzyZp2.js +0 -1
@@ -64,16 +64,10 @@ var NodeRenderer = memo(function NodeRenderer({ node }) {
64
64
  node,
65
65
  children
66
66
  });
67
- if (registration.mode === "lazy") {
68
- const FallbackComponent = registration.fallback;
69
- return /* @__PURE__ */ jsx(Suspense, {
70
- fallback: FallbackComponent ? /* @__PURE__ */ jsx(FallbackComponent, {
71
- node,
72
- children: null
73
- }) : null,
74
- children: renderedComponent
75
- });
76
- }
67
+ if (registration.mode === "lazy") return /* @__PURE__ */ jsx(Suspense, {
68
+ fallback: null,
69
+ children: renderedComponent
70
+ });
77
71
  return renderedComponent;
78
72
  });
79
73
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.js","names":[],"sources":["../../resources/js/core/renderer.tsx"],"sourcesContent":["import { memo, Suspense } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { Node } from \"./types\";\nimport { nodeKey } from \"./nodes\";\nimport { useCollapsed } from \"./collapsed-context\";\nimport { useComponentRegistry } from \"./registry-context\";\n\nconst warnedMissingTypes = new Set<string>();\n\nfunction warnMissingComponent(type: string): void {\n if (!import.meta.env.DEV || warnedMissingTypes.has(type)) {\n return;\n }\n\n warnedMissingTypes.add(type);\n console.warn(\n `[lattice] No component registered for node type \"${type}\" — Lattice rendered a fallback ` +\n \"placeholder. Likely causes: your app registry was not passed to \" +\n \"createLatticeApp({ registry }), or the registry key does not match the PHP \" +\n \"#[AsComponent]/AsField type.\",\n );\n}\n\nfunction MissingComponentIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n className=\"size-lt-icon-md shrink-0\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <rect height=\"18\" rx=\"2\" strokeDasharray=\"4 3\" width=\"18\" x=\"3\" y=\"3\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n </svg>\n );\n}\n\n/**\n * Fallback for a node whose type has no registered renderer. Always renders a\n * visible, muted marker — icon-only survives tight spots like table cells — so\n * the gap is never invisible. Shows the type inline in development; keeps it\n * screen-reader-only (plus a hover tooltip) in production.\n */\nfunction MissingComponent({ node }: { node: Node }) {\n warnMissingComponent(node.type);\n\n const label = `Missing component: ${node.type}`;\n\n return (\n <span\n className=\"inline-flex items-center gap-1.5 align-middle text-lt-muted-fg\"\n data-lattice-missing-component={node.type}\n title={label}\n >\n <MissingComponentIcon />\n <span className={import.meta.env.DEV ? \"text-sm\" : \"sr-only\"}>{label}</span>\n </span>\n );\n}\n\nexport function Renderer({ nodes }: { nodes: Node[] }): ReactNode {\n return nodes.map((node, index) => <NodeRenderer key={nodeKey(node, index)} node={node} />);\n}\n\nexport function RenderNode({ node }: { node: Node }): ReactNode {\n return <NodeRenderer node={node} />;\n}\n\nconst NodeRenderer = memo(function NodeRenderer({ node }: { node: Node }) {\n const collapsed = useCollapsed();\n const registry = useComponentRegistry();\n const registration = registry[node.type];\n\n if (collapsed && node.props?.hideWhenCollapsed === true) {\n return null;\n }\n\n if (!registration) {\n return <MissingComponent node={node} />;\n }\n\n const Component = registration.component;\n const children = node.schema?.length ? <Renderer nodes={node.schema} /> : null;\n const renderedComponent = <Component node={node}>{children}</Component>;\n\n if (registration.mode === \"lazy\") {\n const FallbackComponent = registration.fallback;\n const fallback = FallbackComponent ? (\n <FallbackComponent node={node}>{null}</FallbackComponent>\n ) : null;\n\n return <Suspense fallback={fallback}>{renderedComponent}</Suspense>;\n }\n\n return renderedComponent;\n});\n"],"mappings":";;;;;;AAuBA,SAAS,uBAAuB;CAC9B,OACE,qBAAC,OAAD;EACE,eAAY;EACZ,WAAU;EACV,MAAK;EACL,QAAO;EACP,eAAc;EACd,gBAAe;EACf,aAAY;EACZ,SAAQ;EARV,UAAA;GAUE,oBAAC,QAAD;IAAM,QAAO;IAAK,IAAG;IAAI,iBAAgB;IAAM,OAAM;IAAK,GAAE;IAAI,GAAE;GAAK,CAAA;GACvE,oBAAC,QAAD,EAAM,GAAE,UAAW,CAAA;GACnB,oBAAC,QAAD,EAAM,GAAE,aAAc,CAAA;EACnB;;AAET;;;;;;;AAQA,SAAS,iBAAiB,EAAE,QAAwB;CAClD,KAA0B;CAE1B,MAAM,QAAQ,sBAAsB,KAAK;CAEzC,OACE,qBAAC,QAAD;EACE,WAAU;EACV,kCAAgC,KAAK;EACrC,OAAO;EAHT,UAAA,CAKE,oBAAC,sBAAD,CAAuB,CAAA,GACvB,oBAAC,QAAD;GAAM,WAA6C;GAAY,UAAA;EAAY,CAAA,CACvE;;AAEV;AAEA,SAAgB,SAAS,EAAE,SAAuC;CAChE,OAAO,MAAM,KAAK,MAAM,UAAU,oBAAC,cAAD,EAA+C,KAAO,GAAnC,QAAQ,MAAM,KAAK,CAAgB,CAAC;AAC3F;AAEA,SAAgB,WAAW,EAAE,QAAmC;CAC9D,OAAO,oBAAC,cAAD,EAAoB,KAAO,CAAA;AACpC;AAEA,IAAM,eAAe,KAAK,SAAS,aAAa,EAAE,QAAwB;CACxE,MAAM,YAAY,aAAa;CAE/B,MAAM,eADW,qBACI,CAAA,CAAS,KAAK;CAEnC,IAAI,aAAa,KAAK,OAAO,sBAAsB,MACjD,OAAO;CAGT,IAAI,CAAC,cACH,OAAO,oBAAC,kBAAD,EAAwB,KAAO,CAAA;CAGxC,MAAM,YAAY,aAAa;CAC/B,MAAM,WAAW,KAAK,QAAQ,SAAS,oBAAC,UAAD,EAAU,OAAO,KAAK,OAAS,CAAA,IAAI;CAC1E,MAAM,oBAAoB,oBAAC,WAAD;EAAiB;EAAO;CAAoB,CAAA;CAEtE,IAAI,aAAa,SAAS,QAAQ;EAChC,MAAM,oBAAoB,aAAa;EAKvC,OAAO,oBAAC,UAAD;GAAoB,UAJV,oBACf,oBAAC,mBAAD;IAAyB;IAAO,UAAA;GAAwB,CAAA,IACtD;GAEkC,UAAA;EAA4B,CAAA;CACpE;CAEA,OAAO;AACT,CAAC"}
1
+ {"version":3,"file":"renderer.js","names":[],"sources":["../../resources/js/core/renderer.tsx"],"sourcesContent":["import { memo, Suspense } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { Node } from \"./types\";\nimport { nodeKey } from \"./nodes\";\nimport { useCollapsed } from \"./collapsed-context\";\nimport { useComponentRegistry } from \"./registry-context\";\n\nconst warnedMissingTypes = new Set<string>();\n\nfunction warnMissingComponent(type: string): void {\n if (!import.meta.env.DEV || warnedMissingTypes.has(type)) {\n return;\n }\n\n warnedMissingTypes.add(type);\n console.warn(\n `[lattice] No component registered for node type \"${type}\" — Lattice rendered a fallback ` +\n \"placeholder. Likely causes: your app registry was not passed to \" +\n \"createLatticeApp({ registry }), or the registry key does not match the PHP \" +\n \"#[AsComponent]/AsField type.\",\n );\n}\n\nfunction MissingComponentIcon() {\n return (\n <svg\n aria-hidden=\"true\"\n className=\"size-lt-icon-md shrink-0\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <rect height=\"18\" rx=\"2\" strokeDasharray=\"4 3\" width=\"18\" x=\"3\" y=\"3\" />\n <path d=\"M12 8v4\" />\n <path d=\"M12 16h.01\" />\n </svg>\n );\n}\n\n/**\n * Fallback for a node whose type has no registered renderer. Always renders a\n * visible, muted marker — icon-only survives tight spots like table cells — so\n * the gap is never invisible. Shows the type inline in development; keeps it\n * screen-reader-only (plus a hover tooltip) in production.\n */\nfunction MissingComponent({ node }: { node: Node }) {\n warnMissingComponent(node.type);\n\n const label = `Missing component: ${node.type}`;\n\n return (\n <span\n className=\"inline-flex items-center gap-1.5 align-middle text-lt-muted-fg\"\n data-lattice-missing-component={node.type}\n title={label}\n >\n <MissingComponentIcon />\n <span className={import.meta.env.DEV ? \"text-sm\" : \"sr-only\"}>{label}</span>\n </span>\n );\n}\n\nexport function Renderer({ nodes }: { nodes: Node[] }): ReactNode {\n return nodes.map((node, index) => <NodeRenderer key={nodeKey(node, index)} node={node} />);\n}\n\nexport function RenderNode({ node }: { node: Node }): ReactNode {\n return <NodeRenderer node={node} />;\n}\n\nconst NodeRenderer = memo(function NodeRenderer({ node }: { node: Node }) {\n const collapsed = useCollapsed();\n const registry = useComponentRegistry();\n const registration = registry[node.type];\n\n if (collapsed && node.props?.hideWhenCollapsed === true) {\n return null;\n }\n\n if (!registration) {\n return <MissingComponent node={node} />;\n }\n\n const Component = registration.component;\n const children = node.schema?.length ? <Renderer nodes={node.schema} /> : null;\n const renderedComponent = <Component node={node}>{children}</Component>;\n\n if (registration.mode === \"lazy\") {\n return <Suspense fallback={null}>{renderedComponent}</Suspense>;\n }\n\n return renderedComponent;\n});\n"],"mappings":";;;;;;AAuBA,SAAS,uBAAuB;CAC9B,OACE,qBAAC,OAAD;EACE,eAAY;EACZ,WAAU;EACV,MAAK;EACL,QAAO;EACP,eAAc;EACd,gBAAe;EACf,aAAY;EACZ,SAAQ;EARV,UAAA;GAUE,oBAAC,QAAD;IAAM,QAAO;IAAK,IAAG;IAAI,iBAAgB;IAAM,OAAM;IAAK,GAAE;IAAI,GAAE;GAAK,CAAA;GACvE,oBAAC,QAAD,EAAM,GAAE,UAAW,CAAA;GACnB,oBAAC,QAAD,EAAM,GAAE,aAAc,CAAA;EACnB;;AAET;;;;;;;AAQA,SAAS,iBAAiB,EAAE,QAAwB;CAClD,KAA0B;CAE1B,MAAM,QAAQ,sBAAsB,KAAK;CAEzC,OACE,qBAAC,QAAD;EACE,WAAU;EACV,kCAAgC,KAAK;EACrC,OAAO;EAHT,UAAA,CAKE,oBAAC,sBAAD,CAAuB,CAAA,GACvB,oBAAC,QAAD;GAAM,WAA6C;GAAY,UAAA;EAAY,CAAA,CACvE;;AAEV;AAEA,SAAgB,SAAS,EAAE,SAAuC;CAChE,OAAO,MAAM,KAAK,MAAM,UAAU,oBAAC,cAAD,EAA+C,KAAO,GAAnC,QAAQ,MAAM,KAAK,CAAgB,CAAC;AAC3F;AAEA,SAAgB,WAAW,EAAE,QAAmC;CAC9D,OAAO,oBAAC,cAAD,EAAoB,KAAO,CAAA;AACpC;AAEA,IAAM,eAAe,KAAK,SAAS,aAAa,EAAE,QAAwB;CACxE,MAAM,YAAY,aAAa;CAE/B,MAAM,eADW,qBACI,CAAA,CAAS,KAAK;CAEnC,IAAI,aAAa,KAAK,OAAO,sBAAsB,MACjD,OAAO;CAGT,IAAI,CAAC,cACH,OAAO,oBAAC,kBAAD,EAAwB,KAAO,CAAA;CAGxC,MAAM,YAAY,aAAa;CAC/B,MAAM,WAAW,KAAK,QAAQ,SAAS,oBAAC,UAAD,EAAU,OAAO,KAAK,OAAS,CAAA,IAAI;CAC1E,MAAM,oBAAoB,oBAAC,WAAD;EAAiB;EAAO;CAAoB,CAAA;CAEtE,IAAI,aAAa,SAAS,QACxB,OAAO,oBAAC,UAAD;EAAU,UAAU;EAAO,UAAA;CAA4B,CAAA;CAGhE,OAAO;AACT,CAAC"}
@@ -35,10 +35,7 @@ var builtinEffectHandlers = {
35
35
  "toggle-sidebar": bridge(LATTICE_EVENT.toggleSidebar)
36
36
  };
37
37
  function mergeEffectHandlers(...registries) {
38
- return registries.reduce((merged, registry) => ({
39
- ...merged,
40
- ...registry
41
- }), {});
38
+ return Object.assign({}, ...registries);
42
39
  }
43
40
  //#endregion
44
41
  export { builtinEffectHandlers, effectHandler, mergeEffectHandlers };
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","names":[],"sources":["../../resources/js/effects/registry.ts"],"sourcesContent":["import { router } from \"@inertiajs/react\";\nimport type {\n EffectOf,\n EffectProps,\n EffectPropsMap,\n EffectPropsOf,\n} from \"@lattice-php/lattice/types/generated\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\nimport { setLocale } from \"@lattice-php/lattice/i18n/locale\";\n\nexport type { EffectOf, EffectProps, EffectPropsOf };\n\nexport type EffectHandler<TType extends string = string> = (effect: EffectOf<TType>) => void;\n\nexport type EffectHandlerRegistry = Record<string, EffectHandler>;\n\nexport type EffectHandlerRegistryFor<TTypes extends keyof EffectPropsMap & string> = Record<\n TTypes,\n EffectHandler\n>;\n\n/**\n * Author a handler against `EffectHandler<\"my.type\">` for a typed payload, then\n * register it through this — it erases the type parameter for the loose registry.\n */\nexport function effectHandler<TType extends string>(\n _type: TType,\n fn: EffectHandler<TType>,\n): EffectHandler {\n return fn as unknown as EffectHandler;\n}\n\nfunction triggerDownload(url: string): void {\n const link = document.createElement(\"a\");\n link.href = url;\n link.rel = \"noopener\";\n document.body.appendChild(link);\n link.click();\n link.remove();\n}\n\nfunction bridge<TType extends keyof EffectPropsMap & string>(event: string): EffectHandler<TType> {\n return (effect) => window.dispatchEvent(new CustomEvent(event, { detail: effect.props }));\n}\n\n/**\n * Imperative effects act directly; the rest bridge to the `lattice:*` DOM events\n * that toast/callout/modal/fragment/form subscribe to. The export cast erases\n * the mapped type to the loose registry shape — the same variance erasure\n * effectHandler performs.\n */\nconst typedBuiltinHandlers: { [K in keyof EffectPropsMap]: EffectHandler<K> } = {\n \"reload-page\": (effect) => (effect.props.full ? window.location.reload() : router.reload()),\n redirect: (effect) => router.visit(effect.props.url),\n download: (effect) => triggerDownload(effect.props.url),\n \"locale-change\": (effect) => setLocale(effect.props.locale),\n toast: bridge<\"toast\">(LATTICE_EVENT.toast),\n callout: bridge<\"callout\">(LATTICE_EVENT.callout),\n \"retract-callout\": bridge<\"retract-callout\">(LATTICE_EVENT.retractCallout),\n \"reload-component\": bridge<\"reload-component\">(LATTICE_EVENT.reloadComponent),\n \"open-modal\": bridge<\"open-modal\">(LATTICE_EVENT.openModal),\n \"close-modal\": bridge<\"close-modal\">(LATTICE_EVENT.closeModal),\n \"reset-form\": bridge<\"reset-form\">(LATTICE_EVENT.resetForm),\n \"toggle-sidebar\": bridge<\"toggle-sidebar\">(LATTICE_EVENT.toggleSidebar),\n};\n\nexport const builtinEffectHandlers: EffectHandlerRegistryFor<keyof EffectPropsMap & string> =\n typedBuiltinHandlers as EffectHandlerRegistryFor<keyof EffectPropsMap & string>;\n\nexport function mergeEffectHandlers(\n ...registries: Array<EffectHandlerRegistry | undefined>\n): EffectHandlerRegistry {\n return registries.reduce<EffectHandlerRegistry>(\n (merged, registry) => ({ ...merged, ...registry }),\n {},\n );\n}\n"],"mappings":";;;;;;;;AAyBA,SAAgB,cACd,OACA,IACe;CACf,OAAO;AACT;AAEA,SAAS,gBAAgB,KAAmB;CAC1C,MAAM,OAAO,SAAS,cAAc,GAAG;CACvC,KAAK,OAAO;CACZ,KAAK,MAAM;CACX,SAAS,KAAK,YAAY,IAAI;CAC9B,KAAK,MAAM;CACX,KAAK,OAAO;AACd;AAEA,SAAS,OAAoD,OAAqC;CAChG,QAAQ,WAAW,OAAO,cAAc,IAAI,YAAY,OAAO,EAAE,QAAQ,OAAO,MAAM,CAAC,CAAC;AAC1F;AAuBA,IAAa,wBACX;CAfA,gBAAgB,WAAY,OAAO,MAAM,OAAO,OAAO,SAAS,OAAO,IAAI,OAAO,OAAO;CACzF,WAAW,WAAW,OAAO,MAAM,OAAO,MAAM,GAAG;CACnD,WAAW,WAAW,gBAAgB,OAAO,MAAM,GAAG;CACtD,kBAAkB,WAAW,UAAU,OAAO,MAAM,MAAM;CAC1D,OAAO,OAAgB,cAAc,KAAK;CAC1C,SAAS,OAAkB,cAAc,OAAO;CAChD,mBAAmB,OAA0B,cAAc,cAAc;CACzE,oBAAoB,OAA2B,cAAc,eAAe;CAC5E,cAAc,OAAqB,cAAc,SAAS;CAC1D,eAAe,OAAsB,cAAc,UAAU;CAC7D,cAAc,OAAqB,cAAc,SAAS;CAC1D,kBAAkB,OAAyB,cAAc,aAAa;AAItE;AAEF,SAAgB,oBACd,GAAG,YACoB;CACvB,OAAO,WAAW,QACf,QAAQ,cAAc;EAAE,GAAG;EAAQ,GAAG;CAAS,IAChD,CAAC,CACH;AACF"}
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../resources/js/effects/registry.ts"],"sourcesContent":["import { router } from \"@inertiajs/react\";\nimport type {\n EffectOf,\n EffectProps,\n EffectPropsMap,\n EffectPropsOf,\n} from \"@lattice-php/lattice/types/generated\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\nimport { setLocale } from \"@lattice-php/lattice/i18n/locale\";\n\nexport type { EffectOf, EffectProps, EffectPropsOf };\n\nexport type EffectHandler<TType extends string = string> = (effect: EffectOf<TType>) => void;\n\nexport type EffectHandlerRegistry = Record<string, EffectHandler>;\n\nexport type EffectHandlerRegistryFor<TTypes extends keyof EffectPropsMap & string> = Record<\n TTypes,\n EffectHandler\n>;\n\n/**\n * Author a handler against `EffectHandler<\"my.type\">` for a typed payload, then\n * register it through this — it erases the type parameter for the loose registry.\n */\nexport function effectHandler<TType extends string>(\n _type: TType,\n fn: EffectHandler<TType>,\n): EffectHandler {\n return fn as unknown as EffectHandler;\n}\n\nfunction triggerDownload(url: string): void {\n const link = document.createElement(\"a\");\n link.href = url;\n link.rel = \"noopener\";\n document.body.appendChild(link);\n link.click();\n link.remove();\n}\n\nfunction bridge<TType extends keyof EffectPropsMap & string>(event: string): EffectHandler<TType> {\n return (effect) => window.dispatchEvent(new CustomEvent(event, { detail: effect.props }));\n}\n\n/**\n * Imperative effects act directly; the rest bridge to the `lattice:*` DOM events\n * that toast/callout/modal/fragment/form subscribe to. The export cast erases\n * the mapped type to the loose registry shape — the same variance erasure\n * effectHandler performs.\n */\nconst typedBuiltinHandlers: { [K in keyof EffectPropsMap]: EffectHandler<K> } = {\n \"reload-page\": (effect) => (effect.props.full ? window.location.reload() : router.reload()),\n redirect: (effect) => router.visit(effect.props.url),\n download: (effect) => triggerDownload(effect.props.url),\n \"locale-change\": (effect) => setLocale(effect.props.locale),\n toast: bridge<\"toast\">(LATTICE_EVENT.toast),\n callout: bridge<\"callout\">(LATTICE_EVENT.callout),\n \"retract-callout\": bridge<\"retract-callout\">(LATTICE_EVENT.retractCallout),\n \"reload-component\": bridge<\"reload-component\">(LATTICE_EVENT.reloadComponent),\n \"open-modal\": bridge<\"open-modal\">(LATTICE_EVENT.openModal),\n \"close-modal\": bridge<\"close-modal\">(LATTICE_EVENT.closeModal),\n \"reset-form\": bridge<\"reset-form\">(LATTICE_EVENT.resetForm),\n \"toggle-sidebar\": bridge<\"toggle-sidebar\">(LATTICE_EVENT.toggleSidebar),\n};\n\nexport const builtinEffectHandlers: EffectHandlerRegistryFor<keyof EffectPropsMap & string> =\n typedBuiltinHandlers as EffectHandlerRegistryFor<keyof EffectPropsMap & string>;\n\nexport function mergeEffectHandlers(\n ...registries: Array<EffectHandlerRegistry | undefined>\n): EffectHandlerRegistry {\n return Object.assign({}, ...registries);\n}\n"],"mappings":";;;;;;;;AAyBA,SAAgB,cACd,OACA,IACe;CACf,OAAO;AACT;AAEA,SAAS,gBAAgB,KAAmB;CAC1C,MAAM,OAAO,SAAS,cAAc,GAAG;CACvC,KAAK,OAAO;CACZ,KAAK,MAAM;CACX,SAAS,KAAK,YAAY,IAAI;CAC9B,KAAK,MAAM;CACX,KAAK,OAAO;AACd;AAEA,SAAS,OAAoD,OAAqC;CAChG,QAAQ,WAAW,OAAO,cAAc,IAAI,YAAY,OAAO,EAAE,QAAQ,OAAO,MAAM,CAAC,CAAC;AAC1F;AAuBA,IAAa,wBACX;CAfA,gBAAgB,WAAY,OAAO,MAAM,OAAO,OAAO,SAAS,OAAO,IAAI,OAAO,OAAO;CACzF,WAAW,WAAW,OAAO,MAAM,OAAO,MAAM,GAAG;CACnD,WAAW,WAAW,gBAAgB,OAAO,MAAM,GAAG;CACtD,kBAAkB,WAAW,UAAU,OAAO,MAAM,MAAM;CAC1D,OAAO,OAAgB,cAAc,KAAK;CAC1C,SAAS,OAAkB,cAAc,OAAO;CAChD,mBAAmB,OAA0B,cAAc,cAAc;CACzE,oBAAoB,OAA2B,cAAc,eAAe;CAC5E,cAAc,OAAqB,cAAc,SAAS;CAC1D,eAAe,OAAsB,cAAc,UAAU;CAC7D,cAAc,OAAqB,cAAc,SAAS;CAC1D,kBAAkB,OAAyB,cAAc,aAAa;AAItE;AAEF,SAAgB,oBACd,GAAG,YACoB;CACvB,OAAO,OAAO,OAAO,CAAC,GAAG,GAAG,UAAU;AACxC"}
@@ -1,9 +1,6 @@
1
- import { ToastMessage } from './toast/index.js';
2
1
  import { Appearance } from './appearance/index.js';
3
2
  type EventBridgeProps = {
4
3
  onAppearanceChange?: (appearance: Appearance) => void;
5
- onLocaleChange?: (locale: string) => void;
6
- onToast?: (toast: ToastMessage) => void;
7
4
  };
8
- export declare function EventBridge({ onAppearanceChange, onLocaleChange, onToast }: EventBridgeProps): null;
5
+ export declare function EventBridge({ onAppearanceChange }: EventBridgeProps): null;
9
6
  export {};
@@ -1,22 +1,12 @@
1
1
  import { isAppearance } from "./appearance/index.js";
2
2
  import { LATTICE_EVENT } from "./core/event-names.js";
3
3
  import { useWindowEvent } from "./core/hooks/use-window-event.js";
4
- import { onToast } from "./toast/toast.js";
5
- import { useEffect } from "react";
6
4
  //#region resources/js/event-bridge.tsx
7
- function EventBridge({ onAppearanceChange, onLocaleChange, onToast: onToast$1 }) {
8
- useEffect(() => {
9
- if (!onToast$1) return;
10
- return onToast(onToast$1);
11
- }, [onToast$1]);
5
+ function EventBridge({ onAppearanceChange }) {
12
6
  useWindowEvent(LATTICE_EVENT.appearanceChange, (event) => {
13
7
  const value = event.detail?.value;
14
8
  if (isAppearance(value)) onAppearanceChange?.(value);
15
9
  }, { enabled: Boolean(onAppearanceChange) });
16
- useWindowEvent(LATTICE_EVENT.localeChange, (event) => {
17
- const locale = event.detail?.locale;
18
- if (typeof locale === "string" && locale !== "") onLocaleChange?.(locale);
19
- }, { enabled: Boolean(onLocaleChange) });
20
10
  return null;
21
11
  }
22
12
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"event-bridge.js","names":[],"sources":["../resources/js/event-bridge.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport { onToast as subscribeToToasts } from \"@lattice-php/lattice/toast\";\nimport type { ToastMessage } from \"@lattice-php/lattice/toast\";\nimport { useWindowEvent } from \"@lattice-php/lattice/core/hooks/use-window-event\";\nimport { isAppearance, type Appearance } from \"./appearance\";\nimport { LATTICE_EVENT } from \"./core/event-names\";\n\ntype EventBridgeProps = {\n onAppearanceChange?: (appearance: Appearance) => void;\n onLocaleChange?: (locale: string) => void;\n onToast?: (toast: ToastMessage) => void;\n};\n\ntype AppearanceEvent = CustomEvent<{\n value?: unknown;\n}>;\n\ntype LocaleEvent = CustomEvent<{\n locale?: unknown;\n}>;\n\nexport function EventBridge({ onAppearanceChange, onLocaleChange, onToast }: EventBridgeProps) {\n useEffect(() => {\n if (!onToast) {\n return;\n }\n\n return subscribeToToasts(onToast);\n }, [onToast]);\n\n useWindowEvent(\n LATTICE_EVENT.appearanceChange,\n (event) => {\n const value = (event as AppearanceEvent).detail?.value;\n\n if (isAppearance(value)) {\n onAppearanceChange?.(value);\n }\n },\n { enabled: Boolean(onAppearanceChange) },\n );\n\n useWindowEvent(\n LATTICE_EVENT.localeChange,\n (event) => {\n const locale = (event as LocaleEvent).detail?.locale;\n\n if (typeof locale === \"string\" && locale !== \"\") {\n onLocaleChange?.(locale);\n }\n },\n { enabled: Boolean(onLocaleChange) },\n );\n\n return null;\n}\n"],"mappings":";;;;;;AAqBA,SAAgB,YAAY,EAAE,oBAAoB,gBAAgB,SAAA,aAA6B;CAC7F,gBAAgB;EACd,IAAI,CAAC,WACH;EAGF,OAAO,QAAkB,SAAO;CAClC,GAAG,CAAC,SAAO,CAAC;CAEZ,eACE,cAAc,mBACb,UAAU;EACT,MAAM,QAAS,MAA0B,QAAQ;EAEjD,IAAI,aAAa,KAAK,GACpB,qBAAqB,KAAK;CAE9B,GACA,EAAE,SAAS,QAAQ,kBAAkB,EAAE,CACzC;CAEA,eACE,cAAc,eACb,UAAU;EACT,MAAM,SAAU,MAAsB,QAAQ;EAE9C,IAAI,OAAO,WAAW,YAAY,WAAW,IAC3C,iBAAiB,MAAM;CAE3B,GACA,EAAE,SAAS,QAAQ,cAAc,EAAE,CACrC;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"event-bridge.js","names":[],"sources":["../resources/js/event-bridge.tsx"],"sourcesContent":["import { useWindowEvent } from \"@lattice-php/lattice/core/hooks/use-window-event\";\nimport { isAppearance, type Appearance } from \"./appearance\";\nimport { LATTICE_EVENT } from \"./core/event-names\";\n\ntype EventBridgeProps = {\n onAppearanceChange?: (appearance: Appearance) => void;\n};\n\ntype AppearanceEvent = CustomEvent<{\n value?: unknown;\n}>;\n\nexport function EventBridge({ onAppearanceChange }: EventBridgeProps) {\n useWindowEvent(\n LATTICE_EVENT.appearanceChange,\n (event) => {\n const value = (event as AppearanceEvent).detail?.value;\n\n if (isAppearance(value)) {\n onAppearanceChange?.(value);\n }\n },\n { enabled: Boolean(onAppearanceChange) },\n );\n\n return null;\n}\n"],"mappings":";;;;AAYA,SAAgB,YAAY,EAAE,sBAAwC;CACpE,eACE,cAAc,mBACb,UAAU;EACT,MAAM,QAAS,MAA0B,QAAQ;EAEjD,IAAI,aAAa,KAAK,GACpB,qBAAqB,KAAK;CAE9B,GACA,EAAE,SAAS,QAAQ,kBAAkB,EAAE,CACzC;CAEA,OAAO;AACT"}
@@ -29,7 +29,7 @@ var ChoiceComponent = ({ node }) => {
29
29
  ariaLabel: node.props.label ?? void 0,
30
30
  autoFocus: node.props.autoFocus ?? void 0,
31
31
  disabled: readOnly || disabled,
32
- name: testId,
32
+ name: testId ?? "segment",
33
33
  onSelect: commit,
34
34
  options,
35
35
  tabIndex: node.props.tabIndex ?? void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"choice.js","names":[],"sources":["../../../../resources/js/form/components/fields/choice.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { Option, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { SegmentedPills } from \"@lattice-php/lattice/ui/segmented-pills\";\nimport { FormFieldFrame } from \"@lattice-php/lattice/form/components/base/field\";\nimport { useControlledField } from \"@lattice-php/lattice/form/hooks/use-controlled-field\";\nimport { useResolvedNode } from \"@lattice-php/lattice/form/hooks/resolved-nodes\";\nimport { useSeedDefault } from \"@lattice-php/lattice/form/hooks/use-seed-default\";\n\nexport const ChoiceComponent: RendererComponent<\"field.choice\"> = ({ node }) => {\n const resolvedNode = useResolvedNode(node);\n const { localName, name, testId, value, error, hidden, required, readOnly, disabled, commit } =\n useControlledField(node);\n const options = useMemo(\n () => (resolvedNode.props as { options?: Option[] }).options ?? [],\n [resolvedNode.props],\n );\n const fallbackValue = options[0]?.value ?? \"\";\n const selected = value || fallbackValue;\n\n useSeedDefault(localName, selected || undefined);\n\n if (hidden || options.length === 0) {\n return null;\n }\n\n return (\n <FormFieldFrame\n error={error}\n helperText={node.props.helperText ?? undefined}\n tooltip={node.props.tooltip ?? undefined}\n label={node.props.label ?? \"\"}\n name={name}\n required={required}\n >\n <input name={name} type=\"hidden\" value={selected} />\n <SegmentedPills\n ariaLabel={node.props.label ?? undefined}\n autoFocus={node.props.autoFocus ?? undefined}\n disabled={readOnly || disabled}\n name={testId}\n onSelect={commit}\n options={options}\n tabIndex={node.props.tabIndex ?? undefined}\n value={selected}\n />\n </FormFieldFrame>\n );\n};\n"],"mappings":";;;;;;;;AAQA,IAAa,mBAAsD,EAAE,WAAW;CAC9E,MAAM,eAAe,gBAAgB,IAAI;CACzC,MAAM,EAAE,WAAW,MAAM,QAAQ,OAAO,OAAO,QAAQ,UAAU,UAAU,UAAU,WACnF,mBAAmB,IAAI;CACzB,MAAM,UAAU,cACP,aAAa,MAAiC,WAAW,CAAC,GACjE,CAAC,aAAa,KAAK,CACrB;CACA,MAAM,gBAAgB,QAAQ,EAAE,EAAE,SAAS;CAC3C,MAAM,WAAW,SAAS;CAE1B,eAAe,WAAW,YAAY,KAAA,CAAS;CAE/C,IAAI,UAAU,QAAQ,WAAW,GAC/B,OAAO;CAGT,OACE,qBAAC,gBAAD;EACS;EACP,YAAY,KAAK,MAAM,cAAc,KAAA;EACrC,SAAS,KAAK,MAAM,WAAW,KAAA;EAC/B,OAAO,KAAK,MAAM,SAAS;EACrB;EACI;EANZ,UAAA,CAQE,oBAAC,SAAD;GAAa;GAAM,MAAK;GAAS,OAAO;EAAW,CAAA,GACnD,oBAAC,gBAAD;GACE,WAAW,KAAK,MAAM,SAAS,KAAA;GAC/B,WAAW,KAAK,MAAM,aAAa,KAAA;GACnC,UAAU,YAAY;GACtB,MAAM;GACN,UAAU;GACD;GACT,UAAU,KAAK,MAAM,YAAY,KAAA;GACjC,OAAO;EACR,CAAA,CACa;;AAEpB"}
1
+ {"version":3,"file":"choice.js","names":[],"sources":["../../../../resources/js/form/components/fields/choice.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport type { Option, RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { SegmentedPills } from \"@lattice-php/lattice/ui/segmented-pills\";\nimport { FormFieldFrame } from \"@lattice-php/lattice/form/components/base/field\";\nimport { useControlledField } from \"@lattice-php/lattice/form/hooks/use-controlled-field\";\nimport { useResolvedNode } from \"@lattice-php/lattice/form/hooks/resolved-nodes\";\nimport { useSeedDefault } from \"@lattice-php/lattice/form/hooks/use-seed-default\";\n\nexport const ChoiceComponent: RendererComponent<\"field.choice\"> = ({ node }) => {\n const resolvedNode = useResolvedNode(node);\n const { localName, name, testId, value, error, hidden, required, readOnly, disabled, commit } =\n useControlledField(node);\n const options = useMemo(\n () => (resolvedNode.props as { options?: Option[] }).options ?? [],\n [resolvedNode.props],\n );\n const fallbackValue = options[0]?.value ?? \"\";\n const selected = value || fallbackValue;\n\n useSeedDefault(localName, selected || undefined);\n\n if (hidden || options.length === 0) {\n return null;\n }\n\n return (\n <FormFieldFrame\n error={error}\n helperText={node.props.helperText ?? undefined}\n tooltip={node.props.tooltip ?? undefined}\n label={node.props.label ?? \"\"}\n name={name}\n required={required}\n >\n <input name={name} type=\"hidden\" value={selected} />\n <SegmentedPills\n ariaLabel={node.props.label ?? undefined}\n autoFocus={node.props.autoFocus ?? undefined}\n disabled={readOnly || disabled}\n name={testId ?? \"segment\"}\n onSelect={commit}\n options={options}\n tabIndex={node.props.tabIndex ?? undefined}\n value={selected}\n />\n </FormFieldFrame>\n );\n};\n"],"mappings":";;;;;;;;AAQA,IAAa,mBAAsD,EAAE,WAAW;CAC9E,MAAM,eAAe,gBAAgB,IAAI;CACzC,MAAM,EAAE,WAAW,MAAM,QAAQ,OAAO,OAAO,QAAQ,UAAU,UAAU,UAAU,WACnF,mBAAmB,IAAI;CACzB,MAAM,UAAU,cACP,aAAa,MAAiC,WAAW,CAAC,GACjE,CAAC,aAAa,KAAK,CACrB;CACA,MAAM,gBAAgB,QAAQ,EAAE,EAAE,SAAS;CAC3C,MAAM,WAAW,SAAS;CAE1B,eAAe,WAAW,YAAY,KAAA,CAAS;CAE/C,IAAI,UAAU,QAAQ,WAAW,GAC/B,OAAO;CAGT,OACE,qBAAC,gBAAD;EACS;EACP,YAAY,KAAK,MAAM,cAAc,KAAA;EACrC,SAAS,KAAK,MAAM,WAAW,KAAA;EAC/B,OAAO,KAAK,MAAM,SAAS;EACrB;EACI;EANZ,UAAA,CAQE,oBAAC,SAAD;GAAa;GAAM,MAAK;GAAS,OAAO;EAAW,CAAA,GACnD,oBAAC,gBAAD;GACE,WAAW,KAAK,MAAM,SAAS,KAAA;GAC/B,WAAW,KAAK,MAAM,aAAa,KAAA;GACnC,UAAU,YAAY;GACtB,MAAM,UAAU;GAChB,UAAU;GACD;GACT,UAAU,KAAK,MAAM,YAAY,KAAA;GACjC,OAAO;EACR,CAAA,CACa;;AAEpB"}
@@ -1,7 +1,4 @@
1
- import { Method } from '@inertiajs/core';
2
1
  import { NodeUnionOf } from '../core/types.js';
3
- import { FormFieldNodeType, FormNodeType } from '../types/generated.js';
2
+ import { FormNodeType } from '../types/generated.js';
4
3
  export type { Checkbox, Choice, DateInput, DateTimeInput, Form, FormNodeType, HiddenInput, LabelAction, NumberInput, PasswordInput, RichEditor, Select, Textarea, TextInput, TimeInput, } from '../types/generated.js';
5
- export type FormFieldNode = NodeUnionOf<FormFieldNodeType>;
6
4
  export type FormNode = NodeUnionOf<FormNodeType>;
7
- export type FormMethod = Method;
@@ -3,8 +3,8 @@ type Config = {
3
3
  readonly locales: readonly string[];
4
4
  readonly timezone: string | null;
5
5
  };
6
+ export declare const subscribeConfig: (callback: () => void) => () => void;
6
7
  export declare function setConfig(config: I18nConfig | undefined): void;
7
8
  export declare function configTimezone(): string | null;
8
- export declare function subscribeConfig(callback: () => void): () => void;
9
9
  export declare function useConfig(): Config;
10
10
  export {};
@@ -1,33 +1,23 @@
1
+ import { createListeners } from "../lib/listeners.js";
1
2
  import { useSyncExternalStore } from "react";
2
3
  //#region resources/js/i18n/config.ts
3
4
  var fallback = {
4
5
  locales: [],
5
6
  timezone: null
6
7
  };
7
- var listeners = /* @__PURE__ */ new Set();
8
+ var { subscribe, notify } = createListeners();
8
9
  var active = fallback;
9
10
  function normalizeLocales(locales) {
10
11
  return Array.from(new Set((locales ?? []).map((locale) => locale.trim()).filter(Boolean)));
11
12
  }
12
- function sameLocales(left, right) {
13
- return left.length === right.length && left.every((locale, index) => locale === right[index]);
14
- }
15
13
  function snapshot() {
16
14
  return active;
17
15
  }
18
- function subscribe(callback) {
19
- listeners.add(callback);
20
- return () => {
21
- listeners.delete(callback);
22
- };
23
- }
24
- function notify() {
25
- listeners.forEach((listener) => listener());
26
- }
16
+ var subscribeConfig = subscribe;
27
17
  function setConfig(config) {
28
18
  const locales = normalizeLocales(config?.locales);
29
19
  const timezone = config?.timezone ?? null;
30
- if (sameLocales(active.locales, locales) && active.timezone === timezone) return;
20
+ if (active.locales.join("") === locales.join("") && active.timezone === timezone) return;
31
21
  active = {
32
22
  locales,
33
23
  timezone
@@ -37,14 +27,8 @@ function setConfig(config) {
37
27
  function configTimezone() {
38
28
  return active.timezone;
39
29
  }
40
- function subscribeConfig(callback) {
41
- listeners.add(callback);
42
- return () => {
43
- listeners.delete(callback);
44
- };
45
- }
46
30
  function useConfig() {
47
- return useSyncExternalStore(subscribe, snapshot, () => fallback);
31
+ return useSyncExternalStore(subscribeConfig, snapshot, () => fallback);
48
32
  }
49
33
  //#endregion
50
34
  export { configTimezone, setConfig, subscribeConfig, useConfig };
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":[],"sources":["../../resources/js/i18n/config.ts"],"sourcesContent":["import type { I18nConfig } from \"@lattice-php/lattice/types/generated\";\nimport { useSyncExternalStore } from \"react\";\n\ntype Config = {\n readonly locales: readonly string[];\n readonly timezone: string | null;\n};\n\nconst fallback: Config = { locales: [], timezone: null };\nconst listeners = new Set<() => void>();\n\nlet active: Config = fallback;\n\nfunction normalizeLocales(locales: readonly string[] | undefined): string[] {\n return Array.from(new Set((locales ?? []).map((locale) => locale.trim()).filter(Boolean)));\n}\n\nfunction sameLocales(left: readonly string[], right: readonly string[]): boolean {\n return left.length === right.length && left.every((locale, index) => locale === right[index]);\n}\n\nfunction snapshot(): Config {\n return active;\n}\n\nfunction subscribe(callback: () => void): () => void {\n listeners.add(callback);\n\n return () => {\n listeners.delete(callback);\n };\n}\n\nfunction notify(): void {\n listeners.forEach((listener) => listener());\n}\n\nexport function setConfig(config: I18nConfig | undefined): void {\n const locales = normalizeLocales(config?.locales);\n const timezone = config?.timezone ?? null;\n\n if (sameLocales(active.locales, locales) && active.timezone === timezone) {\n return;\n }\n\n active = { locales, timezone };\n notify();\n}\n\nexport function configTimezone(): string | null {\n return active.timezone;\n}\n\nexport function subscribeConfig(callback: () => void): () => void {\n listeners.add(callback);\n\n return () => {\n listeners.delete(callback);\n };\n}\n\nexport function useConfig(): Config {\n return useSyncExternalStore(subscribe, snapshot, () => fallback);\n}\n"],"mappings":";;AAQA,IAAM,WAAmB;CAAE,SAAS,CAAC;CAAG,UAAU;AAAK;AACvD,IAAM,4BAAY,IAAI,IAAgB;AAEtC,IAAI,SAAiB;AAErB,SAAS,iBAAiB,SAAkD;CAC1E,OAAO,MAAM,KAAK,IAAI,KAAK,WAAW,CAAC,EAAA,CAAG,KAAK,WAAW,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC;AAC3F;AAEA,SAAS,YAAY,MAAyB,OAAmC;CAC/E,OAAO,KAAK,WAAW,MAAM,UAAU,KAAK,OAAO,QAAQ,UAAU,WAAW,MAAM,MAAM;AAC9F;AAEA,SAAS,WAAmB;CAC1B,OAAO;AACT;AAEA,SAAS,UAAU,UAAkC;CACnD,UAAU,IAAI,QAAQ;CAEtB,aAAa;EACX,UAAU,OAAO,QAAQ;CAC3B;AACF;AAEA,SAAS,SAAe;CACtB,UAAU,SAAS,aAAa,SAAS,CAAC;AAC5C;AAEA,SAAgB,UAAU,QAAsC;CAC9D,MAAM,UAAU,iBAAiB,QAAQ,OAAO;CAChD,MAAM,WAAW,QAAQ,YAAY;CAErC,IAAI,YAAY,OAAO,SAAS,OAAO,KAAK,OAAO,aAAa,UAC9D;CAGF,SAAS;EAAE;EAAS;CAAS;CAC7B,OAAO;AACT;AAEA,SAAgB,iBAAgC;CAC9C,OAAO,OAAO;AAChB;AAEA,SAAgB,gBAAgB,UAAkC;CAChE,UAAU,IAAI,QAAQ;CAEtB,aAAa;EACX,UAAU,OAAO,QAAQ;CAC3B;AACF;AAEA,SAAgB,YAAoB;CAClC,OAAO,qBAAqB,WAAW,gBAAgB,QAAQ;AACjE"}
1
+ {"version":3,"file":"config.js","names":[],"sources":["../../resources/js/i18n/config.ts"],"sourcesContent":["import type { I18nConfig } from \"@lattice-php/lattice/types/generated\";\nimport { useSyncExternalStore } from \"react\";\nimport { createListeners } from \"@lattice-php/lattice/lib/listeners\";\n\ntype Config = {\n readonly locales: readonly string[];\n readonly timezone: string | null;\n};\n\nconst fallback: Config = { locales: [], timezone: null };\nconst { subscribe, notify } = createListeners();\n\nlet active: Config = fallback;\n\nfunction normalizeLocales(locales: readonly string[] | undefined): string[] {\n return Array.from(new Set((locales ?? []).map((locale) => locale.trim()).filter(Boolean)));\n}\n\nfunction snapshot(): Config {\n return active;\n}\n\nexport const subscribeConfig = subscribe;\n\nexport function setConfig(config: I18nConfig | undefined): void {\n const locales = normalizeLocales(config?.locales);\n const timezone = config?.timezone ?? null;\n\n if (active.locales.join(\"\u001f\") === locales.join(\"\u001f\") && active.timezone === timezone) {\n return;\n }\n\n active = { locales, timezone };\n notify();\n}\n\nexport function configTimezone(): string | null {\n return active.timezone;\n}\n\nexport function useConfig(): Config {\n return useSyncExternalStore(subscribeConfig, snapshot, () => fallback);\n}\n"],"mappings":";;;AASA,IAAM,WAAmB;CAAE,SAAS,CAAC;CAAG,UAAU;AAAK;AACvD,IAAM,EAAE,WAAW,WAAW,gBAAgB;AAE9C,IAAI,SAAiB;AAErB,SAAS,iBAAiB,SAAkD;CAC1E,OAAO,MAAM,KAAK,IAAI,KAAK,WAAW,CAAC,EAAA,CAAG,KAAK,WAAW,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC;AAC3F;AAEA,SAAS,WAAmB;CAC1B,OAAO;AACT;AAEA,IAAa,kBAAkB;AAE/B,SAAgB,UAAU,QAAsC;CAC9D,MAAM,UAAU,iBAAiB,QAAQ,OAAO;CAChD,MAAM,WAAW,QAAQ,YAAY;CAErC,IAAI,OAAO,QAAQ,KAAK,GAAG,MAAM,QAAQ,KAAK,GAAG,KAAK,OAAO,aAAa,UACxE;CAGF,SAAS;EAAE;EAAS;CAAS;CAC7B,OAAO;AACT;AAEA,SAAgB,iBAAgC;CAC9C,OAAO,OAAO;AAChB;AAEA,SAAgB,YAAoB;CAClC,OAAO,qBAAqB,iBAAiB,gBAAgB,QAAQ;AACvE"}
@@ -2,10 +2,10 @@ export { i18n, useT, translate } from './instance.js';
2
2
  export { configureI18n, enableBackend } from './backend.js';
3
3
  export { currentLocale, localeHeader, setLocale, useLocale } from './locale.js';
4
4
  export { LocaleReload } from './locale-reload.js';
5
- export { LocaleSwitcher, useLocaleOptions } from './locale-switcher.js';
5
+ export { useLocaleOptions } from './locale-switcher.js';
6
6
  export { configureI18nFromPageProps, i18nConfigFromPageProps } from './page-props.js';
7
7
  export type { BackendOptions, ConfigureI18nOptions, I18nConfig } from './backend.js';
8
- export type { LocaleOption, LocaleSwitcherProps, UseLocaleOptionsOptions, UseLocaleOptionsReturn, } from './locale-switcher.js';
8
+ export type { LocaleOption, UseLocaleOptionsOptions, UseLocaleOptionsReturn, } from './locale-switcher.js';
9
9
  export type { UseLocaleReturn } from './locale.js';
10
10
  export { currentTimezone, setTimezone, useTimezone } from './timezone.js';
11
11
  export type { UseTimezoneReturn } from './timezone.js';
@@ -4,7 +4,7 @@ import { i18n, translate, useT } from "./instance.js";
4
4
  import { LocaleReload } from "./locale-reload.js";
5
5
  import { i18nConfigFromPageProps } from "./shared-props.js";
6
6
  import { configureI18n, enableBackend } from "./backend.js";
7
- import { LocaleSwitcher, useLocaleOptions } from "./locale-switcher.js";
7
+ import { useLocaleOptions } from "./locale-switcher.js";
8
8
  import { configureI18nFromPageProps } from "./page-props.js";
9
9
  import { DateTime } from "./date-time.js";
10
- export { DateTime, LocaleReload, LocaleSwitcher, configureI18n, configureI18nFromPageProps, currentLocale, currentTimezone, enableBackend, i18n, i18nConfigFromPageProps, localeHeader, setLocale, setTimezone, translate, useLocale, useLocaleOptions, useT, useTimezone };
10
+ export { DateTime, LocaleReload, configureI18n, configureI18nFromPageProps, currentLocale, currentTimezone, enableBackend, i18n, i18nConfigFromPageProps, localeHeader, setLocale, setTimezone, translate, useLocale, useLocaleOptions, useT, useTimezone };
@@ -1,4 +1,3 @@
1
- import { ReactNode } from 'react';
2
1
  export type LocaleOption = {
3
2
  readonly value: string;
4
3
  readonly label: string;
@@ -14,8 +13,4 @@ export type UseLocaleOptionsReturn = {
14
13
  readonly options: readonly LocaleOption[];
15
14
  readonly setLocale: (locale: string) => void;
16
15
  };
17
- export type LocaleSwitcherProps = UseLocaleOptionsOptions & {
18
- readonly children: (state: UseLocaleOptionsReturn) => ReactNode;
19
- };
20
16
  export declare function useLocaleOptions({ namespace, label, }?: UseLocaleOptionsOptions): UseLocaleOptionsReturn;
21
- export declare function LocaleSwitcher({ children, ...options }: LocaleSwitcherProps): import("react").JSX.Element;
@@ -1,5 +1,4 @@
1
1
  import { useT } from "./instance.js";
2
- import { Fragment, jsx } from "react/jsx-runtime";
3
2
  //#region resources/js/i18n/locale-switcher.tsx
4
3
  function useLocaleOptions({ namespace = "lattice", label } = {}) {
5
4
  const { t, locale, locales, setLocale } = useT(namespace);
@@ -16,10 +15,7 @@ function useLocaleOptions({ namespace = "lattice", label } = {}) {
16
15
  setLocale
17
16
  };
18
17
  }
19
- function LocaleSwitcher({ children, ...options }) {
20
- return /* @__PURE__ */ jsx(Fragment, { children: children(useLocaleOptions(options)) });
21
- }
22
18
  //#endregion
23
- export { LocaleSwitcher, useLocaleOptions };
19
+ export { useLocaleOptions };
24
20
 
25
21
  //# sourceMappingURL=locale-switcher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"locale-switcher.js","names":[],"sources":["../../resources/js/i18n/locale-switcher.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { useT } from \"./instance\";\n\nexport type LocaleOption = {\n readonly value: string;\n readonly label: string;\n readonly active: boolean;\n};\n\nexport type UseLocaleOptionsOptions = {\n readonly namespace?: string;\n readonly label?: (locale: string) => string;\n};\n\nexport type UseLocaleOptionsReturn = {\n readonly locale: string;\n readonly locales: readonly string[];\n readonly options: readonly LocaleOption[];\n readonly setLocale: (locale: string) => void;\n};\n\nexport type LocaleSwitcherProps = UseLocaleOptionsOptions & {\n readonly children: (state: UseLocaleOptionsReturn) => ReactNode;\n};\n\nexport function useLocaleOptions({\n namespace = \"lattice\",\n label,\n}: UseLocaleOptionsOptions = {}): UseLocaleOptionsReturn {\n const { t, locale, locales, setLocale } = useT(namespace);\n const values = locales.length > 0 ? locales : [locale];\n const labelFor = label ?? ((value: string): string => t(`language.${value}`, value));\n\n return {\n locale,\n locales: values,\n options: values.map((value) => ({\n value,\n label: labelFor(value),\n active: value === locale,\n })),\n setLocale,\n };\n}\n\nexport function LocaleSwitcher({ children, ...options }: LocaleSwitcherProps) {\n return <>{children(useLocaleOptions(options))}</>;\n}\n"],"mappings":";;;AAyBA,SAAgB,iBAAiB,EAC/B,YAAY,WACZ,UAC2B,CAAC,GAA2B;CACvD,MAAM,EAAE,GAAG,QAAQ,SAAS,cAAc,KAAK,SAAS;CACxD,MAAM,SAAS,QAAQ,SAAS,IAAI,UAAU,CAAC,MAAM;CACrD,MAAM,WAAW,WAAW,UAA0B,EAAE,YAAY,SAAS,KAAK;CAElF,OAAO;EACL;EACA,SAAS;EACT,SAAS,OAAO,KAAK,WAAW;GAC9B;GACA,OAAO,SAAS,KAAK;GACrB,QAAQ,UAAU;EACpB,EAAE;EACF;CACF;AACF;AAEA,SAAgB,eAAe,EAAE,UAAU,GAAG,WAAgC;CAC5E,OAAO,oBAAA,UAAA,EAAA,UAAG,SAAS,iBAAiB,OAAO,CAAC,EAAI,CAAA;AAClD"}
1
+ {"version":3,"file":"locale-switcher.js","names":[],"sources":["../../resources/js/i18n/locale-switcher.tsx"],"sourcesContent":["import { useT } from \"./instance\";\n\nexport type LocaleOption = {\n readonly value: string;\n readonly label: string;\n readonly active: boolean;\n};\n\nexport type UseLocaleOptionsOptions = {\n readonly namespace?: string;\n readonly label?: (locale: string) => string;\n};\n\nexport type UseLocaleOptionsReturn = {\n readonly locale: string;\n readonly locales: readonly string[];\n readonly options: readonly LocaleOption[];\n readonly setLocale: (locale: string) => void;\n};\n\nexport function useLocaleOptions({\n namespace = \"lattice\",\n label,\n}: UseLocaleOptionsOptions = {}): UseLocaleOptionsReturn {\n const { t, locale, locales, setLocale } = useT(namespace);\n const values = locales.length > 0 ? locales : [locale];\n const labelFor = label ?? ((value: string): string => t(`language.${value}`, value));\n\n return {\n locale,\n locales: values,\n options: values.map((value) => ({\n value,\n label: labelFor(value),\n active: value === locale,\n })),\n setLocale,\n };\n}\n"],"mappings":";;AAoBA,SAAgB,iBAAiB,EAC/B,YAAY,WACZ,UAC2B,CAAC,GAA2B;CACvD,MAAM,EAAE,GAAG,QAAQ,SAAS,cAAc,KAAK,SAAS;CACxD,MAAM,SAAS,QAAQ,SAAS,IAAI,UAAU,CAAC,MAAM;CACrD,MAAM,WAAW,WAAW,UAA0B,EAAE,YAAY,SAAS,KAAK;CAElF,OAAO;EACL;EACA,SAAS;EACT,SAAS,OAAO,KAAK,WAAW;GAC9B;GACA,OAAO,SAAS,KAAK;GACrB,QAAQ,UAAU;EACpB,EAAE;EACF;CACF;AACF"}
@@ -1,10 +1,11 @@
1
+ import { createListeners } from "../lib/listeners.js";
1
2
  import { LATTICE_EVENT } from "../core/event-names.js";
2
3
  import { useSyncExternalStore } from "react";
3
4
  //#region resources/js/i18n/locale.ts
4
5
  var key = "locale";
5
6
  var fallback = "en";
6
7
  var maxAge = 31536e3;
7
- var listeners = /* @__PURE__ */ new Set();
8
+ var { subscribe, notify } = createListeners();
8
9
  var active;
9
10
  function normalize(value) {
10
11
  const next = value.trim();
@@ -50,15 +51,6 @@ function snapshot() {
50
51
  active ??= detectedLocale();
51
52
  return active;
52
53
  }
53
- function subscribe(callback) {
54
- listeners.add(callback);
55
- return () => {
56
- listeners.delete(callback);
57
- };
58
- }
59
- function notify() {
60
- listeners.forEach((listener) => listener());
61
- }
62
54
  function dispatch(locale) {
63
55
  if (typeof window === "undefined") return;
64
56
  window.dispatchEvent(new CustomEvent(LATTICE_EVENT.localeChange, { detail: { locale } }));
@@ -1 +1 @@
1
- {"version":3,"file":"locale.js","names":[],"sources":["../../resources/js/i18n/locale.ts"],"sourcesContent":["import { useSyncExternalStore } from \"react\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\n\nexport type UseLocaleReturn = {\n readonly locale: string;\n readonly setLocale: (locale: string) => void;\n};\n\nconst key = \"locale\";\nconst fallback = \"en\";\nconst maxAge = 365 * 24 * 60 * 60;\nconst listeners = new Set<() => void>();\n\nlet active: string | undefined;\n\nfunction normalize(value: string): string {\n const next = value.trim();\n\n return next === \"\" ? fallback : next;\n}\n\nfunction storedValue(): string | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n}\n\nfunction cookieValue(): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const item = document.cookie\n .split(\";\")\n .map((cookie) => cookie.trim())\n .find((cookie) => cookie.startsWith(`${key}=`));\n\n if (!item) {\n return null;\n }\n\n try {\n return decodeURIComponent(item.slice(key.length + 1));\n } catch {\n return null;\n }\n}\n\nfunction documentValue(): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n return document.documentElement.lang || null;\n}\n\nfunction detectedLocale(): string {\n return normalize(storedValue() ?? cookieValue() ?? documentValue() ?? fallback);\n}\n\nfunction persist(locale: string): void {\n if (typeof document !== \"undefined\") {\n document.cookie = `${key}=${encodeURIComponent(locale)};path=/;max-age=${maxAge};SameSite=Lax`;\n document.documentElement.lang = locale;\n }\n\n if (typeof window !== \"undefined\") {\n try {\n localStorage.setItem(key, locale);\n } catch {\n return;\n }\n }\n}\n\nfunction snapshot(): string {\n active ??= detectedLocale();\n\n return active;\n}\n\nfunction subscribe(callback: () => void): () => void {\n listeners.add(callback);\n\n return () => {\n listeners.delete(callback);\n };\n}\n\nfunction notify(): void {\n listeners.forEach((listener) => listener());\n}\n\nfunction dispatch(locale: string): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n window.dispatchEvent(new CustomEvent(LATTICE_EVENT.localeChange, { detail: { locale } }));\n}\n\nexport function currentLocale(): string {\n return snapshot();\n}\n\nexport function localeHeader(): Record<string, string> {\n return { \"Accept-Language\": currentLocale() };\n}\n\nexport function subscribeLocale(callback: (locale: string) => void): () => void {\n return subscribe(() => callback(currentLocale()));\n}\n\nexport function setLocale(locale: string): void {\n const previous = currentLocale();\n const next = normalize(locale);\n\n active = next;\n persist(next);\n\n if (next === previous) {\n return;\n }\n\n notify();\n dispatch(next);\n}\n\nexport function useLocale(): UseLocaleReturn {\n const locale = useSyncExternalStore(subscribe, snapshot, () => fallback);\n\n return { locale, setLocale } as const;\n}\n"],"mappings":";;;AAQA,IAAM,MAAM;AACZ,IAAM,WAAW;AACjB,IAAM,SAAS;AACf,IAAM,4BAAY,IAAI,IAAgB;AAEtC,IAAI;AAEJ,SAAS,UAAU,OAAuB;CACxC,MAAM,OAAO,MAAM,KAAK;CAExB,OAAO,SAAS,KAAK,WAAW;AAClC;AAEA,SAAS,cAA6B;CACpC,IAAI,OAAO,WAAW,aACpB,OAAO;CAGT,IAAI;EACF,OAAO,aAAa,QAAQ,GAAG;CACjC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,cAA6B;CACpC,IAAI,OAAO,aAAa,aACtB,OAAO;CAGT,MAAM,OAAO,SAAS,OACnB,MAAM,GAAG,CAAC,CACV,KAAK,WAAW,OAAO,KAAK,CAAC,CAAC,CAC9B,MAAM,WAAW,OAAO,WAAW,GAAG,IAAI,EAAE,CAAC;CAEhD,IAAI,CAAC,MACH,OAAO;CAGT,IAAI;EACF,OAAO,mBAAmB,KAAK,MAAM,CAAc,CAAC;CACtD,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,gBAA+B;CACtC,IAAI,OAAO,aAAa,aACtB,OAAO;CAGT,OAAO,SAAS,gBAAgB,QAAQ;AAC1C;AAEA,SAAS,iBAAyB;CAChC,OAAO,UAAU,YAAY,KAAK,YAAY,KAAK,cAAc,KAAK,QAAQ;AAChF;AAEA,SAAS,QAAQ,QAAsB;CACrC,IAAI,OAAO,aAAa,aAAa;EACnC,SAAS,SAAS,GAAG,IAAI,GAAG,mBAAmB,MAAM,EAAE,kBAAkB,OAAO;EAChF,SAAS,gBAAgB,OAAO;CAClC;CAEA,IAAI,OAAO,WAAW,aACpB,IAAI;EACF,aAAa,QAAQ,KAAK,MAAM;CAClC,QAAQ;EACN;CACF;AAEJ;AAEA,SAAS,WAAmB;CAC1B,WAAW,eAAe;CAE1B,OAAO;AACT;AAEA,SAAS,UAAU,UAAkC;CACnD,UAAU,IAAI,QAAQ;CAEtB,aAAa;EACX,UAAU,OAAO,QAAQ;CAC3B;AACF;AAEA,SAAS,SAAe;CACtB,UAAU,SAAS,aAAa,SAAS,CAAC;AAC5C;AAEA,SAAS,SAAS,QAAsB;CACtC,IAAI,OAAO,WAAW,aACpB;CAGF,OAAO,cAAc,IAAI,YAAY,cAAc,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;AAC1F;AAEA,SAAgB,gBAAwB;CACtC,OAAO,SAAS;AAClB;AAEA,SAAgB,eAAuC;CACrD,OAAO,EAAE,mBAAmB,cAAc,EAAE;AAC9C;AAEA,SAAgB,gBAAgB,UAAgD;CAC9E,OAAO,gBAAgB,SAAS,cAAc,CAAC,CAAC;AAClD;AAEA,SAAgB,UAAU,QAAsB;CAC9C,MAAM,WAAW,cAAc;CAC/B,MAAM,OAAO,UAAU,MAAM;CAE7B,SAAS;CACT,QAAQ,IAAI;CAEZ,IAAI,SAAS,UACX;CAGF,OAAO;CACP,SAAS,IAAI;AACf;AAEA,SAAgB,YAA6B;CAG3C,OAAO;EAAE,QAFM,qBAAqB,WAAW,gBAAgB,QAEtD;EAAQ;CAAU;AAC7B"}
1
+ {"version":3,"file":"locale.js","names":[],"sources":["../../resources/js/i18n/locale.ts"],"sourcesContent":["import { useSyncExternalStore } from \"react\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\nimport { createListeners } from \"@lattice-php/lattice/lib/listeners\";\n\nexport type UseLocaleReturn = {\n readonly locale: string;\n readonly setLocale: (locale: string) => void;\n};\n\nconst key = \"locale\";\nconst fallback = \"en\";\nconst maxAge = 365 * 24 * 60 * 60;\nconst { subscribe, notify } = createListeners();\n\nlet active: string | undefined;\n\nfunction normalize(value: string): string {\n const next = value.trim();\n\n return next === \"\" ? fallback : next;\n}\n\nfunction storedValue(): string | null {\n if (typeof window === \"undefined\") {\n return null;\n }\n\n try {\n return localStorage.getItem(key);\n } catch {\n return null;\n }\n}\n\nfunction cookieValue(): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const item = document.cookie\n .split(\";\")\n .map((cookie) => cookie.trim())\n .find((cookie) => cookie.startsWith(`${key}=`));\n\n if (!item) {\n return null;\n }\n\n try {\n return decodeURIComponent(item.slice(key.length + 1));\n } catch {\n return null;\n }\n}\n\nfunction documentValue(): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n return document.documentElement.lang || null;\n}\n\nfunction detectedLocale(): string {\n return normalize(storedValue() ?? cookieValue() ?? documentValue() ?? fallback);\n}\n\nfunction persist(locale: string): void {\n if (typeof document !== \"undefined\") {\n document.cookie = `${key}=${encodeURIComponent(locale)};path=/;max-age=${maxAge};SameSite=Lax`;\n document.documentElement.lang = locale;\n }\n\n if (typeof window !== \"undefined\") {\n try {\n localStorage.setItem(key, locale);\n } catch {\n return;\n }\n }\n}\n\nfunction snapshot(): string {\n active ??= detectedLocale();\n\n return active;\n}\n\nfunction dispatch(locale: string): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n window.dispatchEvent(new CustomEvent(LATTICE_EVENT.localeChange, { detail: { locale } }));\n}\n\nexport function currentLocale(): string {\n return snapshot();\n}\n\nexport function localeHeader(): Record<string, string> {\n return { \"Accept-Language\": currentLocale() };\n}\n\nexport function subscribeLocale(callback: (locale: string) => void): () => void {\n return subscribe(() => callback(currentLocale()));\n}\n\nexport function setLocale(locale: string): void {\n const previous = currentLocale();\n const next = normalize(locale);\n\n active = next;\n persist(next);\n\n if (next === previous) {\n return;\n }\n\n notify();\n dispatch(next);\n}\n\nexport function useLocale(): UseLocaleReturn {\n const locale = useSyncExternalStore(subscribe, snapshot, () => fallback);\n\n return { locale, setLocale } as const;\n}\n"],"mappings":";;;;AASA,IAAM,MAAM;AACZ,IAAM,WAAW;AACjB,IAAM,SAAS;AACf,IAAM,EAAE,WAAW,WAAW,gBAAgB;AAE9C,IAAI;AAEJ,SAAS,UAAU,OAAuB;CACxC,MAAM,OAAO,MAAM,KAAK;CAExB,OAAO,SAAS,KAAK,WAAW;AAClC;AAEA,SAAS,cAA6B;CACpC,IAAI,OAAO,WAAW,aACpB,OAAO;CAGT,IAAI;EACF,OAAO,aAAa,QAAQ,GAAG;CACjC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,cAA6B;CACpC,IAAI,OAAO,aAAa,aACtB,OAAO;CAGT,MAAM,OAAO,SAAS,OACnB,MAAM,GAAG,CAAC,CACV,KAAK,WAAW,OAAO,KAAK,CAAC,CAAC,CAC9B,MAAM,WAAW,OAAO,WAAW,GAAG,IAAI,EAAE,CAAC;CAEhD,IAAI,CAAC,MACH,OAAO;CAGT,IAAI;EACF,OAAO,mBAAmB,KAAK,MAAM,CAAc,CAAC;CACtD,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,gBAA+B;CACtC,IAAI,OAAO,aAAa,aACtB,OAAO;CAGT,OAAO,SAAS,gBAAgB,QAAQ;AAC1C;AAEA,SAAS,iBAAyB;CAChC,OAAO,UAAU,YAAY,KAAK,YAAY,KAAK,cAAc,KAAK,QAAQ;AAChF;AAEA,SAAS,QAAQ,QAAsB;CACrC,IAAI,OAAO,aAAa,aAAa;EACnC,SAAS,SAAS,GAAG,IAAI,GAAG,mBAAmB,MAAM,EAAE,kBAAkB,OAAO;EAChF,SAAS,gBAAgB,OAAO;CAClC;CAEA,IAAI,OAAO,WAAW,aACpB,IAAI;EACF,aAAa,QAAQ,KAAK,MAAM;CAClC,QAAQ;EACN;CACF;AAEJ;AAEA,SAAS,WAAmB;CAC1B,WAAW,eAAe;CAE1B,OAAO;AACT;AAEA,SAAS,SAAS,QAAsB;CACtC,IAAI,OAAO,WAAW,aACpB;CAGF,OAAO,cAAc,IAAI,YAAY,cAAc,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;AAC1F;AAEA,SAAgB,gBAAwB;CACtC,OAAO,SAAS;AAClB;AAEA,SAAgB,eAAuC;CACrD,OAAO,EAAE,mBAAmB,cAAc,EAAE;AAC9C;AAEA,SAAgB,gBAAgB,UAAgD;CAC9E,OAAO,gBAAgB,SAAS,cAAc,CAAC,CAAC;AAClD;AAEA,SAAgB,UAAU,QAAsB;CAC9C,MAAM,WAAW,cAAc;CAC/B,MAAM,OAAO,UAAU,MAAM;CAE7B,SAAS;CACT,QAAQ,IAAI;CAEZ,IAAI,SAAS,UACX;CAGF,OAAO;CACP,SAAS,IAAI;AACf;AAEA,SAAgB,YAA6B;CAG3C,OAAO;EAAE,QAFM,qBAAqB,WAAW,gBAAgB,QAEtD;EAAQ;CAAU;AAC7B"}
@@ -1,9 +1,10 @@
1
+ import { createListeners } from "../lib/listeners.js";
1
2
  import { LATTICE_EVENT } from "../core/event-names.js";
2
3
  import { configTimezone, subscribeConfig } from "./config.js";
3
4
  import { useSyncExternalStore } from "react";
4
5
  //#region resources/js/i18n/timezone.ts
5
6
  var fallback = "UTC";
6
- var listeners = /* @__PURE__ */ new Set();
7
+ var { subscribe, notify } = createListeners();
7
8
  var override;
8
9
  function detectedTimezone() {
9
10
  if (typeof Intl === "undefined") return fallback;
@@ -16,15 +17,6 @@ function detectedTimezone() {
16
17
  function snapshot() {
17
18
  return override ?? configTimezone() ?? detectedTimezone();
18
19
  }
19
- function subscribe(callback) {
20
- listeners.add(callback);
21
- return () => {
22
- listeners.delete(callback);
23
- };
24
- }
25
- function notify() {
26
- listeners.forEach((listener) => listener());
27
- }
28
20
  subscribeConfig(() => notify());
29
21
  function dispatch(timezone) {
30
22
  if (typeof window === "undefined") return;
@@ -1 +1 @@
1
- {"version":3,"file":"timezone.js","names":[],"sources":["../../resources/js/i18n/timezone.ts"],"sourcesContent":["import { useSyncExternalStore } from \"react\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\nimport { configTimezone, subscribeConfig } from \"./config\";\n\nexport type UseTimezoneReturn = {\n readonly timezone: string;\n readonly setTimezone: (timezone: string) => void;\n};\n\nconst fallback = \"UTC\";\nconst listeners = new Set<() => void>();\n\nlet override: string | undefined;\n\nfunction detectedTimezone(): string {\n if (typeof Intl === \"undefined\") {\n return fallback;\n }\n\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || fallback;\n } catch {\n return fallback;\n }\n}\n\nfunction snapshot(): string {\n return override ?? configTimezone() ?? detectedTimezone();\n}\n\nfunction subscribe(callback: () => void): () => void {\n listeners.add(callback);\n\n return () => {\n listeners.delete(callback);\n };\n}\n\nfunction notify(): void {\n listeners.forEach((listener) => listener());\n}\n\nsubscribeConfig(() => notify());\n\nfunction dispatch(timezone: string): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n window.dispatchEvent(new CustomEvent(LATTICE_EVENT.timezoneChange, { detail: { timezone } }));\n}\n\nexport function currentTimezone(): string {\n return snapshot();\n}\n\nexport function setTimezone(timezone: string): void {\n const previous = currentTimezone();\n const next = timezone.trim();\n\n override = next === \"\" ? undefined : next;\n\n if (currentTimezone() === previous) {\n return;\n }\n\n notify();\n dispatch(currentTimezone());\n}\n\nexport function useTimezone(): UseTimezoneReturn {\n const timezone = useSyncExternalStore(subscribe, snapshot, () => fallback);\n\n return { timezone, setTimezone } as const;\n}\n"],"mappings":";;;;AASA,IAAM,WAAW;AACjB,IAAM,4BAAY,IAAI,IAAgB;AAEtC,IAAI;AAEJ,SAAS,mBAA2B;CAClC,IAAI,OAAO,SAAS,aAClB,OAAO;CAGT,IAAI;EACF,OAAO,KAAK,eAAe,CAAC,CAAC,gBAAgB,CAAC,CAAC,YAAY;CAC7D,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,WAAmB;CAC1B,OAAO,YAAY,eAAe,KAAK,iBAAiB;AAC1D;AAEA,SAAS,UAAU,UAAkC;CACnD,UAAU,IAAI,QAAQ;CAEtB,aAAa;EACX,UAAU,OAAO,QAAQ;CAC3B;AACF;AAEA,SAAS,SAAe;CACtB,UAAU,SAAS,aAAa,SAAS,CAAC;AAC5C;AAEA,sBAAsB,OAAO,CAAC;AAE9B,SAAS,SAAS,UAAwB;CACxC,IAAI,OAAO,WAAW,aACpB;CAGF,OAAO,cAAc,IAAI,YAAY,cAAc,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;AAC9F;AAEA,SAAgB,kBAA0B;CACxC,OAAO,SAAS;AAClB;AAEA,SAAgB,YAAY,UAAwB;CAClD,MAAM,WAAW,gBAAgB;CACjC,MAAM,OAAO,SAAS,KAAK;CAE3B,WAAW,SAAS,KAAK,KAAA,IAAY;CAErC,IAAI,gBAAgB,MAAM,UACxB;CAGF,OAAO;CACP,SAAS,gBAAgB,CAAC;AAC5B;AAEA,SAAgB,cAAiC;CAG/C,OAAO;EAAE,UAFQ,qBAAqB,WAAW,gBAAgB,QAExD;EAAU;CAAY;AACjC"}
1
+ {"version":3,"file":"timezone.js","names":[],"sources":["../../resources/js/i18n/timezone.ts"],"sourcesContent":["import { useSyncExternalStore } from \"react\";\nimport { LATTICE_EVENT } from \"@lattice-php/lattice/core/event-names\";\nimport { createListeners } from \"@lattice-php/lattice/lib/listeners\";\nimport { configTimezone, subscribeConfig } from \"./config\";\n\nexport type UseTimezoneReturn = {\n readonly timezone: string;\n readonly setTimezone: (timezone: string) => void;\n};\n\nconst fallback = \"UTC\";\nconst { subscribe, notify } = createListeners();\n\nlet override: string | undefined;\n\nfunction detectedTimezone(): string {\n if (typeof Intl === \"undefined\") {\n return fallback;\n }\n\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || fallback;\n } catch {\n return fallback;\n }\n}\n\nfunction snapshot(): string {\n return override ?? configTimezone() ?? detectedTimezone();\n}\n\nsubscribeConfig(() => notify());\n\nfunction dispatch(timezone: string): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n window.dispatchEvent(new CustomEvent(LATTICE_EVENT.timezoneChange, { detail: { timezone } }));\n}\n\nexport function currentTimezone(): string {\n return snapshot();\n}\n\nexport function setTimezone(timezone: string): void {\n const previous = currentTimezone();\n const next = timezone.trim();\n\n override = next === \"\" ? undefined : next;\n\n if (currentTimezone() === previous) {\n return;\n }\n\n notify();\n dispatch(currentTimezone());\n}\n\nexport function useTimezone(): UseTimezoneReturn {\n const timezone = useSyncExternalStore(subscribe, snapshot, () => fallback);\n\n return { timezone, setTimezone } as const;\n}\n"],"mappings":";;;;;AAUA,IAAM,WAAW;AACjB,IAAM,EAAE,WAAW,WAAW,gBAAgB;AAE9C,IAAI;AAEJ,SAAS,mBAA2B;CAClC,IAAI,OAAO,SAAS,aAClB,OAAO;CAGT,IAAI;EACF,OAAO,KAAK,eAAe,CAAC,CAAC,gBAAgB,CAAC,CAAC,YAAY;CAC7D,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,WAAmB;CAC1B,OAAO,YAAY,eAAe,KAAK,iBAAiB;AAC1D;AAEA,sBAAsB,OAAO,CAAC;AAE9B,SAAS,SAAS,UAAwB;CACxC,IAAI,OAAO,WAAW,aACpB;CAGF,OAAO,cAAc,IAAI,YAAY,cAAc,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;AAC9F;AAEA,SAAgB,kBAA0B;CACxC,OAAO,SAAS;AAClB;AAEA,SAAgB,YAAY,UAAwB;CAClD,MAAM,WAAW,gBAAgB;CACjC,MAAM,OAAO,SAAS,KAAK;CAE3B,WAAW,SAAS,KAAK,KAAA,IAAY;CAErC,IAAI,gBAAgB,MAAM,UACxB;CAGF,OAAO;CACP,SAAS,gBAAgB,CAAC;AAC5B;AAEA,SAAgB,cAAiC;CAG/C,OAAO;EAAE,UAFQ,qBAAqB,WAAW,gBAAgB,QAExD;EAAU;CAAY;AACjC"}
@@ -6,9 +6,8 @@ export type IconRendererProps = {
6
6
  export type IconRendererFunction = (props: IconRendererProps) => ReactNode;
7
7
  type IconRendererProviderProps = {
8
8
  children: ReactNode;
9
- mode?: "replace" | "stack";
10
9
  renderer: IconRendererFunction;
11
10
  };
12
- export declare function IconRendererProvider({ children, mode, renderer, }: IconRendererProviderProps): import("react").JSX.Element;
11
+ export declare function IconRendererProvider({ children, renderer }: IconRendererProviderProps): import("react").JSX.Element;
13
12
  export declare function IconRenderer({ className, icon }: IconRendererProps): string | number | bigint | true | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | import("react").JSX.Element;
14
13
  export {};
@@ -4,13 +4,9 @@ import { createContext, useContext, useMemo } from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region resources/js/icons/icon-renderer.tsx
6
6
  var IconRenderersContext = createContext([]);
7
- function IconRendererProvider({ children, mode = "stack", renderer }) {
7
+ function IconRendererProvider({ children, renderer }) {
8
8
  const parentRenderers = useContext(IconRenderersContext);
9
- const renderers = useMemo(() => mode === "replace" ? [renderer] : [renderer, ...parentRenderers], [
10
- mode,
11
- parentRenderers,
12
- renderer
13
- ]);
9
+ const renderers = useMemo(() => [renderer, ...parentRenderers], [parentRenderers, renderer]);
14
10
  return /* @__PURE__ */ jsx(IconRenderersContext.Provider, {
15
11
  value: renderers,
16
12
  children
@@ -1 +1 @@
1
- {"version":3,"file":"icon-renderer.js","names":[],"sources":["../../resources/js/icons/icon-renderer.tsx"],"sourcesContent":["import { createContext, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { Icon, useSprite } from \"./sprite\";\n\nexport type IconRendererProps = {\n className?: string;\n icon: string;\n};\n\nexport type IconRendererFunction = (props: IconRendererProps) => ReactNode;\n\ntype IconRendererProviderProps = {\n children: ReactNode;\n mode?: \"replace\" | \"stack\";\n renderer: IconRendererFunction;\n};\n\nconst IconRenderersContext = createContext<IconRendererFunction[]>([]);\nconst loggedMissingIcons = new Set<string>();\n\nexport function IconRendererProvider({\n children,\n mode = \"stack\",\n renderer,\n}: IconRendererProviderProps) {\n const parentRenderers = useContext(IconRenderersContext);\n const renderers = useMemo(\n () => (mode === \"replace\" ? [renderer] : [renderer, ...parentRenderers]),\n [mode, parentRenderers, renderer],\n );\n\n return (\n <IconRenderersContext.Provider value={renderers}>{children}</IconRenderersContext.Provider>\n );\n}\n\nexport function IconRenderer({ className, icon }: IconRendererProps) {\n const renderers = useContext(IconRenderersContext);\n const { ids } = useSprite();\n\n for (const renderer of renderers) {\n const rendered = renderer({ className, icon });\n\n if (rendered !== null && rendered !== undefined && rendered !== false) {\n return rendered;\n }\n }\n\n // When the sprite is wired and the icon is genuinely absent, show a visible\n // marker. When `ids` is unknown (not yet wired), optimistically emit the\n // sprite reference rather than crying wolf.\n if (ids && !ids.includes(icon)) {\n logMissingIcon(icon);\n return <MissingIcon className={className} />;\n }\n\n return <Icon className={className} name={icon} />;\n}\n\nfunction MissingIcon({ className }: { className?: string }) {\n return (\n <svg\n aria-hidden=\"true\"\n className={cn(\"size-lt-icon-md text-lt-muted-fg\", className)}\n data-lattice-missing-icon=\"\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n}\n\nfunction logMissingIcon(icon: string): void {\n if (!import.meta.env.DEV || loggedMissingIcons.has(icon)) {\n return;\n }\n\n loggedMissingIcons.add(icon);\n console.log(`[Lattice] Missing icon renderer for \"${icon}\".`);\n}\n"],"mappings":";;;;;AAkBA,IAAM,uBAAuB,cAAsC,CAAC,CAAC;AAGrE,SAAgB,qBAAqB,EACnC,UACA,OAAO,SACP,YAC4B;CAC5B,MAAM,kBAAkB,WAAW,oBAAoB;CACvD,MAAM,YAAY,cACT,SAAS,YAAY,CAAC,QAAQ,IAAI,CAAC,UAAU,GAAG,eAAe,GACtE;EAAC;EAAM;EAAiB;CAAQ,CAClC;CAEA,OACE,oBAAC,qBAAqB,UAAtB;EAA+B,OAAO;EAAY;CAAwC,CAAA;AAE9F;AAEA,SAAgB,aAAa,EAAE,WAAW,QAA2B;CACnE,MAAM,YAAY,WAAW,oBAAoB;CACjD,MAAM,EAAE,QAAQ,UAAU;CAE1B,KAAK,MAAM,YAAY,WAAW;EAChC,MAAM,WAAW,SAAS;GAAE;GAAW;EAAK,CAAC;EAE7C,IAAI,aAAa,QAAQ,aAAa,KAAA,KAAa,aAAa,OAC9D,OAAO;CAEX;CAKA,IAAI,OAAO,CAAC,IAAI,SAAS,IAAI,GAE3B,OAAO,oBAAC,aAAD,EAAwB,UAAY,CAAA;CAG7C,OAAO,oBAAC,MAAD;EAAiB;EAAW,MAAM;CAAO,CAAA;AAClD;AAEA,SAAS,YAAY,EAAE,aAAqC;CAC1D,OACE,qBAAC,OAAD;EACE,eAAY;EACZ,WAAW,GAAG,oCAAoC,SAAS;EAC3D,6BAA0B;EAC1B,MAAK;EACL,QAAO;EACP,eAAc;EACd,gBAAe;EACf,aAAY;EACZ,SAAQ;EATV,UAAA;GAWE,oBAAC,UAAD;IAAQ,IAAG;IAAK,IAAG;IAAK,GAAE;GAAM,CAAA;GAChC,oBAAC,QAAD,EAAM,GAAE,uCAAwC,CAAA;GAChD,oBAAC,QAAD,EAAM,GAAE,aAAc,CAAA;EACnB;;AAET"}
1
+ {"version":3,"file":"icon-renderer.js","names":[],"sources":["../../resources/js/icons/icon-renderer.tsx"],"sourcesContent":["import { createContext, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { Icon, useSprite } from \"./sprite\";\n\nexport type IconRendererProps = {\n className?: string;\n icon: string;\n};\n\nexport type IconRendererFunction = (props: IconRendererProps) => ReactNode;\n\ntype IconRendererProviderProps = {\n children: ReactNode;\n renderer: IconRendererFunction;\n};\n\nconst IconRenderersContext = createContext<IconRendererFunction[]>([]);\nconst loggedMissingIcons = new Set<string>();\n\nexport function IconRendererProvider({ children, renderer }: IconRendererProviderProps) {\n const parentRenderers = useContext(IconRenderersContext);\n const renderers = useMemo(() => [renderer, ...parentRenderers], [parentRenderers, renderer]);\n\n return (\n <IconRenderersContext.Provider value={renderers}>{children}</IconRenderersContext.Provider>\n );\n}\n\nexport function IconRenderer({ className, icon }: IconRendererProps) {\n const renderers = useContext(IconRenderersContext);\n const { ids } = useSprite();\n\n for (const renderer of renderers) {\n const rendered = renderer({ className, icon });\n\n if (rendered !== null && rendered !== undefined && rendered !== false) {\n return rendered;\n }\n }\n\n // When the sprite is wired and the icon is genuinely absent, show a visible\n // marker. When `ids` is unknown (not yet wired), optimistically emit the\n // sprite reference rather than crying wolf.\n if (ids && !ids.includes(icon)) {\n logMissingIcon(icon);\n return <MissingIcon className={className} />;\n }\n\n return <Icon className={className} name={icon} />;\n}\n\nfunction MissingIcon({ className }: { className?: string }) {\n return (\n <svg\n aria-hidden=\"true\"\n className={cn(\"size-lt-icon-md text-lt-muted-fg\", className)}\n data-lattice-missing-icon=\"\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n viewBox=\"0 0 24 24\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\" />\n <path d=\"M12 17h.01\" />\n </svg>\n );\n}\n\nfunction logMissingIcon(icon: string): void {\n if (!import.meta.env.DEV || loggedMissingIcons.has(icon)) {\n return;\n }\n\n loggedMissingIcons.add(icon);\n console.log(`[Lattice] Missing icon renderer for \"${icon}\".`);\n}\n"],"mappings":";;;;;AAiBA,IAAM,uBAAuB,cAAsC,CAAC,CAAC;AAGrE,SAAgB,qBAAqB,EAAE,UAAU,YAAuC;CACtF,MAAM,kBAAkB,WAAW,oBAAoB;CACvD,MAAM,YAAY,cAAc,CAAC,UAAU,GAAG,eAAe,GAAG,CAAC,iBAAiB,QAAQ,CAAC;CAE3F,OACE,oBAAC,qBAAqB,UAAtB;EAA+B,OAAO;EAAY;CAAwC,CAAA;AAE9F;AAEA,SAAgB,aAAa,EAAE,WAAW,QAA2B;CACnE,MAAM,YAAY,WAAW,oBAAoB;CACjD,MAAM,EAAE,QAAQ,UAAU;CAE1B,KAAK,MAAM,YAAY,WAAW;EAChC,MAAM,WAAW,SAAS;GAAE;GAAW;EAAK,CAAC;EAE7C,IAAI,aAAa,QAAQ,aAAa,KAAA,KAAa,aAAa,OAC9D,OAAO;CAEX;CAKA,IAAI,OAAO,CAAC,IAAI,SAAS,IAAI,GAE3B,OAAO,oBAAC,aAAD,EAAwB,UAAY,CAAA;CAG7C,OAAO,oBAAC,MAAD;EAAiB;EAAW,MAAM;CAAO,CAAA;AAClD;AAEA,SAAS,YAAY,EAAE,aAAqC;CAC1D,OACE,qBAAC,OAAD;EACE,eAAY;EACZ,WAAW,GAAG,oCAAoC,SAAS;EAC3D,6BAA0B;EAC1B,MAAK;EACL,QAAO;EACP,eAAc;EACd,gBAAe;EACf,aAAY;EACZ,SAAQ;EATV,UAAA;GAWE,oBAAC,UAAD;IAAQ,IAAG;IAAK,IAAG;IAAK,GAAE;GAAM,CAAA;GAChC,oBAAC,QAAD,EAAM,GAAE,uCAAwC,CAAA;GAChD,oBAAC,QAAD,EAAM,GAAE,aAAc,CAAA;EACnB;;AAET"}
package/dist/lattice.css CHANGED
@@ -357,6 +357,95 @@
357
357
  z-index: var(--lt-z-toast);
358
358
  }
359
359
 
360
+ /*
361
+ * Responsive grid templates and spans driven by CSS variables the Grid
362
+ * component sets inline (mobile-first fallback chains, so only the breakpoints
363
+ * a grid declares need a variable). Variables instead of generated utility
364
+ * classes so arbitrary column counts and track lists survive Tailwind's static
365
+ * class scanning and the prebuilt standalone bundle.
366
+ */
367
+ @utility lt-grid {
368
+ grid-template-columns: var(--lt-grid-cols-default, none);
369
+
370
+ & > [data-slot="grid-item"] {
371
+ grid-column: var(--lt-col-span-default, auto);
372
+ min-width: 0;
373
+ }
374
+
375
+ /* A child renderer that returns null (e.g. a condition-hidden field) must
376
+ not leave an empty cell behind. */
377
+ & > [data-slot="grid-item"]:empty {
378
+ display: none;
379
+ }
380
+
381
+ @media (width >= theme(--breakpoint-sm)) {
382
+ grid-template-columns: var(--lt-grid-cols-sm, var(--lt-grid-cols-default, none));
383
+
384
+ & > [data-slot="grid-item"] {
385
+ grid-column: var(--lt-col-span-sm, var(--lt-col-span-default, auto));
386
+ }
387
+ }
388
+
389
+ @media (width >= theme(--breakpoint-md)) {
390
+ grid-template-columns: var(
391
+ --lt-grid-cols-md,
392
+ var(--lt-grid-cols-sm, var(--lt-grid-cols-default, none))
393
+ );
394
+
395
+ & > [data-slot="grid-item"] {
396
+ grid-column: var(--lt-col-span-md, var(--lt-col-span-sm, var(--lt-col-span-default, auto)));
397
+ }
398
+ }
399
+
400
+ @media (width >= theme(--breakpoint-lg)) {
401
+ grid-template-columns: var(
402
+ --lt-grid-cols-lg,
403
+ var(--lt-grid-cols-md, var(--lt-grid-cols-sm, var(--lt-grid-cols-default, none)))
404
+ );
405
+
406
+ & > [data-slot="grid-item"] {
407
+ grid-column: var(
408
+ --lt-col-span-lg,
409
+ var(--lt-col-span-md, var(--lt-col-span-sm, var(--lt-col-span-default, auto)))
410
+ );
411
+ }
412
+ }
413
+
414
+ @media (width >= theme(--breakpoint-xl)) {
415
+ grid-template-columns: var(
416
+ --lt-grid-cols-xl,
417
+ var(--lt-grid-cols-lg, var(--lt-grid-cols-md, var(--lt-grid-cols-sm, var(--lt-grid-cols-default, none))))
418
+ );
419
+
420
+ & > [data-slot="grid-item"] {
421
+ grid-column: var(
422
+ --lt-col-span-xl,
423
+ var(--lt-col-span-lg, var(--lt-col-span-md, var(--lt-col-span-sm, var(--lt-col-span-default, auto))))
424
+ );
425
+ }
426
+ }
427
+
428
+ @media (width >= theme(--breakpoint-2xl)) {
429
+ grid-template-columns: var(
430
+ --lt-grid-cols-2xl,
431
+ var(
432
+ --lt-grid-cols-xl,
433
+ var(--lt-grid-cols-lg, var(--lt-grid-cols-md, var(--lt-grid-cols-sm, var(--lt-grid-cols-default, none))))
434
+ )
435
+ );
436
+
437
+ & > [data-slot="grid-item"] {
438
+ grid-column: var(
439
+ --lt-col-span-2xl,
440
+ var(
441
+ --lt-col-span-xl,
442
+ var(--lt-col-span-lg, var(--lt-col-span-md, var(--lt-col-span-sm, var(--lt-col-span-default, auto))))
443
+ )
444
+ );
445
+ }
446
+ }
447
+ }
448
+
360
449
  @keyframes lt-toast-in {
361
450
  from {
362
451
  opacity: 0;
@@ -0,0 +1,5 @@
1
+ export type Listeners = {
2
+ subscribe: (callback: () => void) => () => void;
3
+ notify: () => void;
4
+ };
5
+ export declare function createListeners(): Listeners;
@@ -0,0 +1,19 @@
1
+ //#region resources/js/lib/listeners.ts
2
+ function createListeners() {
3
+ const listeners = /* @__PURE__ */ new Set();
4
+ return {
5
+ subscribe(callback) {
6
+ listeners.add(callback);
7
+ return () => {
8
+ listeners.delete(callback);
9
+ };
10
+ },
11
+ notify() {
12
+ listeners.forEach((listener) => listener());
13
+ }
14
+ };
15
+ }
16
+ //#endregion
17
+ export { createListeners };
18
+
19
+ //# sourceMappingURL=listeners.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listeners.js","names":[],"sources":["../../resources/js/lib/listeners.ts"],"sourcesContent":["export type Listeners = {\n subscribe: (callback: () => void) => () => void;\n notify: () => void;\n};\n\nexport function createListeners(): Listeners {\n const listeners = new Set<() => void>();\n\n return {\n subscribe(callback) {\n listeners.add(callback);\n\n return () => {\n listeners.delete(callback);\n };\n },\n notify() {\n listeners.forEach((listener) => listener());\n },\n };\n}\n"],"mappings":";AAKA,SAAgB,kBAA6B;CAC3C,MAAM,4BAAY,IAAI,IAAgB;CAEtC,OAAO;EACL,UAAU,UAAU;GAClB,UAAU,IAAI,QAAQ;GAEtB,aAAa;IACX,UAAU,OAAO,QAAQ;GAC3B;EACF;EACA,SAAS;GACP,UAAU,SAAS,aAAa,SAAS,CAAC;EAC5C;CACF;AACF"}