@dimaan/ui 0.0.18 → 0.0.19
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 +39 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -4
- package/dist/index.d.ts +38 -4
- package/dist/index.js +39 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1468,8 +1468,16 @@ interface TableProps<T> {
|
|
|
1468
1468
|
data: readonly T[];
|
|
1469
1469
|
/** Column definitions. */
|
|
1470
1470
|
columns: ReadonlyArray<Column<T>>;
|
|
1471
|
-
/**
|
|
1472
|
-
|
|
1471
|
+
/**
|
|
1472
|
+
* Stable id for each row. Required for selection; recommended always.
|
|
1473
|
+
*
|
|
1474
|
+
* **Optional with a default**: when omitted, Table reads `row.id` (most
|
|
1475
|
+
* APIs use it) and falls back to the row index. Provide this explicitly
|
|
1476
|
+
* for records that use a different identifier (`_id`, `uuid`) or any
|
|
1477
|
+
* time the list can reorder — index-based ids break selection across
|
|
1478
|
+
* reorders.
|
|
1479
|
+
*/
|
|
1480
|
+
getRowId?: (row: T, index: number) => string;
|
|
1473
1481
|
/**
|
|
1474
1482
|
* Total row count across all pages. Pass this when the parent paginates/sorts
|
|
1475
1483
|
* server-side — Table will skip its local sort + slice.
|
|
@@ -1576,14 +1584,40 @@ interface ListPageProps<T> {
|
|
|
1576
1584
|
actions?: ReactNode;
|
|
1577
1585
|
data: T[];
|
|
1578
1586
|
columns: Column<T>[];
|
|
1579
|
-
|
|
1587
|
+
/**
|
|
1588
|
+
* Stable id for each row. Required for row selection across re-renders and
|
|
1589
|
+
* for stable React keys.
|
|
1590
|
+
*
|
|
1591
|
+
* Defaults to reading `row.id` when present, falling back to the row index.
|
|
1592
|
+
* Provide this explicitly when your records use a different identifier
|
|
1593
|
+
* (e.g. `_id`, `uuid`, a composite key) — index-based ids break selection
|
|
1594
|
+
* when the data list reorders.
|
|
1595
|
+
*/
|
|
1596
|
+
getRowId?: (row: T) => string;
|
|
1580
1597
|
/** Show skeleton rows in the table area while data is fetching. */
|
|
1581
1598
|
isLoading?: boolean;
|
|
1582
1599
|
/** Number of skeleton rows rendered while loading. Defaults to the table page size. */
|
|
1583
1600
|
loadingRowCount?: number;
|
|
1584
1601
|
/** Keys on `T` to search. Search input only renders when this is provided. */
|
|
1585
1602
|
searchKeys?: Array<keyof T>;
|
|
1603
|
+
/**
|
|
1604
|
+
* Controlled search input value. Pair with `onSearchChange` to drive the
|
|
1605
|
+
* search from outside (typical for server-side filtering). When both are
|
|
1606
|
+
* provided, ListPage **stops filtering `data` locally** for search —
|
|
1607
|
+
* `data` is trusted to already match the query.
|
|
1608
|
+
*/
|
|
1609
|
+
searchValue?: string;
|
|
1610
|
+
/** Fires on every search input change. Pair with `searchValue` for controlled mode. */
|
|
1611
|
+
onSearchChange?: (value: string) => void;
|
|
1586
1612
|
filters?: ListPageFilter<T>[];
|
|
1613
|
+
/**
|
|
1614
|
+
* Controlled filter values keyed by `filter.key`. When provided alongside
|
|
1615
|
+
* `onFilterChange`, ListPage **stops filtering `data` locally** — `data`
|
|
1616
|
+
* is trusted to already match the active filter selections.
|
|
1617
|
+
*/
|
|
1618
|
+
filterValues?: Record<string, string>;
|
|
1619
|
+
/** Fires when any filter Select changes. Pair with `filterValues` for controlled mode. */
|
|
1620
|
+
onFilterChange?: (key: string, value: string) => void;
|
|
1587
1621
|
enableRowSelection?: boolean;
|
|
1588
1622
|
bulkActions?: (selected: T[]) => ReactNode;
|
|
1589
1623
|
/**
|
|
@@ -1686,7 +1720,7 @@ interface ListPageProps<T> {
|
|
|
1686
1720
|
* />
|
|
1687
1721
|
* ```
|
|
1688
1722
|
*/
|
|
1689
|
-
declare function ListPage<T>({ title, description, bordered, actions, data, columns, getRowId, isLoading, loadingRowCount, searchKeys, filters, enableRowSelection, bulkActions, pagination, defaultPagination, onPaginationChange, totalCount, pageSizeOptions, emptyState, noDataState, labels: labelsProp, className, }: ListPageProps<T>): react_jsx_runtime.JSX.Element;
|
|
1723
|
+
declare function ListPage<T>({ title, description, bordered, actions, data, columns, getRowId, isLoading, loadingRowCount, searchKeys, searchValue: searchValueProp, onSearchChange, filters, filterValues: filterValuesProp, onFilterChange, enableRowSelection, bulkActions, pagination, defaultPagination, onPaginationChange, totalCount, pageSizeOptions, emptyState, noDataState, labels: labelsProp, className, }: ListPageProps<T>): react_jsx_runtime.JSX.Element;
|
|
1690
1724
|
|
|
1691
1725
|
type RadioGroupSize = 'sm' | 'md' | 'lg';
|
|
1692
1726
|
/** Outer circle (radio button itself) — sized + bordered. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1468,8 +1468,16 @@ interface TableProps<T> {
|
|
|
1468
1468
|
data: readonly T[];
|
|
1469
1469
|
/** Column definitions. */
|
|
1470
1470
|
columns: ReadonlyArray<Column<T>>;
|
|
1471
|
-
/**
|
|
1472
|
-
|
|
1471
|
+
/**
|
|
1472
|
+
* Stable id for each row. Required for selection; recommended always.
|
|
1473
|
+
*
|
|
1474
|
+
* **Optional with a default**: when omitted, Table reads `row.id` (most
|
|
1475
|
+
* APIs use it) and falls back to the row index. Provide this explicitly
|
|
1476
|
+
* for records that use a different identifier (`_id`, `uuid`) or any
|
|
1477
|
+
* time the list can reorder — index-based ids break selection across
|
|
1478
|
+
* reorders.
|
|
1479
|
+
*/
|
|
1480
|
+
getRowId?: (row: T, index: number) => string;
|
|
1473
1481
|
/**
|
|
1474
1482
|
* Total row count across all pages. Pass this when the parent paginates/sorts
|
|
1475
1483
|
* server-side — Table will skip its local sort + slice.
|
|
@@ -1576,14 +1584,40 @@ interface ListPageProps<T> {
|
|
|
1576
1584
|
actions?: ReactNode;
|
|
1577
1585
|
data: T[];
|
|
1578
1586
|
columns: Column<T>[];
|
|
1579
|
-
|
|
1587
|
+
/**
|
|
1588
|
+
* Stable id for each row. Required for row selection across re-renders and
|
|
1589
|
+
* for stable React keys.
|
|
1590
|
+
*
|
|
1591
|
+
* Defaults to reading `row.id` when present, falling back to the row index.
|
|
1592
|
+
* Provide this explicitly when your records use a different identifier
|
|
1593
|
+
* (e.g. `_id`, `uuid`, a composite key) — index-based ids break selection
|
|
1594
|
+
* when the data list reorders.
|
|
1595
|
+
*/
|
|
1596
|
+
getRowId?: (row: T) => string;
|
|
1580
1597
|
/** Show skeleton rows in the table area while data is fetching. */
|
|
1581
1598
|
isLoading?: boolean;
|
|
1582
1599
|
/** Number of skeleton rows rendered while loading. Defaults to the table page size. */
|
|
1583
1600
|
loadingRowCount?: number;
|
|
1584
1601
|
/** Keys on `T` to search. Search input only renders when this is provided. */
|
|
1585
1602
|
searchKeys?: Array<keyof T>;
|
|
1603
|
+
/**
|
|
1604
|
+
* Controlled search input value. Pair with `onSearchChange` to drive the
|
|
1605
|
+
* search from outside (typical for server-side filtering). When both are
|
|
1606
|
+
* provided, ListPage **stops filtering `data` locally** for search —
|
|
1607
|
+
* `data` is trusted to already match the query.
|
|
1608
|
+
*/
|
|
1609
|
+
searchValue?: string;
|
|
1610
|
+
/** Fires on every search input change. Pair with `searchValue` for controlled mode. */
|
|
1611
|
+
onSearchChange?: (value: string) => void;
|
|
1586
1612
|
filters?: ListPageFilter<T>[];
|
|
1613
|
+
/**
|
|
1614
|
+
* Controlled filter values keyed by `filter.key`. When provided alongside
|
|
1615
|
+
* `onFilterChange`, ListPage **stops filtering `data` locally** — `data`
|
|
1616
|
+
* is trusted to already match the active filter selections.
|
|
1617
|
+
*/
|
|
1618
|
+
filterValues?: Record<string, string>;
|
|
1619
|
+
/** Fires when any filter Select changes. Pair with `filterValues` for controlled mode. */
|
|
1620
|
+
onFilterChange?: (key: string, value: string) => void;
|
|
1587
1621
|
enableRowSelection?: boolean;
|
|
1588
1622
|
bulkActions?: (selected: T[]) => ReactNode;
|
|
1589
1623
|
/**
|
|
@@ -1686,7 +1720,7 @@ interface ListPageProps<T> {
|
|
|
1686
1720
|
* />
|
|
1687
1721
|
* ```
|
|
1688
1722
|
*/
|
|
1689
|
-
declare function ListPage<T>({ title, description, bordered, actions, data, columns, getRowId, isLoading, loadingRowCount, searchKeys, filters, enableRowSelection, bulkActions, pagination, defaultPagination, onPaginationChange, totalCount, pageSizeOptions, emptyState, noDataState, labels: labelsProp, className, }: ListPageProps<T>): react_jsx_runtime.JSX.Element;
|
|
1723
|
+
declare function ListPage<T>({ title, description, bordered, actions, data, columns, getRowId, isLoading, loadingRowCount, searchKeys, searchValue: searchValueProp, onSearchChange, filters, filterValues: filterValuesProp, onFilterChange, enableRowSelection, bulkActions, pagination, defaultPagination, onPaginationChange, totalCount, pageSizeOptions, emptyState, noDataState, labels: labelsProp, className, }: ListPageProps<T>): react_jsx_runtime.JSX.Element;
|
|
1690
1724
|
|
|
1691
1725
|
type RadioGroupSize = 'sm' | 'md' | 'lg';
|
|
1692
1726
|
/** Outer circle (radio button itself) — sized + bordered. */
|
package/dist/index.js
CHANGED
|
@@ -2164,11 +2164,15 @@ function useTableState(props) {
|
|
|
2164
2164
|
};
|
|
2165
2165
|
}
|
|
2166
2166
|
var DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50];
|
|
2167
|
+
function defaultGetRowId(row, index) {
|
|
2168
|
+
const rowId = row.id;
|
|
2169
|
+
return rowId === void 0 || rowId === null ? String(index) : String(rowId);
|
|
2170
|
+
}
|
|
2167
2171
|
function Table(props) {
|
|
2168
2172
|
const {
|
|
2169
2173
|
data,
|
|
2170
2174
|
columns,
|
|
2171
|
-
getRowId,
|
|
2175
|
+
getRowId = defaultGetRowId,
|
|
2172
2176
|
enableRowSelection = false,
|
|
2173
2177
|
isRowSelectable,
|
|
2174
2178
|
bulkActions,
|
|
@@ -2493,7 +2497,11 @@ function ListPage({
|
|
|
2493
2497
|
isLoading = false,
|
|
2494
2498
|
loadingRowCount,
|
|
2495
2499
|
searchKeys,
|
|
2500
|
+
searchValue: searchValueProp,
|
|
2501
|
+
onSearchChange,
|
|
2496
2502
|
filters,
|
|
2503
|
+
filterValues: filterValuesProp,
|
|
2504
|
+
onFilterChange,
|
|
2497
2505
|
enableRowSelection,
|
|
2498
2506
|
bulkActions,
|
|
2499
2507
|
pagination,
|
|
@@ -2514,14 +2522,30 @@ function ListPage({
|
|
|
2514
2522
|
}
|
|
2515
2523
|
return init;
|
|
2516
2524
|
}, [filters]);
|
|
2517
|
-
const
|
|
2518
|
-
const
|
|
2525
|
+
const isSearchControlled = searchValueProp !== void 0;
|
|
2526
|
+
const isFiltersControlled = filterValuesProp !== void 0;
|
|
2527
|
+
const [internalSearch, setInternalSearch] = useState("");
|
|
2528
|
+
const [internalFilterValues, setInternalFilterValues] = useState(initialFilterValues);
|
|
2529
|
+
const search = isSearchControlled ? searchValueProp : internalSearch;
|
|
2530
|
+
const filterValues = isFiltersControlled ? filterValuesProp : internalFilterValues;
|
|
2531
|
+
const setSearch = (next) => {
|
|
2532
|
+
if (!isSearchControlled) setInternalSearch(next);
|
|
2533
|
+
onSearchChange?.(next);
|
|
2534
|
+
};
|
|
2519
2535
|
const setFilter = (key, value) => {
|
|
2520
|
-
|
|
2536
|
+
if (!isFiltersControlled) {
|
|
2537
|
+
setInternalFilterValues((prev) => ({ ...prev, [key]: value }));
|
|
2538
|
+
}
|
|
2539
|
+
onFilterChange?.(key, value);
|
|
2521
2540
|
};
|
|
2522
2541
|
const reset = () => {
|
|
2523
|
-
|
|
2524
|
-
|
|
2542
|
+
if (!isSearchControlled) setInternalSearch("");
|
|
2543
|
+
onSearchChange?.("");
|
|
2544
|
+
if (!isFiltersControlled) setInternalFilterValues(initialFilterValues);
|
|
2545
|
+
for (const f of filters ?? []) {
|
|
2546
|
+
const def = f.defaultValue ?? f.options[0]?.value ?? "";
|
|
2547
|
+
onFilterChange?.(f.key, def);
|
|
2548
|
+
}
|
|
2525
2549
|
};
|
|
2526
2550
|
const hasActiveFilters = useMemo(() => {
|
|
2527
2551
|
if (search.trim() !== "") return true;
|
|
@@ -2534,7 +2558,7 @@ function ListPage({
|
|
|
2534
2558
|
}, [search, filters, filterValues]);
|
|
2535
2559
|
const filtered = useMemo(() => {
|
|
2536
2560
|
return data.filter((row) => {
|
|
2537
|
-
if (search.trim() && searchKeys && searchKeys.length > 0) {
|
|
2561
|
+
if (!isSearchControlled && search.trim() && searchKeys && searchKeys.length > 0) {
|
|
2538
2562
|
const q = search.trim().toLowerCase();
|
|
2539
2563
|
const matches = searchKeys.some((key) => {
|
|
2540
2564
|
const val = row[key];
|
|
@@ -2542,16 +2566,18 @@ function ListPage({
|
|
|
2542
2566
|
});
|
|
2543
2567
|
if (!matches) return false;
|
|
2544
2568
|
}
|
|
2545
|
-
|
|
2546
|
-
const
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
if (
|
|
2569
|
+
if (!isFiltersControlled) {
|
|
2570
|
+
for (const f of filters ?? []) {
|
|
2571
|
+
const value = filterValues[f.key];
|
|
2572
|
+
const def = f.defaultValue ?? f.options[0]?.value ?? "";
|
|
2573
|
+
if (value !== void 0 && value !== def) {
|
|
2574
|
+
if (f.accessor(row) !== value) return false;
|
|
2575
|
+
}
|
|
2550
2576
|
}
|
|
2551
2577
|
}
|
|
2552
2578
|
return true;
|
|
2553
2579
|
});
|
|
2554
|
-
}, [data, search, searchKeys, filters, filterValues]);
|
|
2580
|
+
}, [data, search, searchKeys, filters, filterValues, isSearchControlled, isFiltersControlled]);
|
|
2555
2581
|
const showFilterBar = Boolean(searchKeys?.length) || Boolean(filters?.length);
|
|
2556
2582
|
const tableMode = isLoading ? "loading" : data.length === 0 && !hasActiveFilters ? "no-data" : filtered.length === 0 ? "no-results" : "rows";
|
|
2557
2583
|
return /* @__PURE__ */ jsxs("div", { "data-slot": "list-page", className: cn("space-y-6", className), children: [
|