@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.
- package/dist/action/components/action-form.js +3 -3
- package/dist/action/components/action-group.js +1 -1
- package/dist/action/components/action.js +10 -16
- package/dist/action/components/action.js.map +1 -1
- package/dist/action/run-action.d.ts +9 -0
- package/dist/action/run-action.js +22 -0
- package/dist/action/run-action.js.map +1 -0
- package/dist/chat/components/chat-box.js +31 -14
- package/dist/chat/components/chat-box.js.map +1 -1
- package/dist/chat/components/message.js +1 -1
- package/dist/chat/components/prompt-input.js +1 -1
- package/dist/chat/index.js +2 -0
- package/dist/chat/index.js.map +1 -1
- package/dist/core/components/badge.js +1 -1
- package/dist/core/components/button.js +17 -5
- package/dist/core/components/button.js.map +1 -1
- package/dist/core/components/card.js +2 -1
- package/dist/core/components/card.js.map +1 -1
- package/dist/core/components/chart.js +4 -1
- package/dist/core/components/chart.js.map +1 -1
- package/dist/core/components/dialog.js +1 -1
- package/dist/core/components/floating-panel.js +3 -2
- package/dist/core/components/floating-panel.js.map +1 -1
- package/dist/core/components/fragment.js +3 -6
- package/dist/core/components/fragment.js.map +1 -1
- package/dist/core/components/grid.js +2 -1
- package/dist/core/components/grid.js.map +1 -1
- package/dist/core/components/index.js +0 -2
- package/dist/core/components/index.js.map +1 -1
- package/dist/core/components/section.js +5 -9
- package/dist/core/components/section.js.map +1 -1
- package/dist/core/components/stack.js +2 -1
- package/dist/core/components/stack.js.map +1 -1
- package/dist/core/components/tabs.js +1 -1
- package/dist/core/nodes.d.ts +6 -0
- package/dist/core/nodes.js +13 -0
- package/dist/core/nodes.js.map +1 -0
- package/dist/core/renderer.js +1 -1
- package/dist/create-app.d.ts +21 -0
- package/dist/create-app.js +31 -0
- package/dist/create-app.js.map +1 -0
- package/dist/effects/registry.js +2 -1
- package/dist/effects/registry.js.map +1 -1
- package/dist/effects/use-effect-dispatcher.js +1 -1
- package/dist/effects/use-flash-effects.js +1 -1
- package/dist/events/event-names.d.ts +4 -2
- package/dist/events/event-names.js +4 -2
- package/dist/events/event-names.js.map +1 -1
- package/dist/form/components/base/input-otp.d.ts +7 -0
- package/dist/form/components/base/input-otp.js +30 -0
- package/dist/form/components/base/input-otp.js.map +1 -0
- package/dist/form/components/conditions.js +1 -1
- package/dist/form/components/conditions.js.map +1 -1
- package/dist/form/components/fields/file-upload.js +1 -1
- package/dist/form/components/fields/otp-input.d.ts +2 -0
- package/dist/form/components/fields/otp-input.js +25 -0
- package/dist/form/components/fields/otp-input.js.map +1 -0
- package/dist/form/components/fields/row-item.js +1 -1
- package/dist/form/components/fields/table-rows.js +1 -1
- package/dist/form/components/form.js +1 -1
- package/dist/form/components/index.d.ts +1 -0
- package/dist/form/components/index.js +2 -1
- package/dist/form/components/prefill-targets.d.ts +0 -1
- package/dist/form/components/prefill-targets.js +1 -4
- package/dist/form/components/prefill-targets.js.map +1 -1
- package/dist/form/components/use-form-resolver.js +2 -2
- package/dist/form/components/use-form-resolver.js.map +1 -1
- package/dist/form/index.js +1 -0
- package/dist/form/index.js.map +1 -1
- package/dist/i18n/config.d.ts +3 -0
- package/dist/i18n/config.js +20 -4
- package/dist/i18n/config.js.map +1 -1
- package/dist/i18n/date-time.d.ts +7 -0
- package/dist/i18n/date-time.js +33 -0
- package/dist/i18n/date-time.js.map +1 -0
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/index.js +3 -1
- package/dist/i18n/locale-reload.js +1 -1
- package/dist/i18n/page-props.js +1 -1
- package/dist/i18n/page-props.js.map +1 -1
- package/dist/i18n/timezone.d.ts +7 -0
- package/dist/i18n/timezone.js +53 -0
- package/dist/i18n/timezone.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +14 -13
- package/dist/layout/breadcrumbs.js +3 -2
- package/dist/layout/breadcrumbs.js.map +1 -1
- package/dist/layout/callouts.js +1 -1
- package/dist/layout/components.js +1 -1
- package/dist/layout/menu-item.js +2 -2
- package/dist/layout/menu.js +2 -1
- package/dist/layout/menu.js.map +1 -1
- package/dist/layout/popover.js +1 -1
- package/dist/layout/sidebar.js +69 -29
- package/dist/layout/sidebar.js.map +1 -1
- package/dist/layout/topbar.js +2 -1
- package/dist/layout/topbar.js.map +1 -1
- package/dist/registry.js +1 -1
- package/dist/remote/components/data-list.js +1 -1
- package/dist/remote/index.js +1 -5
- package/dist/remote/index.js.map +1 -1
- package/dist/table/components/bulk-bar.js +10 -15
- package/dist/table/components/bulk-bar.js.map +1 -1
- package/dist/table/components/cells/text-cell.js +46 -4
- package/dist/table/components/cells/text-cell.js.map +1 -1
- package/dist/table/components/table.js +1 -1
- package/dist/table/filter-values.d.ts +5 -0
- package/dist/table/filter-values.js +10 -3
- package/dist/table/filter-values.js.map +1 -1
- package/dist/table/format.d.ts +11 -1
- package/dist/table/format.js +23 -21
- package/dist/table/format.js.map +1 -1
- package/dist/table/query.js +5 -4
- package/dist/table/query.js.map +1 -1
- package/dist/toast/toaster.js +2 -2
- package/dist/types/generated.d.ts +51 -24
- package/dist/vite.js +32 -1
- package/dist/vite.js.map +1 -1
- package/package.json +14 -3
- package/dist/remote/components/chat-box.d.ts +0 -3
- package/dist/remote/components/chat-box.js +0 -65
- package/dist/remote/components/chat-box.js.map +0 -1
package/dist/table/query.js.map
CHANGED
|
@@ -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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"}
|
package/dist/toast/toaster.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { cn } from "../lib/utils.js";
|
|
2
2
|
import { Icon } from "../icons/sprite.js";
|
|
3
|
-
import {
|
|
3
|
+
import { RenderNode } from "../core/renderer.js";
|
|
4
4
|
import { resolveTranslatable } from "../i18n/translatable.js";
|
|
5
5
|
import { onToast } from "./toast.js";
|
|
6
|
-
import {
|
|
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
|
-
|
|
425
|
-
|
|
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
|
-
|
|
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;
|
|
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.
|
|
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,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"}
|