@lattice-php/lattice 0.4.0 → 0.6.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 (122) hide show
  1. package/dist/action/components/action-form.js +3 -3
  2. package/dist/action/components/action-group.js +1 -1
  3. package/dist/action/components/action.js +10 -16
  4. package/dist/action/components/action.js.map +1 -1
  5. package/dist/action/run-action.d.ts +9 -0
  6. package/dist/action/run-action.js +22 -0
  7. package/dist/action/run-action.js.map +1 -0
  8. package/dist/chat/components/chat-box.js +31 -14
  9. package/dist/chat/components/chat-box.js.map +1 -1
  10. package/dist/chat/components/message.js +1 -1
  11. package/dist/chat/components/prompt-input.js +1 -1
  12. package/dist/chat/index.js +2 -0
  13. package/dist/chat/index.js.map +1 -1
  14. package/dist/core/components/badge.js +1 -1
  15. package/dist/core/components/button.js +17 -5
  16. package/dist/core/components/button.js.map +1 -1
  17. package/dist/core/components/card.js +2 -1
  18. package/dist/core/components/card.js.map +1 -1
  19. package/dist/core/components/chart.js +4 -1
  20. package/dist/core/components/chart.js.map +1 -1
  21. package/dist/core/components/dialog.js +1 -1
  22. package/dist/core/components/floating-panel.js +3 -2
  23. package/dist/core/components/floating-panel.js.map +1 -1
  24. package/dist/core/components/fragment.js +3 -6
  25. package/dist/core/components/fragment.js.map +1 -1
  26. package/dist/core/components/grid.js +2 -1
  27. package/dist/core/components/grid.js.map +1 -1
  28. package/dist/core/components/index.js +0 -2
  29. package/dist/core/components/index.js.map +1 -1
  30. package/dist/core/components/section.js +5 -9
  31. package/dist/core/components/section.js.map +1 -1
  32. package/dist/core/components/stack.js +2 -1
  33. package/dist/core/components/stack.js.map +1 -1
  34. package/dist/core/components/tabs.js +1 -1
  35. package/dist/core/nodes.d.ts +6 -0
  36. package/dist/core/nodes.js +13 -0
  37. package/dist/core/nodes.js.map +1 -0
  38. package/dist/core/renderer.js +1 -1
  39. package/dist/create-app.d.ts +21 -0
  40. package/dist/create-app.js +31 -0
  41. package/dist/create-app.js.map +1 -0
  42. package/dist/effects/registry.js +2 -1
  43. package/dist/effects/registry.js.map +1 -1
  44. package/dist/effects/use-effect-dispatcher.js +1 -1
  45. package/dist/effects/use-flash-effects.js +1 -1
  46. package/dist/events/event-names.d.ts +4 -2
  47. package/dist/events/event-names.js +4 -2
  48. package/dist/events/event-names.js.map +1 -1
  49. package/dist/form/components/base/input-otp.d.ts +7 -0
  50. package/dist/form/components/base/input-otp.js +30 -0
  51. package/dist/form/components/base/input-otp.js.map +1 -0
  52. package/dist/form/components/conditions.js +1 -1
  53. package/dist/form/components/conditions.js.map +1 -1
  54. package/dist/form/components/fields/file-upload.js +1 -1
  55. package/dist/form/components/fields/otp-input.d.ts +2 -0
  56. package/dist/form/components/fields/otp-input.js +25 -0
  57. package/dist/form/components/fields/otp-input.js.map +1 -0
  58. package/dist/form/components/fields/row-item.js +1 -1
  59. package/dist/form/components/fields/table-rows.js +1 -1
  60. package/dist/form/components/form.js +1 -1
  61. package/dist/form/components/index.d.ts +1 -0
  62. package/dist/form/components/index.js +2 -1
  63. package/dist/form/components/prefill-targets.d.ts +0 -1
  64. package/dist/form/components/prefill-targets.js +1 -4
  65. package/dist/form/components/prefill-targets.js.map +1 -1
  66. package/dist/form/components/use-form-resolver.js +2 -2
  67. package/dist/form/components/use-form-resolver.js.map +1 -1
  68. package/dist/form/index.js +1 -0
  69. package/dist/form/index.js.map +1 -1
  70. package/dist/i18n/config.d.ts +3 -0
  71. package/dist/i18n/config.js +20 -4
  72. package/dist/i18n/config.js.map +1 -1
  73. package/dist/i18n/date-time.d.ts +7 -0
  74. package/dist/i18n/date-time.js +33 -0
  75. package/dist/i18n/date-time.js.map +1 -0
  76. package/dist/i18n/index.d.ts +4 -0
  77. package/dist/i18n/index.js +3 -1
  78. package/dist/i18n/locale-reload.js +1 -1
  79. package/dist/i18n/page-props.js +1 -1
  80. package/dist/i18n/page-props.js.map +1 -1
  81. package/dist/i18n/timezone.d.ts +7 -0
  82. package/dist/i18n/timezone.js +53 -0
  83. package/dist/i18n/timezone.js.map +1 -0
  84. package/dist/index.d.ts +1 -0
  85. package/dist/index.js +14 -13
  86. package/dist/layout/breadcrumbs.js +3 -2
  87. package/dist/layout/breadcrumbs.js.map +1 -1
  88. package/dist/layout/callouts.js +1 -1
  89. package/dist/layout/components.js +1 -1
  90. package/dist/layout/menu-item.js +2 -2
  91. package/dist/layout/menu.js +2 -1
  92. package/dist/layout/menu.js.map +1 -1
  93. package/dist/layout/popover.js +1 -1
  94. package/dist/layout/sidebar.js +69 -29
  95. package/dist/layout/sidebar.js.map +1 -1
  96. package/dist/layout/topbar.js +2 -1
  97. package/dist/layout/topbar.js.map +1 -1
  98. package/dist/registry.js +1 -1
  99. package/dist/remote/components/data-list.js +1 -1
  100. package/dist/remote/index.js +1 -5
  101. package/dist/remote/index.js.map +1 -1
  102. package/dist/table/components/bulk-bar.js +10 -15
  103. package/dist/table/components/bulk-bar.js.map +1 -1
  104. package/dist/table/components/cells/text-cell.js +46 -4
  105. package/dist/table/components/cells/text-cell.js.map +1 -1
  106. package/dist/table/components/table.js +1 -1
  107. package/dist/table/filter-values.d.ts +5 -0
  108. package/dist/table/filter-values.js +10 -3
  109. package/dist/table/filter-values.js.map +1 -1
  110. package/dist/table/format.d.ts +11 -1
  111. package/dist/table/format.js +23 -21
  112. package/dist/table/format.js.map +1 -1
  113. package/dist/table/query.js +5 -4
  114. package/dist/table/query.js.map +1 -1
  115. package/dist/toast/toaster.js +2 -2
  116. package/dist/types/generated.d.ts +51 -24
  117. package/dist/vite.js +32 -1
  118. package/dist/vite.js.map +1 -1
  119. package/package.json +14 -3
  120. package/dist/remote/components/chat-box.d.ts +0 -3
  121. package/dist/remote/components/chat-box.js +0 -65
  122. package/dist/remote/components/chat-box.js.map +0 -1
@@ -1,11 +1,11 @@
1
+ import { Renderer } from "../../core/renderer.js";
2
+ import { useT } from "../../i18n/instance.js";
3
+ import { dispatchActionError } from "../../effects/dispatch.js";
1
4
  import { Button } from "../../core/components/button.js";
2
5
  import { Dialog, DialogContent, DialogHeader } from "../../core/components/dialog.js";
3
- import { useT } from "../../i18n/instance.js";
4
6
  import { Spinner } from "../../core/components/spinner.js";
5
- import { dispatchActionError } from "../../effects/dispatch.js";
6
7
  import { apiFetch } from "../../core/api.js";
7
8
  import { Skeleton } from "../../core/components/skeleton.js";
8
- import { Renderer } from "../../core/renderer.js";
9
9
  import { FormProvider } from "../../form/components/context.js";
10
10
  import { walkFields } from "../../form/components/field-props.js";
11
11
  import "../../form/components/form-transport.js";
@@ -1,7 +1,7 @@
1
1
  import { cn } from "../../lib/utils.js";
2
+ import { Icon } from "../../icons/sprite.js";
2
3
  import { nodeIdentity } from "../../core/test-id.js";
3
4
  import { Button } from "../../core/components/button.js";
4
- import { Icon } from "../../icons/sprite.js";
5
5
  import { ActionMenuProvider } from "./action-menu-context.js";
6
6
  import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "../../core/components/dropdown-menu.js";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,15 +1,16 @@
1
1
  import { withHeaders } from "../../core/headers.js";
2
+ import { IconRenderer } from "../../icons/icon-renderer.js";
2
3
  import { prefixedTestId } from "../../core/test-id.js";
4
+ import { getActionEffects } from "../../effects/dispatch.js";
5
+ import { useEffectDispatcher } from "../../effects/use-effect-dispatcher.js";
3
6
  import { Button } from "../../core/components/button.js";
4
- import { IconRenderer } from "../../icons/icon-renderer.js";
5
7
  import { Spinner } from "../../core/components/spinner.js";
6
8
  import { ConfirmDialog } from "../../core/components/confirm-dialog.js";
7
- import { dispatchActionError, getActionEffects } from "../../effects/dispatch.js";
8
- import { useEffectDispatcher } from "../../effects/use-effect-dispatcher.js";
9
+ import { runAction } from "../run-action.js";
9
10
  import { ActionForm, useLazyActionForm } from "./action-form.js";
10
11
  import { actionMenuItemClassName, useActionMenu } from "./action-menu-context.js";
11
- import { useState } from "react";
12
12
  import { router, useHttp } from "@inertiajs/react";
13
+ import { useState } from "react";
13
14
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
14
15
  //#region resources/js/action/components/action.tsx
