@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 +1 @@
1
- {"version":3,"file":"query.js","names":[],"sources":["../../resources/js/table/query.ts"],"sourcesContent":["import { translate } from \"@lattice-php/lattice/i18n\";\nimport { DEFAULT_COLUMN_WIDTH } from \"@lattice-php/lattice/core/column-sizing\";\nimport type { ColumnWidth } from \"@lattice-php/lattice/types/generated\";\nimport type { TableColumn, TableSort, TableState } from \"./types\";\n\nexport function getColumnSort(state: TableState, column: TableColumn): TableSort | undefined {\n return state.sorts.find((currentSort) => currentSort.key === column.key);\n}\n\nexport function getColumnAriaSort(\n sort: TableSort | undefined,\n): \"ascending\" | \"descending\" | undefined {\n if (sort?.direction === \"asc\") {\n return \"ascending\";\n }\n\n if (sort?.direction === \"desc\") {\n return \"descending\";\n }\n\n return undefined;\n}\n\nexport function buildEndpoint(endpoint: string, state: TableState): string {\n const url = new URL(endpoint, window.location.origin);\n\n if (state.filters.length > 0) {\n url.searchParams.set(\"filter\", serializeFilters(state));\n }\n\n if (state.sorts.length > 0) {\n url.searchParams.set(\"sort\", serializeSorts(state));\n }\n\n appendTableFilters(url, state.tableFilters);\n\n url.searchParams.set(\"page\", String(state.page));\n url.searchParams.set(\"per_page\", String(state.perPage));\n\n return `${url.pathname}${url.search}`;\n}\n\n/**\n * Serialize the dedicated table filters as Laravel-native bracket params:\n * `tf[key]=v`, repeated `tf[key][]=v` for multi-value, and `tf[key][sub]=v`\n * for structured values (e.g. a date range's from/until). Empty values are\n * dropped so an unset filter never reaches the server.\n */\nfunction appendTableFilters(url: URL, tableFilters: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(getTableFilterParams(tableFilters))) {\n if (typeof value === \"string\") {\n url.searchParams.set(`tf[${key}]`, value);\n\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item != null && item !== \"\") {\n url.searchParams.append(`tf[${key}][]`, String(item));\n }\n }\n\n continue;\n }\n\n if (typeof value === \"object\" && value !== null) {\n for (const [subKey, subValue] of Object.entries(value as Record<string, unknown>)) {\n url.searchParams.set(`tf[${key}][${subKey}]`, String(subValue));\n }\n }\n }\n}\n\nfunction getTableFilterParams(tableFilters: Record<string, unknown>): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(tableFilters)) {\n const normalized = normalizeTableFilterValue(value);\n\n if (normalized !== undefined) {\n params[key] = normalized;\n }\n }\n\n return params;\n}\n\nfunction normalizeTableFilterValue(value: unknown): unknown | undefined {\n if (value == null || value === \"\") {\n return undefined;\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n if (Array.isArray(value)) {\n const items = value.filter((item) => item != null && item !== \"\").map(String);\n\n return items.length > 0 ? items : undefined;\n }\n\n if (typeof value === \"object\") {\n const entries = Object.entries(value)\n .filter(([, subValue]) => subValue != null && subValue !== \"\")\n .map(([subKey, subValue]) => [subKey, String(subValue)]);\n\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n }\n\n return String(value);\n}\n\nexport function getQueryParams(state: TableState): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n if (state.filters.length > 0) {\n params.filter = serializeFilters(state);\n }\n\n if (state.sorts.length > 0) {\n params.sort = serializeSorts(state);\n }\n\n const tableFilters = getTableFilterParams(state.tableFilters);\n\n if (Object.keys(tableFilters).length > 0) {\n params.tf = tableFilters;\n }\n\n return params;\n}\n\nfunction serializeFilters(state: TableState): string {\n return state.filters\n .map((clause) => `${clause.field}:${clause.operator}:${encodeURIComponent(clause.value)}`)\n .join(\",\");\n}\n\nfunction serializeSorts(state: TableState): string {\n return state.sorts\n .map((sort) => (sort.direction === \"desc\" ? `-${sort.key}` : sort.key))\n .join(\",\");\n}\n\nconst operatorLabels: Record<string, string> = {\n contains: \"contains\",\n starts_with: \"starts with\",\n ends_with: \"ends with\",\n eq: \"equals\",\n neq: \"not equals\",\n gt: \">\",\n gte: \"≥\",\n lt: \"<\",\n lte: \"≤\",\n in: \"in\",\n not_in: \"not in\",\n before: \"before\",\n after: \"after\",\n empty: \"is empty\",\n filled: \"is not empty\",\n};\n\nexport const VALUELESS_FILTER_OPERATORS = new Set<string>([\"empty\", \"filled\"]);\n\nexport function operatorLabel(operator: string): string {\n return translate(\"lattice\", `operators.${operator}`, operatorLabels[operator] ?? operator);\n}\n\nexport function getSortDirectionLabel(direction: string): string {\n return direction === \"desc\" ? \"descending\" : \"ascending\";\n}\n\nexport function nextSort(sorts: TableSort[], column: TableColumn): TableSort[] {\n if (!column.sortable) {\n return sorts;\n }\n\n const currentSort = sorts.find((sort) => sort.key === column.key);\n const remainingSorts = sorts.filter((sort) => sort.key !== column.key);\n\n if (!currentSort) {\n return [...sorts, { key: column.key, direction: \"asc\" }];\n }\n\n if (currentSort.direction === \"asc\") {\n return [...remainingSorts, { key: column.key, direction: \"desc\" }];\n }\n\n return remainingSorts;\n}\n\nexport function getVisiblePages(currentPage: number, lastPage: number): number[] {\n if (lastPage <= 5) {\n return Array.from({ length: lastPage }, (_, index) => index + 1);\n }\n\n const start = Math.max(1, Math.min(currentPage - 2, lastPage - 4));\n\n return Array.from({ length: 5 }, (_, index) => start + index);\n}\n\nexport function getTableSizingColumns(columns: TableColumn[]) {\n return columns.map((column) => ({\n key: column.key,\n label: column.label,\n width: columnWidthOrDefault(column),\n }));\n}\n\nfunction columnWidthOrDefault(column: TableColumn): ColumnWidth {\n return (column.width ??\n (column.type === \"column.stack\" ? \"xl\" : DEFAULT_COLUMN_WIDTH)) as ColumnWidth;\n}\n\nexport function getTableUtilityTracks(hasActions: boolean, hasSelection: boolean) {\n // Utility tracks are fixed because the independent header/filter/body grids would drift with content-sized tracks.\n return {\n leadingTracks: hasSelection ? [\"3rem\"] : [],\n trailingTracks: hasActions ? [\"10rem\"] : [],\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"query.js","names":[],"sources":["../../resources/js/table/query.ts"],"sourcesContent":["import { translate } from \"@lattice-php/lattice/i18n\";\nimport { DEFAULT_COLUMN_WIDTH } from \"@lattice-php/lattice/core/column-sizing\";\nimport type { ColumnWidth } from \"@lattice-php/lattice/types/generated\";\nimport { isEmptyMember } from \"./filter-values\";\nimport type { TableColumn, TableSort, TableState } from \"./types\";\n\nexport function getColumnSort(state: TableState, column: TableColumn): TableSort | undefined {\n return state.sorts.find((currentSort) => currentSort.key === column.key);\n}\n\nexport function getColumnAriaSort(\n sort: TableSort | undefined,\n): \"ascending\" | \"descending\" | undefined {\n if (sort?.direction === \"asc\") {\n return \"ascending\";\n }\n\n if (sort?.direction === \"desc\") {\n return \"descending\";\n }\n\n return undefined;\n}\n\nexport function buildEndpoint(endpoint: string, state: TableState): string {\n const url = new URL(endpoint, window.location.origin);\n\n if (state.filters.length > 0) {\n url.searchParams.set(\"filter\", serializeFilters(state));\n }\n\n if (state.sorts.length > 0) {\n url.searchParams.set(\"sort\", serializeSorts(state));\n }\n\n appendTableFilters(url, state.tableFilters);\n\n url.searchParams.set(\"page\", String(state.page));\n url.searchParams.set(\"per_page\", String(state.perPage));\n\n return `${url.pathname}${url.search}`;\n}\n\n/**\n * Serialize the dedicated table filters as Laravel-native bracket params:\n * `tf[key]=v`, repeated `tf[key][]=v` for multi-value, and `tf[key][sub]=v`\n * for structured values (e.g. a date range's from/until). Empty values are\n * dropped so an unset filter never reaches the server.\n */\nfunction appendTableFilters(url: URL, tableFilters: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(getTableFilterParams(tableFilters))) {\n if (typeof value === \"string\") {\n url.searchParams.set(`tf[${key}]`, value);\n\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n if (!isEmptyMember(item)) {\n url.searchParams.append(`tf[${key}][]`, String(item));\n }\n }\n\n continue;\n }\n\n if (typeof value === \"object\" && value !== null) {\n for (const [subKey, subValue] of Object.entries(value as Record<string, unknown>)) {\n url.searchParams.set(`tf[${key}][${subKey}]`, String(subValue));\n }\n }\n }\n}\n\nfunction getTableFilterParams(tableFilters: Record<string, unknown>): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(tableFilters)) {\n const normalized = normalizeTableFilterValue(value);\n\n if (normalized !== undefined) {\n params[key] = normalized;\n }\n }\n\n return params;\n}\n\nfunction normalizeTableFilterValue(value: unknown): unknown | undefined {\n if (isEmptyMember(value)) {\n return undefined;\n }\n\n if (typeof value === \"string\") {\n return value;\n }\n\n if (Array.isArray(value)) {\n const items = value.filter((item) => !isEmptyMember(item)).map(String);\n\n return items.length > 0 ? items : undefined;\n }\n\n if (typeof value === \"object\") {\n const entries = Object.entries(value)\n .filter(([, subValue]) => !isEmptyMember(subValue))\n .map(([subKey, subValue]) => [subKey, String(subValue)]);\n\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n }\n\n return String(value);\n}\n\nexport function getQueryParams(state: TableState): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n if (state.filters.length > 0) {\n params.filter = serializeFilters(state);\n }\n\n if (state.sorts.length > 0) {\n params.sort = serializeSorts(state);\n }\n\n const tableFilters = getTableFilterParams(state.tableFilters);\n\n if (Object.keys(tableFilters).length > 0) {\n params.tf = tableFilters;\n }\n\n return params;\n}\n\nfunction serializeFilters(state: TableState): string {\n return state.filters\n .map((clause) => `${clause.field}:${clause.operator}:${encodeURIComponent(clause.value)}`)\n .join(\",\");\n}\n\nfunction serializeSorts(state: TableState): string {\n return state.sorts\n .map((sort) => (sort.direction === \"desc\" ? `-${sort.key}` : sort.key))\n .join(\",\");\n}\n\nconst operatorLabels: Record<string, string> = {\n contains: \"contains\",\n starts_with: \"starts with\",\n ends_with: \"ends with\",\n eq: \"equals\",\n neq: \"not equals\",\n gt: \">\",\n gte: \"≥\",\n lt: \"<\",\n lte: \"≤\",\n in: \"in\",\n not_in: \"not in\",\n before: \"before\",\n after: \"after\",\n empty: \"is empty\",\n filled: \"is not empty\",\n};\n\nexport const VALUELESS_FILTER_OPERATORS = new Set<string>([\"empty\", \"filled\"]);\n\nexport function operatorLabel(operator: string): string {\n return translate(\"lattice\", `operators.${operator}`, operatorLabels[operator] ?? operator);\n}\n\nexport function getSortDirectionLabel(direction: string): string {\n return direction === \"desc\" ? \"descending\" : \"ascending\";\n}\n\nexport function nextSort(sorts: TableSort[], column: TableColumn): TableSort[] {\n if (!column.sortable) {\n return sorts;\n }\n\n const currentSort = sorts.find((sort) => sort.key === column.key);\n const remainingSorts = sorts.filter((sort) => sort.key !== column.key);\n\n if (!currentSort) {\n return [...sorts, { key: column.key, direction: \"asc\" }];\n }\n\n if (currentSort.direction === \"asc\") {\n return [...remainingSorts, { key: column.key, direction: \"desc\" }];\n }\n\n return remainingSorts;\n}\n\nexport function getVisiblePages(currentPage: number, lastPage: number): number[] {\n if (lastPage <= 5) {\n return Array.from({ length: lastPage }, (_, index) => index + 1);\n }\n\n const start = Math.max(1, Math.min(currentPage - 2, lastPage - 4));\n\n return Array.from({ length: 5 }, (_, index) => start + index);\n}\n\nexport function getTableSizingColumns(columns: TableColumn[]) {\n return columns.map((column) => ({\n key: column.key,\n label: column.label,\n width: columnWidthOrDefault(column),\n }));\n}\n\nfunction columnWidthOrDefault(column: TableColumn): ColumnWidth {\n return (column.width ??\n (column.type === \"column.stack\" ? \"xl\" : DEFAULT_COLUMN_WIDTH)) as ColumnWidth;\n}\n\nexport function getTableUtilityTracks(hasActions: boolean, hasSelection: boolean) {\n // Utility tracks are fixed because the independent header/filter/body grids would drift with content-sized tracks.\n return {\n leadingTracks: hasSelection ? [\"3rem\"] : [],\n trailingTracks: hasActions ? [\"10rem\"] : [],\n };\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import { cn } from "../lib/utils.js";
2
2
  import { Icon } from "../icons/sprite.js";
3
- import { useT } from "../i18n/instance.js";
3
+ import { RenderNode } from "../core/renderer.js";
4
4
  import { resolveTranslatable } from "../i18n/translatable.js";
5
5
  import { onToast } from "./toast.js";
6
- import { RenderNode } from "../core/renderer.js";
6
+ import { useT } from "../i18n/instance.js";
7
7
  import { variantStyles } from "./variant-styles.js";
8
8
  import { useEffect, useState } from "react";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,6 +1,5 @@
1
1
  export type Action = {
2
2
  confirmation: Confirmation | null;
3
- effects: Effect[];
4
3
  endpoint: string | null;
5
4
  form: Node | null;
6
5
  icon: string | null;
@@ -91,7 +90,6 @@ export type Builder = {
91
90
  };
92
91
  export type BulkAction = {
93
92
  confirmation: Confirmation | null;
94
- effects: Effect[];
95
93
  endpoint: string | null;
96
94
  form: Node | null;
97
95
  icon: string | null;
@@ -103,7 +101,9 @@ export type BulkAction = {
103
101
  };
104
102
  export type Button = {
105
103
  buttonType: ButtonType;
104
+ effects: Effect[];
106
105
  href: string | null;
106
+ icon: string | null;
107
107
  label: string;
108
108
  variant: ButtonVariant | null;
109
109
  };
@@ -148,10 +148,10 @@ export type ChartSeries = {
148
148
  };
149
149
  export type ChartSeriesType = "area" | "bar" | "line" | "pie";
150
150
  export type ChatBox = {
151
- conversationId: string | null;
152
151
  fill: boolean;
153
152
  historyEndpoint: string | null;
154
153
  placeholder: string | null;
154
+ remote: RemoteAccess | null;
155
155
  streamEndpoint: string | null;
156
156
  title: string | null;
157
157
  };
@@ -161,6 +161,10 @@ export type ChatMessage = {
161
161
  readonly parts: Node[];
162
162
  };
163
163
  export type ChatNode = {
164
+ type: "chat.box";
165
+ key?: string;
166
+ props: ChatBox;
167
+ } | {
164
168
  type: "chat.part.text";
165
169
  key?: string;
166
170
  props: TextPart;
@@ -296,10 +300,6 @@ export type CoreNode = {
296
300
  type: "chart";
297
301
  key?: string;
298
302
  props: Chart;
299
- } | {
300
- type: "chat.box";
301
- key?: string;
302
- props: ChatBox;
303
303
  } | {
304
304
  type: "floating-panel";
305
305
  key?: string;
@@ -393,6 +393,7 @@ export type DateInput = {
393
393
  tooltip: string | null;
394
394
  value: unknown;
395
395
  };
396
+ export type DateTimeStyle = "full" | "long" | "medium" | "short";
396
397
  export type DownloadEffect = {
397
398
  readonly url: string;
398
399
  };
@@ -420,9 +421,10 @@ export type Effect = ({
420
421
  type: "resetForm";
421
422
  } & ResetFormEffect) | ({
422
423
  type: "toast";
423
- } & ToastEffect);
424
- export type EffectType = "toast" | "callout" | "reloadComponent" | "reloadPage" | "redirect" | "download" | "openModal" | "closeModal" | "resetForm" | "localeChange";
425
- export type FieldType = "field.builder" | "field.checkbox" | "field.choice" | "field.date-input" | "field.file-upload" | "field.hidden-input" | "field.number-input" | "field.password-input" | "field.repeater" | "field.rich-editor" | "field.select" | "field.textarea" | "field.text-input";
424
+ } & ToastEffect) | ({
425
+ type: "toggleSidebar";
426
+ } & ToggleSidebarEffect);
427
+ export type FieldType = "field.builder" | "field.checkbox" | "field.choice" | "field.date-input" | "field.file-upload" | "field.hidden-input" | "field.number-input" | "field.otp" | "field.password-input" | "field.repeater" | "field.rich-editor" | "field.select" | "field.textarea" | "field.text-input";
426
428
  export type FileUpload = {
427
429
  accept: string | null;
428
430
  columnWidth: ColumnWidth;
@@ -522,6 +524,10 @@ export type FormFieldNode = {
522
524
  type: "field.number-input";
523
525
  key?: string;
524
526
  props: NumberInput;
527
+ } | {
528
+ type: "field.otp";
529
+ key?: string;
530
+ props: OtpInput;
525
531
  } | {
526
532
  type: "field.password-input";
527
533
  key?: string;
@@ -606,6 +612,7 @@ export type I18nConfig = {
606
612
  readonly saveMissing: boolean;
607
613
  readonly locales: string[];
608
614
  readonly preloadLocales: string[];
615
+ readonly timezone: string | null;
609
616
  };
610
617
  export type Icon = {
611
618
  class: string | null;
@@ -747,6 +754,31 @@ export type Option = {
747
754
  readonly value: string;
748
755
  };
749
756
  export type Orientation = "horizontal" | "vertical";
757
+ export type OtpInput = {
758
+ autoFocus: boolean;
759
+ columnWidth: ColumnWidth;
760
+ conditions: {
761
+ visible?: Condition[];
762
+ required?: Condition[];
763
+ readOnly?: Condition[];
764
+ disabled?: Condition[];
765
+ } | null;
766
+ dependsOnAny: boolean;
767
+ dependsOnKeys: string[] | null;
768
+ disabled: boolean;
769
+ editablePrefill: boolean;
770
+ helperText: string | null;
771
+ hidden: boolean;
772
+ label: string | null;
773
+ length: number;
774
+ name: string;
775
+ prefillRefreshOn: string[] | null;
776
+ prefillResetOn: string[] | null;
777
+ readOnly: boolean;
778
+ required: boolean;
779
+ tooltip: string | null;
780
+ value: unknown;
781
+ };
750
782
  export type Outlet = Record<string, never>;
751
783
  export type PageContainer = "centered" | "default";
752
784
  export type PageLayout = "app" | "auth" | "none";
@@ -811,20 +843,7 @@ export type RemoteAccess = {
811
843
  readonly tokenEndpoint: string;
812
844
  readonly ref: string;
813
845
  };
814
- export type RemoteChatBox = {
815
- conversationId: string | null;
816
- fill: boolean;
817
- historyEndpoint: string | null;
818
- placeholder: string | null;
819
- remote: RemoteAccess | null;
820
- streamEndpoint: string | null;
821
- title: string | null;
822
- };
823
846
  export type RemoteNode = {
824
- type: "remote.chat-box";
825
- key?: string;
826
- props: RemoteChatBox;
827
- } | {
828
847
  type: "remote.data-list";
829
848
  key?: string;
830
849
  props: DataList;
@@ -1025,14 +1044,19 @@ export type Text = {
1025
1044
  text: string;
1026
1045
  };
1027
1046
  export type TextColumn = {
1047
+ badge: {
1048
+ colorKey: string;
1049
+ } | null;
1028
1050
  copyable: boolean;
1029
1051
  date: {
1030
- format: string | null;
1052
+ dateStyle: string | null;
1053
+ timeStyle: string | null;
1031
1054
  } | null;
1032
1055
  link: {
1033
1056
  href: string | null;
1034
1057
  external: boolean;
1035
1058
  } | null;
1059
+ multiple: string | null;
1036
1060
  };
1037
1061
  export type TextInput = {
1038
1062
  autoComplete: string | null;
@@ -1105,6 +1129,9 @@ export type ToastMessage = {
1105
1129
  variant: Variant;
1106
1130
  message: Translatable | string;
1107
1131
  };
1132
+ export type ToggleSidebarEffect = {
1133
+ readonly target: string | null;
1134
+ };
1108
1135
  export type ToolCallPart = {
1109
1136
  args: Record<string, unknown>;
1110
1137
  name: string;
package/dist/vite.js CHANGED
@@ -3,7 +3,7 @@ import { svgSprite } from "@lattice-php/vite-svg-sprite";
3
3
  import { searchForWorkspaceRoot } from "vite";
4
4
  //#region resources/js/vite.ts
5
5
  function lattice(options = {}) {
6
- const plugins = [corePlugin(options)];
6
+ const plugins = [corePlugin(options), optionalPeersPlugin()];
7
7
  const iconOptions = resolveIconOptions(options);
8
8
  if (iconOptions) plugins.push(svgSprite(iconOptions));
9
9
  return plugins;
@@ -43,6 +43,37 @@ function corePlugin(options) {
43
43
  }
44
44
  };
45
45
  }
46
+ var OPTIONAL_PEER_STUB_PREFIX = "\0lattice-optional-peer/";
47
+ /**
48
+ * Real-time listeners statically import their optional Echo peers. A consumer
49
+ * that never uses real-time should still build, so stub a missing peer with
50
+ * hooks that throw — the `RealtimeListeners` error boundary then degrades
51
+ * gracefully and warns to install the peer, exactly as when it is absent.
52
+ */
53
+ var OPTIONAL_PEER_STUBS = { "@laravel/echo-react": [
54
+ "const missing = () => {",
55
+ " throw new Error(",
56
+ " \"[lattice] Real-time listeners require @laravel/echo-react. Install it and call configureEcho().\",",
57
+ " );",
58
+ "};",
59
+ "export const useEcho = missing;",
60
+ "export const useEchoPublic = missing;",
61
+ "export const useEchoPresence = missing;"
62
+ ].join("\n") };
63
+ function optionalPeersPlugin() {
64
+ return {
65
+ name: "lattice:optional-peers",
66
+ enforce: "pre",
67
+ async resolveId(id) {
68
+ if (!Object.prototype.hasOwnProperty.call(OPTIONAL_PEER_STUBS, id)) return null;
69
+ return await this.resolve(id, void 0, { skipSelf: true }) ? null : `${OPTIONAL_PEER_STUB_PREFIX}${id}`;
70
+ },
71
+ load(id) {
72
+ if (!id.startsWith(OPTIONAL_PEER_STUB_PREFIX)) return null;
73
+ return OPTIONAL_PEER_STUBS[id.slice(23)] ?? null;
74
+ }
75
+ };
76
+ }
46
77
  function resolveIconOptions(options) {
47
78
  const icons = options.icons ?? true;
48
79
  if (icons === false) return null;
package/dist/vite.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vite.js","names":[],"sources":["../resources/js/vite.ts"],"sourcesContent":["import path from \"node:path\";\nimport { svgSprite } from \"@lattice-php/vite-svg-sprite\";\nimport type { SvgSpriteOptions } from \"@lattice-php/vite-svg-sprite\";\nimport { searchForWorkspaceRoot } from \"vite\";\nimport type { Plugin, PluginOption, UserConfig } from \"vite\";\n\ntype InlineDependency = string | RegExp;\n\ntype ConfigWithTest = UserConfig & {\n test?: {\n server?: {\n deps?: {\n inline?: InlineDependency[];\n };\n };\n };\n};\n\nexport type LatticeViteIconsOptions = Omit<SvgSpriteOptions, \"dts\" | \"iconDirs\"> & {\n dirs?: string[];\n dts?: SvgSpriteOptions[\"dts\"] | false;\n};\n\nexport type LatticeViteOptions = {\n appRoot?: string;\n icons?: boolean | LatticeViteIconsOptions;\n root?: string;\n source?: boolean;\n};\n\ntype Roots = {\n appRoot: string;\n root: string;\n};\n\nexport function lattice(options: LatticeViteOptions = {}): PluginOption[] {\n const plugins: PluginOption[] = [corePlugin(options)];\n const iconOptions = resolveIconOptions(options);\n\n if (iconOptions) {\n plugins.push(svgSprite(iconOptions));\n }\n\n return plugins;\n}\n\nexport function latticeConfig(options: LatticeViteOptions = {}): ConfigWithTest {\n const { appRoot, root } = resolveRoots(options);\n\n return {\n resolve: {\n alias: options.source\n ? {\n \"@lattice-php/lattice/css\": path.resolve(root, \"resources/css/lattice.css\"),\n \"@lattice-php/lattice\": path.resolve(root, \"resources/js\"),\n }\n : {\n react: path.resolve(appRoot, \"node_modules/react\"),\n \"react-dom\": path.resolve(appRoot, \"node_modules/react-dom\"),\n },\n dedupe: [\"@inertiajs/react\", \"react\", \"react-dom\"],\n },\n server: options.source\n ? {\n fs: {\n allow: [searchForWorkspaceRoot(appRoot), root],\n },\n }\n : undefined,\n test: {\n server: {\n deps: {\n inline: [\n \"@lattice-php/lattice\",\n /[/\\\\]lattice[/\\\\]dist[/\\\\]/,\n /[/\\\\]lattice[/\\\\]node_modules[/\\\\]@radix-ui[/\\\\]/,\n /[/\\\\]lattice[/\\\\]node_modules[/\\\\]@tiptap[/\\\\]/,\n /[/\\\\]lattice[/\\\\]node_modules[/\\\\]react-i18next[/\\\\]/,\n ],\n },\n },\n },\n };\n}\n\nfunction corePlugin(options: LatticeViteOptions): Plugin {\n return {\n name: \"lattice\",\n config() {\n return latticeConfig(options);\n },\n };\n}\n\nfunction resolveIconOptions(options: LatticeViteOptions): SvgSpriteOptions | null {\n const icons = options.icons ?? true;\n\n if (icons === false) {\n return null;\n }\n\n const { root } = resolveRoots(options);\n const iconOptions = icons === true ? {} : icons;\n const { dirs = [], dts, ...spriteOptions } = iconOptions;\n const defaultTypes = {\n file: \"resources/js/types/sprite-icons.ts\",\n augmentModule: \"@lattice-php/lattice\",\n augmentInterface: \"KnownIcons\",\n };\n\n return {\n ...spriteOptions,\n iconDirs: [path.resolve(root, \"resources/icons\"), ...dirs],\n ...(dts === false ? {} : { dts: dts ?? defaultTypes }),\n };\n}\n\nfunction resolveRoots(options: LatticeViteOptions): Roots {\n const appRoot = options.appRoot ?? process.cwd();\n const root = options.root ?? path.resolve(appRoot, \"vendor/lattice-php/lattice\");\n\n return { appRoot, root };\n}\n"],"mappings":";;;;AAmCA,SAAgB,QAAQ,UAA8B,CAAC,GAAmB;CACxE,MAAM,UAA0B,CAAC,WAAW,OAAO,CAAC;CACpD,MAAM,cAAc,mBAAmB,OAAO;CAE9C,IAAI,aACF,QAAQ,KAAK,UAAU,WAAW,CAAC;CAGrC,OAAO;AACT;AAEA,SAAgB,cAAc,UAA8B,CAAC,GAAmB;CAC9E,MAAM,EAAE,SAAS,SAAS,aAAa,OAAO;CAE9C,OAAO;EACL,SAAS;GACP,OAAO,QAAQ,SACX;IACE,4BAA4B,KAAK,QAAQ,MAAM,2BAA2B;IAC1E,wBAAwB,KAAK,QAAQ,MAAM,cAAc;GAC3D,IACA;IACE,OAAO,KAAK,QAAQ,SAAS,oBAAoB;IACjD,aAAa,KAAK,QAAQ,SAAS,wBAAwB;GAC7D;GACJ,QAAQ;IAAC;IAAoB;IAAS;GAAW;EACnD;EACA,QAAQ,QAAQ,SACZ,EACE,IAAI,EACF,OAAO,CAAC,uBAAuB,OAAO,GAAG,IAAI,EAC/C,EACF,IACA,KAAA;EACJ,MAAM,EACJ,QAAQ,EACN,MAAM,EACJ,QAAQ;GACN;GACA;GACA;GACA;GACA;EACF,EACF,EACF,EACF;CACF;AACF;AAEA,SAAS,WAAW,SAAqC;CACvD,OAAO;EACL,MAAM;EACN,SAAS;GACP,OAAO,cAAc,OAAO;EAC9B;CACF;AACF;AAEA,SAAS,mBAAmB,SAAsD;CAChF,MAAM,QAAQ,QAAQ,SAAS;CAE/B,IAAI,UAAU,OACZ,OAAO;CAGT,MAAM,EAAE,SAAS,aAAa,OAAO;CAErC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,GAAG,kBADP,UAAU,OAAO,CAAC,IAAI;CAE1C,MAAM,eAAe;EACnB,MAAM;EACN,eAAe;EACf,kBAAkB;CACpB;CAEA,OAAO;EACL,GAAG;EACH,UAAU,CAAC,KAAK,QAAQ,MAAM,iBAAiB,GAAG,GAAG,IAAI;EACzD,GAAI,QAAQ,QAAQ,CAAC,IAAI,EAAE,KAAK,OAAO,aAAa;CACtD;AACF;AAEA,SAAS,aAAa,SAAoC;CACxD,MAAM,UAAU,QAAQ,WAAW,QAAQ,IAAI;CAG/C,OAAO;EAAE;EAAS,MAFL,QAAQ,QAAQ,KAAK,QAAQ,SAAS,4BAA4B;CAExD;AACzB"}
1
+ {"version":3,"file":"vite.js","names":[],"sources":["../resources/js/vite.ts"],"sourcesContent":["import path from \"node:path\";\nimport { svgSprite } from \"@lattice-php/vite-svg-sprite\";\nimport type { SvgSpriteOptions } from \"@lattice-php/vite-svg-sprite\";\nimport { searchForWorkspaceRoot } from \"vite\";\nimport type { Plugin, PluginOption, UserConfig } from \"vite\";\n\ntype InlineDependency = string | RegExp;\n\ntype ConfigWithTest = UserConfig & {\n test?: {\n server?: {\n deps?: {\n inline?: InlineDependency[];\n };\n };\n };\n};\n\nexport type LatticeViteIconsOptions = Omit<SvgSpriteOptions, \"dts\" | \"iconDirs\"> & {\n dirs?: string[];\n dts?: SvgSpriteOptions[\"dts\"] | false;\n};\n\nexport type LatticeViteOptions = {\n appRoot?: string;\n icons?: boolean | LatticeViteIconsOptions;\n root?: string;\n source?: boolean;\n};\n\ntype Roots = {\n appRoot: string;\n root: string;\n};\n\nexport function lattice(options: LatticeViteOptions = {}): PluginOption[] {\n const plugins: PluginOption[] = [corePlugin(options), optionalPeersPlugin()];\n const iconOptions = resolveIconOptions(options);\n\n if (iconOptions) {\n plugins.push(svgSprite(iconOptions));\n }\n\n return plugins;\n}\n\nexport function latticeConfig(options: LatticeViteOptions = {}): ConfigWithTest {\n const { appRoot, root } = resolveRoots(options);\n\n return {\n resolve: {\n alias: options.source\n ? {\n \"@lattice-php/lattice/css\": path.resolve(root, \"resources/css/lattice.css\"),\n \"@lattice-php/lattice\": path.resolve(root, \"resources/js\"),\n }\n : {\n react: path.resolve(appRoot, \"node_modules/react\"),\n \"react-dom\": path.resolve(appRoot, \"node_modules/react-dom\"),\n },\n dedupe: [\"@inertiajs/react\", \"react\", \"react-dom\"],\n },\n server: options.source\n ? {\n fs: {\n allow: [searchForWorkspaceRoot(appRoot), root],\n },\n }\n : undefined,\n test: {\n server: {\n deps: {\n inline: [\n \"@lattice-php/lattice\",\n /[/\\\\]lattice[/\\\\]dist[/\\\\]/,\n /[/\\\\]lattice[/\\\\]node_modules[/\\\\]@radix-ui[/\\\\]/,\n /[/\\\\]lattice[/\\\\]node_modules[/\\\\]@tiptap[/\\\\]/,\n /[/\\\\]lattice[/\\\\]node_modules[/\\\\]react-i18next[/\\\\]/,\n ],\n },\n },\n },\n };\n}\n\nfunction corePlugin(options: LatticeViteOptions): Plugin {\n return {\n name: \"lattice\",\n config() {\n return latticeConfig(options);\n },\n };\n}\n\nconst OPTIONAL_PEER_STUB_PREFIX = \"\\0lattice-optional-peer/\";\n\n/**\n * Real-time listeners statically import their optional Echo peers. A consumer\n * that never uses real-time should still build, so stub a missing peer with\n * hooks that throw — the `RealtimeListeners` error boundary then degrades\n * gracefully and warns to install the peer, exactly as when it is absent.\n */\nconst OPTIONAL_PEER_STUBS: Record<string, string> = {\n \"@laravel/echo-react\": [\n \"const missing = () => {\",\n \" throw new Error(\",\n ' \"[lattice] Real-time listeners require @laravel/echo-react. Install it and call configureEcho().\",',\n \" );\",\n \"};\",\n \"export const useEcho = missing;\",\n \"export const useEchoPublic = missing;\",\n \"export const useEchoPresence = missing;\",\n ].join(\"\\n\"),\n};\n\nfunction optionalPeersPlugin(): Plugin {\n return {\n name: \"lattice:optional-peers\",\n enforce: \"pre\",\n async resolveId(id) {\n if (!Object.prototype.hasOwnProperty.call(OPTIONAL_PEER_STUBS, id)) {\n return null;\n }\n\n const installed = await this.resolve(id, undefined, { skipSelf: true });\n\n return installed ? null : `${OPTIONAL_PEER_STUB_PREFIX}${id}`;\n },\n load(id) {\n if (!id.startsWith(OPTIONAL_PEER_STUB_PREFIX)) {\n return null;\n }\n\n return OPTIONAL_PEER_STUBS[id.slice(OPTIONAL_PEER_STUB_PREFIX.length)] ?? null;\n },\n };\n}\n\nfunction resolveIconOptions(options: LatticeViteOptions): SvgSpriteOptions | null {\n const icons = options.icons ?? true;\n\n if (icons === false) {\n return null;\n }\n\n const { root } = resolveRoots(options);\n const iconOptions = icons === true ? {} : icons;\n const { dirs = [], dts, ...spriteOptions } = iconOptions;\n const defaultTypes = {\n file: \"resources/js/types/sprite-icons.ts\",\n augmentModule: \"@lattice-php/lattice\",\n augmentInterface: \"KnownIcons\",\n };\n\n return {\n ...spriteOptions,\n iconDirs: [path.resolve(root, \"resources/icons\"), ...dirs],\n ...(dts === false ? {} : { dts: dts ?? defaultTypes }),\n };\n}\n\nfunction resolveRoots(options: LatticeViteOptions): Roots {\n const appRoot = options.appRoot ?? process.cwd();\n const root = options.root ?? path.resolve(appRoot, \"vendor/lattice-php/lattice\");\n\n return { appRoot, root };\n}\n"],"mappings":";;;;AAmCA,SAAgB,QAAQ,UAA8B,CAAC,GAAmB;CACxE,MAAM,UAA0B,CAAC,WAAW,OAAO,GAAG,oBAAoB,CAAC;CAC3E,MAAM,cAAc,mBAAmB,OAAO;CAE9C,IAAI,aACF,QAAQ,KAAK,UAAU,WAAW,CAAC;CAGrC,OAAO;AACT;AAEA,SAAgB,cAAc,UAA8B,CAAC,GAAmB;CAC9E,MAAM,EAAE,SAAS,SAAS,aAAa,OAAO;CAE9C,OAAO;EACL,SAAS;GACP,OAAO,QAAQ,SACX;IACE,4BAA4B,KAAK,QAAQ,MAAM,2BAA2B;IAC1E,wBAAwB,KAAK,QAAQ,MAAM,cAAc;GAC3D,IACA;IACE,OAAO,KAAK,QAAQ,SAAS,oBAAoB;IACjD,aAAa,KAAK,QAAQ,SAAS,wBAAwB;GAC7D;GACJ,QAAQ;IAAC;IAAoB;IAAS;GAAW;EACnD;EACA,QAAQ,QAAQ,SACZ,EACE,IAAI,EACF,OAAO,CAAC,uBAAuB,OAAO,GAAG,IAAI,EAC/C,EACF,IACA,KAAA;EACJ,MAAM,EACJ,QAAQ,EACN,MAAM,EACJ,QAAQ;GACN;GACA;GACA;GACA;GACA;EACF,EACF,EACF,EACF;CACF;AACF;AAEA,SAAS,WAAW,SAAqC;CACvD,OAAO;EACL,MAAM;EACN,SAAS;GACP,OAAO,cAAc,OAAO;EAC9B;CACF;AACF;AAEA,IAAM,4BAA4B;;;;;;;AAQlC,IAAM,sBAA8C,EAClD,uBAAuB;CACrB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,EAAE,KAAK,IAAI,EACb;AAEA,SAAS,sBAA8B;CACrC,OAAO;EACL,MAAM;EACN,SAAS;EACT,MAAM,UAAU,IAAI;GAClB,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,qBAAqB,EAAE,GAC/D,OAAO;GAKT,OAAO,MAFiB,KAAK,QAAQ,IAAI,KAAA,GAAW,EAAE,UAAU,KAAK,CAAC,IAEnD,OAAO,GAAG,4BAA4B;EAC3D;EACA,KAAK,IAAI;GACP,IAAI,CAAC,GAAG,WAAW,yBAAyB,GAC1C,OAAO;GAGT,OAAO,oBAAoB,GAAG,MAAM,EAAgC,MAAM;EAC5E;CACF;AACF;AAEA,SAAS,mBAAmB,SAAsD;CAChF,MAAM,QAAQ,QAAQ,SAAS;CAE/B,IAAI,UAAU,OACZ,OAAO;CAGT,MAAM,EAAE,SAAS,aAAa,OAAO;CAErC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,GAAG,kBADP,UAAU,OAAO,CAAC,IAAI;CAE1C,MAAM,eAAe;EACnB,MAAM;EACN,eAAe;EACf,kBAAkB;CACpB;CAEA,OAAO;EACL,GAAG;EACH,UAAU,CAAC,KAAK,QAAQ,MAAM,iBAAiB,GAAG,GAAG,IAAI;EACzD,GAAI,QAAQ,QAAQ,CAAC,IAAI,EAAE,KAAK,OAAO,aAAa;CACtD;AACF;AAEA,SAAS,aAAa,SAAoC;CACxD,MAAM,UAAU,QAAQ,WAAW,QAAQ,IAAI;CAG/C,OAAO;EAAE;EAAS,MAFL,QAAQ,QAAQ,KAAK,QAAQ,SAAS,4BAA4B;CAExD;AACzB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lattice-php/lattice",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Server-driven React components for Laravel and Inertia.",
5
5
  "license": "MIT",
6
6
  "author": "Manuel Christlieb <manuel@christlieb.eu>",
@@ -135,6 +135,14 @@
135
135
  "types": "./dist/registry.d.ts",
136
136
  "import": "./dist/registry.js"
137
137
  },
138
+ "./remote": {
139
+ "types": "./dist/remote/index.d.ts",
140
+ "import": "./dist/remote/index.js"
141
+ },
142
+ "./remote/*": {
143
+ "types": "./dist/remote/*.d.ts",
144
+ "import": "./dist/remote/*.js"
145
+ },
138
146
  "./table": {
139
147
  "types": "./dist/table/index.d.ts",
140
148
  "import": "./dist/table/index.js"
@@ -195,8 +203,8 @@
195
203
  "lint": "oxlint resources/js workbench/resources/js",
196
204
  "lint:fix": "oxlint resources/js workbench/resources/js --fix",
197
205
  "lint:github": "oxlint resources/js workbench/resources/js --format=github",
198
- "format": "oxfmt --write \"resources/js/**/*.{ts,tsx}\" \"workbench/resources/js/**/*.{ts,tsx}\"",
199
- "format:check": "oxfmt --check \"resources/js/**/*.{ts,tsx}\" \"workbench/resources/js/**/*.{ts,tsx}\"",
206
+ "format": "oxfmt --write \"resources/js/**/*.{ts,tsx}\" \"workbench/resources/js/**/*.{ts,tsx}\" \"docs/**/*.{ts,tsx,md,mdx}\"",
207
+ "format:check": "oxfmt --check \"resources/js/**/*.{ts,tsx}\" \"workbench/resources/js/**/*.{ts,tsx}\" \"docs/**/*.{ts,tsx,md,mdx}\"",
200
208
  "analyze": "SONDA=1 vite build && mkdir -p docs/public && cp docs/generated/bundle-report.html docs/public/bundle-report.html",
201
209
  "docs:dev": "npm run analyze && astro dev",
202
210
  "docs:build": "npm run analyze && astro build",
@@ -222,7 +230,9 @@
222
230
  "clsx": "^2.1.1",
223
231
  "i18next": "^26.3.1",
224
232
  "i18next-http-backend": "^4.0.0",
233
+ "input-otp": "^1.4.2",
225
234
  "recharts": "^3.8.1",
235
+ "starlight-llms-txt": "^0.10.0",
226
236
  "tailwind-merge": "^3.0.1"
227
237
  },
228
238
  "peerDependencies": {
@@ -264,6 +274,7 @@
264
274
  "laravel-echo": "^2.3.7",
265
275
  "laravel-vite-plugin": "^3.0.0",
266
276
  "lucide-static": "^1.18.0",
277
+ "mermaid": "^11.15.0",
267
278
  "oxfmt": "^0.54.0",
268
279
  "oxlint": "^1.68.0",
269
280
  "playwright": "^1.60.0",
@@ -1,3 +0,0 @@
1
- import { RendererComponent } from '../../core/types';
2
- export declare const RemoteChatBox: RendererComponent<"remote.chat-box">;
3
- export default RemoteChatBox;
@@ -1,65 +0,0 @@
1
- import { cn } from "../../lib/utils.js";
2
- import { testIdentity } from "../../core/test-id.js";
3
- import { useT } from "../../i18n/instance.js";
4
- import { remoteJson } from "../../core/api.js";
5
- import { createRemoteNdjsonChatTransport, ndjsonChatTransport } from "../../chat/transport.js";
6
- import { useChat } from "../../chat/use-chat.js";
7
- import { MessageList } from "../../chat/components/message-list.js";
8
- import { PromptInput } from "../../chat/components/prompt-input.js";
9
- import { useCallback, useEffect, useMemo, useRef } from "react";
10
- import { jsx, jsxs } from "react/jsx-runtime";
11
- //#region resources/js/remote/components/chat-box.tsx
12
- var RemoteChatBox = ({ node }) => {
13
- const props = node.props;
14
- const { t } = useT("lattice");
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
- });
20
- const seededRef = useRef(false);
21
- const seedHistory = useCallback(async () => {
22
- if (seededRef.current || !props.historyEndpoint || !props.remote) return;
23
- seededRef.current = true;
24
- setMessages((await remoteJson(props.historyEndpoint, { remote: props.remote })).messages);
25
- }, [
26
- props.historyEndpoint,
27
- props.remote,
28
- setMessages
29
- ]);
30
- useEffect(() => {
31
- seedHistory().catch(() => {});
32
- }, [seedHistory]);
33
- const disabled = status === "submitted" || status === "streaming" || !props.remote || !props.streamEndpoint;
34
- const visibleError = error;
35
- return /* @__PURE__ */ jsxs("div", {
36
- 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"),
37
- "data-test": testIdentity("chat-box"),
38
- children: [
39
- /* @__PURE__ */ jsx("div", {
40
- className: "flex items-center border-b border-lt-border px-3 py-2",
41
- children: /* @__PURE__ */ jsx("span", {
42
- className: "text-sm font-medium text-lt-fg",
43
- children: props.title ?? t("chat.title", "Chat")
44
- })
45
- }),
46
- /* @__PURE__ */ jsx("div", {
47
- className: "flex-1 overflow-y-auto",
48
- children: /* @__PURE__ */ jsx(MessageList, { messages })
49
- }),
50
- visibleError ? /* @__PURE__ */ jsx("div", {
51
- className: "border-t border-lt-danger/40 px-3 py-2 text-xs text-lt-danger",
52
- children: visibleError
53
- }) : null,
54
- /* @__PURE__ */ jsx(PromptInput, {
55
- disabled,
56
- onSubmit: sendMessage,
57
- placeholder: props.placeholder ?? void 0
58
- })
59
- ]
60
- });
61
- };
62
- //#endregion
63
- export { RemoteChatBox, RemoteChatBox as default };
64
-
65
- //# sourceMappingURL=chat-box.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat-box.js","names":[],"sources":["../../../resources/js/remote/components/chat-box.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { 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 { RemoteChatBox as RemoteChatBoxProps } from \"@lattice-php/lattice/types/generated\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport {\n createRemoteNdjsonChatTransport,\n ndjsonChatTransport,\n} from \"@lattice-php/lattice/chat/transport\";\nimport { useChat } from \"@lattice-php/lattice/chat/use-chat\";\nimport type { ChatMessage } from \"@lattice-php/lattice/chat/types\";\nimport { MessageList } from \"@lattice-php/lattice/chat/components/message-list\";\nimport { PromptInput } from \"@lattice-php/lattice/chat/components/prompt-input\";\n\ntype ChatHistoryResponse = { messages: ChatMessage[] };\n\nexport const RemoteChatBox: RendererComponent<\"remote.chat-box\"> = ({ node }) => {\n const props: RemoteChatBoxProps = 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 || !props.remote) {\n return;\n }\n\n seededRef.current = true;\n\n const payload = await remoteJson<ChatHistoryResponse>(props.historyEndpoint, {\n remote: props.remote,\n });\n\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.remote || !props.streamEndpoint;\n const visibleError = error;\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 {visibleError ? (\n <div className=\"border-t border-lt-danger/40 px-3 py-2 text-xs text-lt-danger\">\n {visibleError}\n </div>\n ) : null}\n <PromptInput\n disabled={disabled}\n onSubmit={sendMessage}\n placeholder={props.placeholder ?? undefined}\n />\n </div>\n );\n};\n\nexport default RemoteChatBox;\n"],"mappings":";;;;;;;;;;;AAkBA,IAAa,iBAAuD,EAAE,WAAW;CAC/E,MAAM,QAA4B,KAAK;CACvC,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,mBAAmB,CAAC,MAAM,QACxD;EAGF,UAAU,UAAU;EAMpB,aAAY,MAJU,WAAgC,MAAM,iBAAiB,EAC3E,QAAQ,MAAM,OAChB,CAAC,GAEmB,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,UAAU,CAAC,MAAM;CACjD,MAAM,eAAe;CAErB,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,eACC,oBAAC,OAAD;IAAK,WAAU;cACZ;GACE,CAAA,IACH;GACJ,oBAAC,aAAD;IACY;IACV,UAAU;IACV,aAAa,MAAM,eAAe,KAAA;GACnC,CAAA;EACE;;AAET"}