@dimaan/ui 0.0.19 → 0.0.21
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/index.cjs +135 -182
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +191 -166
- package/dist/index.d.ts +191 -166
- package/dist/index.js +136 -183
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -756,7 +756,6 @@ function SidebarNavItem({
|
|
|
756
756
|
}
|
|
757
757
|
);
|
|
758
758
|
}
|
|
759
|
-
console.log("AppShell");
|
|
760
759
|
function isGroup(entry) {
|
|
761
760
|
return "items" in entry && Array.isArray(entry.items);
|
|
762
761
|
}
|
|
@@ -1724,12 +1723,26 @@ var formPageBodyClass = "flex-1";
|
|
|
1724
1723
|
var formPageActionsBarClass = "sticky bottom-0 -mx-6 -mb-6 mt-6 flex items-center justify-end gap-2 border-t border-border bg-background/95 px-6 py-3 backdrop-blur supports-[backdrop-filter]:bg-background/80";
|
|
1725
1724
|
var formPageSkeletonRowClass = "h-10 w-full animate-pulse rounded-md bg-muted";
|
|
1726
1725
|
var DEFAULT_SKELETON_ROW_COUNT2 = 6;
|
|
1726
|
+
var DEFAULT_LABELS_LTR = {
|
|
1727
|
+
back: "Back",
|
|
1728
|
+
cancel: "Cancel",
|
|
1729
|
+
save: "Save",
|
|
1730
|
+
saving: "Saving\u2026"
|
|
1731
|
+
};
|
|
1732
|
+
var DEFAULT_LABELS_RTL = {
|
|
1733
|
+
back: "\u0631\u062C\u0648\u0639",
|
|
1734
|
+
cancel: "\u0625\u0644\u063A\u0627\u0621",
|
|
1735
|
+
save: "\u062D\u0641\u0638",
|
|
1736
|
+
saving: "\u062C\u0627\u0631\u064D \u0627\u0644\u062D\u0641\u0638\u2026"
|
|
1737
|
+
};
|
|
1727
1738
|
function FormPage({
|
|
1728
1739
|
title,
|
|
1729
1740
|
description,
|
|
1730
|
-
back,
|
|
1731
1741
|
bordered = true,
|
|
1732
1742
|
onSubmit,
|
|
1743
|
+
onCancel,
|
|
1744
|
+
isSubmitting,
|
|
1745
|
+
labels: labelsProp,
|
|
1733
1746
|
isLoading = false,
|
|
1734
1747
|
loadingRowCount = DEFAULT_SKELETON_ROW_COUNT2,
|
|
1735
1748
|
actions,
|
|
@@ -1739,8 +1752,23 @@ function FormPage({
|
|
|
1739
1752
|
bodyClassName,
|
|
1740
1753
|
actionsClassName
|
|
1741
1754
|
}) {
|
|
1755
|
+
const navigate = reactRouterDom.useNavigate();
|
|
1756
|
+
const dir = useDirection();
|
|
1757
|
+
const formContext = reactHookForm.useFormContext();
|
|
1758
|
+
const submitting = isSubmitting ?? formContext?.formState?.isSubmitting ?? false;
|
|
1759
|
+
const defaults = dir === "rtl" ? DEFAULT_LABELS_RTL : DEFAULT_LABELS_LTR;
|
|
1760
|
+
const labels = { ...defaults, ...labelsProp };
|
|
1761
|
+
const goBack = () => navigate(-1);
|
|
1742
1762
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "form-page", className: cn(formPageBaseClass, className), children: [
|
|
1743
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1763
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1764
|
+
PageHeader,
|
|
1765
|
+
{
|
|
1766
|
+
title,
|
|
1767
|
+
description,
|
|
1768
|
+
back: { label: labels.back, onClick: goBack },
|
|
1769
|
+
bordered
|
|
1770
|
+
}
|
|
1771
|
+
),
|
|
1744
1772
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1745
1773
|
"form",
|
|
1746
1774
|
{
|
|
@@ -1751,14 +1779,27 @@ function FormPage({
|
|
|
1751
1779
|
className: cn("flex flex-1 flex-col gap-6", formClassName),
|
|
1752
1780
|
children: [
|
|
1753
1781
|
/* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "form-page-body", className: cn(formPageBodyClass, bodyClassName), children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(FormPageSkeleton, { rowCount: loadingRowCount }) : children }),
|
|
1754
|
-
|
|
1782
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1755
1783
|
"div",
|
|
1756
1784
|
{
|
|
1757
1785
|
"data-slot": "form-page-actions",
|
|
1758
1786
|
className: cn(formPageActionsBarClass, actionsClassName),
|
|
1759
|
-
children:
|
|
1787
|
+
children: [
|
|
1788
|
+
actions,
|
|
1789
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "outline", onClick: onCancel ?? goBack, children: labels.cancel }),
|
|
1790
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1791
|
+
Button,
|
|
1792
|
+
{
|
|
1793
|
+
type: "submit",
|
|
1794
|
+
loading: submitting,
|
|
1795
|
+
loadingText: labels.saving,
|
|
1796
|
+
disabled: isLoading,
|
|
1797
|
+
children: labels.save
|
|
1798
|
+
}
|
|
1799
|
+
)
|
|
1800
|
+
]
|
|
1760
1801
|
}
|
|
1761
|
-
)
|
|
1802
|
+
)
|
|
1762
1803
|
]
|
|
1763
1804
|
}
|
|
1764
1805
|
)
|
|
@@ -2009,15 +2050,35 @@ var SelectItem = react.forwardRef(function SelectItem2({ className, children, ..
|
|
|
2009
2050
|
/* @__PURE__ */ jsxRuntime.jsx(RadixSelect__namespace.ItemText, { children })
|
|
2010
2051
|
] });
|
|
2011
2052
|
});
|
|
2053
|
+
var EN_LABELS = {
|
|
2054
|
+
rowsPerPage: "Rows per page",
|
|
2055
|
+
pageRangeOf: "of",
|
|
2056
|
+
previousPage: "Previous page",
|
|
2057
|
+
nextPage: "Next page"
|
|
2058
|
+
};
|
|
2059
|
+
var AR_LABELS = {
|
|
2060
|
+
rowsPerPage: "\u0635\u0641\u0648\u0641 \u0644\u0643\u0644 \u0635\u0641\u062D\u0629",
|
|
2061
|
+
pageRangeOf: "\u0645\u0646",
|
|
2062
|
+
previousPage: "\u0627\u0644\u0635\u0641\u062D\u0629 \u0627\u0644\u0633\u0627\u0628\u0642\u0629",
|
|
2063
|
+
nextPage: "\u0627\u0644\u0635\u0641\u062D\u0629 \u0627\u0644\u062A\u0627\u0644\u064A\u0629"
|
|
2064
|
+
};
|
|
2012
2065
|
function Pagination({
|
|
2013
2066
|
pageIndex,
|
|
2014
2067
|
pageSize,
|
|
2015
2068
|
pageCount,
|
|
2016
2069
|
totalRowCount,
|
|
2017
2070
|
pageSizeOptions,
|
|
2018
|
-
onChange
|
|
2071
|
+
onChange,
|
|
2072
|
+
labels: labelsProp
|
|
2019
2073
|
}) {
|
|
2020
2074
|
const dir = useDirection();
|
|
2075
|
+
const localeDefaults = dir === "rtl" ? AR_LABELS : EN_LABELS;
|
|
2076
|
+
const labels = {
|
|
2077
|
+
rowsPerPage: labelsProp?.rowsPerPage ?? localeDefaults.rowsPerPage,
|
|
2078
|
+
pageRangeOf: labelsProp?.pageRangeOf ?? localeDefaults.pageRangeOf,
|
|
2079
|
+
previousPage: labelsProp?.previousPage ?? localeDefaults.previousPage,
|
|
2080
|
+
nextPage: labelsProp?.nextPage ?? localeDefaults.nextPage
|
|
2081
|
+
};
|
|
2021
2082
|
const isRtl = dir === "rtl";
|
|
2022
2083
|
const isFirst = pageIndex <= 0;
|
|
2023
2084
|
const isLast = pageIndex >= pageCount - 1;
|
|
@@ -2031,7 +2092,7 @@ function Pagination({
|
|
|
2031
2092
|
const end = Math.min(totalRowCount, (pageIndex + 1) * pageSize);
|
|
2032
2093
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3 text-sm text-muted-foreground", children: [
|
|
2033
2094
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-2", children: [
|
|
2034
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children:
|
|
2095
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: labels.rowsPerPage }),
|
|
2035
2096
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2036
2097
|
"select",
|
|
2037
2098
|
{
|
|
@@ -2050,7 +2111,9 @@ function Pagination({
|
|
|
2050
2111
|
start,
|
|
2051
2112
|
"\u2013",
|
|
2052
2113
|
end,
|
|
2053
|
-
"
|
|
2114
|
+
" ",
|
|
2115
|
+
labels.pageRangeOf,
|
|
2116
|
+
" ",
|
|
2054
2117
|
totalRowCount
|
|
2055
2118
|
] }),
|
|
2056
2119
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
@@ -2062,7 +2125,7 @@ function Pagination({
|
|
|
2062
2125
|
size: "sm",
|
|
2063
2126
|
disabled: isFirst,
|
|
2064
2127
|
onClick: goPrev,
|
|
2065
|
-
"aria-label":
|
|
2128
|
+
"aria-label": labels.previousPage,
|
|
2066
2129
|
children: isRtl ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { "aria-hidden": "true", className: "h-3.5 w-3.5" })
|
|
2067
2130
|
}
|
|
2068
2131
|
),
|
|
@@ -2079,7 +2142,7 @@ function Pagination({
|
|
|
2079
2142
|
size: "sm",
|
|
2080
2143
|
disabled: isLast,
|
|
2081
2144
|
onClick: goNext,
|
|
2082
|
-
"aria-label":
|
|
2145
|
+
"aria-label": labels.nextPage,
|
|
2083
2146
|
children: isRtl ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { "aria-hidden": "true", className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true", className: "h-3.5 w-3.5" })
|
|
2084
2147
|
}
|
|
2085
2148
|
)
|
|
@@ -2132,66 +2195,28 @@ var alignClass = {
|
|
|
2132
2195
|
end: "text-end"
|
|
2133
2196
|
};
|
|
2134
2197
|
var EMPTY_SELECTION = /* @__PURE__ */ new Set();
|
|
2135
|
-
var NO_SORT = { columnId: null, direction: "asc" };
|
|
2136
2198
|
function useTableState(props) {
|
|
2137
2199
|
const {
|
|
2138
|
-
defaultSort,
|
|
2139
|
-
sort: sortProp,
|
|
2140
|
-
onSortChange,
|
|
2141
|
-
defaultPagination,
|
|
2142
|
-
pagination: paginationProp,
|
|
2143
|
-
onPaginationChange,
|
|
2144
|
-
pageSizeOptions,
|
|
2145
2200
|
defaultSelectedRowIds,
|
|
2146
2201
|
selectedRowIds: selectedRowIdsProp,
|
|
2147
|
-
onSelectedRowIdsChange
|
|
2148
|
-
totalCount
|
|
2202
|
+
onSelectedRowIdsChange
|
|
2149
2203
|
} = props;
|
|
2150
|
-
const [internalSort, setInternalSort] = react.useState(defaultSort ?? NO_SORT);
|
|
2151
|
-
const isSortControlled = sortProp !== void 0;
|
|
2152
|
-
const sort = isSortControlled ? sortProp : internalSort;
|
|
2153
|
-
const setSort = react.useCallback(
|
|
2154
|
-
(next) => {
|
|
2155
|
-
if (!isSortControlled) setInternalSort(next);
|
|
2156
|
-
onSortChange?.(next);
|
|
2157
|
-
},
|
|
2158
|
-
[isSortControlled, onSortChange]
|
|
2159
|
-
);
|
|
2160
|
-
const [internalPagination, setInternalPagination] = react.useState(
|
|
2161
|
-
defaultPagination ?? { pageIndex: 0, pageSize: pageSizeOptions?.[0] ?? 10 }
|
|
2162
|
-
);
|
|
2163
|
-
const isPaginationControlled = paginationProp !== void 0;
|
|
2164
|
-
const pagination = isPaginationControlled ? paginationProp : internalPagination;
|
|
2165
|
-
const setPagination = react.useCallback(
|
|
2166
|
-
(next) => {
|
|
2167
|
-
if (!isPaginationControlled) setInternalPagination(next);
|
|
2168
|
-
onPaginationChange?.(next);
|
|
2169
|
-
},
|
|
2170
|
-
[isPaginationControlled, onPaginationChange]
|
|
2171
|
-
);
|
|
2172
2204
|
const [internalSelected, setInternalSelected] = react.useState(
|
|
2173
2205
|
defaultSelectedRowIds ?? EMPTY_SELECTION
|
|
2174
2206
|
);
|
|
2175
|
-
const
|
|
2176
|
-
const selected =
|
|
2207
|
+
const isControlled = selectedRowIdsProp !== void 0;
|
|
2208
|
+
const selected = isControlled ? selectedRowIdsProp : internalSelected;
|
|
2177
2209
|
const setSelected = react.useCallback(
|
|
2178
2210
|
(next) => {
|
|
2179
|
-
if (!
|
|
2211
|
+
if (!isControlled) setInternalSelected(next);
|
|
2180
2212
|
onSelectedRowIdsChange?.(next);
|
|
2181
2213
|
},
|
|
2182
|
-
[
|
|
2214
|
+
[isControlled, onSelectedRowIdsChange]
|
|
2183
2215
|
);
|
|
2184
|
-
return {
|
|
2185
|
-
sort,
|
|
2186
|
-
setSort,
|
|
2187
|
-
pagination,
|
|
2188
|
-
setPagination,
|
|
2189
|
-
selected,
|
|
2190
|
-
setSelected,
|
|
2191
|
-
isServerSide: totalCount !== void 0
|
|
2192
|
-
};
|
|
2216
|
+
return { selected, setSelected };
|
|
2193
2217
|
}
|
|
2194
2218
|
var DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50];
|
|
2219
|
+
var DEFAULT_PAGE_SIZE = 10;
|
|
2195
2220
|
function defaultGetRowId(row, index) {
|
|
2196
2221
|
const rowId = row.id;
|
|
2197
2222
|
return rowId === void 0 || rowId === null ? String(index) : String(rowId);
|
|
@@ -2218,36 +2243,26 @@ function Table(props) {
|
|
|
2218
2243
|
tableRef,
|
|
2219
2244
|
pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
|
|
2220
2245
|
showPagination,
|
|
2221
|
-
caption
|
|
2246
|
+
caption,
|
|
2247
|
+
sort,
|
|
2248
|
+
onSortChange,
|
|
2249
|
+
pagination,
|
|
2250
|
+
onPaginationChange,
|
|
2251
|
+
totalCount,
|
|
2252
|
+
labels
|
|
2222
2253
|
} = props;
|
|
2223
2254
|
const ariaLabel = props["aria-label"];
|
|
2224
2255
|
const ariaLabelledBy = props["aria-labelledby"];
|
|
2225
|
-
const {
|
|
2226
|
-
const
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
if (!get) return data;
|
|
2232
|
-
const tagged = data.map((row, index) => ({ row, index }));
|
|
2233
|
-
tagged.sort((a, b) => {
|
|
2234
|
-
const cmp = compareValues(get(a.row), get(b.row));
|
|
2235
|
-
if (cmp !== 0) return sort.direction === "asc" ? cmp : -cmp;
|
|
2236
|
-
return a.index - b.index;
|
|
2237
|
-
});
|
|
2238
|
-
return tagged.map((entry) => entry.row);
|
|
2239
|
-
}, [data, columns, sort, isServerSide]);
|
|
2240
|
-
const pagedRows = react.useMemo(() => {
|
|
2241
|
-
if (isServerSide) return sortedRows;
|
|
2242
|
-
const start = pagination.pageIndex * pagination.pageSize;
|
|
2243
|
-
return sortedRows.slice(start, start + pagination.pageSize);
|
|
2244
|
-
}, [sortedRows, pagination, isServerSide]);
|
|
2245
|
-
const totalRowCount = isServerSide ? props.totalCount ?? 0 : data.length;
|
|
2246
|
-
const pageCount = Math.max(1, Math.ceil(totalRowCount / pagination.pageSize));
|
|
2256
|
+
const { selected, setSelected } = useTableState(props);
|
|
2257
|
+
const effectiveSort = sort ?? { columnId: null, direction: "asc" };
|
|
2258
|
+
const pageSize = pagination?.pageSize ?? pageSizeOptions[0] ?? DEFAULT_PAGE_SIZE;
|
|
2259
|
+
const pageIndex = pagination?.pageIndex ?? 0;
|
|
2260
|
+
const totalRowCount = totalCount ?? data.length;
|
|
2261
|
+
const pageCount = Math.max(1, Math.ceil(totalRowCount / pageSize));
|
|
2247
2262
|
const selectableRowIds = react.useMemo(() => {
|
|
2248
2263
|
if (!enableRowSelection) return [];
|
|
2249
|
-
return
|
|
2250
|
-
}, [
|
|
2264
|
+
return data.map((row, index) => ({ row, index })).filter(({ row }) => isRowSelectable ? isRowSelectable(row) : true).map(({ row, index }) => getRowId(row, index));
|
|
2265
|
+
}, [data, enableRowSelection, isRowSelectable, getRowId]);
|
|
2251
2266
|
const selectedOnPageCount = selectableRowIds.reduce(
|
|
2252
2267
|
(acc, id) => selected.has(id) ? acc + 1 : acc,
|
|
2253
2268
|
0
|
|
@@ -2275,13 +2290,16 @@ function Table(props) {
|
|
|
2275
2290
|
};
|
|
2276
2291
|
const clearSelection = () => setSelected(/* @__PURE__ */ new Set());
|
|
2277
2292
|
const handleSortClick = (columnId) => {
|
|
2278
|
-
|
|
2293
|
+
if (!onSortChange) return;
|
|
2294
|
+
onSortChange(nextSort(effectiveSort, columnId));
|
|
2279
2295
|
};
|
|
2296
|
+
const handlePaginationChange = onPaginationChange ?? (() => {
|
|
2297
|
+
});
|
|
2280
2298
|
const totalColumnCount = columns.length + (enableRowSelection ? 1 : 0);
|
|
2281
|
-
const paginationVisible = showPagination ?? totalRowCount >
|
|
2299
|
+
const paginationVisible = Boolean(pagination) && (showPagination ?? totalRowCount > pageSize);
|
|
2282
2300
|
const sizeClasses = tableSizeClass[size];
|
|
2283
2301
|
const showToolbar = enableRowSelection && bulkActions !== void 0 && selected.size > 0;
|
|
2284
|
-
const skeletonCount = loadingRowCount ??
|
|
2302
|
+
const skeletonCount = loadingRowCount ?? pageSize;
|
|
2285
2303
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex w-full flex-col gap-3", className), children: [
|
|
2286
2304
|
showToolbar && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2287
2305
|
Toolbar,
|
|
@@ -2330,8 +2348,8 @@ function Table(props) {
|
|
|
2330
2348
|
}
|
|
2331
2349
|
) }) : null,
|
|
2332
2350
|
columns.map((column) => {
|
|
2333
|
-
const isSorted =
|
|
2334
|
-
const ariaSort = isSorted ?
|
|
2351
|
+
const isSorted = effectiveSort.columnId === column.id;
|
|
2352
|
+
const ariaSort = isSorted ? effectiveSort.direction === "asc" ? "ascending" : "descending" : "none";
|
|
2335
2353
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2336
2354
|
"th",
|
|
2337
2355
|
{
|
|
@@ -2348,14 +2366,14 @@ function Table(props) {
|
|
|
2348
2366
|
type: "button",
|
|
2349
2367
|
onClick: () => handleSortClick(column.id),
|
|
2350
2368
|
className: "inline-flex items-center gap-1.5 font-inherit uppercase tracking-inherit text-inherit hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background",
|
|
2351
|
-
"aria-label": sortAriaLabel(column,
|
|
2369
|
+
"aria-label": sortAriaLabel(column, effectiveSort),
|
|
2352
2370
|
children: [
|
|
2353
2371
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: renderHeader(column.header) }),
|
|
2354
2372
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2355
2373
|
SortIndicator,
|
|
2356
2374
|
{
|
|
2357
2375
|
active: isSorted,
|
|
2358
|
-
direction: isSorted ?
|
|
2376
|
+
direction: isSorted ? effectiveSort.direction : null
|
|
2359
2377
|
}
|
|
2360
2378
|
)
|
|
2361
2379
|
]
|
|
@@ -2375,14 +2393,14 @@ function Table(props) {
|
|
|
2375
2393
|
columnCount: totalColumnCount,
|
|
2376
2394
|
cellClassName: sizeClasses.cell
|
|
2377
2395
|
}
|
|
2378
|
-
) :
|
|
2396
|
+
) : data.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2379
2397
|
"td",
|
|
2380
2398
|
{
|
|
2381
2399
|
colSpan: totalColumnCount,
|
|
2382
2400
|
className: cn(sizeClasses.cell, "py-10 text-center text-muted-foreground"),
|
|
2383
2401
|
children: emptyState ?? "No data"
|
|
2384
2402
|
}
|
|
2385
|
-
) }) :
|
|
2403
|
+
) }) : data.map((row, rowIndex) => {
|
|
2386
2404
|
const id = getRowId(row, rowIndex);
|
|
2387
2405
|
const isSelected = selected.has(id);
|
|
2388
2406
|
const rowSelectable = isRowSelectable ? isRowSelectable(row) : true;
|
|
@@ -2435,12 +2453,13 @@ function Table(props) {
|
|
|
2435
2453
|
paginationVisible ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2436
2454
|
Pagination,
|
|
2437
2455
|
{
|
|
2438
|
-
pageIndex
|
|
2439
|
-
pageSize
|
|
2456
|
+
pageIndex,
|
|
2457
|
+
pageSize,
|
|
2440
2458
|
pageCount,
|
|
2441
2459
|
totalRowCount,
|
|
2442
2460
|
pageSizeOptions,
|
|
2443
|
-
onChange:
|
|
2461
|
+
onChange: handlePaginationChange,
|
|
2462
|
+
labels
|
|
2444
2463
|
}
|
|
2445
2464
|
) : null
|
|
2446
2465
|
] });
|
|
@@ -2456,24 +2475,6 @@ function renderCell(column, row, rowIndex) {
|
|
|
2456
2475
|
}
|
|
2457
2476
|
return null;
|
|
2458
2477
|
}
|
|
2459
|
-
function resolveSortGetter(column) {
|
|
2460
|
-
if (column.sortAccessor) return column.sortAccessor;
|
|
2461
|
-
if (column.accessor !== void 0) {
|
|
2462
|
-
const key = column.accessor;
|
|
2463
|
-
return (row) => row[key];
|
|
2464
|
-
}
|
|
2465
|
-
return null;
|
|
2466
|
-
}
|
|
2467
|
-
function compareValues(a, b) {
|
|
2468
|
-
if (a === b) return 0;
|
|
2469
|
-
if (a === null || a === void 0) return 1;
|
|
2470
|
-
if (b === null || b === void 0) return -1;
|
|
2471
|
-
if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();
|
|
2472
|
-
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
2473
|
-
if (typeof a === "bigint" && typeof b === "bigint") return a < b ? -1 : 1;
|
|
2474
|
-
if (typeof a === "boolean" && typeof b === "boolean") return a === b ? 0 : a ? 1 : -1;
|
|
2475
|
-
return String(a).localeCompare(String(b), void 0, { numeric: true, sensitivity: "base" });
|
|
2476
|
-
}
|
|
2477
2478
|
function nextSort(current, columnId) {
|
|
2478
2479
|
if (current.columnId !== columnId) return { columnId, direction: "asc" };
|
|
2479
2480
|
if (current.direction === "asc") return { columnId, direction: "desc" };
|
|
@@ -2524,16 +2525,14 @@ function ListPage({
|
|
|
2524
2525
|
getRowId,
|
|
2525
2526
|
isLoading = false,
|
|
2526
2527
|
loadingRowCount,
|
|
2527
|
-
|
|
2528
|
-
searchValue: searchValueProp,
|
|
2528
|
+
searchValue,
|
|
2529
2529
|
onSearchChange,
|
|
2530
2530
|
filters,
|
|
2531
|
-
filterValues
|
|
2531
|
+
filterValues,
|
|
2532
2532
|
onFilterChange,
|
|
2533
2533
|
enableRowSelection,
|
|
2534
2534
|
bulkActions,
|
|
2535
2535
|
pagination,
|
|
2536
|
-
defaultPagination,
|
|
2537
2536
|
onPaginationChange,
|
|
2538
2537
|
totalCount,
|
|
2539
2538
|
pageSizeOptions,
|
|
@@ -2543,82 +2542,36 @@ function ListPage({
|
|
|
2543
2542
|
className
|
|
2544
2543
|
}) {
|
|
2545
2544
|
const labels = { ...DEFAULT_LABELS2, ...labelsProp };
|
|
2546
|
-
const
|
|
2547
|
-
|
|
2545
|
+
const showSearch = onSearchChange !== void 0;
|
|
2546
|
+
const showFilterBar = showSearch || Boolean(filters?.length);
|
|
2547
|
+
const hasActiveQuery = react.useMemo(() => {
|
|
2548
|
+
if ((searchValue ?? "").trim() !== "") return true;
|
|
2548
2549
|
for (const f of filters ?? []) {
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
}, [filters]);
|
|
2553
|
-
const isSearchControlled = searchValueProp !== void 0;
|
|
2554
|
-
const isFiltersControlled = filterValuesProp !== void 0;
|
|
2555
|
-
const [internalSearch, setInternalSearch] = react.useState("");
|
|
2556
|
-
const [internalFilterValues, setInternalFilterValues] = react.useState(initialFilterValues);
|
|
2557
|
-
const search = isSearchControlled ? searchValueProp : internalSearch;
|
|
2558
|
-
const filterValues = isFiltersControlled ? filterValuesProp : internalFilterValues;
|
|
2559
|
-
const setSearch = (next) => {
|
|
2560
|
-
if (!isSearchControlled) setInternalSearch(next);
|
|
2561
|
-
onSearchChange?.(next);
|
|
2562
|
-
};
|
|
2563
|
-
const setFilter = (key, value) => {
|
|
2564
|
-
if (!isFiltersControlled) {
|
|
2565
|
-
setInternalFilterValues((prev) => ({ ...prev, [key]: value }));
|
|
2550
|
+
const current = filterValues?.[f.key];
|
|
2551
|
+
const def = f.options[0]?.value ?? "";
|
|
2552
|
+
if (current !== void 0 && current !== def) return true;
|
|
2566
2553
|
}
|
|
2567
|
-
|
|
2568
|
-
};
|
|
2554
|
+
return false;
|
|
2555
|
+
}, [searchValue, filters, filterValues]);
|
|
2569
2556
|
const reset = () => {
|
|
2570
|
-
if (!isSearchControlled) setInternalSearch("");
|
|
2571
2557
|
onSearchChange?.("");
|
|
2572
|
-
if (!isFiltersControlled) setInternalFilterValues(initialFilterValues);
|
|
2573
2558
|
for (const f of filters ?? []) {
|
|
2574
|
-
const def = f.
|
|
2559
|
+
const def = f.options[0]?.value ?? "";
|
|
2575
2560
|
onFilterChange?.(f.key, def);
|
|
2576
2561
|
}
|
|
2577
2562
|
};
|
|
2578
|
-
const
|
|
2579
|
-
if (search.trim() !== "") return true;
|
|
2580
|
-
for (const f of filters ?? []) {
|
|
2581
|
-
const current = filterValues[f.key];
|
|
2582
|
-
const def = f.defaultValue ?? f.options[0]?.value ?? "";
|
|
2583
|
-
if (current !== def) return true;
|
|
2584
|
-
}
|
|
2585
|
-
return false;
|
|
2586
|
-
}, [search, filters, filterValues]);
|
|
2587
|
-
const filtered = react.useMemo(() => {
|
|
2588
|
-
return data.filter((row) => {
|
|
2589
|
-
if (!isSearchControlled && search.trim() && searchKeys && searchKeys.length > 0) {
|
|
2590
|
-
const q = search.trim().toLowerCase();
|
|
2591
|
-
const matches = searchKeys.some((key) => {
|
|
2592
|
-
const val = row[key];
|
|
2593
|
-
return val != null && String(val).toLowerCase().includes(q);
|
|
2594
|
-
});
|
|
2595
|
-
if (!matches) return false;
|
|
2596
|
-
}
|
|
2597
|
-
if (!isFiltersControlled) {
|
|
2598
|
-
for (const f of filters ?? []) {
|
|
2599
|
-
const value = filterValues[f.key];
|
|
2600
|
-
const def = f.defaultValue ?? f.options[0]?.value ?? "";
|
|
2601
|
-
if (value !== void 0 && value !== def) {
|
|
2602
|
-
if (f.accessor(row) !== value) return false;
|
|
2603
|
-
}
|
|
2604
|
-
}
|
|
2605
|
-
}
|
|
2606
|
-
return true;
|
|
2607
|
-
});
|
|
2608
|
-
}, [data, search, searchKeys, filters, filterValues, isSearchControlled, isFiltersControlled]);
|
|
2609
|
-
const showFilterBar = Boolean(searchKeys?.length) || Boolean(filters?.length);
|
|
2610
|
-
const tableMode = isLoading ? "loading" : data.length === 0 && !hasActiveFilters ? "no-data" : filtered.length === 0 ? "no-results" : "rows";
|
|
2563
|
+
const tableMode = isLoading ? "loading" : data.length === 0 && !hasActiveQuery ? "no-data" : data.length === 0 && hasActiveQuery ? "no-results" : "rows";
|
|
2611
2564
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "list-page", className: cn("space-y-6", className), children: [
|
|
2612
2565
|
/* @__PURE__ */ jsxRuntime.jsx(PageHeader, { title, description, bordered, actions }),
|
|
2613
2566
|
showFilterBar ? /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "list-page-filter-bar", className: "flex flex-wrap items-center gap-3", children: [
|
|
2614
|
-
|
|
2567
|
+
showSearch ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2615
2568
|
Input,
|
|
2616
2569
|
{
|
|
2617
2570
|
type: "search",
|
|
2618
2571
|
placeholder: labels.searchPlaceholder,
|
|
2619
2572
|
"aria-label": labels.searchAriaLabel || labels.searchPlaceholder,
|
|
2620
|
-
value:
|
|
2621
|
-
onChange: (e) =>
|
|
2573
|
+
value: searchValue ?? "",
|
|
2574
|
+
onChange: (e) => onSearchChange?.(e.target.value),
|
|
2622
2575
|
leadingIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, {}),
|
|
2623
2576
|
wrapperClassName: "sm:max-w-xs",
|
|
2624
2577
|
disabled: isLoading
|
|
@@ -2627,16 +2580,16 @@ function ListPage({
|
|
|
2627
2580
|
filters?.map((f) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2628
2581
|
Select,
|
|
2629
2582
|
{
|
|
2630
|
-
"aria-label": f.
|
|
2631
|
-
value: filterValues[f.key],
|
|
2632
|
-
onValueChange: (v) =>
|
|
2583
|
+
"aria-label": typeof f.label === "string" ? f.label : f.key,
|
|
2584
|
+
value: filterValues?.[f.key] ?? f.options[0]?.value ?? "",
|
|
2585
|
+
onValueChange: (v) => onFilterChange?.(f.key, v),
|
|
2633
2586
|
options: f.options,
|
|
2634
2587
|
className: FILTER_WIDTH_CLASS[f.width ?? "default"],
|
|
2635
2588
|
disabled: isLoading
|
|
2636
2589
|
},
|
|
2637
2590
|
f.key
|
|
2638
2591
|
)),
|
|
2639
|
-
|
|
2592
|
+
hasActiveQuery && !isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "ghost", onClick: reset, children: [
|
|
2640
2593
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, {}),
|
|
2641
2594
|
labels.reset
|
|
2642
2595
|
] }) : null
|
|
@@ -2645,7 +2598,7 @@ function ListPage({
|
|
|
2645
2598
|
Table,
|
|
2646
2599
|
{
|
|
2647
2600
|
"aria-label": typeof title === "string" ? title : void 0,
|
|
2648
|
-
data
|
|
2601
|
+
data,
|
|
2649
2602
|
columns,
|
|
2650
2603
|
getRowId,
|
|
2651
2604
|
enableRowSelection,
|
|
@@ -2653,10 +2606,10 @@ function ListPage({
|
|
|
2653
2606
|
loading: isLoading,
|
|
2654
2607
|
loadingRowCount,
|
|
2655
2608
|
pagination,
|
|
2656
|
-
defaultPagination,
|
|
2657
2609
|
onPaginationChange,
|
|
2658
2610
|
totalCount,
|
|
2659
|
-
pageSizeOptions
|
|
2611
|
+
pageSizeOptions,
|
|
2612
|
+
labels
|
|
2660
2613
|
}
|
|
2661
2614
|
) : tableMode === "no-data" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2662
2615
|
"div",
|