15
16
  var ActionComponent = ({ node }) => {
@@ -32,18 +33,12 @@ var ActionComponent = ({ node }) => {
32
33
  const formNode = lazyForm ? lazyNode : inlineForm;
33
34
  const submit = async () => {
34
35
  if (!endpoint) return;
35
- try {
36
- if (method === "get") {
37
- router.visit(endpoint, { headers: withHeaders(componentRef) });
38
- setIsConfirming(false);
39
- return;
40
- }
41
- const responseEffects = getActionEffects((await http[method](endpoint, { headers: withHeaders(componentRef) })).effects);
42
- dispatch(responseEffects.length > 0 ? responseEffects : getActionEffects(node.props.effects));
36
+ if (method === "get") {
37
+ router.visit(endpoint, { headers: withHeaders(componentRef) });
43
38
  setIsConfirming(false);
44
- } catch (error) {
45
- dispatchActionError(error);
39
+ return;
46
40
  }
41
+ if (await runAction(() => http[method](endpoint, { headers: withHeaders(componentRef) }), dispatch)) setIsConfirming(false);
47
42
  };
48
43
  const requestSubmit = () => {
49
44
  if (hasForm) {
@@ -94,8 +89,7 @@ var ActionComponent = ({ node }) => {
94
89
  method,
95
90
  onClose: () => setIsFilling(false),
96
91
  onSuccess: (response) => {
97
- const responseEffects = getActionEffects(response.effects);
98
- dispatch(responseEffects.length > 0 ? responseEffects : getActionEffects(node.props.effects));
92
+ dispatch(getActionEffects(response.effects));
99
93
  setIsFilling(false);
100
94
  },
101
95
  submitLabel: confirmationConfirmLabel,
@@ -1 +1 @@
1
- {"version":3,"file":"action.js","names":[],"sources":["../../../resources/js/action/components/action.tsx"],"sourcesContent":["import { router, useHttp } from \"@inertiajs/react\";\nimport type { Method } from \"@inertiajs/core\";\nimport { useState } from \"react\";\nimport { withHeaders } from \"@lattice-php/lattice/core/headers\";\nimport { Button } from \"@lattice-php/lattice/core/components/button\";\nimport { ConfirmDialog } from \"@lattice-php/lattice/core/components/confirm-dialog\";\nimport { Spinner } from \"@lattice-php/lattice/core/components/spinner\";\nimport { prefixedTestId } from \"@lattice-php/lattice/core/test-id\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { IconRenderer } from \"@lattice-php/lattice/icons\";\nimport { dispatchActionError, getActionEffects } from \"@lattice-php/lattice/effects/dispatch\";\nimport type { ActionResponse } from \"@lattice-php/lattice/effects/dispatch\";\nimport { useEffectDispatcher } from \"@lattice-php/lattice/effects/use-effect-dispatcher\";\nimport { ActionForm, useLazyActionForm } from \"./action-form\";\nimport { actionMenuItemClassName, useActionMenu } from \"./action-menu-context\";\n\nconst ActionComponent: RendererComponent<\"action\"> = ({ node }) => {\n const endpoint = node.props.endpoint ?? \"\";\n const icon = node.props.icon;\n const label = node.props.label ?? \"Run action\";\n const componentRef = node.props.ref ?? \"\";\n const method: Method = node.props.method ?? \"post\";\n const http = useHttp<Record<string, never>, ActionResponse>({});\n const dispatch = useEffectDispatcher();\n const [isConfirming, setIsConfirming] = useState(false);\n const [isFilling, setIsFilling] = useState(false);\n const isMenuItem = useActionMenu();\n const confirmation = node.props.confirmation;\n const variant = node.props.variant ?? \"default\";\n const inlineForm = node.props.form;\n const lazyForm = node.props.lazyForm === true;\n const hasForm = Boolean(inlineForm) || lazyForm;\n const lazyNode = useLazyActionForm(endpoint, componentRef, isFilling && lazyForm);\n const formNode = lazyForm ? lazyNode : inlineForm;\n\n const submit = async (): Promise<void> => {\n if (!endpoint) {\n return;\n }\n\n try {\n if (method === \"get\") {\n router.visit(endpoint, { headers: withHeaders(componentRef) });\n setIsConfirming(false);\n\n return;\n }\n\n const response = await http[method](endpoint, { headers: withHeaders(componentRef) });\n const responseEffects = getActionEffects(response.effects);\n\n dispatch(responseEffects.length > 0 ? responseEffects : getActionEffects(node.props.effects));\n setIsConfirming(false);\n } catch (error) {\n dispatchActionError(error);\n }\n };\n\n const requestSubmit = (): void => {\n if (hasForm) {\n setIsFilling(true);\n\n return;\n }\n\n if (confirmation) {\n setIsConfirming(true);\n\n return;\n }\n\n void submit();\n };\n\n const confirmationTitle = confirmation?.title ?? label;\n const confirmationConfirmLabel = confirmation?.confirmLabel ?? label;\n const confirmationCancelLabel = confirmation?.cancelLabel ?? \"Cancel\";\n const testId = node.key ?? prefixedTestId(\"action\", node.id);\n\n return (\n <>\n <Button\n className={isMenuItem ? actionMenuItemClassName : undefined}\n data-lattice-component={node.id}\n data-test={testId}\n disabled={http.processing || !endpoint}\n onClick={requestSubmit}\n type=\"button\"\n variant={isMenuItem ? \"ghost\" : variant}\n >\n {http.processing ? (\n <Spinner className={isMenuItem ? \"size-lt-icon-sm\" : undefined} />\n ) : (\n icon && (\n <IconRenderer\n className={isMenuItem ? \"size-lt-icon-sm\" : \"size-lt-icon-md\"}\n icon={icon}\n />\n )\n )}\n {label}\n </Button>\n\n {isConfirming && confirmation && (\n <ConfirmDialog\n title={confirmationTitle}\n description={confirmation.description ?? undefined}\n confirmLabel={confirmationConfirmLabel}\n cancelLabel={confirmationCancelLabel}\n confirmVariant={variant}\n processing={http.processing}\n confirmDisabled={!endpoint}\n onConfirm={() => void submit()}\n onCancel={() => setIsConfirming(false)}\n />\n )}\n\n {isFilling && hasForm && (\n <ActionForm\n cancelLabel={confirmationCancelLabel}\n componentRef={componentRef}\n description={confirmation?.description ?? undefined}\n endpoint={endpoint}\n formNode={formNode}\n method={method}\n onClose={() => setIsFilling(false)}\n onSuccess={(response) => {\n const responseEffects = getActionEffects(response.effects);\n\n dispatch(\n responseEffects.length > 0 ? responseEffects : getActionEffects(node.props.effects),\n );\n setIsFilling(false);\n }}\n submitLabel={confirmationConfirmLabel}\n title={confirmationTitle}\n />\n )}\n </>\n );\n};\n\nexport default ActionComponent;\n"],"mappings":";;;;;;;;;;;;;;AAgBA,IAAM,mBAAgD,EAAE,WAAW;CACjE,MAAM,WAAW,KAAK,MAAM,YAAY;CACxC,MAAM,OAAO,KAAK,MAAM;CACxB,MAAM,QAAQ,KAAK,MAAM,SAAS;CAClC,MAAM,eAAe,KAAK,MAAM,OAAO;CACvC,MAAM,SAAiB,KAAK,MAAM,UAAU;CAC5C,MAAM,OAAO,QAA+C,CAAC,CAAC;CAC9D,MAAM,WAAW,oBAAoB;CACrC,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,aAAa,cAAc;CACjC,MAAM,eAAe,KAAK,MAAM;CAChC,MAAM,UAAU,KAAK,MAAM,WAAW;CACtC,MAAM,aAAa,KAAK,MAAM;CAC9B,MAAM,WAAW,KAAK,MAAM,aAAa;CACzC,MAAM,UAAU,QAAQ,UAAU,KAAK;CACvC,MAAM,WAAW,kBAAkB,UAAU,cAAc,aAAa,QAAQ;CAChF,MAAM,WAAW,WAAW,WAAW;CAEvC,MAAM,SAAS,YAA2B;EACxC,IAAI,CAAC,UACH;EAGF,IAAI;GACF,IAAI,WAAW,OAAO;IACpB,OAAO,MAAM,UAAU,EAAE,SAAS,YAAY,YAAY,EAAE,CAAC;IAC7D,gBAAgB,KAAK;IAErB;GACF;GAGA,MAAM,kBAAkB,kBAAiB,MADlB,KAAK,QAAQ,UAAU,EAAE,SAAS,YAAY,YAAY,EAAE,CAAC,GAClC,OAAO;GAEzD,SAAS,gBAAgB,SAAS,IAAI,kBAAkB,iBAAiB,KAAK,MAAM,OAAO,CAAC;GAC5F,gBAAgB,KAAK;EACvB,SAAS,OAAO;GACd,oBAAoB,KAAK;EAC3B;CACF;CAEA,MAAM,sBAA4B;EAChC,IAAI,SAAS;GACX,aAAa,IAAI;GAEjB;EACF;EAEA,IAAI,cAAc;GAChB,gBAAgB,IAAI;GAEpB;EACF;EAEA,OAAY;CACd;CAEA,MAAM,oBAAoB,cAAc,SAAS;CACjD,MAAM,2BAA2B,cAAc,gBAAgB;CAC/D,MAAM,0BAA0B,cAAc,eAAe;CAC7D,MAAM,SAAS,KAAK,OAAO,eAAe,UAAU,KAAK,EAAE;CAE3D,OACE,qBAAA,YAAA,EAAA,UAAA;EACE,qBAAC,QAAD;GACE,WAAW,aAAa,0BAA0B,KAAA;GAClD,0BAAwB,KAAK;GAC7B,aAAW;GACX,UAAU,KAAK,cAAc,CAAC;GAC9B,SAAS;GACT,MAAK;GACL,SAAS,aAAa,UAAU;aAPlC,CASG,KAAK,aACJ,oBAAC,SAAD,EAAS,WAAW,aAAa,oBAAoB,KAAA,EAAY,CAAA,IAEjE,QACE,oBAAC,cAAD;IACE,WAAW,aAAa,oBAAoB;IACtC;GACP,CAAA,GAGJ,KACK;;EAEP,gBAAgB,gBACf,oBAAC,eAAD;GACE,OAAO;GACP,aAAa,aAAa,eAAe,KAAA;GACzC,cAAc;GACd,aAAa;GACb,gBAAgB;GAChB,YAAY,KAAK;GACjB,iBAAiB,CAAC;GAClB,iBAAiB,KAAK,OAAO;GAC7B,gBAAgB,gBAAgB,KAAK;EACtC,CAAA;EAGF,aAAa,WACZ,oBAAC,YAAD;GACE,aAAa;GACC;GACd,aAAa,cAAc,eAAe,KAAA;GAChC;GACA;GACF;GACR,eAAe,aAAa,KAAK;GACjC,YAAY,aAAa;IACvB,MAAM,kBAAkB,iBAAiB,SAAS,OAAO;IAEzD,SACE,gBAAgB,SAAS,IAAI,kBAAkB,iBAAiB,KAAK,MAAM,OAAO,CACpF;IACA,aAAa,KAAK;GACpB;GACA,aAAa;GACb,OAAO;EACR,CAAA;CAEH,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"action.js","names":[],"sources":["../../../resources/js/action/components/action.tsx"],"sourcesContent":["import { router, useHttp } from \"@inertiajs/react\";\nimport type { Method } from \"@inertiajs/core\";\nimport { useState } from \"react\";\nimport { withHeaders } from \"@lattice-php/lattice/core/headers\";\nimport { Button } from \"@lattice-php/lattice/core/components/button\";\nimport { ConfirmDialog } from \"@lattice-php/lattice/core/components/confirm-dialog\";\nimport { Spinner } from \"@lattice-php/lattice/core/components/spinner\";\nimport { prefixedTestId } from \"@lattice-php/lattice/core/test-id\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { IconRenderer } from \"@lattice-php/lattice/icons\";\nimport { getActionEffects } from \"@lattice-php/lattice/effects/dispatch\";\nimport type { ActionResponse } from \"@lattice-php/lattice/effects/dispatch\";\nimport { useEffectDispatcher } from \"@lattice-php/lattice/effects/use-effect-dispatcher\";\nimport { runAction } from \"../run-action\";\nimport { ActionForm, useLazyActionForm } from \"./action-form\";\nimport { actionMenuItemClassName, useActionMenu } from \"./action-menu-context\";\n\nconst ActionComponent: RendererComponent<\"action\"> = ({ node }) => {\n const endpoint = node.props.endpoint ?? \"\";\n const icon = node.props.icon;\n const label = node.props.label ?? \"Run action\";\n const componentRef = node.props.ref ?? \"\";\n const method: Method = node.props.method ?? \"post\";\n const http = useHttp<Record<string, never>, ActionResponse>({});\n const dispatch = useEffectDispatcher();\n const [isConfirming, setIsConfirming] = useState(false);\n const [isFilling, setIsFilling] = useState(false);\n const isMenuItem = useActionMenu();\n const confirmation = node.props.confirmation;\n const variant = node.props.variant ?? \"default\";\n const inlineForm = node.props.form;\n const lazyForm = node.props.lazyForm === true;\n const hasForm = Boolean(inlineForm) || lazyForm;\n const lazyNode = useLazyActionForm(endpoint, componentRef, isFilling && lazyForm);\n const formNode = lazyForm ? lazyNode : inlineForm;\n\n const submit = async (): Promise<void> => {\n if (!endpoint) {\n return;\n }\n\n if (method === \"get\") {\n router.visit(endpoint, { headers: withHeaders(componentRef) });\n setIsConfirming(false);\n\n return;\n }\n\n const ok = await runAction(\n () => http[method](endpoint, { headers: withHeaders(componentRef) }),\n dispatch,\n );\n\n if (ok) {\n setIsConfirming(false);\n }\n };\n\n const requestSubmit = (): void => {\n if (hasForm) {\n setIsFilling(true);\n\n return;\n }\n\n if (confirmation) {\n setIsConfirming(true);\n\n return;\n }\n\n void submit();\n };\n\n const confirmationTitle = confirmation?.title ?? label;\n const confirmationConfirmLabel = confirmation?.confirmLabel ?? label;\n const confirmationCancelLabel = confirmation?.cancelLabel ?? \"Cancel\";\n const testId = node.key ?? prefixedTestId(\"action\", node.id);\n\n return (\n <>\n <Button\n className={isMenuItem ? actionMenuItemClassName : undefined}\n data-lattice-component={node.id}\n data-test={testId}\n disabled={http.processing || !endpoint}\n onClick={requestSubmit}\n type=\"button\"\n variant={isMenuItem ? \"ghost\" : variant}\n >\n {http.processing ? (\n <Spinner className={isMenuItem ? \"size-lt-icon-sm\" : undefined} />\n ) : (\n icon && (\n <IconRenderer\n className={isMenuItem ? \"size-lt-icon-sm\" : \"size-lt-icon-md\"}\n icon={icon}\n />\n )\n )}\n {label}\n </Button>\n\n {isConfirming && confirmation && (\n <ConfirmDialog\n title={confirmationTitle}\n description={confirmation.description ?? undefined}\n confirmLabel={confirmationConfirmLabel}\n cancelLabel={confirmationCancelLabel}\n confirmVariant={variant}\n processing={http.processing}\n confirmDisabled={!endpoint}\n onConfirm={() => void submit()}\n onCancel={() => setIsConfirming(false)}\n />\n )}\n\n {isFilling && hasForm && (\n <ActionForm\n cancelLabel={confirmationCancelLabel}\n componentRef={componentRef}\n description={confirmation?.description ?? undefined}\n endpoint={endpoint}\n formNode={formNode}\n method={method}\n onClose={() => setIsFilling(false)}\n onSuccess={(response) => {\n dispatch(getActionEffects(response.effects));\n setIsFilling(false);\n }}\n submitLabel={confirmationConfirmLabel}\n title={confirmationTitle}\n />\n )}\n </>\n );\n};\n\nexport default ActionComponent;\n"],"mappings":";;;;;;;;;;;;;;;AAiBA,IAAM,mBAAgD,EAAE,WAAW;CACjE,MAAM,WAAW,KAAK,MAAM,YAAY;CACxC,MAAM,OAAO,KAAK,MAAM;CACxB,MAAM,QAAQ,KAAK,MAAM,SAAS;CAClC,MAAM,eAAe,KAAK,MAAM,OAAO;CACvC,MAAM,SAAiB,KAAK,MAAM,UAAU;CAC5C,MAAM,OAAO,QAA+C,CAAC,CAAC;CAC9D,MAAM,WAAW,oBAAoB;CACrC,MAAM,CAAC,cAAc,mBAAmB,SAAS,KAAK;CACtD,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;CAChD,MAAM,aAAa,cAAc;CACjC,MAAM,eAAe,KAAK,MAAM;CAChC,MAAM,UAAU,KAAK,MAAM,WAAW;CACtC,MAAM,aAAa,KAAK,MAAM;CAC9B,MAAM,WAAW,KAAK,MAAM,aAAa;CACzC,MAAM,UAAU,QAAQ,UAAU,KAAK;CACvC,MAAM,WAAW,kBAAkB,UAAU,cAAc,aAAa,QAAQ;CAChF,MAAM,WAAW,WAAW,WAAW;CAEvC,MAAM,SAAS,YAA2B;EACxC,IAAI,CAAC,UACH;EAGF,IAAI,WAAW,OAAO;GACpB,OAAO,MAAM,UAAU,EAAE,SAAS,YAAY,YAAY,EAAE,CAAC;GAC7D,gBAAgB,KAAK;GAErB;EACF;EAOA,IAAI,MALa,gBACT,KAAK,QAAQ,UAAU,EAAE,SAAS,YAAY,YAAY,EAAE,CAAC,GACnE,QACF,GAGE,gBAAgB,KAAK;CAEzB;CAEA,MAAM,sBAA4B;EAChC,IAAI,SAAS;GACX,aAAa,IAAI;GAEjB;EACF;EAEA,IAAI,cAAc;GAChB,gBAAgB,IAAI;GAEpB;EACF;EAEA,OAAY;CACd;CAEA,MAAM,oBAAoB,cAAc,SAAS;CACjD,MAAM,2BAA2B,cAAc,gBAAgB;CAC/D,MAAM,0BAA0B,cAAc,eAAe;CAC7D,MAAM,SAAS,KAAK,OAAO,eAAe,UAAU,KAAK,EAAE;CAE3D,OACE,qBAAA,YAAA,EAAA,UAAA;EACE,qBAAC,QAAD;GACE,WAAW,aAAa,0BAA0B,KAAA;GAClD,0BAAwB,KAAK;GAC7B,aAAW;GACX,UAAU,KAAK,cAAc,CAAC;GAC9B,SAAS;GACT,MAAK;GACL,SAAS,aAAa,UAAU;aAPlC,CASG,KAAK,aACJ,oBAAC,SAAD,EAAS,WAAW,aAAa,oBAAoB,KAAA,EAAY,CAAA,IAEjE,QACE,oBAAC,cAAD;IACE,WAAW,aAAa,oBAAoB;IACtC;GACP,CAAA,GAGJ,KACK;;EAEP,gBAAgB,gBACf,oBAAC,eAAD;GACE,OAAO;GACP,aAAa,aAAa,eAAe,KAAA;GACzC,cAAc;GACd,aAAa;GACb,gBAAgB;GAChB,YAAY,KAAK;GACjB,iBAAiB,CAAC;GAClB,iBAAiB,KAAK,OAAO;GAC7B,gBAAgB,gBAAgB,KAAK;EACtC,CAAA;EAGF,aAAa,WACZ,oBAAC,YAAD;GACE,aAAa;GACC;GACd,aAAa,cAAc,eAAe,KAAA;GAChC;GACA;GACF;GACR,eAAe,aAAa,KAAK;GACjC,YAAY,aAAa;IACvB,SAAS,iBAAiB,SAAS,OAAO,CAAC;IAC3C,aAAa,KAAK;GACpB;GACA,aAAa;GACb,OAAO;EACR,CAAA;CAEH,EAAA,CAAA;AAEN"}
@@ -0,0 +1,9 @@
1
+ import { ActionEffect, ActionResponse } from '../effects/dispatch';
2
+ /**
3
+ * Runs an action request and dispatches the effects from its response, routing
4
+ * any failure through dispatchActionError. Returns whether the request
5
+ * succeeded so callers run their own post-success cleanup (closing a dialog,
6
+ * reloading a table). Shared by the single action button and the bulk bar so
7
+ * the invocation contract stays in one place.
8
+ */
9
+ export declare function runAction(request: () => Promise<ActionResponse>, dispatch: (effects: ActionEffect[]) => void): Promise<boolean>;
@@ -0,0 +1,22 @@
1
+ import { dispatchActionError, getActionEffects } from "../effects/dispatch.js";
2
+ //#region resources/js/action/run-action.ts
3
+ /**
4
+ * Runs an action request and dispatches the effects from its response, routing
5
+ * any failure through dispatchActionError. Returns whether the request
6
+ * succeeded so callers run their own post-success cleanup (closing a dialog,
7
+ * reloading a table). Shared by the single action button and the bulk bar so
8
+ * the invocation contract stays in one place.
9
+ */
10
+ async function runAction(request, dispatch) {
11
+ try {
12
+ dispatch(getActionEffects((await request()).effects));
13
+ return true;
14
+ } catch (error) {
15
+ dispatchActionError(error);
16
+ return false;
17
+ }
18
+ }
19
+ //#endregion
20
+ export { runAction };
21
+
22
+ //# sourceMappingURL=run-action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-action.js","names":[],"sources":["../../resources/js/action/run-action.ts"],"sourcesContent":["import {\n type ActionEffect,\n type ActionResponse,\n dispatchActionError,\n getActionEffects,\n} from \"@lattice-php/lattice/effects/dispatch\";\n\n/**\n * Runs an action request and dispatches the effects from its response, routing\n * any failure through dispatchActionError. Returns whether the request\n * succeeded so callers run their own post-success cleanup (closing a dialog,\n * reloading a table). Shared by the single action button and the bulk bar so\n * the invocation contract stays in one place.\n */\nexport async function runAction(\n request: () => Promise<ActionResponse>,\n dispatch: (effects: ActionEffect[]) => void,\n): Promise<boolean> {\n try {\n const response = await request();\n dispatch(getActionEffects(response.effects));\n\n return true;\n } catch (error) {\n dispatchActionError(error);\n\n return false;\n }\n}\n"],"mappings":";;;;;;;;;AAcA,eAAsB,UACpB,SACA,UACkB;CAClB,IAAI;EAEF,SAAS,kBAAiB,MADH,QAAQ,GACI,OAAO,CAAC;EAE3C,OAAO;CACT,SAAS,OAAO;EACd,oBAAoB,KAAK;EAEzB,OAAO;CACT;AACF"}
@@ -1,48 +1,65 @@
1
1
  import { cn } from "../../lib/utils.js";
2
- import { testIdentity } from "../../core/test-id.js";
3
2
  import { useT } from "../../i18n/instance.js";
4
- import { apiFetch } from "../../core/api.js";
3
+ import { testIdentity } from "../../core/test-id.js";
4
+ import { apiFetch, remoteJson } from "../../core/api.js";
5
+ import { createRemoteNdjsonChatTransport, ndjsonChatTransport } from "../transport.js";
5
6
  import { useChat } from "../use-chat.js";
6
7
  import { MessageList } from "./message-list.js";
7
8
  import { PromptInput } from "./prompt-input.js";
8
- import { useCallback, useEffect, useRef } from "react";
9
+ import { useCallback, useEffect, useMemo, useRef } from "react";
9
10
  import { jsx, jsxs } from "react/jsx-runtime";
10
11
  //#region resources/js/chat/components/chat-box.tsx
11
12
  var ChatBox = ({ node }) => {
12
- const { streamEndpoint, historyEndpoint, placeholder, title, fill } = node.props;
13
+ const props = node.props;
13
14
  const { t } = useT("lattice");
14
- const { messages, status, sendMessage, setMessages } = useChat({ endpoint: streamEndpoint ?? "" });
15
+ const transport = useMemo(() => props.remote ? createRemoteNdjsonChatTransport(props.remote) : ndjsonChatTransport, [props.remote]);
16
+ const { messages, status, error, sendMessage, setMessages } = useChat({
17
+ endpoint: props.streamEndpoint ?? "",
18
+ transport
19
+ });
15
20
  const seededRef = useRef(false);
16
21
  const seedHistory = useCallback(async () => {
17
- if (seededRef.current || !historyEndpoint) return;
22
+ if (seededRef.current || !props.historyEndpoint) return;
18
23
  seededRef.current = true;
19
- const response = await apiFetch(historyEndpoint, { throwOnError: false });
24
+ if (props.remote) {
25
+ setMessages((await remoteJson(props.historyEndpoint, { remote: props.remote })).messages);
26
+ return;
27
+ }
28
+ const response = await apiFetch(props.historyEndpoint, { throwOnError: false });
20
29
  if (!response.ok) return;
21
30
  setMessages((await response.json()).messages);
22
- }, [historyEndpoint, setMessages]);
31
+ }, [
32
+ props.historyEndpoint,
33
+ props.remote,
34
+ setMessages
35
+ ]);
23
36
  useEffect(() => {
24
- seedHistory();
37
+ seedHistory().catch(() => {});
25
38
  }, [seedHistory]);
26
- const busy = status === "submitted" || status === "streaming";
39
+ const disabled = status === "submitted" || status === "streaming" || !props.streamEndpoint;
27
40
  return /* @__PURE__ */ jsxs("div", {
28
- className: cn("flex flex-col overflow-hidden border border-lt-border bg-lt-bg", fill ? "sticky top-0 h-full min-h-[28rem] w-full" : "h-[28rem] w-80 rounded-lt shadow-lt-lg"),
41
+ className: cn("flex flex-col overflow-hidden border border-lt-border bg-lt-bg", props.fill ? "sticky top-0 h-full min-h-[28rem] w-full" : "h-[28rem] w-80 rounded-lt shadow-lt-lg"),
29
42
  "data-test": testIdentity("chat-box"),
30
43
  children: [
31
44
  /* @__PURE__ */ jsx("div", {
32
45
  className: "flex items-center border-b border-lt-border px-3 py-2",
33
46
  children: /* @__PURE__ */ jsx("span", {
34
47
  className: "text-sm font-medium text-lt-fg",
35
- children: title ?? t("chat.title", "Chat")
48
+ children: props.title ?? t("chat.title", "Chat")
36
49
  })
37
50
  }),
38
51
  /* @__PURE__ */ jsx("div", {
39
52
  className: "flex-1 overflow-y-auto",
40
53
  children: /* @__PURE__ */ jsx(MessageList, { messages })
41
54
  }),
55
+ error ? /* @__PURE__ */ jsx("div", {
56
+ className: "border-t border-lt-danger/40 px-3 py-2 text-xs text-lt-danger",
57
+ children: error
58
+ }) : null,
42
59
  /* @__PURE__ */ jsx(PromptInput, {
43
- disabled: busy,
60
+ disabled,
44
61
  onSubmit: sendMessage,
45
- placeholder: placeholder ?? void 0
62
+ placeholder: props.placeholder ?? void 0
46
63
  })
47
64
  ]
48
65
  });
@@ -1 +1 @@
1
- {"version":3,"file":"chat-box.js","names":[],"sources":["../../../resources/js/chat/components/chat-box.tsx"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\nimport { apiFetch } from \"@lattice-php/lattice/core/api\";\nimport { testIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { useChat } from \"../use-chat\";\nimport type { ChatMessage } from \"../types\";\nimport { MessageList } from \"./message-list\";\nimport { PromptInput } from \"./prompt-input\";\n\ntype ChatHistoryResponse = { messages: ChatMessage[] };\n\nexport const ChatBox: RendererComponent<\"chat.box\"> = ({ node }) => {\n const { streamEndpoint, historyEndpoint, placeholder, title, fill } = node.props;\n const { t } = useT(\"lattice\");\n const { messages, status, sendMessage, setMessages } = useChat({\n endpoint: streamEndpoint ?? \"\",\n });\n\n const seededRef = useRef(false);\n\n const seedHistory = useCallback(async (): Promise<void> => {\n if (seededRef.current || !historyEndpoint) {\n return;\n }\n\n seededRef.current = true;\n\n const response = await apiFetch(historyEndpoint, { throwOnError: false });\n\n if (!response.ok) {\n return;\n }\n\n const payload = (await response.json()) as ChatHistoryResponse;\n setMessages(payload.messages);\n }, [historyEndpoint, setMessages]);\n\n useEffect(() => {\n void seedHistory();\n }, [seedHistory]);\n\n const busy = status === \"submitted\" || status === \"streaming\";\n\n return (\n <div\n className={cn(\n \"flex flex-col overflow-hidden border border-lt-border bg-lt-bg\",\n fill\n ? \"sticky top-0 h-full min-h-[28rem] w-full\"\n : \"h-[28rem] w-80 rounded-lt shadow-lt-lg\",\n )}\n data-test={testIdentity(\"chat-box\")}\n >\n <div className=\"flex items-center border-b border-lt-border px-3 py-2\">\n <span className=\"text-sm font-medium text-lt-fg\">{title ?? t(\"chat.title\", \"Chat\")}</span>\n </div>\n <div className=\"flex-1 overflow-y-auto\">\n <MessageList messages={messages} />\n </div>\n <PromptInput disabled={busy} onSubmit={sendMessage} placeholder={placeholder ?? undefined} />\n </div>\n );\n};\n\nexport default ChatBox;\n"],"mappings":";;;;;;;;;;AAaA,IAAa,WAA0C,EAAE,WAAW;CAClE,MAAM,EAAE,gBAAgB,iBAAiB,aAAa,OAAO,SAAS,KAAK;CAC3E,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,EAAE,UAAU,QAAQ,aAAa,gBAAgB,QAAQ,EAC7D,UAAU,kBAAkB,GAC9B,CAAC;CAED,MAAM,YAAY,OAAO,KAAK;CAE9B,MAAM,cAAc,YAAY,YAA2B;EACzD,IAAI,UAAU,WAAW,CAAC,iBACxB;EAGF,UAAU,UAAU;EAEpB,MAAM,WAAW,MAAM,SAAS,iBAAiB,EAAE,cAAc,MAAM,CAAC;EAExE,IAAI,CAAC,SAAS,IACZ;EAIF,aAAY,MADW,SAAS,KAAK,GACjB,QAAQ;CAC9B,GAAG,CAAC,iBAAiB,WAAW,CAAC;CAEjC,gBAAgB;EACd,YAAiB;CACnB,GAAG,CAAC,WAAW,CAAC;CAEhB,MAAM,OAAO,WAAW,eAAe,WAAW;CAElD,OACE,qBAAC,OAAD;EACE,WAAW,GACT,kEACA,OACI,6CACA,wCACN;EACA,aAAW,aAAa,UAAU;YAPpC;GASE,oBAAC,OAAD;IAAK,WAAU;cACb,oBAAC,QAAD;KAAM,WAAU;eAAkC,SAAS,EAAE,cAAc,MAAM;IAAQ,CAAA;GACtF,CAAA;GACL,oBAAC,OAAD;IAAK,WAAU;cACb,oBAAC,aAAD,EAAuB,SAAW,CAAA;GAC/B,CAAA;GACL,oBAAC,aAAD;IAAa,UAAU;IAAM,UAAU;IAAa,aAAa,eAAe,KAAA;GAAY,CAAA;EACzF;;AAET"}
1
+ {"version":3,"file":"chat-box.js","names":[],"sources":["../../../resources/js/chat/components/chat-box.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { apiFetch, remoteJson } from \"@lattice-php/lattice/core/api\";\nimport { testIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport type { ChatBox as ChatBoxProps } from \"@lattice-php/lattice/types/generated\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { createRemoteNdjsonChatTransport, ndjsonChatTransport } from \"../transport\";\nimport { useChat } from \"../use-chat\";\nimport type { ChatMessage } from \"../types\";\nimport { MessageList } from \"./message-list\";\nimport { PromptInput } from \"./prompt-input\";\n\ntype ChatHistoryResponse = { messages: ChatMessage[] };\n\nexport const ChatBox: RendererComponent<\"chat.box\"> = ({ node }) => {\n const props: ChatBoxProps = node.props;\n const { t } = useT(\"lattice\");\n const transport = useMemo(\n () => (props.remote ? createRemoteNdjsonChatTransport(props.remote) : ndjsonChatTransport),\n [props.remote],\n );\n const { messages, status, error, sendMessage, setMessages } = useChat({\n endpoint: props.streamEndpoint ?? \"\",\n transport,\n });\n\n const seededRef = useRef(false);\n\n const seedHistory = useCallback(async (): Promise<void> => {\n if (seededRef.current || !props.historyEndpoint) {\n return;\n }\n\n seededRef.current = true;\n\n if (props.remote) {\n const payload = await remoteJson<ChatHistoryResponse>(props.historyEndpoint, {\n remote: props.remote,\n });\n setMessages(payload.messages);\n\n return;\n }\n\n const response = await apiFetch(props.historyEndpoint, { throwOnError: false });\n\n if (!response.ok) {\n return;\n }\n\n const payload = (await response.json()) as ChatHistoryResponse;\n setMessages(payload.messages);\n }, [props.historyEndpoint, props.remote, setMessages]);\n\n useEffect(() => {\n void seedHistory().catch(() => {});\n }, [seedHistory]);\n\n const busy = status === \"submitted\" || status === \"streaming\";\n const disabled = busy || !props.streamEndpoint;\n\n return (\n <div\n className={cn(\n \"flex flex-col overflow-hidden border border-lt-border bg-lt-bg\",\n props.fill\n ? \"sticky top-0 h-full min-h-[28rem] w-full\"\n : \"h-[28rem] w-80 rounded-lt shadow-lt-lg\",\n )}\n data-test={testIdentity(\"chat-box\")}\n >\n <div className=\"flex items-center border-b border-lt-border px-3 py-2\">\n <span className=\"text-sm font-medium text-lt-fg\">\n {props.title ?? t(\"chat.title\", \"Chat\")}\n </span>\n </div>\n <div className=\"flex-1 overflow-y-auto\">\n <MessageList messages={messages} />\n </div>\n {error ? (\n <div className=\"border-t border-lt-danger/40 px-3 py-2 text-xs text-lt-danger\">{error}</div>\n ) : null}\n <PromptInput\n disabled={disabled}\n onSubmit={sendMessage}\n placeholder={props.placeholder ?? undefined}\n />\n </div>\n );\n};\n\nexport default ChatBox;\n"],"mappings":";;;;;;;;;;;AAeA,IAAa,WAA0C,EAAE,WAAW;CAClE,MAAM,QAAsB,KAAK;CACjC,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,YAAY,cACT,MAAM,SAAS,gCAAgC,MAAM,MAAM,IAAI,qBACtE,CAAC,MAAM,MAAM,CACf;CACA,MAAM,EAAE,UAAU,QAAQ,OAAO,aAAa,gBAAgB,QAAQ;EACpE,UAAU,MAAM,kBAAkB;EAClC;CACF,CAAC;CAED,MAAM,YAAY,OAAO,KAAK;CAE9B,MAAM,cAAc,YAAY,YAA2B;EACzD,IAAI,UAAU,WAAW,CAAC,MAAM,iBAC9B;EAGF,UAAU,UAAU;EAEpB,IAAI,MAAM,QAAQ;GAIhB,aAAY,MAHU,WAAgC,MAAM,iBAAiB,EAC3E,QAAQ,MAAM,OAChB,CAAC,GACmB,QAAQ;GAE5B;EACF;EAEA,MAAM,WAAW,MAAM,SAAS,MAAM,iBAAiB,EAAE,cAAc,MAAM,CAAC;EAE9E,IAAI,CAAC,SAAS,IACZ;EAIF,aAAY,MADW,SAAS,KAAK,GACjB,QAAQ;CAC9B,GAAG;EAAC,MAAM;EAAiB,MAAM;EAAQ;CAAW,CAAC;CAErD,gBAAgB;EACd,YAAiB,EAAE,YAAY,CAAC,CAAC;CACnC,GAAG,CAAC,WAAW,CAAC;CAGhB,MAAM,WADO,WAAW,eAAe,WAAW,eACzB,CAAC,MAAM;CAEhC,OACE,qBAAC,OAAD;EACE,WAAW,GACT,kEACA,MAAM,OACF,6CACA,wCACN;EACA,aAAW,aAAa,UAAU;YAPpC;GASE,oBAAC,OAAD;IAAK,WAAU;cACb,oBAAC,QAAD;KAAM,WAAU;eACb,MAAM,SAAS,EAAE,cAAc,MAAM;IAClC,CAAA;GACH,CAAA;GACL,oBAAC,OAAD;IAAK,WAAU;cACb,oBAAC,aAAD,EAAuB,SAAW,CAAA;GAC/B,CAAA;GACJ,QACC,oBAAC,OAAD;IAAK,WAAU;cAAiE;GAAW,CAAA,IACzF;GACJ,oBAAC,aAAD;IACY;IACV,UAAU;IACV,aAAa,MAAM,eAAe,KAAA;GACnC,CAAA;EACE;;AAET"}
@@ -1,6 +1,6 @@
1
1
  import { cn } from "../../lib/utils.js";
2
- import { testIdentity } from "../../core/test-id.js";
3
2
  import { RenderNode } from "../../core/renderer.js";
3
+ import { testIdentity } from "../../core/test-id.js";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  //#region resources/js/chat/components/message.tsx
6
6
  function Message({ message }) {
@@ -1,7 +1,7 @@
1
1
  import { cn } from "../../lib/utils.js";
2
+ import { useT } from "../../i18n/instance.js";
2
3
  import { testIdentity } from "../../core/test-id.js";
3
4
  import { Button } from "../../core/components/button.js";
4
- import { useT } from "../../i18n/instance.js";
5
5
  import { useState } from "react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region resources/js/chat/components/prompt-input.tsx
@@ -1,10 +1,12 @@
1
1
  import { createPlugin, eagerComponent } from "../core/registry.js";
2
+ import { ChatBox } from "./components/chat-box.js";
2
3
  import { TextPart } from "./parts/text.js";
3
4
  import { ToolCallPart } from "./parts/tool-call.js";
4
5
  //#region resources/js/chat/index.ts
5
6
  var chatPlugin = createPlugin({
6
7
  name: "chat",
7
8
  components: {
9
+ "chat.box": eagerComponent(ChatBox),
8
10
  "chat.part.text": eagerComponent(TextPart),
9
11
  "chat.part.tool-call": eagerComponent(ToolCallPart)
10
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../resources/js/chat/index.ts"],"sourcesContent":["import { createPlugin, eagerComponent } from \"@lattice-php/lattice/core/registry\";\nimport { TextPart } from \"./parts/text\";\nimport { ToolCallPart } from \"./parts/tool-call\";\n\nexport const chatPlugin = createPlugin({\n name: \"chat\",\n components: {\n \"chat.part.text\": eagerComponent(TextPart),\n \"chat.part.tool-call\": eagerComponent(ToolCallPart),\n },\n});\n"],"mappings":";;;;AAIA,IAAa,aAAa,aAAa;CACrC,MAAM;CACN,YAAY;EACV,kBAAkB,eAAe,QAAQ;EACzC,uBAAuB,eAAe,YAAY;CACpD;AACF,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../resources/js/chat/index.ts"],"sourcesContent":["import { createPlugin, eagerComponent } from \"@lattice-php/lattice/core/registry\";\nimport ChatBoxComponent from \"./components/chat-box\";\nimport { TextPart } from \"./parts/text\";\nimport { ToolCallPart } from \"./parts/tool-call\";\n\nexport const chatPlugin = createPlugin({\n name: \"chat\",\n components: {\n \"chat.box\": eagerComponent(ChatBoxComponent),\n \"chat.part.text\": eagerComponent(TextPart),\n \"chat.part.tool-call\": eagerComponent(ToolCallPart),\n },\n});\n"],"mappings":";;;;;AAKA,IAAa,aAAa,aAAa;CACrC,MAAM;CACN,YAAY;EACV,YAAY,eAAe,OAAgB;EAC3C,kBAAkB,eAAe,QAAQ;EACzC,uBAAuB,eAAe,YAAY;CACpD;AACF,CAAC"}
@@ -1,8 +1,8 @@
1
1
  import { cn } from "../../lib/utils.js";
2
2
  import "react";
3
+ import { jsx } from "react/jsx-runtime";
3
4
  import { Slot } from "@radix-ui/react-slot";
4
5
  import { cva } from "class-variance-authority";
5
- import { jsx } from "react/jsx-runtime";
6
6
  //#region resources/js/core/components/badge.tsx
7
7
  var badgeVariants = cva("inline-flex items-center justify-center rounded-lt-sm border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-lt-icon-xs gap-1 [&>svg]:pointer-events-none focus-visible:border-lt-ring focus-visible:ring-lt-ring/50 focus-visible:ring-[3px] aria-invalid:ring-lt-danger/20 dark:aria-invalid:ring-lt-danger/40 aria-invalid:border-lt-danger transition-[color,box-shadow] overflow-hidden", {
8
8
  variants: { variant: {
@@ -1,10 +1,13 @@
1
1
  import { cn } from "../../lib/utils.js";
2
+ import { IconRenderer } from "../../icons/icon-renderer.js";
2
3
  import { nodeIdentity } from "../test-id.js";
3
- import "react";
4
+ import { getActionEffects } from "../../effects/dispatch.js";
5
+ import { useEffectDispatcher } from "../../effects/use-effect-dispatcher.js";
4
6
  import { Link } from "@inertiajs/react";
7
+ import "react";
8
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
5
9
  import { Slot } from "@radix-ui/react-slot";
6
10
  import { cva } from "class-variance-authority";
7
- import { jsx } from "react/jsx-runtime";
8
11
  //#region resources/js/core/components/button.tsx
9
12
  var buttonVariants = cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lt-sm text-base font-medium transition-[color,box-shadow] disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-lt-icon-md [&_svg]:shrink-0 outline-none focus-visible:border-lt-ring focus-visible:ring-lt-ring/50 focus-visible:ring-[3px] aria-invalid:ring-lt-danger/20 dark:aria-invalid:ring-lt-danger/40 aria-invalid:border-lt-danger", {
10
13
  variants: {
@@ -42,9 +45,11 @@ function Button({ className, variant, size, asChild = false, ...props }) {
42
45
  });
43
46
  }
44
47
  var ButtonComponent = ({ node }) => {
45
- const { href, label } = node.props;
48
+ const { href, label, icon } = node.props;
49
+ const effects = node.props.effects ?? [];
46
50
  const variant = node.props.variant ?? "default";
47
51
  const testId = nodeIdentity(node);
52
+ const dispatch = useEffectDispatcher();
48
53
  if (href) return /* @__PURE__ */ jsx(Button, {
49
54
  asChild: true,
50
55
  "data-test": testId,
@@ -57,10 +62,17 @@ var ButtonComponent = ({ node }) => {
57
62
  });
58
63
  return /* @__PURE__ */ jsx(Button, {
59
64
  "data-test": testId,
65
+ onClick: effects.length > 0 ? () => dispatch(getActionEffects(effects)) : void 0,
66
+ size: icon ? "icon" : "default",
60
67
  type: node.props.buttonType,
61
68
  variant,
62
- size: "default",
63
- children: label
69
+ children: icon ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(IconRenderer, {
70
+ className: "size-lt-icon-md",
71
+ icon
72
+ }), label ? /* @__PURE__ */ jsx("span", {
73
+ className: "sr-only",
74
+ children: label
75
+ }) : null] }) : label
64
76
  });
65
77
  };
66
78
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","names":[],"sources":["../../../resources/js/core/components/button.tsx"],"sourcesContent":["import { Link } from \"@inertiajs/react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport type { ButtonVariant } from \"@lattice-php/lattice/types/generated\";\n\nexport type { ButtonVariant };\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lt-sm text-base font-medium transition-[color,box-shadow] disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-lt-icon-md [&_svg]:shrink-0 outline-none focus-visible:border-lt-ring focus-visible:ring-lt-ring/50 focus-visible:ring-[3px] aria-invalid:ring-lt-danger/20 dark:aria-invalid:ring-lt-danger/40 aria-invalid:border-lt-danger\",\n {\n variants: {\n variant: {\n default:\n \"bg-lt-primary text-lt-primary-fg shadow-lt-xs hover:bg-lt-primary-hover active:bg-lt-primary-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n destructive:\n \"bg-lt-danger text-lt-danger-fg shadow-lt-xs hover:bg-lt-danger-hover active:bg-lt-danger-active focus-visible:ring-lt-danger/20 dark:focus-visible:ring-lt-danger/40 disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n success:\n \"bg-lt-success text-lt-success-fg shadow-lt-xs hover:bg-lt-success-hover active:bg-lt-success-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n info: \"bg-lt-info text-lt-info-fg shadow-lt-xs hover:bg-lt-info-hover active:bg-lt-info-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n outline:\n \"border border-lt-input bg-lt-bg shadow-lt-xs hover:bg-lt-accent hover:text-lt-accent-fg disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:border-transparent disabled:shadow-none\",\n secondary:\n \"bg-lt-secondary text-lt-secondary-fg shadow-lt-xs hover:bg-lt-secondary-hover active:bg-lt-secondary-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n ghost: \"hover:bg-lt-accent hover:text-lt-accent-fg disabled:text-lt-disabled-fg\",\n link: \"text-lt-primary underline-offset-4 hover:underline disabled:text-lt-disabled-fg disabled:no-underline\",\n },\n size: {\n default: \"h-lt-control-md px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-lt-control-sm rounded-lt-sm px-3 has-[>svg]:px-2.5\",\n lg: \"h-lt-control-lg rounded-lt-sm px-6 has-[>svg]:px-4\",\n icon: \"size-lt-control-md\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nconst ButtonComponent: RendererComponent<\"button\"> = ({ node }) => {\n const { href, label } = node.props;\n const variant = node.props.variant ?? \"default\";\n const testId = nodeIdentity(node);\n\n if (href) {\n return (\n <Button asChild data-test={testId} variant={variant} size=\"default\">\n <Link href={href}>{label}</Link>\n </Button>\n );\n }\n\n return (\n <Button data-test={testId} type={node.props.buttonType} variant={variant} size=\"default\">\n {label}\n </Button>\n );\n};\n\nexport default ButtonComponent;\nexport { Button, buttonVariants };\n"],"mappings":";;;;;;;;AAWA,IAAM,iBAAiB,IACrB,+bACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,aACE;GACF,SACE;GACF,MAAM;GACN,SACE;GACF,WACE;GACF,OAAO;GACP,MAAM;EACR;EACA,MAAM;GACJ,SAAS;GACT,IAAI;GACJ,IAAI;GACJ,MAAM;EACR;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CACF;AAEA,SAAS,OAAO,EACd,WACA,SACA,MACA,UAAU,OACV,GAAG,SAIA;CAGH,OACE,oBAHW,UAAU,OAAO,UAG5B;EACE,aAAU;EACV,WAAW,GAAG,eAAe;GAAE;GAAS;GAAM;EAAU,CAAC,CAAC;EAC1D,GAAI;CACL,CAAA;AAEL;AAEA,IAAM,mBAAgD,EAAE,WAAW;CACjE,MAAM,EAAE,MAAM,UAAU,KAAK;CAC7B,MAAM,UAAU,KAAK,MAAM,WAAW;CACtC,MAAM,SAAS,aAAa,IAAI;CAEhC,IAAI,MACF,OACE,oBAAC,QAAD;EAAQ,SAAA;EAAQ,aAAW;EAAiB;EAAS,MAAK;YACxD,oBAAC,MAAD;GAAY;aAAO;EAAY,CAAA;CACzB,CAAA;CAIZ,OACE,oBAAC,QAAD;EAAQ,aAAW;EAAQ,MAAM,KAAK,MAAM;EAAqB;EAAS,MAAK;YAC5E;CACK,CAAA;AAEZ"}
1
+ {"version":3,"file":"button.js","names":[],"sources":["../../../resources/js/core/components/button.tsx"],"sourcesContent":["import { Link } from \"@inertiajs/react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { getActionEffects } from \"@lattice-php/lattice/effects/dispatch\";\nimport { IconRenderer } from \"@lattice-php/lattice/icons\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport { useEffectDispatcher } from \"@lattice-php/lattice/effects/use-effect-dispatcher\";\nimport type { ButtonVariant } from \"@lattice-php/lattice/types/generated\";\n\nexport type { ButtonVariant };\n\nconst buttonVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lt-sm text-base font-medium transition-[color,box-shadow] disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-lt-icon-md [&_svg]:shrink-0 outline-none focus-visible:border-lt-ring focus-visible:ring-lt-ring/50 focus-visible:ring-[3px] aria-invalid:ring-lt-danger/20 dark:aria-invalid:ring-lt-danger/40 aria-invalid:border-lt-danger\",\n {\n variants: {\n variant: {\n default:\n \"bg-lt-primary text-lt-primary-fg shadow-lt-xs hover:bg-lt-primary-hover active:bg-lt-primary-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n destructive:\n \"bg-lt-danger text-lt-danger-fg shadow-lt-xs hover:bg-lt-danger-hover active:bg-lt-danger-active focus-visible:ring-lt-danger/20 dark:focus-visible:ring-lt-danger/40 disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n success:\n \"bg-lt-success text-lt-success-fg shadow-lt-xs hover:bg-lt-success-hover active:bg-lt-success-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n info: \"bg-lt-info text-lt-info-fg shadow-lt-xs hover:bg-lt-info-hover active:bg-lt-info-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n outline:\n \"border border-lt-input bg-lt-bg shadow-lt-xs hover:bg-lt-accent hover:text-lt-accent-fg disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:border-transparent disabled:shadow-none\",\n secondary:\n \"bg-lt-secondary text-lt-secondary-fg shadow-lt-xs hover:bg-lt-secondary-hover active:bg-lt-secondary-active disabled:bg-lt-disabled disabled:text-lt-disabled-fg disabled:shadow-none\",\n ghost: \"hover:bg-lt-accent hover:text-lt-accent-fg disabled:text-lt-disabled-fg\",\n link: \"text-lt-primary underline-offset-4 hover:underline disabled:text-lt-disabled-fg disabled:no-underline\",\n },\n size: {\n default: \"h-lt-control-md px-4 py-2 has-[>svg]:px-3\",\n sm: \"h-lt-control-sm rounded-lt-sm px-3 has-[>svg]:px-2.5\",\n lg: \"h-lt-control-lg rounded-lt-sm px-6 has-[>svg]:px-4\",\n icon: \"size-lt-control-md\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n },\n);\n\nfunction Button({\n className,\n variant,\n size,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : \"button\";\n\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nconst ButtonComponent: RendererComponent<\"button\"> = ({ node }) => {\n const { href, label, icon } = node.props;\n const effects = node.props.effects ?? [];\n const variant = node.props.variant ?? \"default\";\n const testId = nodeIdentity(node);\n const dispatch = useEffectDispatcher();\n\n if (href) {\n return (\n <Button asChild data-test={testId} variant={variant} size=\"default\">\n <Link href={href}>{label}</Link>\n </Button>\n );\n }\n\n const hasEffects = effects.length > 0;\n\n return (\n <Button\n data-test={testId}\n onClick={hasEffects ? () => dispatch(getActionEffects(effects)) : undefined}\n size={icon ? \"icon\" : \"default\"}\n type={node.props.buttonType}\n variant={variant}\n >\n {icon ? (\n <>\n <IconRenderer className=\"size-lt-icon-md\" icon={icon} />\n {label ? <span className=\"sr-only\">{label}</span> : null}\n </>\n ) : (\n label\n )}\n </Button>\n );\n};\n\nexport default ButtonComponent;\nexport { Button, buttonVariants };\n"],"mappings":";;;;;;;;;;;AAcA,IAAM,iBAAiB,IACrB,+bACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,aACE;GACF,SACE;GACF,MAAM;GACN,SACE;GACF,WACE;GACF,OAAO;GACP,MAAM;EACR;EACA,MAAM;GACJ,SAAS;GACT,IAAI;GACJ,IAAI;GACJ,MAAM;EACR;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CACF;AAEA,SAAS,OAAO,EACd,WACA,SACA,MACA,UAAU,OACV,GAAG,SAIA;CAGH,OACE,oBAHW,UAAU,OAAO,UAG5B;EACE,aAAU;EACV,WAAW,GAAG,eAAe;GAAE;GAAS;GAAM;EAAU,CAAC,CAAC;EAC1D,GAAI;CACL,CAAA;AAEL;AAEA,IAAM,mBAAgD,EAAE,WAAW;CACjE,MAAM,EAAE,MAAM,OAAO,SAAS,KAAK;CACnC,MAAM,UAAU,KAAK,MAAM,WAAW,CAAC;CACvC,MAAM,UAAU,KAAK,MAAM,WAAW;CACtC,MAAM,SAAS,aAAa,IAAI;CAChC,MAAM,WAAW,oBAAoB;CAErC,IAAI,MACF,OACE,oBAAC,QAAD;EAAQ,SAAA;EAAQ,aAAW;EAAiB;EAAS,MAAK;YACxD,oBAAC,MAAD;GAAY;aAAO;EAAY,CAAA;CACzB,CAAA;CAMZ,OACE,oBAAC,QAAD;EACE,aAAW;EACX,SALe,QAAQ,SAAS,UAKJ,SAAS,iBAAiB,OAAO,CAAC,IAAI,KAAA;EAClE,MAAM,OAAO,SAAS;EACtB,MAAM,KAAK,MAAM;EACR;YAER,OACC,qBAAA,YAAA,EAAA,UAAA,CACE,oBAAC,cAAD;GAAc,WAAU;GAAwB;EAAO,CAAA,GACtD,QAAQ,oBAAC,QAAD;GAAM,WAAU;aAAW;EAAY,CAAA,IAAI,IACpD,EAAA,CAAA,IAEF;CAEI,CAAA;AAEZ"}
@@ -1,4 +1,5 @@
1
1
  import { cn } from "../../lib/utils.js";
2
+ import { nodeIdentity } from "../test-id.js";
2
3
  import "react";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region resources/js/core/components/card.tsx
@@ -47,7 +48,7 @@ function CardFooter({ className, ...props }) {
47
48
  var CardComponent = ({ children, node }) => {
48
49
  const { title, description } = node.props;
49
50
  return /* @__PURE__ */ jsxs(Card, {
50
- "data-lattice-component": node.id,
51
+ "data-lattice-component": nodeIdentity(node),
51
52
  children: [(title || description) && /* @__PURE__ */ jsxs(CardHeader, { children: [title && /* @__PURE__ */ jsx(CardTitle, { children: title }), description && /* @__PURE__ */ jsx(CardDescription, { children: description })] }), children && /* @__PURE__ */ jsx(CardContent, {
52
53
  className: "flex flex-col gap-6",
53
54
  children
@@ -1 +1 @@
1
- {"version":3,"file":"card.js","names":[],"sources":["../../../resources/js/core/components/card.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\n\nfunction Card({ className, ...props }: React.ComponentProps<\"article\">) {\n return (\n <article\n data-slot=\"card\"\n className={cn(\n \"flex flex-col gap-6 rounded-lt border border-lt-border bg-lt-surface py-6 text-lt-surface-fg shadow-lt-sm\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\"flex flex-col gap-1.5 px-6\", className)}\n {...props}\n />\n );\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\"font-semibold leading-none\", className)}\n {...props}\n />\n );\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-sm text-lt-muted-fg\", className)}\n {...props}\n />\n );\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div data-slot=\"card-content\" className={cn(\"px-6\", className)} {...props} />;\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div data-slot=\"card-footer\" className={cn(\"flex items-center px-6\", className)} {...props} />\n );\n}\n\nconst CardComponent: RendererComponent<\"card\"> = ({ children, node }) => {\n const { title, description } = node.props;\n\n return (\n <Card data-lattice-component={node.id}>\n {(title || description) && (\n <CardHeader>\n {title && <CardTitle>{title}</CardTitle>}\n {description && <CardDescription>{description}</CardDescription>}\n </CardHeader>\n )}\n {children && <CardContent className=\"flex flex-col gap-6\">{children}</CardContent>}\n </Card>\n );\n};\n\nexport default CardComponent;\nexport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };\n"],"mappings":";;;;AAIA,SAAS,KAAK,EAAE,WAAW,GAAG,SAA0C;CACtE,OACE,oBAAC,WAAD;EACE,aAAU;EACV,WAAW,GACT,6GACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,8BAA8B,SAAS;EACrD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAsC;CACvE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,8BAA8B,SAAS;EACrD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAsC;CAC7E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,4BAA4B,SAAS;EACnD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OAAO,oBAAC,OAAD;EAAK,aAAU;EAAe,WAAW,GAAG,QAAQ,SAAS;EAAG,GAAI;CAAQ,CAAA;AACrF;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EAAK,aAAU;EAAc,WAAW,GAAG,0BAA0B,SAAS;EAAG,GAAI;CAAQ,CAAA;AAEjG;AAEA,IAAM,iBAA4C,EAAE,UAAU,WAAW;CACvE,MAAM,EAAE,OAAO,gBAAgB,KAAK;CAEpC,OACE,qBAAC,MAAD;EAAM,0BAAwB,KAAK;YAAnC,EACI,SAAS,gBACT,qBAAC,YAAD,EAAA,UAAA,CACG,SAAS,oBAAC,WAAD,EAAA,UAAY,MAAiB,CAAA,GACtC,eAAe,oBAAC,iBAAD,EAAA,UAAkB,YAA6B,CAAA,CACrD,EAAA,CAAA,GAEb,YAAY,oBAAC,aAAD;GAAa,WAAU;GAAuB;EAAsB,CAAA,CAC7E;;AAEV"}
1
+ {"version":3,"file":"card.js","names":[],"sources":["../../../resources/js/core/components/card.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\n\nfunction Card({ className, ...props }: React.ComponentProps<\"article\">) {\n return (\n <article\n data-slot=\"card\"\n className={cn(\n \"flex flex-col gap-6 rounded-lt border border-lt-border bg-lt-surface py-6 text-lt-surface-fg shadow-lt-sm\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\"flex flex-col gap-1.5 px-6\", className)}\n {...props}\n />\n );\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\"font-semibold leading-none\", className)}\n {...props}\n />\n );\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-sm text-lt-muted-fg\", className)}\n {...props}\n />\n );\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div data-slot=\"card-content\" className={cn(\"px-6\", className)} {...props} />;\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div data-slot=\"card-footer\" className={cn(\"flex items-center px-6\", className)} {...props} />\n );\n}\n\nconst CardComponent: RendererComponent<\"card\"> = ({ children, node }) => {\n const { title, description } = node.props;\n\n return (\n <Card data-lattice-component={nodeIdentity(node)}>\n {(title || description) && (\n <CardHeader>\n {title && <CardTitle>{title}</CardTitle>}\n {description && <CardDescription>{description}</CardDescription>}\n </CardHeader>\n )}\n {children && <CardContent className=\"flex flex-col gap-6\">{children}</CardContent>}\n </Card>\n );\n};\n\nexport default CardComponent;\nexport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };\n"],"mappings":";;;;;AAKA,SAAS,KAAK,EAAE,WAAW,GAAG,SAA0C;CACtE,OACE,oBAAC,WAAD;EACE,aAAU;EACV,WAAW,GACT,6GACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,8BAA8B,SAAS;EACrD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAsC;CACvE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,8BAA8B,SAAS;EACrD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAsC;CAC7E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,4BAA4B,SAAS;EACnD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OAAO,oBAAC,OAAD;EAAK,aAAU;EAAe,WAAW,GAAG,QAAQ,SAAS;EAAG,GAAI;CAAQ,CAAA;AACrF;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EAAK,aAAU;EAAc,WAAW,GAAG,0BAA0B,SAAS;EAAG,GAAI;CAAQ,CAAA;AAEjG;AAEA,IAAM,iBAA4C,EAAE,UAAU,WAAW;CACvE,MAAM,EAAE,OAAO,gBAAgB,KAAK;CAEpC,OACE,qBAAC,MAAD;EAAM,0BAAwB,aAAa,IAAI;YAA/C,EACI,SAAS,gBACT,qBAAC,YAAD,EAAA,UAAA,CACG,SAAS,oBAAC,WAAD,EAAA,UAAY,MAAiB,CAAA,GACtC,eAAe,oBAAC,iBAAD,EAAA,UAAkB,YAA6B,CAAA,CACrD,EAAA,CAAA,GAEb,YAAY,oBAAC,aAAD;GAAa,WAAU;GAAuB;EAAsB,CAAA,CAC7E;;AAEV"}
@@ -1,3 +1,4 @@
1
+ import { nodeIdentity } from "../test-id.js";
1
2
  import { jsx, jsxs } from "react/jsx-runtime";
2
3
  import { Area, AreaChart, Bar, BarChart, CartesianGrid, Cell, ComposedChart, Legend, Line, LineChart, Pie, PieChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
3
4
  //#region resources/js/core/components/chart.tsx
@@ -72,6 +73,7 @@ function CartesianChart({ props }) {
72
73
  return /* @__PURE__ */ jsx(ResponsiveContainer, {
73
74
  width: "100%",
74
75
  height: props.height,
76
+ debounce: 100,
75
77
  children: /* @__PURE__ */ jsxs(RechartsChart, {
76
78
  data: props.data,
77
79
  margin: chartMargin,
@@ -135,6 +137,7 @@ function PieChartView({ props, series }) {
135
137
  return /* @__PURE__ */ jsx(ResponsiveContainer, {
136
138
  width: "100%",
137
139
  height: props.height,
140
+ debounce: 100,
138
141
  children: /* @__PURE__ */ jsxs(PieChart, {
139
142
  margin: chartMargin,
140
143
  children: [
@@ -158,7 +161,7 @@ var ChartComponent = ({ node }) => {
158
161
  const hasCartesianSeries = props.series.some(isCartesianSeries);
159
162
  return /* @__PURE__ */ jsx(ChartFrame, {
160
163
  description: props.description,
161
- id: node.id,
164
+ id: nodeIdentity(node),
162
165
  title: props.title,
163
166
  children: /* @__PURE__ */ jsx("div", {
164
167
  className: "min-h-0 w-full",
@@ -1 +1 @@
1
- {"version":3,"file":"chart.js","names":[],"sources":["../../../resources/js/core/components/chart.tsx"],"sourcesContent":["import {\n Area,\n AreaChart,\n Bar,\n BarChart,\n CartesianGrid,\n Cell,\n ComposedChart,\n Legend,\n Line,\n LineChart,\n Pie,\n PieChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport type { PropsOf, RendererComponent } from \"@lattice-php/lattice/core/types\";\n\ntype ChartProps = PropsOf<\"chart\">;\ntype ChartSeries = ChartProps[\"series\"][number];\ntype ChartDatum = ChartProps[\"data\"][number];\ntype CartesianSeries = ChartSeries & { type: \"area\" | \"bar\" | \"line\" };\ntype ChartMargin = { bottom: number; left: number; right: number; top: number };\ntype CartesianChartComponent = ComponentType<{\n children: ReactNode;\n data: ChartProps[\"data\"];\n margin?: ChartMargin;\n}>;\n\nconst chartMargin: ChartMargin = { bottom: 0, left: 0, right: 16, top: 8 };\nconst compactLegendProps = {\n align: \"center\" as const,\n height: 24,\n iconSize: 7,\n verticalAlign: \"top\" as const,\n wrapperStyle: { fontSize: 11, lineHeight: \"14px\", paddingBottom: 6 },\n};\nconst axisTick = { fontSize: 10 };\n\nconst palette = [\n \"var(--lt-primary)\",\n \"var(--lt-success)\",\n \"var(--lt-info)\",\n \"var(--lt-warning)\",\n \"var(--lt-danger)\",\n \"var(--lt-muted-fg)\",\n];\n\nfunction colorAt(index: number): string {\n return palette[index % palette.length] ?? \"var(--lt-primary)\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction datumColor(datum: ChartDatum, series: ChartSeries, index: number): string {\n if (isRecord(datum) && typeof datum.color === \"string\") {\n return datum.color;\n }\n\n return series.color ?? colorAt(index);\n}\n\nfunction isCartesianSeries(series: ChartSeries): series is CartesianSeries {\n return series.type === \"area\" || series.type === \"bar\" || series.type === \"line\";\n}\n\nfunction cartesianChartFor(series: CartesianSeries[]): CartesianChartComponent {\n const types = new Set(series.map((item) => item.type));\n const firstSeries = series[0];\n\n if (firstSeries === undefined || types.size !== 1) {\n return ComposedChart;\n }\n\n switch (firstSeries.type) {\n case \"area\":\n return AreaChart;\n case \"bar\":\n return BarChart;\n case \"line\":\n return LineChart;\n }\n}\n\nfunction ChartFrame({\n children,\n description,\n id,\n title,\n}: {\n children: ReactNode;\n description: string | null;\n id?: string;\n title: string | null;\n}) {\n const hasHeader = title !== null || description !== null;\n\n return (\n <div\n className=\"flex flex-col gap-3 rounded-lt border border-lt-border bg-lt-surface p-4 text-lt-surface-fg shadow-lt-sm\"\n data-lattice-component={id}\n >\n {hasHeader && (\n <div className=\"flex min-w-0 flex-col gap-1.5\">\n {title !== null && <div className=\"text-sm font-semibold leading-tight\">{title}</div>}\n {description !== null && (\n <div className=\"text-xs leading-5 text-lt-muted-fg\">{description}</div>\n )}\n </div>\n )}\n {children}\n </div>\n );\n}\n\nfunction CartesianChart({ props }: { props: ChartProps }) {\n const series = props.series.filter(isCartesianSeries);\n const RechartsChart = cartesianChartFor(series);\n\n return (\n <ResponsiveContainer width=\"100%\" height={props.height}>\n <RechartsChart data={props.data} margin={chartMargin}>\n {props.grid && <CartesianGrid strokeDasharray=\"3 3\" stroke=\"var(--lt-border)\" />}\n {props.xAxis && props.categoryKey !== null && (\n <XAxis\n dataKey={props.categoryKey}\n stroke=\"var(--lt-muted-fg)\"\n tick={axisTick}\n tickLine={false}\n />\n )}\n {props.yAxis && (\n <YAxis stroke=\"var(--lt-muted-fg)\" tick={axisTick} tickLine={false} width={42} />\n )}\n {props.tooltip && <Tooltip />}\n {props.legend && <Legend {...compactLegendProps} />}\n {series.map((item, index) => {\n const color = item.color ?? colorAt(index);\n const key = `${item.type}:${item.dataKey}`;\n\n if (item.type === \"area\") {\n return (\n <Area\n key={key}\n dataKey={item.dataKey}\n fill={color}\n fillOpacity={0.16}\n name={item.name ?? undefined}\n stackId={item.stackId ?? undefined}\n stroke={color}\n type=\"monotone\"\n />\n );\n }\n\n if (item.type === \"bar\") {\n return (\n <Bar\n key={key}\n dataKey={item.dataKey}\n fill={color}\n name={item.name ?? undefined}\n radius={[4, 4, 0, 0]}\n stackId={item.stackId ?? undefined}\n />\n );\n }\n\n return (\n <Line\n key={key}\n dataKey={item.dataKey}\n dot={false}\n name={item.name ?? undefined}\n stroke={color}\n strokeWidth={2}\n type=\"monotone\"\n />\n );\n })}\n </RechartsChart>\n </ResponsiveContainer>\n );\n}\n\nfunction PieChartView({ props, series }: { props: ChartProps; series: ChartSeries }) {\n return (\n <ResponsiveContainer width=\"100%\" height={props.height}>\n <PieChart margin={chartMargin}>\n {props.tooltip && <Tooltip />}\n {props.legend && <Legend {...compactLegendProps} />}\n <Pie\n data={props.data}\n dataKey={series.dataKey}\n name={series.name ?? undefined}\n nameKey={series.nameKey ?? undefined}\n outerRadius=\"68%\"\n >\n {props.data.map((datum, index) => (\n <Cell key={index} fill={datumColor(datum, series, index)} />\n ))}\n </Pie>\n </PieChart>\n </ResponsiveContainer>\n );\n}\n\nconst ChartComponent: RendererComponent<\"chart\"> = ({ node }) => {\n const props = node.props;\n const pieSeries = props.series.find((series) => series.type === \"pie\");\n const hasCartesianSeries = props.series.some(isCartesianSeries);\n\n return (\n <ChartFrame description={props.description} id={node.id} title={props.title}>\n <div className=\"min-h-0 w-full\">\n {pieSeries && !hasCartesianSeries ? (\n <PieChartView props={props} series={pieSeries} />\n ) : (\n <CartesianChart props={props} />\n )}\n </div>\n </ChartFrame>\n );\n};\n\nexport default ChartComponent;\n"],"mappings":"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"}
1
+ {"version":3,"file":"chart.js","names":[],"sources":["../../../resources/js/core/components/chart.tsx"],"sourcesContent":["import {\n Area,\n AreaChart,\n Bar,\n BarChart,\n CartesianGrid,\n Cell,\n ComposedChart,\n Legend,\n Line,\n LineChart,\n Pie,\n PieChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport type { PropsOf, RendererComponent } from \"@lattice-php/lattice/core/types\";\n\ntype ChartProps = PropsOf<\"chart\">;\ntype ChartSeries = ChartProps[\"series\"][number];\ntype ChartDatum = ChartProps[\"data\"][number];\ntype CartesianSeries = ChartSeries & { type: \"area\" | \"bar\" | \"line\" };\ntype ChartMargin = { bottom: number; left: number; right: number; top: number };\ntype CartesianChartComponent = ComponentType<{\n children: ReactNode;\n data: ChartProps[\"data\"];\n margin?: ChartMargin;\n}>;\n\nconst chartMargin: ChartMargin = { bottom: 0, left: 0, right: 16, top: 8 };\nconst compactLegendProps = {\n align: \"center\" as const,\n height: 24,\n iconSize: 7,\n verticalAlign: \"top\" as const,\n wrapperStyle: { fontSize: 11, lineHeight: \"14px\", paddingBottom: 6 },\n};\nconst axisTick = { fontSize: 10 };\n\nconst palette = [\n \"var(--lt-primary)\",\n \"var(--lt-success)\",\n \"var(--lt-info)\",\n \"var(--lt-warning)\",\n \"var(--lt-danger)\",\n \"var(--lt-muted-fg)\",\n];\n\nfunction colorAt(index: number): string {\n return palette[index % palette.length] ?? \"var(--lt-primary)\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction datumColor(datum: ChartDatum, series: ChartSeries, index: number): string {\n if (isRecord(datum) && typeof datum.color === \"string\") {\n return datum.color;\n }\n\n return series.color ?? colorAt(index);\n}\n\nfunction isCartesianSeries(series: ChartSeries): series is CartesianSeries {\n return series.type === \"area\" || series.type === \"bar\" || series.type === \"line\";\n}\n\nfunction cartesianChartFor(series: CartesianSeries[]): CartesianChartComponent {\n const types = new Set(series.map((item) => item.type));\n const firstSeries = series[0];\n\n if (firstSeries === undefined || types.size !== 1) {\n return ComposedChart;\n }\n\n switch (firstSeries.type) {\n case \"area\":\n return AreaChart;\n case \"bar\":\n return BarChart;\n case \"line\":\n return LineChart;\n }\n}\n\nfunction ChartFrame({\n children,\n description,\n id,\n title,\n}: {\n children: ReactNode;\n description: string | null;\n id?: string;\n title: string | null;\n}) {\n const hasHeader = title !== null || description !== null;\n\n return (\n <div\n className=\"flex flex-col gap-3 rounded-lt border border-lt-border bg-lt-surface p-4 text-lt-surface-fg shadow-lt-sm\"\n data-lattice-component={id}\n >\n {hasHeader && (\n <div className=\"flex min-w-0 flex-col gap-1.5\">\n {title !== null && <div className=\"text-sm font-semibold leading-tight\">{title}</div>}\n {description !== null && (\n <div className=\"text-xs leading-5 text-lt-muted-fg\">{description}</div>\n )}\n </div>\n )}\n {children}\n </div>\n );\n}\n\nfunction CartesianChart({ props }: { props: ChartProps }) {\n const series = props.series.filter(isCartesianSeries);\n const RechartsChart = cartesianChartFor(series);\n\n return (\n <ResponsiveContainer width=\"100%\" height={props.height} debounce={100}>\n <RechartsChart data={props.data} margin={chartMargin}>\n {props.grid && <CartesianGrid strokeDasharray=\"3 3\" stroke=\"var(--lt-border)\" />}\n {props.xAxis && props.categoryKey !== null && (\n <XAxis\n dataKey={props.categoryKey}\n stroke=\"var(--lt-muted-fg)\"\n tick={axisTick}\n tickLine={false}\n />\n )}\n {props.yAxis && (\n <YAxis stroke=\"var(--lt-muted-fg)\" tick={axisTick} tickLine={false} width={42} />\n )}\n {props.tooltip && <Tooltip />}\n {props.legend && <Legend {...compactLegendProps} />}\n {series.map((item, index) => {\n const color = item.color ?? colorAt(index);\n const key = `${item.type}:${item.dataKey}`;\n\n if (item.type === \"area\") {\n return (\n <Area\n key={key}\n dataKey={item.dataKey}\n fill={color}\n fillOpacity={0.16}\n name={item.name ?? undefined}\n stackId={item.stackId ?? undefined}\n stroke={color}\n type=\"monotone\"\n />\n );\n }\n\n if (item.type === \"bar\") {\n return (\n <Bar\n key={key}\n dataKey={item.dataKey}\n fill={color}\n name={item.name ?? undefined}\n radius={[4, 4, 0, 0]}\n stackId={item.stackId ?? undefined}\n />\n );\n }\n\n return (\n <Line\n key={key}\n dataKey={item.dataKey}\n dot={false}\n name={item.name ?? undefined}\n stroke={color}\n strokeWidth={2}\n type=\"monotone\"\n />\n );\n })}\n </RechartsChart>\n </ResponsiveContainer>\n );\n}\n\nfunction PieChartView({ props, series }: { props: ChartProps; series: ChartSeries }) {\n return (\n <ResponsiveContainer width=\"100%\" height={props.height} debounce={100}>\n <PieChart margin={chartMargin}>\n {props.tooltip && <Tooltip />}\n {props.legend && <Legend {...compactLegendProps} />}\n <Pie\n data={props.data}\n dataKey={series.dataKey}\n name={series.name ?? undefined}\n nameKey={series.nameKey ?? undefined}\n outerRadius=\"68%\"\n >\n {props.data.map((datum, index) => (\n <Cell key={index} fill={datumColor(datum, series, index)} />\n ))}\n </Pie>\n </PieChart>\n </ResponsiveContainer>\n );\n}\n\nconst ChartComponent: RendererComponent<\"chart\"> = ({ node }) => {\n const props = node.props;\n const pieSeries = props.series.find((series) => series.type === \"pie\");\n const hasCartesianSeries = props.series.some(isCartesianSeries);\n\n return (\n <ChartFrame description={props.description} id={nodeIdentity(node)} title={props.title}>\n <div className=\"min-h-0 w-full\">\n {pieSeries && !hasCartesianSeries ? (\n <PieChartView props={props} series={pieSeries} />\n ) : (\n <CartesianChart props={props} />\n )}\n </div>\n </ChartFrame>\n );\n};\n\nexport default ChartComponent;\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { cn } from "../../lib/utils.js";
2
- import { Button } from "./button.js";
3
2
  import { Icon } from "../../icons/sprite.js";
3
+ import { Button } from "./button.js";
4
4
  import "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  import * as DialogPrimitive from "@radix-ui/react-dialog";
@@ -1,5 +1,6 @@
1
1
  import { cn } from "../../lib/utils.js";
2
2
  import { RenderNode } from "../renderer.js";
3
+ import { nodeIdentity } from "../test-id.js";
3
4
  import { useState } from "react";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  //#region resources/js/core/components/floating-panel.tsx
@@ -30,7 +31,7 @@ var FloatingPanelComponent = ({ children, node }) => {
30
31
  if (trigger.length === 0) return /* @__PURE__ */ jsx("div", {
31
32
  "aria-label": label,
32
33
  className: "fixed z-50 max-w-[calc(100vw-2rem)] rounded-lt border border-lt-border bg-lt-popover p-1 text-lt-popover-fg shadow-lt-md",
33
- "data-lattice-component": node.id,
34
+ "data-lattice-component": nodeIdentity(node),
34
35
  role: label ? "group" : void 0,
35
36
  style: placementStyle(placement, offset),
36
37
  children
@@ -40,7 +41,7 @@ var FloatingPanelComponent = ({ children, node }) => {
40
41
  return /* @__PURE__ */ jsx("div", {
41
42
  "aria-label": label,
42
43
  className: "fixed z-50 max-w-[calc(100vw-2rem)]",
43
- "data-lattice-component": node.id,
44
+ "data-lattice-component": nodeIdentity(node),
44
45
  role: label ? "group" : void 0,
45
46
  style: placementStyle(placement, offset),
46
47
  children: /* @__PURE__ */ jsxs("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"floating-panel.js","names":[],"sources":["../../../resources/js/core/components/floating-panel.tsx"],"sourcesContent":["import { type CSSProperties, useState } from \"react\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport type { FloatingPlacement } from \"@lattice-php/lattice/types/generated\";\nimport { RenderNode } from \"@lattice-php/lattice/core/renderer\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nfunction placementStyle(placement: FloatingPlacement, offset: number): CSSProperties {\n if (placement === \"top-start\") {\n return { left: offset, top: offset };\n }\n\n if (placement === \"top-end\") {\n return { right: offset, top: offset };\n }\n\n if (placement === \"bottom-start\") {\n return { bottom: offset, left: offset };\n }\n\n return { bottom: offset, right: offset };\n}\n\nconst FloatingPanelComponent: RendererComponent<\"floating-panel\"> = ({ children, node }) => {\n const label = node.props.label ?? undefined;\n const offset = Math.max(0, node.props.offset ?? 16);\n const placement = node.props.placement ?? \"bottom-end\";\n const trigger = node.props.trigger ?? [];\n const [open, setOpen] = useState(false);\n\n if (trigger.length === 0) {\n return (\n <div\n aria-label={label}\n className=\"fixed z-50 max-w-[calc(100vw-2rem)] rounded-lt border border-lt-border bg-lt-popover p-1 text-lt-popover-fg shadow-lt-md\"\n data-lattice-component={node.id}\n role={label ? \"group\" : undefined}\n style={placementStyle(placement, offset)}\n >\n {children}\n </div>\n );\n }\n\n const expandsUpward = placement === \"bottom-start\" || placement === \"bottom-end\";\n const anchorsToStart = placement === \"top-start\" || placement === \"bottom-start\";\n\n return (\n <div\n aria-label={label}\n className=\"fixed z-50 max-w-[calc(100vw-2rem)]\"\n data-lattice-component={node.id}\n role={label ? \"group\" : undefined}\n style={placementStyle(placement, offset)}\n >\n <div className={cn(\"flex w-fit gap-2\", expandsUpward ? \"flex-col-reverse\" : \"flex-col\")}>\n <button\n aria-expanded={open}\n className={cn(\n \"inline-flex items-center gap-2 rounded-lt border border-lt-border bg-lt-popover px-3 py-1.5 text-sm font-medium text-lt-popover-fg shadow-lt-md hover:bg-lt-muted\",\n anchorsToStart ? \"self-start\" : \"self-end\",\n )}\n data-test={node.key ? `${node.key}-trigger` : undefined}\n onClick={() => setOpen((value) => !value)}\n type=\"button\"\n >\n {trigger.map((triggerNode, index) => (\n <RenderNode\n key={triggerNode.key ?? `${triggerNode.type}-${index}`}\n node={triggerNode}\n />\n ))}\n </button>\n <div className={open ? \"block\" : \"hidden\"}>{children}</div>\n </div>\n </div>\n );\n};\n\nexport default FloatingPanelComponent;\n"],"mappings":";;;;;AAMA,SAAS,eAAe,WAA8B,QAA+B;CACnF,IAAI,cAAc,aAChB,OAAO;EAAE,MAAM;EAAQ,KAAK;CAAO;CAGrC,IAAI,cAAc,WAChB,OAAO;EAAE,OAAO;EAAQ,KAAK;CAAO;CAGtC,IAAI,cAAc,gBAChB,OAAO;EAAE,QAAQ;EAAQ,MAAM;CAAO;CAGxC,OAAO;EAAE,QAAQ;EAAQ,OAAO;CAAO;AACzC;AAEA,IAAM,0BAA+D,EAAE,UAAU,WAAW;CAC1F,MAAM,QAAQ,KAAK,MAAM,SAAS,KAAA;CAClC,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,EAAE;CAClD,MAAM,YAAY,KAAK,MAAM,aAAa;CAC1C,MAAM,UAAU,KAAK,MAAM,WAAW,CAAC;CACvC,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CAEtC,IAAI,QAAQ,WAAW,GACrB,OACE,oBAAC,OAAD;EACE,cAAY;EACZ,WAAU;EACV,0BAAwB,KAAK;EAC7B,MAAM,QAAQ,UAAU,KAAA;EACxB,OAAO,eAAe,WAAW,MAAM;EAEtC;CACE,CAAA;CAIT,MAAM,gBAAgB,cAAc,kBAAkB,cAAc;CACpE,MAAM,iBAAiB,cAAc,eAAe,cAAc;CAElE,OACE,oBAAC,OAAD;EACE,cAAY;EACZ,WAAU;EACV,0BAAwB,KAAK;EAC7B,MAAM,QAAQ,UAAU,KAAA;EACxB,OAAO,eAAe,WAAW,MAAM;YAEvC,qBAAC,OAAD;GAAK,WAAW,GAAG,oBAAoB,gBAAgB,qBAAqB,UAAU;aAAtF,CACE,oBAAC,UAAD;IACE,iBAAe;IACf,WAAW,GACT,qKACA,iBAAiB,eAAe,UAClC;IACA,aAAW,KAAK,MAAM,GAAG,KAAK,IAAI,YAAY,KAAA;IAC9C,eAAe,SAAS,UAAU,CAAC,KAAK;IACxC,MAAK;cAEJ,QAAQ,KAAK,aAAa,UACzB,oBAAC,YAAD,EAEE,MAAM,YACP,GAFM,YAAY,OAAO,GAAG,YAAY,KAAK,GAAG,OAEhD,CACF;GACK,CAAA,GACR,oBAAC,OAAD;IAAK,WAAW,OAAO,UAAU;IAAW;GAAc,CAAA,CACvD;;CACF,CAAA;AAET"}
1
+ {"version":3,"file":"floating-panel.js","names":[],"sources":["../../../resources/js/core/components/floating-panel.tsx"],"sourcesContent":["import { type CSSProperties, useState } from \"react\";\nimport type { RendererComponent } from \"@lattice-php/lattice/core/types\";\nimport type { FloatingPlacement } from \"@lattice-php/lattice/types/generated\";\nimport { RenderNode } from \"@lattice-php/lattice/core/renderer\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\n\nfunction placementStyle(placement: FloatingPlacement, offset: number): CSSProperties {\n if (placement === \"top-start\") {\n return { left: offset, top: offset };\n }\n\n if (placement === \"top-end\") {\n return { right: offset, top: offset };\n }\n\n if (placement === \"bottom-start\") {\n return { bottom: offset, left: offset };\n }\n\n return { bottom: offset, right: offset };\n}\n\nconst FloatingPanelComponent: RendererComponent<\"floating-panel\"> = ({ children, node }) => {\n const label = node.props.label ?? undefined;\n const offset = Math.max(0, node.props.offset ?? 16);\n const placement = node.props.placement ?? \"bottom-end\";\n const trigger = node.props.trigger ?? [];\n const [open, setOpen] = useState(false);\n\n if (trigger.length === 0) {\n return (\n <div\n aria-label={label}\n className=\"fixed z-50 max-w-[calc(100vw-2rem)] rounded-lt border border-lt-border bg-lt-popover p-1 text-lt-popover-fg shadow-lt-md\"\n data-lattice-component={nodeIdentity(node)}\n role={label ? \"group\" : undefined}\n style={placementStyle(placement, offset)}\n >\n {children}\n </div>\n );\n }\n\n const expandsUpward = placement === \"bottom-start\" || placement === \"bottom-end\";\n const anchorsToStart = placement === \"top-start\" || placement === \"bottom-start\";\n\n return (\n <div\n aria-label={label}\n className=\"fixed z-50 max-w-[calc(100vw-2rem)]\"\n data-lattice-component={nodeIdentity(node)}\n role={label ? \"group\" : undefined}\n style={placementStyle(placement, offset)}\n >\n <div className={cn(\"flex w-fit gap-2\", expandsUpward ? \"flex-col-reverse\" : \"flex-col\")}>\n <button\n aria-expanded={open}\n className={cn(\n \"inline-flex items-center gap-2 rounded-lt border border-lt-border bg-lt-popover px-3 py-1.5 text-sm font-medium text-lt-popover-fg shadow-lt-md hover:bg-lt-muted\",\n anchorsToStart ? \"self-start\" : \"self-end\",\n )}\n data-test={node.key ? `${node.key}-trigger` : undefined}\n onClick={() => setOpen((value) => !value)}\n type=\"button\"\n >\n {trigger.map((triggerNode, index) => (\n <RenderNode\n key={triggerNode.key ?? `${triggerNode.type}-${index}`}\n node={triggerNode}\n />\n ))}\n </button>\n <div className={open ? \"block\" : \"hidden\"}>{children}</div>\n </div>\n </div>\n );\n};\n\nexport default FloatingPanelComponent;\n"],"mappings":";;;;;;AAOA,SAAS,eAAe,WAA8B,QAA+B;CACnF,IAAI,cAAc,aAChB,OAAO;EAAE,MAAM;EAAQ,KAAK;CAAO;CAGrC,IAAI,cAAc,WAChB,OAAO;EAAE,OAAO;EAAQ,KAAK;CAAO;CAGtC,IAAI,cAAc,gBAChB,OAAO;EAAE,QAAQ;EAAQ,MAAM;CAAO;CAGxC,OAAO;EAAE,QAAQ;EAAQ,OAAO;CAAO;AACzC;AAEA,IAAM,0BAA+D,EAAE,UAAU,WAAW;CAC1F,MAAM,QAAQ,KAAK,MAAM,SAAS,KAAA;CAClC,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,UAAU,EAAE;CAClD,MAAM,YAAY,KAAK,MAAM,aAAa;CAC1C,MAAM,UAAU,KAAK,MAAM,WAAW,CAAC;CACvC,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CAEtC,IAAI,QAAQ,WAAW,GACrB,OACE,oBAAC,OAAD;EACE,cAAY;EACZ,WAAU;EACV,0BAAwB,aAAa,IAAI;EACzC,MAAM,QAAQ,UAAU,KAAA;EACxB,OAAO,eAAe,WAAW,MAAM;EAEtC;CACE,CAAA;CAIT,MAAM,gBAAgB,cAAc,kBAAkB,cAAc;CACpE,MAAM,iBAAiB,cAAc,eAAe,cAAc;CAElE,OACE,oBAAC,OAAD;EACE,cAAY;EACZ,WAAU;EACV,0BAAwB,aAAa,IAAI;EACzC,MAAM,QAAQ,UAAU,KAAA;EACxB,OAAO,eAAe,WAAW,MAAM;YAEvC,qBAAC,OAAD;GAAK,WAAW,GAAG,oBAAoB,gBAAgB,qBAAqB,UAAU;aAAtF,CACE,oBAAC,UAAD;IACE,iBAAe;IACf,WAAW,GACT,qKACA,iBAAiB,eAAe,UAClC;IACA,aAAW,KAAK,MAAM,GAAG,KAAK,IAAI,YAAY,KAAA;IAC9C,eAAe,SAAS,UAAU,CAAC,KAAK;IACxC,MAAK;cAEJ,QAAQ,KAAK,aAAa,UACzB,oBAAC,YAAD,EAEE,MAAM,YACP,GAFM,YAAY,OAAO,GAAG,YAAY,KAAK,GAAG,OAEhD,CACF;GACK,CAAA,GACR,oBAAC,OAAD;IAAK,WAAW,OAAO,UAAU;IAAW;GAAc,CAAA,CACvD;;CACF,CAAA;AAET"}
@@ -1,7 +1,8 @@
1
1
  import { LATTICE_EVENT } from "../../events/event-names.js";
2
+ import { Renderer } from "../renderer.js";
2
3
  import { apiJson } from "../api.js";
3
4
  import { Skeleton } from "./skeleton.js";
4
- import { Renderer } from "../renderer.js";
5
+ import { toNodes } from "../nodes.js";
5
6
  import { useCallback, useEffect, useState } from "react";
6
7
  import { jsx } from "react/jsx-runtime";
7
8
  //#region resources/js/core/components/fragment.tsx
@@ -12,10 +13,6 @@ var fragmentSizeHeights = {
12
13
  xl: 384,
13
14
  xs: 32
14
15
  };
15
- function getComponents(value) {
16
- if (!Array.isArray(value)) return [];
17
- return value.filter((node) => typeof node === "object" && node !== null && "type" in node && typeof node.type === "string");
18
- }
19
16
  var FragmentComponent = ({ node }) => {
20
17
  const endpoint = node.props.endpoint ?? "";
21
18
  const isLazy = node.props.lazy === true;
@@ -28,7 +25,7 @@ var FragmentComponent = ({ node }) => {
28
25
  if (!endpoint) return;
29
26
  setProcessing(true);
30
27
  try {
31
- setComponents(getComponents((await apiJson(endpoint, { ref: componentRef })).schema));
28
+ setComponents(toNodes((await apiJson(endpoint, { ref: componentRef })).schema));
32
29
  setHasLoaded(true);
33
30
  } finally {
34
31
  setProcessing(false);