@lattice-php/lattice 0.9.0 → 0.11.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 +1 -1
- package/dist/action/components/action-form.js.map +1 -1
- package/dist/chat/components/chat-box.js +1 -1
- package/dist/chat/components/chat-box.js.map +1 -1
- package/dist/chat/components/prompt-input.js +2 -2
- package/dist/chat/components/prompt-input.js.map +1 -1
- package/dist/core/components/combobox.js +1 -1
- package/dist/core/components/combobox.js.map +1 -1
- package/dist/core/components/fragment.js +4 -1
- package/dist/core/components/fragment.js.map +1 -1
- package/dist/core/components/icon.js +4 -1
- package/dist/core/components/icon.js.map +1 -1
- package/dist/core/components/info-tooltip.js +1 -1
- package/dist/core/components/info-tooltip.js.map +1 -1
- package/dist/core/components/spinner.js +1 -1
- package/dist/core/components/spinner.js.map +1 -1
- package/dist/core/components/tabs.js +1 -1
- package/dist/core/components/tabs.js.map +1 -1
- package/dist/core/components/text.js +4 -1
- package/dist/core/components/text.js.map +1 -1
- package/dist/form/components/fields/date-input.js +7 -6
- package/dist/form/components/fields/date-input.js.map +1 -1
- package/dist/form/components/fields/date-picker-control.d.ts +18 -0
- package/dist/form/components/fields/date-picker-control.js +199 -0
- package/dist/form/components/fields/date-picker-control.js.map +1 -0
- package/dist/form/components/fields/date-picker-value.d.ts +10 -0
- package/dist/form/components/fields/date-picker-value.js +125 -0
- package/dist/form/components/fields/date-picker-value.js.map +1 -0
- package/dist/form/components/fields/date-time-input.d.ts +2 -0
- package/dist/form/components/fields/date-time-input.js +34 -0
- package/dist/form/components/fields/date-time-input.js.map +1 -0
- package/dist/form/components/fields/file-upload.js +3 -3
- package/dist/form/components/fields/file-upload.js.map +1 -1
- package/dist/form/components/fields/lazy-date-picker-control.d.ts +2 -0
- package/dist/form/components/fields/lazy-date-picker-control.js +17 -0
- package/dist/form/components/fields/lazy-date-picker-control.js.map +1 -0
- package/dist/form/components/fields/number-input.js +1 -1
- package/dist/form/components/fields/rich-editor.js +3 -3
- package/dist/form/components/fields/rich-editor.js.map +1 -1
- package/dist/form/components/fields/row-action-menu.js +2 -2
- package/dist/form/components/fields/row-action-menu.js.map +1 -1
- package/dist/form/components/fields/select.js +1 -1
- package/dist/form/components/fields/select.js.map +1 -1
- package/dist/form/components/fields/table-rows.js +2 -2
- package/dist/form/components/fields/table-rows.js.map +1 -1
- package/dist/form/components/fields/text-input.js +1 -1
- package/dist/form/components/fields/time-input.d.ts +2 -0
- package/dist/form/components/fields/time-input.js +30 -0
- package/dist/form/components/fields/time-input.js.map +1 -0
- package/dist/form/components/fields/toggle.d.ts +2 -0
- package/dist/form/components/fields/toggle.js +65 -0
- package/dist/form/components/fields/toggle.js.map +1 -0
- package/dist/form/components/index.d.ts +3 -0
- package/dist/form/components/index.js +4 -1
- package/dist/form/components/types.d.ts +1 -1
- package/dist/form/components/use-controlled-field.d.ts +2 -0
- package/dist/form/components/use-controlled-field.js +6 -2
- package/dist/form/components/use-controlled-field.js.map +1 -1
- package/dist/form/index.js +4 -1
- package/dist/form/index.js.map +1 -1
- package/dist/lattice.css +6 -0
- package/dist/layout/callouts.js +1 -1
- package/dist/layout/callouts.js.map +1 -1
- package/dist/lib/utils.js +11 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/remote/components/data-list.js +3 -3
- package/dist/remote/components/data-list.js.map +1 -1
- package/dist/table/components/bulk-bar.js +2 -2
- package/dist/table/components/bulk-bar.js.map +1 -1
- package/dist/table/components/column-filter-control.js +5 -5
- package/dist/table/components/column-filter-control.js.map +1 -1
- package/dist/table/components/filter-bar.js +3 -3
- package/dist/table/components/filter-bar.js.map +1 -1
- package/dist/table/components/filter-controls.js +9 -9
- package/dist/table/components/filter-controls.js.map +1 -1
- package/dist/table/components/filter-stack-bar.js +1 -1
- package/dist/table/components/filter-stack-bar.js.map +1 -1
- package/dist/table/components/filter-value-input.js +5 -5
- package/dist/table/components/filter-value-input.js.map +1 -1
- package/dist/table/components/pagination.js +8 -8
- package/dist/table/components/pagination.js.map +1 -1
- package/dist/table/components/table.js +4 -4
- package/dist/table/components/table.js.map +1 -1
- package/dist/table/query.js +1 -1
- package/dist/table/query.js.map +1 -1
- package/dist/toast/toaster.js +1 -1
- package/dist/toast/toaster.js.map +1 -1
- package/dist/types/generated.d.ts +97 -2
- package/package.json +8 -2
- package/resources/icons/calendar.svg +18 -0
- package/resources/icons/chevron-left.svg +15 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-value-input.js","names":[],"sources":["../../../resources/js/table/components/filter-value-input.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { useEffect, useState } from \"react\";\nimport { controlSurface } from \"@lattice-php/lattice/core/components/control\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { FilterType } from \"@lattice-php/lattice/types/generated\";\n\nexport const fieldClass = controlSurface({ density: \"compact\" });\n\nexport function FilterValueInput({\n type,\n label,\n value,\n processing,\n withSearchIcon = false,\n grouped = false,\n ariaLabel,\n testId,\n onCommit,\n onClear,\n}: {\n type: FilterType;\n label: string;\n value: string;\n processing: boolean;\n withSearchIcon?: boolean;\n grouped?: boolean;\n ariaLabel?: string;\n testId?: string;\n onCommit: (value: string) => void;\n onClear?: () => void;\n}) {\n const { t } = useT(\"lattice\");\n const [draft, setDraft] = useState(value);\n const inputLabel = ariaLabel ?? t(\"filter.filterBy\", \"Filter {{label}}\", { label });\n const groupedClass = grouped ? \"rounded-r-none\" : \"\";\n\n useEffect(() => {\n setDraft(value);\n }, [value]);\n\n if (type === \"boolean\") {\n return (\n <select\n aria-label={inputLabel}\n data-test={testId}\n className={`${fieldClass} ${groupedClass}`}\n disabled={processing}\n value={value}\n onChange={(event) => onCommit(event.target.value)}\n >\n <option value=\"\">{t(\"filter.all\", \"All\")}</option>\n <option value=\"true\">{t(\"filter.true\", \"True\")}</option>\n <option value=\"false\">{t(\"filter.false\", \"False\")}</option>\n </select>\n );\n }\n\n if (type === \"date\") {\n return (\n <input\n type=\"date\"\n aria-label={inputLabel}\n data-test={testId}\n className={`${fieldClass} ${groupedClass}`}\n disabled={processing}\n value={draft}\n onChange={(event) => {\n setDraft(event.target.value);\n onCommit(event.target.value);\n }}\n />\n );\n }\n\n return (\n <div className=\"relative flex w-full min-w-0 items-center\">\n {withSearchIcon && (\n <Icon\n name=\"search\"\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2 size-lt-icon-md text-lt-muted-fg\"\n />\n )}\n <input\n type={type === \"number\" ? \"number\" : \"text\"}\n aria-label={inputLabel}\n data-test={testId}\n className={`${fieldClass} ${groupedClass} ${withSearchIcon ? \"pl-8\" : \"\"} ${onClear ? \"pr-8\" : \"\"}`}\n disabled={processing}\n value={draft}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n onCommit(draft);\n }\n }}\n onBlur={() => {\n if (draft !== value) {\n onCommit(draft);\n }\n }}\n />\n {onClear && draft !== \"\" && (\n <button\n type=\"button\"\n aria-label={t(\"filter.clear\", \"Clear {{label}} filter\", { label })}\n data-test={testId ? `${testId}-clear` : undefined}\n className=\"absolute right-1 inline-flex size-6 items-center justify-center rounded-lt-sm hover:bg-lt-muted disabled:opacity-50\"\n disabled={processing}\n onClick={onClear}\n >\n <Icon name=\"x\" aria-hidden=\"true\" className=\"size-lt-icon-sm\" />\n </button>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;AAMA,IAAa,aAAa,eAAe,EAAE,SAAS,UAAU,CAAC;AAE/D,SAAgB,iBAAiB,EAC/B,MACA,OACA,OACA,YACA,iBAAiB,OACjB,UAAU,OACV,WACA,QACA,UACA,WAYC;CACD,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,CAAC,OAAO,YAAY,SAAS,KAAK;CACxC,MAAM,aAAa,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"filter-value-input.js","names":[],"sources":["../../../resources/js/table/components/filter-value-input.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport { useEffect, useState } from \"react\";\nimport { controlSurface } from \"@lattice-php/lattice/core/components/control\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { FilterType } from \"@lattice-php/lattice/types/generated\";\n\nexport const fieldClass = controlSurface({ density: \"compact\" });\n\nexport function FilterValueInput({\n type,\n label,\n value,\n processing,\n withSearchIcon = false,\n grouped = false,\n ariaLabel,\n testId,\n onCommit,\n onClear,\n}: {\n type: FilterType;\n label: string;\n value: string;\n processing: boolean;\n withSearchIcon?: boolean;\n grouped?: boolean;\n ariaLabel?: string;\n testId?: string;\n onCommit: (value: string) => void;\n onClear?: () => void;\n}) {\n const { t } = useT(\"lattice\");\n const [draft, setDraft] = useState(value);\n const inputLabel = ariaLabel ?? t(\"table.filter.filterBy\", \"Filter {{label}}\", { label });\n const groupedClass = grouped ? \"rounded-r-none\" : \"\";\n\n useEffect(() => {\n setDraft(value);\n }, [value]);\n\n if (type === \"boolean\") {\n return (\n <select\n aria-label={inputLabel}\n data-test={testId}\n className={`${fieldClass} ${groupedClass}`}\n disabled={processing}\n value={value}\n onChange={(event) => onCommit(event.target.value)}\n >\n <option value=\"\">{t(\"table.filter.all\", \"All\")}</option>\n <option value=\"true\">{t(\"table.filter.true\", \"True\")}</option>\n <option value=\"false\">{t(\"table.filter.false\", \"False\")}</option>\n </select>\n );\n }\n\n if (type === \"date\") {\n return (\n <input\n type=\"date\"\n aria-label={inputLabel}\n data-test={testId}\n className={`${fieldClass} ${groupedClass}`}\n disabled={processing}\n value={draft}\n onChange={(event) => {\n setDraft(event.target.value);\n onCommit(event.target.value);\n }}\n />\n );\n }\n\n return (\n <div className=\"relative flex w-full min-w-0 items-center\">\n {withSearchIcon && (\n <Icon\n name=\"search\"\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-2 size-lt-icon-md text-lt-muted-fg\"\n />\n )}\n <input\n type={type === \"number\" ? \"number\" : \"text\"}\n aria-label={inputLabel}\n data-test={testId}\n className={`${fieldClass} ${groupedClass} ${withSearchIcon ? \"pl-8\" : \"\"} ${onClear ? \"pr-8\" : \"\"}`}\n disabled={processing}\n value={draft}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n onCommit(draft);\n }\n }}\n onBlur={() => {\n if (draft !== value) {\n onCommit(draft);\n }\n }}\n />\n {onClear && draft !== \"\" && (\n <button\n type=\"button\"\n aria-label={t(\"table.filter.clear\", \"Clear {{label}} filter\", { label })}\n data-test={testId ? `${testId}-clear` : undefined}\n className=\"absolute right-1 inline-flex size-6 items-center justify-center rounded-lt-sm hover:bg-lt-muted disabled:opacity-50\"\n disabled={processing}\n onClick={onClear}\n >\n <Icon name=\"x\" aria-hidden=\"true\" className=\"size-lt-icon-sm\" />\n </button>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;AAMA,IAAa,aAAa,eAAe,EAAE,SAAS,UAAU,CAAC;AAE/D,SAAgB,iBAAiB,EAC/B,MACA,OACA,OACA,YACA,iBAAiB,OACjB,UAAU,OACV,WACA,QACA,UACA,WAYC;CACD,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,CAAC,OAAO,YAAY,SAAS,KAAK;CACxC,MAAM,aAAa,aAAa,EAAE,yBAAyB,oBAAoB,EAAE,MAAM,CAAC;CACxF,MAAM,eAAe,UAAU,mBAAmB;CAElD,gBAAgB;EACd,SAAS,KAAK;CAChB,GAAG,CAAC,KAAK,CAAC;CAEV,IAAI,SAAS,WACX,OACE,qBAAC,UAAD;EACE,cAAY;EACZ,aAAW;EACX,WAAW,GAAG,WAAW,GAAG;EAC5B,UAAU;EACH;EACP,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;YANlD;GAQE,oBAAC,UAAD;IAAQ,OAAM;cAAI,EAAE,oBAAoB,KAAK;GAAU,CAAA;GACvD,oBAAC,UAAD;IAAQ,OAAM;cAAQ,EAAE,qBAAqB,MAAM;GAAU,CAAA;GAC7D,oBAAC,UAAD;IAAQ,OAAM;cAAS,EAAE,sBAAsB,OAAO;GAAU,CAAA;EAC1D;;CAIZ,IAAI,SAAS,QACX,OACE,oBAAC,SAAD;EACE,MAAK;EACL,cAAY;EACZ,aAAW;EACX,WAAW,GAAG,WAAW,GAAG;EAC5B,UAAU;EACV,OAAO;EACP,WAAW,UAAU;GACnB,SAAS,MAAM,OAAO,KAAK;GAC3B,SAAS,MAAM,OAAO,KAAK;EAC7B;CACD,CAAA;CAIL,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACG,kBACC,oBAAC,MAAD;IACE,MAAK;IACL,eAAY;IACZ,WAAU;GACX,CAAA;GAEH,oBAAC,SAAD;IACE,MAAM,SAAS,WAAW,WAAW;IACrC,cAAY;IACZ,aAAW;IACX,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,iBAAiB,SAAS,GAAG,GAAG,UAAU,SAAS;IAC/F,UAAU;IACV,OAAO;IACP,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;IAChD,YAAY,UAAU;KACpB,IAAI,MAAM,QAAQ,SAChB,SAAS,KAAK;IAElB;IACA,cAAc;KACZ,IAAI,UAAU,OACZ,SAAS,KAAK;IAElB;GACD,CAAA;GACA,WAAW,UAAU,MACpB,oBAAC,UAAD;IACE,MAAK;IACL,cAAY,EAAE,sBAAsB,0BAA0B,EAAE,MAAM,CAAC;IACvE,aAAW,SAAS,GAAG,OAAO,UAAU,KAAA;IACxC,WAAU;IACV,UAAU;IACV,SAAS;cAET,oBAAC,MAAD;KAAM,MAAK;KAAI,eAAY;KAAO,WAAU;IAAmB,CAAA;GACzD,CAAA;EAEP;;AAET"}
|
|
@@ -5,7 +5,7 @@ function TablePagination({ pagination, currentPage, processing, mode, hasNextPag
|
|
|
5
5
|
const { t } = useT("lattice");
|
|
6
6
|
return /* @__PURE__ */ jsxs("div", {
|
|
7
7
|
className: "flex items-center justify-between gap-3 border-t border-lt-border p-4 text-sm",
|
|
8
|
-
children: [/* @__PURE__ */ jsx("span", { children: pagination.total == null ? t("pagination.page", "Page {{page}}", { page: currentPage }) : t("pagination.showing", "Showing {{from}}-{{to}} of {{total}}", {
|
|
8
|
+
children: [/* @__PURE__ */ jsx("span", { children: pagination.total == null ? t("table.pagination.page", "Page {{page}}", { page: currentPage }) : t("table.pagination.showing", "Showing {{from}}-{{to}} of {{total}}", {
|
|
9
9
|
from: pagination.from ?? 0,
|
|
10
10
|
to: pagination.to ?? 0,
|
|
11
11
|
total: pagination.total
|
|
@@ -18,10 +18,10 @@ function TablePagination({ pagination, currentPage, processing, mode, hasNextPag
|
|
|
18
18
|
className: "h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
|
|
19
19
|
disabled: processing,
|
|
20
20
|
onClick: onLoadMore,
|
|
21
|
-
children: processing ? t("pagination.loading", "Loading...") : t("pagination.loadMore", "Load more")
|
|
21
|
+
children: processing ? t("table.pagination.loading", "Loading...") : t("table.pagination.loadMore", "Load more")
|
|
22
22
|
}) : /* @__PURE__ */ jsx("span", {
|
|
23
23
|
className: "text-lt-muted-fg",
|
|
24
|
-
children: t("pagination.allLoaded", "All rows loaded")
|
|
24
|
+
children: t("table.pagination.allLoaded", "All rows loaded")
|
|
25
25
|
})
|
|
26
26
|
}) : mode === "simple" ? /* @__PURE__ */ jsxs("div", {
|
|
27
27
|
className: "flex items-center gap-2",
|
|
@@ -31,14 +31,14 @@ function TablePagination({ pagination, currentPage, processing, mode, hasNextPag
|
|
|
31
31
|
className: "h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
|
|
32
32
|
disabled: processing || currentPage <= 1,
|
|
33
33
|
onClick: () => onPage(currentPage - 1),
|
|
34
|
-
children: t("pagination.previous", "Previous")
|
|
34
|
+
children: t("table.pagination.previous", "Previous")
|
|
35
35
|
}), /* @__PURE__ */ jsx("button", {
|
|
36
36
|
type: "button",
|
|
37
37
|
"data-test": "pagination-next",
|
|
38
38
|
className: "h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
|
|
39
39
|
disabled: processing || !hasNextPage,
|
|
40
40
|
onClick: () => onPage(currentPage + 1),
|
|
41
|
-
children: t("pagination.next", "Next")
|
|
41
|
+
children: t("table.pagination.next", "Next")
|
|
42
42
|
})]
|
|
43
43
|
}) : mode === "table" ? /* @__PURE__ */ jsxs("div", {
|
|
44
44
|
className: "flex items-center gap-2",
|
|
@@ -49,7 +49,7 @@ function TablePagination({ pagination, currentPage, processing, mode, hasNextPag
|
|
|
49
49
|
className: "h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
|
|
50
50
|
disabled: processing || currentPage <= 1,
|
|
51
51
|
onClick: () => onPage(currentPage - 1),
|
|
52
|
-
children: t("pagination.previous", "Previous")
|
|
52
|
+
children: t("table.pagination.previous", "Previous")
|
|
53
53
|
}),
|
|
54
54
|
visiblePages.map((pageNumber) => /* @__PURE__ */ jsx("button", {
|
|
55
55
|
type: "button",
|
|
@@ -57,7 +57,7 @@ function TablePagination({ pagination, currentPage, processing, mode, hasNextPag
|
|
|
57
57
|
className: "inline-flex size-9 items-center justify-center rounded-lt-sm border border-lt-border font-medium disabled:opacity-50",
|
|
58
58
|
disabled: processing || pageNumber === currentPage,
|
|
59
59
|
"aria-current": pageNumber === currentPage ? "page" : void 0,
|
|
60
|
-
"aria-label": t("pagination.page", "Page {{page}}", { page: pageNumber }),
|
|
60
|
+
"aria-label": t("table.pagination.page", "Page {{page}}", { page: pageNumber }),
|
|
61
61
|
onClick: () => onPage(pageNumber),
|
|
62
62
|
children: pageNumber
|
|
63
63
|
}, pageNumber)),
|
|
@@ -67,7 +67,7 @@ function TablePagination({ pagination, currentPage, processing, mode, hasNextPag
|
|
|
67
67
|
className: "h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50",
|
|
68
68
|
disabled: processing || !hasNextPage,
|
|
69
69
|
onClick: () => onPage(currentPage + 1),
|
|
70
|
-
children: t("pagination.next", "Next")
|
|
70
|
+
children: t("table.pagination.next", "Next")
|
|
71
71
|
})
|
|
72
72
|
]
|
|
73
73
|
}) : null]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.js","names":[],"sources":["../../../resources/js/table/components/pagination.tsx"],"sourcesContent":["import type { RefObject } from \"react\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { PaginationType } from \"@lattice-php/lattice/types/generated\";\nimport type { TablePagination as TablePaginationData } from \"../types\";\n\nexport function TablePagination({\n pagination,\n currentPage,\n processing,\n mode,\n hasNextPage,\n visiblePages,\n infiniteLoaderRef,\n onPage,\n onLoadMore,\n}: {\n pagination: TablePaginationData;\n currentPage: number;\n processing: boolean;\n mode: PaginationType;\n hasNextPage: boolean;\n visiblePages: number[];\n infiniteLoaderRef: RefObject<HTMLDivElement | null>;\n onPage: (page: number) => void;\n onLoadMore: () => void;\n}) {\n const { t } = useT(\"lattice\");\n\n return (\n <div className=\"flex items-center justify-between gap-3 border-t border-lt-border p-4 text-sm\">\n <span>\n {pagination.total == null\n ? t(\"pagination.page\", \"Page {{page}}\", { page: currentPage })\n : t(\"pagination.showing\", \"Showing {{from}}-{{to}} of {{total}}\", {\n from: pagination.from ?? 0,\n to: pagination.to ?? 0,\n total: pagination.total,\n })}\n </span>\n {mode === \"infinite\" ? (\n <div ref={infiniteLoaderRef} className=\"flex items-center gap-2\">\n {pagination.hasMore ? (\n <button\n type=\"button\"\n data-test=\"pagination-load-more\"\n className=\"h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing}\n onClick={onLoadMore}\n >\n {processing\n ? t(\"pagination.loading\", \"Loading...\")\n : t(\"pagination.loadMore\", \"Load more\")}\n </button>\n ) : (\n <span className=\"text-lt-muted-fg\"
|
|
1
|
+
{"version":3,"file":"pagination.js","names":[],"sources":["../../../resources/js/table/components/pagination.tsx"],"sourcesContent":["import type { RefObject } from \"react\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport type { PaginationType } from \"@lattice-php/lattice/types/generated\";\nimport type { TablePagination as TablePaginationData } from \"../types\";\n\nexport function TablePagination({\n pagination,\n currentPage,\n processing,\n mode,\n hasNextPage,\n visiblePages,\n infiniteLoaderRef,\n onPage,\n onLoadMore,\n}: {\n pagination: TablePaginationData;\n currentPage: number;\n processing: boolean;\n mode: PaginationType;\n hasNextPage: boolean;\n visiblePages: number[];\n infiniteLoaderRef: RefObject<HTMLDivElement | null>;\n onPage: (page: number) => void;\n onLoadMore: () => void;\n}) {\n const { t } = useT(\"lattice\");\n\n return (\n <div className=\"flex items-center justify-between gap-3 border-t border-lt-border p-4 text-sm\">\n <span>\n {pagination.total == null\n ? t(\"table.pagination.page\", \"Page {{page}}\", { page: currentPage })\n : t(\"table.pagination.showing\", \"Showing {{from}}-{{to}} of {{total}}\", {\n from: pagination.from ?? 0,\n to: pagination.to ?? 0,\n total: pagination.total,\n })}\n </span>\n {mode === \"infinite\" ? (\n <div ref={infiniteLoaderRef} className=\"flex items-center gap-2\">\n {pagination.hasMore ? (\n <button\n type=\"button\"\n data-test=\"pagination-load-more\"\n className=\"h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing}\n onClick={onLoadMore}\n >\n {processing\n ? t(\"table.pagination.loading\", \"Loading...\")\n : t(\"table.pagination.loadMore\", \"Load more\")}\n </button>\n ) : (\n <span className=\"text-lt-muted-fg\">\n {t(\"table.pagination.allLoaded\", \"All rows loaded\")}\n </span>\n )}\n </div>\n ) : mode === \"simple\" ? (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-test=\"pagination-previous\"\n className=\"h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing || currentPage <= 1}\n onClick={() => onPage(currentPage - 1)}\n >\n {t(\"table.pagination.previous\", \"Previous\")}\n </button>\n <button\n type=\"button\"\n data-test=\"pagination-next\"\n className=\"h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing || !hasNextPage}\n onClick={() => onPage(currentPage + 1)}\n >\n {t(\"table.pagination.next\", \"Next\")}\n </button>\n </div>\n ) : mode === \"table\" ? (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n data-test=\"pagination-previous\"\n className=\"h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing || currentPage <= 1}\n onClick={() => onPage(currentPage - 1)}\n >\n {t(\"table.pagination.previous\", \"Previous\")}\n </button>\n {visiblePages.map((pageNumber) => (\n <button\n key={pageNumber}\n type=\"button\"\n data-test={`pagination-page-${pageNumber}`}\n className=\"inline-flex size-9 items-center justify-center rounded-lt-sm border border-lt-border font-medium disabled:opacity-50\"\n disabled={processing || pageNumber === currentPage}\n aria-current={pageNumber === currentPage ? \"page\" : undefined}\n aria-label={t(\"table.pagination.page\", \"Page {{page}}\", { page: pageNumber })}\n onClick={() => onPage(pageNumber)}\n >\n {pageNumber}\n </button>\n ))}\n <button\n type=\"button\"\n data-test=\"pagination-next\"\n className=\"h-9 rounded-lt-sm border border-lt-border px-3 font-medium disabled:opacity-50\"\n disabled={processing || !hasNextPage}\n onClick={() => onPage(currentPage + 1)}\n >\n {t(\"table.pagination.next\", \"Next\")}\n </button>\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":";;;AAKA,SAAgB,gBAAgB,EAC9B,YACA,aACA,YACA,MACA,aACA,cACA,mBACA,QACA,cAWC;CACD,MAAM,EAAE,MAAM,KAAK,SAAS;CAE5B,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,QAAD,EAAA,UACG,WAAW,SAAS,OACjB,EAAE,yBAAyB,iBAAiB,EAAE,MAAM,YAAY,CAAC,IACjE,EAAE,4BAA4B,wCAAwC;GACpE,MAAM,WAAW,QAAQ;GACzB,IAAI,WAAW,MAAM;GACrB,OAAO,WAAW;EACpB,CAAC,EACD,CAAA,GACL,SAAS,aACR,oBAAC,OAAD;GAAK,KAAK;GAAmB,WAAU;aACpC,WAAW,UACV,oBAAC,UAAD;IACE,MAAK;IACL,aAAU;IACV,WAAU;IACV,UAAU;IACV,SAAS;cAER,aACG,EAAE,4BAA4B,YAAY,IAC1C,EAAE,6BAA6B,WAAW;GACxC,CAAA,IAER,oBAAC,QAAD;IAAM,WAAU;cACb,EAAE,8BAA8B,iBAAiB;GAC9C,CAAA;EAEL,CAAA,IACH,SAAS,WACX,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,UAAD;IACE,MAAK;IACL,aAAU;IACV,WAAU;IACV,UAAU,cAAc,eAAe;IACvC,eAAe,OAAO,cAAc,CAAC;cAEpC,EAAE,6BAA6B,UAAU;GACpC,CAAA,GACR,oBAAC,UAAD;IACE,MAAK;IACL,aAAU;IACV,WAAU;IACV,UAAU,cAAc,CAAC;IACzB,eAAe,OAAO,cAAc,CAAC;cAEpC,EAAE,yBAAyB,MAAM;GAC5B,CAAA,CACL;OACH,SAAS,UACX,qBAAC,OAAD;GAAK,WAAU;aAAf;IACE,oBAAC,UAAD;KACE,MAAK;KACL,aAAU;KACV,WAAU;KACV,UAAU,cAAc,eAAe;KACvC,eAAe,OAAO,cAAc,CAAC;eAEpC,EAAE,6BAA6B,UAAU;IACpC,CAAA;IACP,aAAa,KAAK,eACjB,oBAAC,UAAD;KAEE,MAAK;KACL,aAAW,mBAAmB;KAC9B,WAAU;KACV,UAAU,cAAc,eAAe;KACvC,gBAAc,eAAe,cAAc,SAAS,KAAA;KACpD,cAAY,EAAE,yBAAyB,iBAAiB,EAAE,MAAM,WAAW,CAAC;KAC5E,eAAe,OAAO,UAAU;eAE/B;IACK,GAVD,UAUC,CACT;IACD,oBAAC,UAAD;KACE,MAAK;KACL,aAAU;KACV,WAAU;KACV,UAAU,cAAc,CAAC;KACzB,eAAe,OAAO,cAAc,CAAC;eAEpC,EAAE,yBAAyB,MAAM;IAC5B,CAAA;GACL;OACH,IACD;;AAET"}
|
|
@@ -66,11 +66,11 @@ var TableComponent = ({ node }) => {
|
|
|
66
66
|
"data-lattice-component": node.id,
|
|
67
67
|
className: "relative",
|
|
68
68
|
children: [hasOverrides && /* @__PURE__ */ jsx("button", {
|
|
69
|
-
"aria-label": t("
|
|
69
|
+
"aria-label": t("table.resetColumnWidths", "Reset column widths"),
|
|
70
70
|
className: "absolute right-1 top-1 z-10 hidden rounded-lt-sm p-1 text-lt-muted-fg hover:text-lt-fg md:inline-flex",
|
|
71
71
|
"data-test": "table-reset-columns",
|
|
72
72
|
onClick: resetColumns,
|
|
73
|
-
title: t("
|
|
73
|
+
title: t("table.resetColumnWidths", "Reset column widths"),
|
|
74
74
|
type: "button",
|
|
75
75
|
children: /* @__PURE__ */ jsx(Icon, {
|
|
76
76
|
name: "rotate-ccw",
|
|
@@ -124,7 +124,7 @@ var TableComponent = ({ node }) => {
|
|
|
124
124
|
className: "flex items-center px-4 py-3",
|
|
125
125
|
role: "columnheader",
|
|
126
126
|
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
127
|
-
"aria-label": t("
|
|
127
|
+
"aria-label": t("table.selectAllRows", "Select all rows"),
|
|
128
128
|
"data-test": "select-all",
|
|
129
129
|
checked: selection.allSelected,
|
|
130
130
|
onCheckedChange: () => selection.toggleAll()
|
|
@@ -207,7 +207,7 @@ var TableComponent = ({ node }) => {
|
|
|
207
207
|
className: "flex items-center p-4",
|
|
208
208
|
role: "cell",
|
|
209
209
|
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
210
|
-
"aria-label": t("
|
|
210
|
+
"aria-label": t("table.selectRow", "Select row {{key}}", { key }),
|
|
211
211
|
"data-test": `select-row-${key}`,
|
|
212
212
|
checked: selection.isSelected(key),
|
|
213
213
|
onCheckedChange: () => selection.toggle(key)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.js","names":[],"sources":["../../../resources/js/table/components/table.tsx"],"sourcesContent":["import { type ReactNode, useMemo } from \"react\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { useColumnResizing } from \"@lattice-php/lattice/core/use-column-resizing\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { Checkbox } from \"@lattice-php/lattice/core/components/checkbox\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { alignJustifyItems, alignText } from \"../align\";\nimport type { TableNode } from \"../types\";\nimport { getBulkActions } from \"../bulk\";\nimport { flattenColumns, getRowActions, getRowKey } from \"../payload\";\nimport {\n getQueryParams,\n getTableSizingColumns,\n getTableUtilityTracks,\n getVisiblePages,\n} from \"../query\";\nimport { useTable } from \"../use-table\";\nimport { useTableSelection } from \"../use-table-selection\";\nimport { BulkBar } from \"./bulk-bar\";\nimport { ColumnFilterControl } from \"./column-filter-control\";\nimport { ColumnHeader } from \"./column-header\";\nimport { FilterBar, FilterMenu } from \"./filter-bar\";\nimport { FilterStackBar } from \"./filter-stack-bar\";\nimport { TablePagination } from \"./pagination\";\nimport { SortBar } from \"./sort-bar\";\nimport { TableActionNode } from \"./table-action-node\";\nimport { ColumnCell } from \"./table-cell\";\n\nconst TableComponent = ({ node }: { children?: ReactNode; node: TableNode }) => {\n const { t } = useT(\"lattice\");\n const {\n columns,\n rows,\n pagination,\n state,\n filters,\n tableFilters,\n addFilter,\n updateFilter,\n removeFilter,\n replaceColumnFilters,\n setTableFilter,\n resetFilters,\n searchFilterOptions,\n processing,\n hasLoaded,\n infiniteLoaderRef,\n sort,\n clearSort,\n goToPage,\n loadMore,\n } = useTable(node);\n\n const bulkActions = useMemo(\n () => getBulkActions(node.props?.bulkActions),\n [node.props?.bulkActions],\n );\n const hasBulkActions = bulkActions.length > 0;\n const rowEntries = useMemo(\n () =>\n rows.map((row, index) => ({ row, actions: getRowActions(row), key: getRowKey(row, index) })),\n [rows],\n );\n const selection = useTableSelection(rowEntries.map((entry) => entry.key));\n\n const columnsByKey = useMemo(\n () => new Map(flattenColumns(columns).map((column) => [column.key, column])),\n [columns],\n );\n const currentPage = pagination.currentPage ?? state.page;\n const lastPage = pagination.lastPage ?? currentPage;\n const mode = pagination.mode ?? \"table\";\n const visiblePages = getVisiblePages(currentPage, lastPage);\n const hasNextPage = pagination.hasMore ?? currentPage < lastPage;\n const hasActions = rowEntries.some((entry) => entry.actions.length > 0);\n const striped = node.props?.striped === true;\n const hasFilters = columns.some((column) => column.filter?.enabled);\n const filterEntries = filters.map((clause, index) => ({ clause, index }));\n const filterDefinitions = useMemo(\n () => (Array.isArray(node.props?.filters) ? node.props.filters : []),\n [node.props?.filters],\n );\n const hasDedicatedFilters = filterDefinitions.length > 0;\n const hasActiveFilters = filters.length > 0 || Object.keys(tableFilters).length > 0;\n const hasTrailingUtility = hasActions || hasDedicatedFilters;\n const sizingColumns = useMemo(() => getTableSizingColumns(columns), [columns]);\n const utilityTracks = useMemo(\n () => getTableUtilityTracks(hasTrailingUtility, hasBulkActions),\n [hasTrailingUtility, hasBulkActions],\n );\n const resizingEnabled = node.props?.resizableColumns === true;\n const resizeStorageIdentity = nodeIdentity(node);\n const { getResizeHandleProps, gridTemplateColumns, hasOverrides, resetColumns } =\n useColumnResizing({\n columns: sizingColumns,\n enabled: resizingEnabled,\n leadingTracks: utilityTracks.leadingTracks,\n showIndicator: node.props?.resizeIndicator === true,\n storageKey:\n resizingEnabled && resizeStorageIdentity\n ? `lattice:table-columns:${resizeStorageIdentity}`\n : undefined,\n trailingTracks: utilityTracks.trailingTracks,\n });\n\n return (\n <div data-lattice-component={node.id} className=\"relative\">\n {hasOverrides && (\n <button\n aria-label={t(\"a11y.resetColumnWidths\", \"Reset column widths\")}\n className=\"absolute right-1 top-1 z-10 hidden rounded-lt-sm p-1 text-lt-muted-fg hover:text-lt-fg md:inline-flex\"\n data-test=\"table-reset-columns\"\n onClick={resetColumns}\n title={t(\"a11y.resetColumnWidths\", \"Reset column widths\")}\n type=\"button\"\n >\n <Icon name=\"rotate-ccw\" className=\"size-lt-icon-sm\" />\n </button>\n )}\n <div className=\"overflow-x-auto rounded-lt-sm border border-lt-border\">\n {hasDedicatedFilters && hasActiveFilters && (\n <FilterBar\n filters={filterDefinitions}\n values={tableFilters}\n processing={processing}\n hasActiveFilters={hasActiveFilters}\n onChange={setTableFilter}\n onReset={resetFilters}\n />\n )}\n {hasBulkActions && selection.active && (\n <BulkBar\n actions={bulkActions}\n selectedKeys={selection.selectedKeys}\n allMatching={selection.allMatching}\n total={pagination.total ?? undefined}\n query={getQueryParams(state)}\n canSelectAllMatching={\n selection.allVisibleSelected &&\n !selection.allMatching &&\n pagination.total != null &&\n pagination.total > selection.selectedKeys.length\n }\n onSelectAllMatching={selection.selectAllMatching}\n onCompleted={selection.clear}\n />\n )}\n {filters.length > 0 && (\n <FilterStackBar\n filters={filters}\n columnsByKey={columnsByKey}\n processing={processing}\n onRemove={removeFilter}\n />\n )}\n {state.sorts.length > 0 && (\n <SortBar\n columnsByKey={columnsByKey}\n state={state}\n processing={processing}\n onClear={clearSort}\n />\n )}\n <div className=\"min-w-full text-base\" role=\"table\">\n <div className=\"border-b border-lt-border bg-lt-muted/50\" role=\"rowgroup\">\n <div\n className=\"hidden min-w-full md:grid md:grid-cols-[var(--lattice-table-columns)]\"\n role=\"row\"\n style={{ \"--lattice-table-columns\": gridTemplateColumns } as never}\n >\n {hasBulkActions && (\n <div className=\"flex items-center px-4 py-3\" role=\"columnheader\">\n <Checkbox\n aria-label={t(\"a11y.selectAllRows\", \"Select all rows\")}\n data-test=\"select-all\"\n checked={selection.allSelected}\n onCheckedChange={() => selection.toggleAll()}\n />\n </div>\n )}\n {columns.map((column, index) => (\n <ColumnHeader\n column={column}\n key={column.key}\n processing={processing}\n resizeHandleProps={\n resizingEnabled ? getResizeHandleProps(sizingColumns[index]) : undefined\n }\n sort={sort}\n state={state}\n />\n ))}\n {hasTrailingUtility && (\n <div\n className=\"flex items-center justify-end gap-2 px-4 py-2 align-middle font-semibold text-lt-fg\"\n role=\"columnheader\"\n >\n {hasDedicatedFilters && (\n <FilterMenu\n filters={filterDefinitions}\n values={tableFilters}\n processing={processing}\n onChange={setTableFilter}\n onSearch={searchFilterOptions}\n />\n )}\n {hasActions && <span className=\"sr-only\">{node.props?.actionsLabel}</span>}\n </div>\n )}\n </div>\n {hasFilters && (\n <div\n className=\"hidden min-w-full border-t border-lt-border md:grid md:grid-cols-[var(--lattice-table-columns)]\"\n role=\"row\"\n style={{ \"--lattice-table-columns\": gridTemplateColumns } as never}\n >\n {hasBulkActions && <div className=\"px-4 py-2\" role=\"cell\" />}\n {columns.map((column) => (\n <div key={column.key} className=\"min-w-0 px-2 py-2\" role=\"cell\">\n {column.filter?.enabled && (\n <ColumnFilterControl\n column={column}\n clauses={filterEntries.filter((entry) => entry.clause.field === column.key)}\n processing={processing}\n onAdd={addFilter}\n onUpdate={updateFilter}\n onRemove={removeFilter}\n onReplace={replaceColumnFilters}\n onSearch={(query) => searchFilterOptions(column.key, query)}\n />\n )}\n </div>\n ))}\n {hasTrailingUtility && <div className=\"px-4 py-2\" role=\"cell\" />}\n </div>\n )}\n </div>\n <div role=\"rowgroup\">\n {!hasLoaded ? (\n <div className=\"p-4 text-lt-muted-fg\" role=\"row\">\n <div role=\"cell\">{t(\"table.loading\", \"Loading rows...\")}</div>\n </div>\n ) : rowEntries.length === 0 ? (\n <div className=\"p-8 text-center text-lt-muted-fg\" role=\"row\">\n <div role=\"cell\">{node.props?.emptyLabel}</div>\n </div>\n ) : (\n rowEntries.map(({ row, actions, key }) => {\n return (\n <div\n key={key}\n className={`grid grid-cols-1 border-b border-lt-border last:border-b-0 md:grid-cols-[var(--lattice-table-columns)] ${\n striped ? \"odd:bg-lt-muted/30\" : \"\"\n }`}\n role=\"row\"\n style={{ \"--lattice-table-columns\": gridTemplateColumns } as never}\n >\n {hasBulkActions && (\n <div className=\"flex items-center p-4\" role=\"cell\">\n <Checkbox\n aria-label={t(\"a11y.selectRow\", \"Select row {{key}}\", { key })}\n data-test={`select-row-${key}`}\n checked={selection.isSelected(key)}\n onCheckedChange={() => selection.toggle(key)}\n />\n </div>\n )}\n {columns.map((column) => (\n <div\n key={column.key}\n className={cn(\n \"grid min-w-0 gap-1 overflow-hidden p-4 align-middle\",\n alignText(column.align),\n alignJustifyItems(column.align),\n )}\n role=\"cell\"\n >\n <span\n aria-hidden=\"true\"\n className=\"text-xs font-medium text-lt-muted-fg md:hidden\"\n >\n {column.label}\n </span>\n <div\n data-slot=\"table-cell-content\"\n className=\"min-w-0 max-w-full overflow-hidden truncate\"\n >\n <ColumnCell column={column} row={row} />\n </div>\n </div>\n ))}\n {hasTrailingUtility && (\n <div\n className={cn(\n \"items-center justify-start gap-2 p-4 md:justify-end\",\n actions.length > 0 ? \"flex\" : \"hidden md:flex\",\n )}\n role=\"cell\"\n >\n {actions.map((action, actionIndex) => (\n <TableActionNode\n key={action.key ?? action.id ?? actionIndex}\n node={action}\n />\n ))}\n </div>\n )}\n </div>\n );\n })\n )}\n </div>\n </div>\n {hasLoaded && (\n <TablePagination\n pagination={pagination}\n currentPage={currentPage}\n processing={processing}\n mode={mode}\n hasNextPage={hasNextPage}\n visiblePages={visiblePages}\n infiniteLoaderRef={infiniteLoaderRef}\n onPage={goToPage}\n onLoadMore={loadMore}\n />\n )}\n </div>\n </div>\n );\n};\n\nexport default TableComponent;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"table.js","names":[],"sources":["../../../resources/js/table/components/table.tsx"],"sourcesContent":["import { type ReactNode, useMemo } from \"react\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { useColumnResizing } from \"@lattice-php/lattice/core/use-column-resizing\";\nimport { nodeIdentity } from \"@lattice-php/lattice/core/test-id\";\nimport { Checkbox } from \"@lattice-php/lattice/core/components/checkbox\";\nimport { Icon } from \"@lattice-php/lattice/icons\";\nimport { alignJustifyItems, alignText } from \"../align\";\nimport type { TableNode } from \"../types\";\nimport { getBulkActions } from \"../bulk\";\nimport { flattenColumns, getRowActions, getRowKey } from \"../payload\";\nimport {\n getQueryParams,\n getTableSizingColumns,\n getTableUtilityTracks,\n getVisiblePages,\n} from \"../query\";\nimport { useTable } from \"../use-table\";\nimport { useTableSelection } from \"../use-table-selection\";\nimport { BulkBar } from \"./bulk-bar\";\nimport { ColumnFilterControl } from \"./column-filter-control\";\nimport { ColumnHeader } from \"./column-header\";\nimport { FilterBar, FilterMenu } from \"./filter-bar\";\nimport { FilterStackBar } from \"./filter-stack-bar\";\nimport { TablePagination } from \"./pagination\";\nimport { SortBar } from \"./sort-bar\";\nimport { TableActionNode } from \"./table-action-node\";\nimport { ColumnCell } from \"./table-cell\";\n\nconst TableComponent = ({ node }: { children?: ReactNode; node: TableNode }) => {\n const { t } = useT(\"lattice\");\n const {\n columns,\n rows,\n pagination,\n state,\n filters,\n tableFilters,\n addFilter,\n updateFilter,\n removeFilter,\n replaceColumnFilters,\n setTableFilter,\n resetFilters,\n searchFilterOptions,\n processing,\n hasLoaded,\n infiniteLoaderRef,\n sort,\n clearSort,\n goToPage,\n loadMore,\n } = useTable(node);\n\n const bulkActions = useMemo(\n () => getBulkActions(node.props?.bulkActions),\n [node.props?.bulkActions],\n );\n const hasBulkActions = bulkActions.length > 0;\n const rowEntries = useMemo(\n () =>\n rows.map((row, index) => ({ row, actions: getRowActions(row), key: getRowKey(row, index) })),\n [rows],\n );\n const selection = useTableSelection(rowEntries.map((entry) => entry.key));\n\n const columnsByKey = useMemo(\n () => new Map(flattenColumns(columns).map((column) => [column.key, column])),\n [columns],\n );\n const currentPage = pagination.currentPage ?? state.page;\n const lastPage = pagination.lastPage ?? currentPage;\n const mode = pagination.mode ?? \"table\";\n const visiblePages = getVisiblePages(currentPage, lastPage);\n const hasNextPage = pagination.hasMore ?? currentPage < lastPage;\n const hasActions = rowEntries.some((entry) => entry.actions.length > 0);\n const striped = node.props?.striped === true;\n const hasFilters = columns.some((column) => column.filter?.enabled);\n const filterEntries = filters.map((clause, index) => ({ clause, index }));\n const filterDefinitions = useMemo(\n () => (Array.isArray(node.props?.filters) ? node.props.filters : []),\n [node.props?.filters],\n );\n const hasDedicatedFilters = filterDefinitions.length > 0;\n const hasActiveFilters = filters.length > 0 || Object.keys(tableFilters).length > 0;\n const hasTrailingUtility = hasActions || hasDedicatedFilters;\n const sizingColumns = useMemo(() => getTableSizingColumns(columns), [columns]);\n const utilityTracks = useMemo(\n () => getTableUtilityTracks(hasTrailingUtility, hasBulkActions),\n [hasTrailingUtility, hasBulkActions],\n );\n const resizingEnabled = node.props?.resizableColumns === true;\n const resizeStorageIdentity = nodeIdentity(node);\n const { getResizeHandleProps, gridTemplateColumns, hasOverrides, resetColumns } =\n useColumnResizing({\n columns: sizingColumns,\n enabled: resizingEnabled,\n leadingTracks: utilityTracks.leadingTracks,\n showIndicator: node.props?.resizeIndicator === true,\n storageKey:\n resizingEnabled && resizeStorageIdentity\n ? `lattice:table-columns:${resizeStorageIdentity}`\n : undefined,\n trailingTracks: utilityTracks.trailingTracks,\n });\n\n return (\n <div data-lattice-component={node.id} className=\"relative\">\n {hasOverrides && (\n <button\n aria-label={t(\"table.resetColumnWidths\", \"Reset column widths\")}\n className=\"absolute right-1 top-1 z-10 hidden rounded-lt-sm p-1 text-lt-muted-fg hover:text-lt-fg md:inline-flex\"\n data-test=\"table-reset-columns\"\n onClick={resetColumns}\n title={t(\"table.resetColumnWidths\", \"Reset column widths\")}\n type=\"button\"\n >\n <Icon name=\"rotate-ccw\" className=\"size-lt-icon-sm\" />\n </button>\n )}\n <div className=\"overflow-x-auto rounded-lt-sm border border-lt-border\">\n {hasDedicatedFilters && hasActiveFilters && (\n <FilterBar\n filters={filterDefinitions}\n values={tableFilters}\n processing={processing}\n hasActiveFilters={hasActiveFilters}\n onChange={setTableFilter}\n onReset={resetFilters}\n />\n )}\n {hasBulkActions && selection.active && (\n <BulkBar\n actions={bulkActions}\n selectedKeys={selection.selectedKeys}\n allMatching={selection.allMatching}\n total={pagination.total ?? undefined}\n query={getQueryParams(state)}\n canSelectAllMatching={\n selection.allVisibleSelected &&\n !selection.allMatching &&\n pagination.total != null &&\n pagination.total > selection.selectedKeys.length\n }\n onSelectAllMatching={selection.selectAllMatching}\n onCompleted={selection.clear}\n />\n )}\n {filters.length > 0 && (\n <FilterStackBar\n filters={filters}\n columnsByKey={columnsByKey}\n processing={processing}\n onRemove={removeFilter}\n />\n )}\n {state.sorts.length > 0 && (\n <SortBar\n columnsByKey={columnsByKey}\n state={state}\n processing={processing}\n onClear={clearSort}\n />\n )}\n <div className=\"min-w-full text-base\" role=\"table\">\n <div className=\"border-b border-lt-border bg-lt-muted/50\" role=\"rowgroup\">\n <div\n className=\"hidden min-w-full md:grid md:grid-cols-[var(--lattice-table-columns)]\"\n role=\"row\"\n style={{ \"--lattice-table-columns\": gridTemplateColumns } as never}\n >\n {hasBulkActions && (\n <div className=\"flex items-center px-4 py-3\" role=\"columnheader\">\n <Checkbox\n aria-label={t(\"table.selectAllRows\", \"Select all rows\")}\n data-test=\"select-all\"\n checked={selection.allSelected}\n onCheckedChange={() => selection.toggleAll()}\n />\n </div>\n )}\n {columns.map((column, index) => (\n <ColumnHeader\n column={column}\n key={column.key}\n processing={processing}\n resizeHandleProps={\n resizingEnabled ? getResizeHandleProps(sizingColumns[index]) : undefined\n }\n sort={sort}\n state={state}\n />\n ))}\n {hasTrailingUtility && (\n <div\n className=\"flex items-center justify-end gap-2 px-4 py-2 align-middle font-semibold text-lt-fg\"\n role=\"columnheader\"\n >\n {hasDedicatedFilters && (\n <FilterMenu\n filters={filterDefinitions}\n values={tableFilters}\n processing={processing}\n onChange={setTableFilter}\n onSearch={searchFilterOptions}\n />\n )}\n {hasActions && <span className=\"sr-only\">{node.props?.actionsLabel}</span>}\n </div>\n )}\n </div>\n {hasFilters && (\n <div\n className=\"hidden min-w-full border-t border-lt-border md:grid md:grid-cols-[var(--lattice-table-columns)]\"\n role=\"row\"\n style={{ \"--lattice-table-columns\": gridTemplateColumns } as never}\n >\n {hasBulkActions && <div className=\"px-4 py-2\" role=\"cell\" />}\n {columns.map((column) => (\n <div key={column.key} className=\"min-w-0 px-2 py-2\" role=\"cell\">\n {column.filter?.enabled && (\n <ColumnFilterControl\n column={column}\n clauses={filterEntries.filter((entry) => entry.clause.field === column.key)}\n processing={processing}\n onAdd={addFilter}\n onUpdate={updateFilter}\n onRemove={removeFilter}\n onReplace={replaceColumnFilters}\n onSearch={(query) => searchFilterOptions(column.key, query)}\n />\n )}\n </div>\n ))}\n {hasTrailingUtility && <div className=\"px-4 py-2\" role=\"cell\" />}\n </div>\n )}\n </div>\n <div role=\"rowgroup\">\n {!hasLoaded ? (\n <div className=\"p-4 text-lt-muted-fg\" role=\"row\">\n <div role=\"cell\">{t(\"table.loading\", \"Loading rows...\")}</div>\n </div>\n ) : rowEntries.length === 0 ? (\n <div className=\"p-8 text-center text-lt-muted-fg\" role=\"row\">\n <div role=\"cell\">{node.props?.emptyLabel}</div>\n </div>\n ) : (\n rowEntries.map(({ row, actions, key }) => {\n return (\n <div\n key={key}\n className={`grid grid-cols-1 border-b border-lt-border last:border-b-0 md:grid-cols-[var(--lattice-table-columns)] ${\n striped ? \"odd:bg-lt-muted/30\" : \"\"\n }`}\n role=\"row\"\n style={{ \"--lattice-table-columns\": gridTemplateColumns } as never}\n >\n {hasBulkActions && (\n <div className=\"flex items-center p-4\" role=\"cell\">\n <Checkbox\n aria-label={t(\"table.selectRow\", \"Select row {{key}}\", { key })}\n data-test={`select-row-${key}`}\n checked={selection.isSelected(key)}\n onCheckedChange={() => selection.toggle(key)}\n />\n </div>\n )}\n {columns.map((column) => (\n <div\n key={column.key}\n className={cn(\n \"grid min-w-0 gap-1 overflow-hidden p-4 align-middle\",\n alignText(column.align),\n alignJustifyItems(column.align),\n )}\n role=\"cell\"\n >\n <span\n aria-hidden=\"true\"\n className=\"text-xs font-medium text-lt-muted-fg md:hidden\"\n >\n {column.label}\n </span>\n <div\n data-slot=\"table-cell-content\"\n className=\"min-w-0 max-w-full overflow-hidden truncate\"\n >\n <ColumnCell column={column} row={row} />\n </div>\n </div>\n ))}\n {hasTrailingUtility && (\n <div\n className={cn(\n \"items-center justify-start gap-2 p-4 md:justify-end\",\n actions.length > 0 ? \"flex\" : \"hidden md:flex\",\n )}\n role=\"cell\"\n >\n {actions.map((action, actionIndex) => (\n <TableActionNode\n key={action.key ?? action.id ?? actionIndex}\n node={action}\n />\n ))}\n </div>\n )}\n </div>\n );\n })\n )}\n </div>\n </div>\n {hasLoaded && (\n <TablePagination\n pagination={pagination}\n currentPage={currentPage}\n processing={processing}\n mode={mode}\n hasNextPage={hasNextPage}\n visiblePages={visiblePages}\n infiniteLoaderRef={infiniteLoaderRef}\n onPage={goToPage}\n onLoadMore={loadMore}\n />\n )}\n </div>\n </div>\n );\n};\n\nexport default TableComponent;\n"],"mappings":"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"}
|
package/dist/table/query.js
CHANGED
|
@@ -91,7 +91,7 @@ var operatorLabels = {
|
|
|
91
91
|
};
|
|
92
92
|
var VALUELESS_FILTER_OPERATORS = new Set(["empty", "filled"]);
|
|
93
93
|
function operatorLabel(operator) {
|
|
94
|
-
return translate("lattice", `operators.${operator}`, operatorLabels[operator] ?? operator);
|
|
94
|
+
return translate("lattice", `table.operators.${operator}`, operatorLabels[operator] ?? operator);
|
|
95
95
|
}
|
|
96
96
|
function getSortDirectionLabel(direction) {
|
|
97
97
|
return direction === "desc" ? "descending" : "ascending";
|
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 { 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
|
+
{"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\", `table.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
|
@@ -45,7 +45,7 @@ function Toaster({ duration = 4e3 }) {
|
|
|
45
45
|
}) : null]
|
|
46
46
|
}),
|
|
47
47
|
toast.dismissible ? /* @__PURE__ */ jsx(Toast.Close, {
|
|
48
|
-
"aria-label": t("
|
|
48
|
+
"aria-label": t("common.dismiss", "Dismiss"),
|
|
49
49
|
className: "shrink-0 rounded-lt-sm p-1 text-lt-muted-fg transition-colors hover:bg-lt-muted hover:text-lt-fg",
|
|
50
50
|
"data-test": "toast-dismiss",
|
|
51
51
|
children: /* @__PURE__ */ jsx(Icon, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toaster.js","names":[],"sources":["../../resources/js/toast/toaster.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport * as Toast from \"@radix-ui/react-toast\";\nimport { useEffect, useState } from \"react\";\nimport { RenderNode } from \"@lattice-php/lattice/core/renderer\";\nimport type { ToastMessage } from \"@lattice-php/lattice/types/generated\";\nimport { onToast } from \"@lattice-php/lattice/toast/toast\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { variantStyles } from \"@lattice-php/lattice/toast/variant-styles\";\nimport { resolveTranslatable } from \"@lattice-php/lattice/i18n/translatable\";\n\ntype ToastItem = ToastMessage & { id: number };\n\nlet nextId = 0;\n\nexport function Toaster({ duration = 4000 }: { duration?: number }) {\n const { t } = useT(\"lattice\");\n const [toasts, setToasts] = useState<ToastItem[]>([]);\n\n function dismiss(id: number): void {\n setToasts((current) => current.filter((toast) => toast.id !== id));\n }\n\n useEffect(\n () =>\n onToast((toast) => {\n setToasts((current) => [...current, { ...toast, id: nextId++ }]);\n }),\n [],\n );\n\n return (\n <Toast.Provider duration={duration} swipeDirection=\"down\">\n {toasts.map((toast) => (\n <Toast.Root\n key={toast.id}\n className={cn(\n \"flex items-start gap-3 rounded-lt border border-l-4 border-lt-border bg-lt-popover p-4 text-lt-popover-fg shadow-lt-lg\",\n variantStyles[toast.variant].accent,\n \"data-[state=open]:animate-lt-toast-in data-[state=closed]:animate-lt-toast-out\",\n \"data-[swipe=move]:translate-y-[var(--radix-toast-swipe-move-y)] data-[swipe=cancel]:translate-y-0 data-[swipe=cancel]:transition-transform\",\n )}\n data-test={`toast-${toast.variant}`}\n duration={toast.persistent ? Infinity : (toast.duration ?? duration)}\n onOpenChange={(open) => {\n if (!open) {\n dismiss(toast.id);\n }\n }}\n >\n {variantStyles[toast.variant].icon}\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n <Toast.Title className=\"text-sm text-lt-fg\">\n {typeof toast.message === \"string\"\n ? toast.message\n : resolveTranslatable(toast.message, {}, t)}\n </Toast.Title>\n {toast.action ? (\n <div className=\"flex flex-wrap gap-2\">\n <RenderNode node={toast.action} />\n </div>\n ) : null}\n </div>\n {toast.dismissible ? (\n <Toast.Close\n aria-label={t(\"
|
|
1
|
+
{"version":3,"file":"toaster.js","names":[],"sources":["../../resources/js/toast/toaster.tsx"],"sourcesContent":["import { Icon } from \"@lattice-php/lattice/icons\";\nimport * as Toast from \"@radix-ui/react-toast\";\nimport { useEffect, useState } from \"react\";\nimport { RenderNode } from \"@lattice-php/lattice/core/renderer\";\nimport type { ToastMessage } from \"@lattice-php/lattice/types/generated\";\nimport { onToast } from \"@lattice-php/lattice/toast/toast\";\nimport { cn } from \"@lattice-php/lattice/lib/utils\";\nimport { useT } from \"@lattice-php/lattice/i18n\";\nimport { variantStyles } from \"@lattice-php/lattice/toast/variant-styles\";\nimport { resolveTranslatable } from \"@lattice-php/lattice/i18n/translatable\";\n\ntype ToastItem = ToastMessage & { id: number };\n\nlet nextId = 0;\n\nexport function Toaster({ duration = 4000 }: { duration?: number }) {\n const { t } = useT(\"lattice\");\n const [toasts, setToasts] = useState<ToastItem[]>([]);\n\n function dismiss(id: number): void {\n setToasts((current) => current.filter((toast) => toast.id !== id));\n }\n\n useEffect(\n () =>\n onToast((toast) => {\n setToasts((current) => [...current, { ...toast, id: nextId++ }]);\n }),\n [],\n );\n\n return (\n <Toast.Provider duration={duration} swipeDirection=\"down\">\n {toasts.map((toast) => (\n <Toast.Root\n key={toast.id}\n className={cn(\n \"flex items-start gap-3 rounded-lt border border-l-4 border-lt-border bg-lt-popover p-4 text-lt-popover-fg shadow-lt-lg\",\n variantStyles[toast.variant].accent,\n \"data-[state=open]:animate-lt-toast-in data-[state=closed]:animate-lt-toast-out\",\n \"data-[swipe=move]:translate-y-[var(--radix-toast-swipe-move-y)] data-[swipe=cancel]:translate-y-0 data-[swipe=cancel]:transition-transform\",\n )}\n data-test={`toast-${toast.variant}`}\n duration={toast.persistent ? Infinity : (toast.duration ?? duration)}\n onOpenChange={(open) => {\n if (!open) {\n dismiss(toast.id);\n }\n }}\n >\n {variantStyles[toast.variant].icon}\n <div className=\"flex min-w-0 flex-1 flex-col gap-2\">\n <Toast.Title className=\"text-sm text-lt-fg\">\n {typeof toast.message === \"string\"\n ? toast.message\n : resolveTranslatable(toast.message, {}, t)}\n </Toast.Title>\n {toast.action ? (\n <div className=\"flex flex-wrap gap-2\">\n <RenderNode node={toast.action} />\n </div>\n ) : null}\n </div>\n {toast.dismissible ? (\n <Toast.Close\n aria-label={t(\"common.dismiss\", \"Dismiss\")}\n className=\"shrink-0 rounded-lt-sm p-1 text-lt-muted-fg transition-colors hover:bg-lt-muted hover:text-lt-fg\"\n data-test=\"toast-dismiss\"\n >\n <Icon name=\"x\" className=\"size-lt-icon-md\" />\n </Toast.Close>\n ) : null}\n </Toast.Root>\n ))}\n <Toast.Viewport className=\"fixed inset-x-0 bottom-0 z-[100] mx-auto flex w-full max-w-sm flex-col gap-2 p-4 outline-none\" />\n </Toast.Provider>\n );\n}\n"],"mappings":";;;;;;;;;;;AAaA,IAAI,SAAS;AAEb,SAAgB,QAAQ,EAAE,WAAW,OAA+B;CAClE,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,CAAC,QAAQ,aAAa,SAAsB,CAAC,CAAC;CAEpD,SAAS,QAAQ,IAAkB;EACjC,WAAW,YAAY,QAAQ,QAAQ,UAAU,MAAM,OAAO,EAAE,CAAC;CACnE;CAEA,gBAEI,SAAS,UAAU;EACjB,WAAW,YAAY,CAAC,GAAG,SAAS;GAAE,GAAG;GAAO,IAAI;EAAS,CAAC,CAAC;CACjE,CAAC,GACH,CAAC,CACH;CAEA,OACE,qBAAC,MAAM,UAAP;EAA0B;EAAU,gBAAe;YAAnD,CACG,OAAO,KAAK,UACX,qBAAC,MAAM,MAAP;GAEE,WAAW,GACT,0HACA,cAAc,MAAM,SAAS,QAC7B,kFACA,4IACF;GACA,aAAW,SAAS,MAAM;GAC1B,UAAU,MAAM,aAAa,WAAY,MAAM,YAAY;GAC3D,eAAe,SAAS;IACtB,IAAI,CAAC,MACH,QAAQ,MAAM,EAAE;GAEpB;aAdF;IAgBG,cAAc,MAAM,SAAS;IAC9B,qBAAC,OAAD;KAAK,WAAU;eAAf,CACE,oBAAC,MAAM,OAAP;MAAa,WAAU;gBACpB,OAAO,MAAM,YAAY,WACtB,MAAM,UACN,oBAAoB,MAAM,SAAS,CAAC,GAAG,CAAC;KACjC,CAAA,GACZ,MAAM,SACL,oBAAC,OAAD;MAAK,WAAU;gBACb,oBAAC,YAAD,EAAY,MAAM,MAAM,OAAS,CAAA;KAC9B,CAAA,IACH,IACD;;IACJ,MAAM,cACL,oBAAC,MAAM,OAAP;KACE,cAAY,EAAE,kBAAkB,SAAS;KACzC,WAAU;KACV,aAAU;eAEV,oBAAC,MAAD;MAAM,MAAK;MAAI,WAAU;KAAmB,CAAA;IACjC,CAAA,IACX;GACM;KArCL,MAAM,EAqCD,CACb,GACD,oBAAC,MAAM,UAAP,EAAgB,WAAU,gGAAiG,CAAA,CAC7G;;AAEpB"}
|
|
@@ -393,6 +393,36 @@ export type DateInput = {
|
|
|
393
393
|
tooltip: string | null;
|
|
394
394
|
value: unknown;
|
|
395
395
|
};
|
|
396
|
+
export type DateTimeInput = {
|
|
397
|
+
autoFocus: boolean;
|
|
398
|
+
columnWidth: ColumnWidth;
|
|
399
|
+
conditions: {
|
|
400
|
+
visible?: Condition[];
|
|
401
|
+
required?: Condition[];
|
|
402
|
+
readOnly?: Condition[];
|
|
403
|
+
disabled?: Condition[];
|
|
404
|
+
} | null;
|
|
405
|
+
convertTimezone: boolean;
|
|
406
|
+
dependsOnAny: boolean;
|
|
407
|
+
dependsOnKeys: string[] | null;
|
|
408
|
+
disabled: boolean;
|
|
409
|
+
editablePrefill: boolean;
|
|
410
|
+
helperText: string | null;
|
|
411
|
+
hidden: boolean;
|
|
412
|
+
label: string | null;
|
|
413
|
+
max: string | null;
|
|
414
|
+
min: string | null;
|
|
415
|
+
name: string;
|
|
416
|
+
prefillRefreshOn: string[] | null;
|
|
417
|
+
prefillResetOn: string[] | null;
|
|
418
|
+
readOnly: boolean;
|
|
419
|
+
required: boolean;
|
|
420
|
+
step: number | null;
|
|
421
|
+
tabIndex: number | null;
|
|
422
|
+
timezone: string | null;
|
|
423
|
+
tooltip: string | null;
|
|
424
|
+
value: unknown;
|
|
425
|
+
};
|
|
396
426
|
export type DateTimeStyle = "full" | "long" | "medium" | "short";
|
|
397
427
|
export type DownloadEffect = {
|
|
398
428
|
readonly url: string;
|
|
@@ -424,7 +454,7 @@ export type Effect = ({
|
|
|
424
454
|
} & ToastEffect) | ({
|
|
425
455
|
type: "toggleSidebar";
|
|
426
456
|
} & 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";
|
|
457
|
+
export type FieldType = "field.builder" | "field.checkbox" | "field.choice" | "field.date-input" | "field.date-time-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" | "field.time-input" | "field.toggle";
|
|
428
458
|
export type FileUpload = {
|
|
429
459
|
accept: string | null;
|
|
430
460
|
columnWidth: ColumnWidth;
|
|
@@ -512,6 +542,10 @@ export type FormFieldNode = {
|
|
|
512
542
|
type: "field.date-input";
|
|
513
543
|
key?: string;
|
|
514
544
|
props: DateInput;
|
|
545
|
+
} | {
|
|
546
|
+
type: "field.date-time-input";
|
|
547
|
+
key?: string;
|
|
548
|
+
props: DateTimeInput;
|
|
515
549
|
} | {
|
|
516
550
|
type: "field.file-upload";
|
|
517
551
|
key?: string;
|
|
@@ -552,6 +586,14 @@ export type FormFieldNode = {
|
|
|
552
586
|
type: "field.textarea";
|
|
553
587
|
key?: string;
|
|
554
588
|
props: Textarea;
|
|
589
|
+
} | {
|
|
590
|
+
type: "field.time-input";
|
|
591
|
+
key?: string;
|
|
592
|
+
props: TimeInput;
|
|
593
|
+
} | {
|
|
594
|
+
type: "field.toggle";
|
|
595
|
+
key?: string;
|
|
596
|
+
props: Toggle;
|
|
555
597
|
};
|
|
556
598
|
export type FormNode = FormFieldNode | {
|
|
557
599
|
type: "form";
|
|
@@ -971,7 +1013,7 @@ export type Sidebar = {
|
|
|
971
1013
|
collapsible: boolean;
|
|
972
1014
|
rememberState: boolean;
|
|
973
1015
|
};
|
|
974
|
-
export type Size = "xs" | "sm" | "md" | "lg" | "xl";
|
|
1016
|
+
export type Size = "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl";
|
|
975
1017
|
export type SortDirection = "asc" | "desc";
|
|
976
1018
|
export type Stack = {
|
|
977
1019
|
align: Align | null;
|
|
@@ -1122,6 +1164,34 @@ export type Textarea = {
|
|
|
1122
1164
|
tooltip: string | null;
|
|
1123
1165
|
value: unknown;
|
|
1124
1166
|
};
|
|
1167
|
+
export type TimeInput = {
|
|
1168
|
+
autoFocus: boolean;
|
|
1169
|
+
columnWidth: ColumnWidth;
|
|
1170
|
+
conditions: {
|
|
1171
|
+
visible?: Condition[];
|
|
1172
|
+
required?: Condition[];
|
|
1173
|
+
readOnly?: Condition[];
|
|
1174
|
+
disabled?: Condition[];
|
|
1175
|
+
} | null;
|
|
1176
|
+
dependsOnAny: boolean;
|
|
1177
|
+
dependsOnKeys: string[] | null;
|
|
1178
|
+
disabled: boolean;
|
|
1179
|
+
editablePrefill: boolean;
|
|
1180
|
+
helperText: string | null;
|
|
1181
|
+
hidden: boolean;
|
|
1182
|
+
label: string | null;
|
|
1183
|
+
max: string | null;
|
|
1184
|
+
min: string | null;
|
|
1185
|
+
name: string;
|
|
1186
|
+
prefillRefreshOn: string[] | null;
|
|
1187
|
+
prefillResetOn: string[] | null;
|
|
1188
|
+
readOnly: boolean;
|
|
1189
|
+
required: boolean;
|
|
1190
|
+
step: number | null;
|
|
1191
|
+
tabIndex: number | null;
|
|
1192
|
+
tooltip: string | null;
|
|
1193
|
+
value: unknown;
|
|
1194
|
+
};
|
|
1125
1195
|
export type ToastEffect = {
|
|
1126
1196
|
readonly toast: ToastMessage;
|
|
1127
1197
|
};
|
|
@@ -1133,6 +1203,31 @@ export type ToastMessage = {
|
|
|
1133
1203
|
variant: Variant;
|
|
1134
1204
|
message: Translatable | string;
|
|
1135
1205
|
};
|
|
1206
|
+
export type Toggle = {
|
|
1207
|
+
autoFocus: boolean;
|
|
1208
|
+
columnWidth: ColumnWidth;
|
|
1209
|
+
conditions: {
|
|
1210
|
+
visible?: Condition[];
|
|
1211
|
+
required?: Condition[];
|
|
1212
|
+
readOnly?: Condition[];
|
|
1213
|
+
disabled?: Condition[];
|
|
1214
|
+
} | null;
|
|
1215
|
+
dependsOnAny: boolean;
|
|
1216
|
+
dependsOnKeys: string[] | null;
|
|
1217
|
+
disabled: boolean;
|
|
1218
|
+
editablePrefill: boolean;
|
|
1219
|
+
helperText: string | null;
|
|
1220
|
+
hidden: boolean;
|
|
1221
|
+
label: string | null;
|
|
1222
|
+
name: string;
|
|
1223
|
+
prefillRefreshOn: string[] | null;
|
|
1224
|
+
prefillResetOn: string[] | null;
|
|
1225
|
+
readOnly: boolean;
|
|
1226
|
+
required: boolean;
|
|
1227
|
+
tabIndex: number | null;
|
|
1228
|
+
tooltip: string | null;
|
|
1229
|
+
value: unknown;
|
|
1230
|
+
};
|
|
1136
1231
|
export type ToggleSidebarEffect = {
|
|
1137
1232
|
readonly target: string | null;
|
|
1138
1233
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lattice-php/lattice",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Server-driven React components for Laravel and Inertia.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Manuel Christlieb <manuel@christlieb.eu>",
|
|
@@ -195,6 +195,7 @@
|
|
|
195
195
|
"build:lib:watch": "vite build --mode lib --watch",
|
|
196
196
|
"prepack": "npm run build:lib",
|
|
197
197
|
"test": "vitest run",
|
|
198
|
+
"test:browser": "vitest run --project browser",
|
|
198
199
|
"test:coverage": "vitest run --coverage",
|
|
199
200
|
"typecheck": "tsc --noEmit",
|
|
200
201
|
"type-coverage": "type-coverage --project tsconfig.json --at-least 99.5",
|
|
@@ -211,6 +212,7 @@
|
|
|
211
212
|
"docs:preview": "astro preview"
|
|
212
213
|
},
|
|
213
214
|
"dependencies": {
|
|
215
|
+
"@internationalized/date": "^3.12.2",
|
|
214
216
|
"@lattice-php/vite-svg-sprite": "^0.2.1",
|
|
215
217
|
"@radix-ui/react-checkbox": "^1.1.4",
|
|
216
218
|
"@radix-ui/react-dialog": "^1.1.16",
|
|
@@ -226,6 +228,8 @@
|
|
|
226
228
|
"@tiptap/pm": "^3.26.0",
|
|
227
229
|
"@tiptap/react": "^3.26.0",
|
|
228
230
|
"@tiptap/starter-kit": "^3.26.0",
|
|
231
|
+
"@zag-js/date-picker": "^1.41.2",
|
|
232
|
+
"@zag-js/react": "^1.41.2",
|
|
229
233
|
"class-variance-authority": "^0.7.1",
|
|
230
234
|
"clsx": "^2.1.1",
|
|
231
235
|
"i18next": "^26.3.1",
|
|
@@ -266,6 +270,7 @@
|
|
|
266
270
|
"@types/react": "^19.2.0",
|
|
267
271
|
"@types/react-dom": "^19.2.0",
|
|
268
272
|
"@vitejs/plugin-react": "^6.0.2",
|
|
273
|
+
"@vitest/browser-playwright": "^4.1.8",
|
|
269
274
|
"@vitest/coverage-v8": "^4.1.8",
|
|
270
275
|
"astro": "7.0.0-beta.3",
|
|
271
276
|
"astro-og-canvas": "^0.11.1",
|
|
@@ -289,6 +294,7 @@
|
|
|
289
294
|
"typescript": "^6.0.3",
|
|
290
295
|
"vite": "^8.0.0",
|
|
291
296
|
"vite-plugin-dts": "^4.5.4",
|
|
292
|
-
"vitest": "^4.1.8"
|
|
297
|
+
"vitest": "^4.1.8",
|
|
298
|
+
"vitest-browser-react": "^2.2.0"
|
|
293
299
|
}
|
|
294
300
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!-- @license lucide-static v1.18.0 - ISC -->
|
|
2
|
+
<svg
|
|
3
|
+
class="lucide lucide-calendar"
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
width="24"
|
|
6
|
+
height="24"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
fill="none"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
stroke-width="2"
|
|
11
|
+
stroke-linecap="round"
|
|
12
|
+
stroke-linejoin="round"
|
|
13
|
+
>
|
|
14
|
+
<path d="M8 2v4" />
|
|
15
|
+
<path d="M16 2v4" />
|
|
16
|
+
<rect width="18" height="18" x="3" y="4" rx="2" />
|
|
17
|
+
<path d="M3 10h18" />
|
|
18
|
+
</svg>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!-- @license lucide-static v1.18.0 - ISC -->
|
|
2
|
+
<svg
|
|
3
|
+
class="lucide lucide-chevron-left"
|
|
4
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
5
|
+
width="24"
|
|
6
|
+
height="24"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
fill="none"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
stroke-width="2"
|
|
11
|
+
stroke-linecap="round"
|
|
12
|
+
stroke-linejoin="round"
|
|
13
|
+
>
|
|
14
|
+
<path d="m15 18-6-6 6-6" />
|
|
15
|
+
</svg>
|