@akshar-technosoft/ui 1.2.2 → 1.3.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/README.md +51 -8
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -13
- package/dist/index.d.ts +83 -13
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -31,8 +31,17 @@ export { GeneralHelper } from './components/general.cjs';
|
|
|
31
31
|
interface PersistGroupRegistry {
|
|
32
32
|
}
|
|
33
33
|
type PersistGroupId = keyof PersistGroupRegistry extends never ? string : keyof PersistGroupRegistry & string;
|
|
34
|
+
/** Every slot across every registered group — the un-narrowed fallback `PersistSlotFor` resolves
|
|
35
|
+
* to when a specific group isn't pinned (e.g. `shared` typed before `persist.group` is set). */
|
|
34
36
|
type PersistSlotId = keyof PersistGroupRegistry extends never ? string : PersistGroupRegistry[keyof PersistGroupRegistry] & string;
|
|
35
|
-
|
|
37
|
+
/**
|
|
38
|
+
* `shared`'s value type, narrowed to ONE group's own slots instead of every group's. `G` is
|
|
39
|
+
* whatever `DataTableProps`'s own group type param resolves to for this table (see there for how
|
|
40
|
+
* it gets pinned) — a real group key narrows to just that group's slots; `undefined` (no group
|
|
41
|
+
* pinned yet) falls back to `PersistSlotId`, every group's slots, same as before this existed.
|
|
42
|
+
*/
|
|
43
|
+
type PersistSlotFor<G extends PersistGroupId | undefined> = G extends keyof PersistGroupRegistry ? PersistGroupRegistry[G] & string : PersistSlotId;
|
|
44
|
+
type PersistConfig<G extends PersistGroupId | undefined = PersistGroupId> = {
|
|
36
45
|
/**
|
|
37
46
|
* Unique id for this table ACROSS THE WHOLE APP (it's the storage map key, and the
|
|
38
47
|
* localStorage key when `local: true`). Two tables with the same key share one saved state —
|
|
@@ -43,8 +52,11 @@ type PersistConfig = {
|
|
|
43
52
|
* Namespace for `shared` filter slots — ONLY tables with the same group exchange those values
|
|
44
53
|
* (a "party" slot in group "inhouse" never leaks into group "sales"). Required for `shared`
|
|
45
54
|
* to do anything; a `shared` filter on a table without a group is inert (dev warning).
|
|
55
|
+
*
|
|
56
|
+
* Setting this is also what narrows `filters[].shared`'s autocomplete/type-check to just THIS
|
|
57
|
+
* group's own slots — see `DataTableProps`'s `G` type param.
|
|
46
58
|
*/
|
|
47
|
-
group?:
|
|
59
|
+
group?: G;
|
|
48
60
|
/**
|
|
49
61
|
* Also write to localStorage so state survives refresh/re-login.
|
|
50
62
|
* NOTE: unlike zustand's `persist` middleware, the default here is IN-MEMORY (back-navigation
|
|
@@ -119,8 +131,10 @@ type AggregationConfig<TData> = {
|
|
|
119
131
|
format?: (value: any, func: AggregationFunction) => string;
|
|
120
132
|
accessor?: (row: TData) => number | null;
|
|
121
133
|
};
|
|
122
|
-
/** Fields shared by every filter control, independent of how it locates its value.
|
|
123
|
-
type
|
|
134
|
+
/** Fields shared by every filter control, independent of how it locates its value. `G` narrows
|
|
135
|
+
* `shared` to one persist group's own slots — see `DataTableProps`'s `G` type param for how a
|
|
136
|
+
* real value gets pinned instead of the default (every group's slots, undiscriminated). */
|
|
137
|
+
type FilterControlConfig<G extends PersistGroupId | undefined = undefined> = {
|
|
124
138
|
/** Input placeholder and the filter's display label (also used on chips and the grouped picker). */
|
|
125
139
|
placeholder: string;
|
|
126
140
|
/**
|
|
@@ -176,7 +190,7 @@ type FilterControlConfig = {
|
|
|
176
190
|
* group opens already filtered to it). The slot stores only the value, so pages can bind it to
|
|
177
191
|
* different filter keys, or even to an `externalSearch` filter. Requires `persist.group`.
|
|
178
192
|
*/
|
|
179
|
-
shared?:
|
|
193
|
+
shared?: PersistSlotFor<G>;
|
|
180
194
|
/**
|
|
181
195
|
* Set false to exclude this one filter from persistence (scan boxes, one-shot searches) while
|
|
182
196
|
* the rest of the table persists. Inert without the table-level `persist` prop. @default true
|
|
@@ -198,7 +212,7 @@ type FilterControlConfig = {
|
|
|
198
212
|
* Reach for {@link CustomFilterConfig} instead only when the match is not a plain contains on one
|
|
199
213
|
* field, for example matching inside an array of objects or across several fields at once.
|
|
200
214
|
*/
|
|
201
|
-
type PathFilterConfig<T> = FilterControlConfig & {
|
|
215
|
+
type PathFilterConfig<T, G extends PersistGroupId | undefined = undefined> = FilterControlConfig<G> & {
|
|
202
216
|
/** Dot path into the row (validated against `T`). Serves as both the value source and the id. */
|
|
203
217
|
key: Paths<T>;
|
|
204
218
|
id?: never;
|
|
@@ -223,7 +237,7 @@ type PathFilterConfig<T> = FilterControlConfig & {
|
|
|
223
237
|
* filterFn: (row, v) => !v || row.lots.some(l => l.isUrgent) },
|
|
224
238
|
* ];
|
|
225
239
|
*/
|
|
226
|
-
type CustomFilterConfig<T> = FilterControlConfig & {
|
|
240
|
+
type CustomFilterConfig<T, G extends PersistGroupId | undefined = undefined> = FilterControlConfig<G> & {
|
|
227
241
|
/** Any unique string identifying this filter. Not required to be a real field, since `filterFn`
|
|
228
242
|
* reads the row directly. */
|
|
229
243
|
id: string;
|
|
@@ -236,8 +250,11 @@ type CustomFilterConfig<T> = FilterControlConfig & {
|
|
|
236
250
|
* {@link PathFilterConfig} — pass `key` (a real dot path). The common case: flat or nested fields.
|
|
237
251
|
* {@link CustomFilterConfig} — pass `id` + `filterFn`. For arrays of objects or multi field matches.
|
|
238
252
|
* Either way the filtering runs through TanStack's model and AND combines; you never edit `columns`.
|
|
253
|
+
*
|
|
254
|
+
* `G` — the table's persist group, for narrowing `shared`'s autocomplete to that one group's
|
|
255
|
+
* slots. Left to its default almost everywhere; see `DataTableProps` for where it's actually set.
|
|
239
256
|
*/
|
|
240
|
-
type FilterConfig<T> = PathFilterConfig<T> | CustomFilterConfig<T>;
|
|
257
|
+
type FilterConfig<T, G extends PersistGroupId | undefined = undefined> = PathFilterConfig<T, G> | CustomFilterConfig<T, G>;
|
|
241
258
|
type PaginationConfig = {
|
|
242
259
|
/** Rows per page initially. @default 10 */
|
|
243
260
|
pageSize?: number;
|
|
@@ -494,7 +511,19 @@ type GroupColumnDef<TData> = ColumnDef<TData> & {
|
|
|
494
511
|
*/
|
|
495
512
|
pinIndex?: number;
|
|
496
513
|
};
|
|
497
|
-
|
|
514
|
+
/**
|
|
515
|
+
* `G` — this table's persist group, ONLY relevant for narrowing `filters[].shared`'s
|
|
516
|
+
* autocomplete/type-check to that one group's own slots (see `PersistSlotFor`). You never set it
|
|
517
|
+
* explicitly for an inline `<DataTable persist={{group:"QC"}} filters={[...]} />` call: TS infers
|
|
518
|
+
* it from `persist.group` and checks `filters` against it in the same pass, same as `TData`
|
|
519
|
+
* infers from `data`/`columns`.
|
|
520
|
+
*
|
|
521
|
+
* It DOES need spelling out when `filters` is a separately declared `const` (the common pattern —
|
|
522
|
+
* `const filters: DataTableProps<Row>["filters"] = [...]`), because that array gets its type at
|
|
523
|
+
* its own declaration, independent of a `persist` prop written later in the same file. Add the
|
|
524
|
+
* group there too: `DataTableProps<Row, "QC">["filters"]`.
|
|
525
|
+
*/
|
|
526
|
+
type DataTableProps<TData, G extends PersistGroupId | undefined = undefined> = {
|
|
498
527
|
/** Row data. Rendered client-side (filter/sort/paginate all in-memory unless server-driven). */
|
|
499
528
|
data: TData[];
|
|
500
529
|
/** Column definitions. TanStack `ColumnDef` plus a few extras; see {@link GroupColumnDef}. */
|
|
@@ -502,7 +531,7 @@ type DataTableProps<TData> = {
|
|
|
502
531
|
/** Toolbar filter controls (see {@link FilterConfig}); place each on the bar or behind the global
|
|
503
532
|
* search's field picker via `FilterConfig.placement`. Debug: filters live in the toolbar, so none
|
|
504
533
|
* render unless `settings.showToolbar: true`. */
|
|
505
|
-
filters?: FilterConfig<TData>[];
|
|
534
|
+
filters?: FilterConfig<TData, G>[];
|
|
506
535
|
/** Pagination config — its presence enables pagination. Omit to render all rows. */
|
|
507
536
|
pagination?: PaginationConfig;
|
|
508
537
|
/** Feature and presentation toggles; see {@link TableSettings} for the full dependency map. */
|
|
@@ -603,13 +632,18 @@ type DataTableProps<TData> = {
|
|
|
603
632
|
* Restore is synchronous (seeded before first render — no unfiltered flash); external filters
|
|
604
633
|
* are replayed through `onExternalSearch` on mount (see `readPersistedExternal` to seed the
|
|
605
634
|
* page's own query instead). Selection is never persisted. See {@link PersistConfig}.
|
|
635
|
+
*
|
|
636
|
+
* Setting `group` here is also what narrows every filter's `shared` (in the SAME `filters`
|
|
637
|
+
* array literal) to just this group's own slots instead of every group's — see `DataTableProps`'s
|
|
638
|
+
* `G` type param doc above for the one case (a separately-declared `filters` const) where you
|
|
639
|
+
* have to spell `G` out yourself for that to kick in.
|
|
606
640
|
* @example persist="qc-completed"
|
|
607
641
|
* @example persist={{ key: "qc-completed", group: "inhouse", local: true }}
|
|
608
642
|
*/
|
|
609
|
-
persist?: string | PersistConfig
|
|
643
|
+
persist?: string | PersistConfig<G>;
|
|
610
644
|
};
|
|
611
645
|
|
|
612
|
-
declare function DataTable<T>({ data, columns: initialColumns, filters, pagination, settings, header, footer, className, maxHeight, loading, error, emptyMessage, onRowSelectionChange, onExport, onRefresh, onTableReady, children, isRowSelectable, getRowId, defaultSelectedRows, onExternalSearch, aggregations, onAggregationChange, rowClassName, persist: persistProp, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
646
|
+
declare function DataTable<T, G extends PersistGroupId | undefined = undefined>({ data, columns: initialColumns, filters, pagination, settings, header, footer, className, maxHeight, loading, error, emptyMessage, onRowSelectionChange, onExport, onRefresh, onTableReady, children, isRowSelectable, getRowId, defaultSelectedRows, onExternalSearch, aggregations, onAggregationChange, rowClassName, persist: persistProp, }: DataTableProps<T, G>): react_jsx_runtime.JSX.Element;
|
|
613
647
|
|
|
614
648
|
declare const buttonVariants: (props?: ({
|
|
615
649
|
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
|
|
@@ -636,6 +670,42 @@ interface DataTableActionBarSelectionProps<TData> {
|
|
|
636
670
|
}
|
|
637
671
|
declare function DataTableActionBarSelection<TData>({ table }: DataTableActionBarSelectionProps<TData>): react_jsx_runtime.JSX.Element | null;
|
|
638
672
|
|
|
673
|
+
/** The union of every `key`/`id` declared in a `filters` array — same array you already pass
|
|
674
|
+
* to `<DataTable filters={...} />`, so there's nothing new to author or keep in sync. Accepts
|
|
675
|
+
* `| undefined` because `DataTableProps<T>["filters"]` (the type most call sites annotate their
|
|
676
|
+
* local `filters` const with) is optional. Deliberately structural (`key?`/`id?`) and a plain
|
|
677
|
+
* indexed access, NOT `FilterConfig<any>` + conditional inference: `PathFilterConfig.key` is the
|
|
678
|
+
* recursive `Paths<T>`, and inferring through it against a union pattern made the checker blow
|
|
679
|
+
* its instantiation-depth budget (TS2589) at real call sites. Indexed access reads the same keys
|
|
680
|
+
* without re-instantiating any of that machinery. */
|
|
681
|
+
type FilterKeys<F extends readonly {
|
|
682
|
+
key?: string;
|
|
683
|
+
id?: string;
|
|
684
|
+
}[] | undefined> = Extract<NonNullable<F>[number]["key" | "id"], string>;
|
|
685
|
+
/**
|
|
686
|
+
* Live, typed escape hatch onto a table's filter state — for the case DataTable itself can't
|
|
687
|
+
* cover: reading (or driving) a specific filter's CURRENT value from outside the table's own
|
|
688
|
+
* subtree, as if it were a controlled `useState`.
|
|
689
|
+
*
|
|
690
|
+
* DataTable keeps `columnFilters` as private internal state — there's no prop/ref that exposes
|
|
691
|
+
* it. But when the table's `persist` is on (the default now syncs filters to the URL, not just
|
|
692
|
+
* memory — see `use-table-persist.ts`), the URL itself becomes that bridge: any component
|
|
693
|
+
* anywhere can read or write a filter's value through it, live, without prop-drilling and
|
|
694
|
+
* without DataTable exposing anything new.
|
|
695
|
+
*
|
|
696
|
+
* Reuses `useSearchParams` (react-router) directly — no separate subscription/store to keep in
|
|
697
|
+
* sync, no effect, so no loop to guard against; `value` is a pure per-render derivation and
|
|
698
|
+
* `setValue` writes with `replace: true` so it doesn't spam browser history.
|
|
699
|
+
*
|
|
700
|
+
* @example
|
|
701
|
+
* const [lotNo, setLotNo] = useTableFilterParam(lotReportFilters, "LotNo")
|
|
702
|
+
*/
|
|
703
|
+
declare function useTableFilterParam<F extends readonly {
|
|
704
|
+
key?: string;
|
|
705
|
+
id?: string;
|
|
706
|
+
}[] | undefined, K extends FilterKeys<F>>(_filters: F, // not read at runtime — only anchors `K` to this table's real filter keys
|
|
707
|
+
key: K): readonly [string | undefined, (next: string | undefined) => void];
|
|
708
|
+
|
|
639
709
|
type DataTemplateField<T> = {
|
|
640
710
|
key: keyof T;
|
|
641
711
|
label: string;
|
|
@@ -848,4 +918,4 @@ declare const OfflineUI: () => react_jsx_runtime.JSX.Element;
|
|
|
848
918
|
|
|
849
919
|
declare const Unauthorized: () => react_jsx_runtime.JSX.Element;
|
|
850
920
|
|
|
851
|
-
export { AppContainer, type AppContainerProps, AppContent, AppContentFooter, AppContentHeader, type AppContentProps, AppFooter, type AppFooterProps, AppHeader, type AppHeaderProps, AppSheet, type AppSheetProps, CurrencyTransfer, DataTable, DataTableActionBar, DataTableActionBarAction, DataTableActionBarSelection, type DataTableProps, DataTemplate, DataTemplateActionBar, DataTemplateActionBarAction, DataTemplateActionBarSelection, type DataTemplateProps, ErrorComponent, type GroupColumnDef, Loader, NotFound, OfflineUI, type PersistConfig, type PersistGroupRegistry, type TableExportColumn, type TableExportView, Unauthorized, getTableExportView, readPersistedExternal };
|
|
921
|
+
export { AppContainer, type AppContainerProps, AppContent, AppContentFooter, AppContentHeader, type AppContentProps, AppFooter, type AppFooterProps, AppHeader, type AppHeaderProps, AppSheet, type AppSheetProps, CurrencyTransfer, DataTable, DataTableActionBar, DataTableActionBarAction, DataTableActionBarSelection, type DataTableProps, DataTemplate, DataTemplateActionBar, DataTemplateActionBarAction, DataTemplateActionBarSelection, type DataTemplateProps, ErrorComponent, type FilterKeys, type GroupColumnDef, Loader, NotFound, OfflineUI, type PersistConfig, type PersistGroupId, type PersistGroupRegistry, type PersistSlotFor, type PersistSlotId, type TableExportColumn, type TableExportView, Unauthorized, getTableExportView, readPersistedExternal, useTableFilterParam };
|
package/dist/index.d.ts
CHANGED
|
@@ -31,8 +31,17 @@ export { GeneralHelper } from './components/general.js';
|
|
|
31
31
|
interface PersistGroupRegistry {
|
|
32
32
|
}
|
|
33
33
|
type PersistGroupId = keyof PersistGroupRegistry extends never ? string : keyof PersistGroupRegistry & string;
|
|
34
|
+
/** Every slot across every registered group — the un-narrowed fallback `PersistSlotFor` resolves
|
|
35
|
+
* to when a specific group isn't pinned (e.g. `shared` typed before `persist.group` is set). */
|
|
34
36
|
type PersistSlotId = keyof PersistGroupRegistry extends never ? string : PersistGroupRegistry[keyof PersistGroupRegistry] & string;
|
|
35
|
-
|
|
37
|
+
/**
|
|
38
|
+
* `shared`'s value type, narrowed to ONE group's own slots instead of every group's. `G` is
|
|
39
|
+
* whatever `DataTableProps`'s own group type param resolves to for this table (see there for how
|
|
40
|
+
* it gets pinned) — a real group key narrows to just that group's slots; `undefined` (no group
|
|
41
|
+
* pinned yet) falls back to `PersistSlotId`, every group's slots, same as before this existed.
|
|
42
|
+
*/
|
|
43
|
+
type PersistSlotFor<G extends PersistGroupId | undefined> = G extends keyof PersistGroupRegistry ? PersistGroupRegistry[G] & string : PersistSlotId;
|
|
44
|
+
type PersistConfig<G extends PersistGroupId | undefined = PersistGroupId> = {
|
|
36
45
|
/**
|
|
37
46
|
* Unique id for this table ACROSS THE WHOLE APP (it's the storage map key, and the
|
|
38
47
|
* localStorage key when `local: true`). Two tables with the same key share one saved state —
|
|
@@ -43,8 +52,11 @@ type PersistConfig = {
|
|
|
43
52
|
* Namespace for `shared` filter slots — ONLY tables with the same group exchange those values
|
|
44
53
|
* (a "party" slot in group "inhouse" never leaks into group "sales"). Required for `shared`
|
|
45
54
|
* to do anything; a `shared` filter on a table without a group is inert (dev warning).
|
|
55
|
+
*
|
|
56
|
+
* Setting this is also what narrows `filters[].shared`'s autocomplete/type-check to just THIS
|
|
57
|
+
* group's own slots — see `DataTableProps`'s `G` type param.
|
|
46
58
|
*/
|
|
47
|
-
group?:
|
|
59
|
+
group?: G;
|
|
48
60
|
/**
|
|
49
61
|
* Also write to localStorage so state survives refresh/re-login.
|
|
50
62
|
* NOTE: unlike zustand's `persist` middleware, the default here is IN-MEMORY (back-navigation
|
|
@@ -119,8 +131,10 @@ type AggregationConfig<TData> = {
|
|
|
119
131
|
format?: (value: any, func: AggregationFunction) => string;
|
|
120
132
|
accessor?: (row: TData) => number | null;
|
|
121
133
|
};
|
|
122
|
-
/** Fields shared by every filter control, independent of how it locates its value.
|
|
123
|
-
type
|
|
134
|
+
/** Fields shared by every filter control, independent of how it locates its value. `G` narrows
|
|
135
|
+
* `shared` to one persist group's own slots — see `DataTableProps`'s `G` type param for how a
|
|
136
|
+
* real value gets pinned instead of the default (every group's slots, undiscriminated). */
|
|
137
|
+
type FilterControlConfig<G extends PersistGroupId | undefined = undefined> = {
|
|
124
138
|
/** Input placeholder and the filter's display label (also used on chips and the grouped picker). */
|
|
125
139
|
placeholder: string;
|
|
126
140
|
/**
|
|
@@ -176,7 +190,7 @@ type FilterControlConfig = {
|
|
|
176
190
|
* group opens already filtered to it). The slot stores only the value, so pages can bind it to
|
|
177
191
|
* different filter keys, or even to an `externalSearch` filter. Requires `persist.group`.
|
|
178
192
|
*/
|
|
179
|
-
shared?:
|
|
193
|
+
shared?: PersistSlotFor<G>;
|
|
180
194
|
/**
|
|
181
195
|
* Set false to exclude this one filter from persistence (scan boxes, one-shot searches) while
|
|
182
196
|
* the rest of the table persists. Inert without the table-level `persist` prop. @default true
|
|
@@ -198,7 +212,7 @@ type FilterControlConfig = {
|
|
|
198
212
|
* Reach for {@link CustomFilterConfig} instead only when the match is not a plain contains on one
|
|
199
213
|
* field, for example matching inside an array of objects or across several fields at once.
|
|
200
214
|
*/
|
|
201
|
-
type PathFilterConfig<T> = FilterControlConfig & {
|
|
215
|
+
type PathFilterConfig<T, G extends PersistGroupId | undefined = undefined> = FilterControlConfig<G> & {
|
|
202
216
|
/** Dot path into the row (validated against `T`). Serves as both the value source and the id. */
|
|
203
217
|
key: Paths<T>;
|
|
204
218
|
id?: never;
|
|
@@ -223,7 +237,7 @@ type PathFilterConfig<T> = FilterControlConfig & {
|
|
|
223
237
|
* filterFn: (row, v) => !v || row.lots.some(l => l.isUrgent) },
|
|
224
238
|
* ];
|
|
225
239
|
*/
|
|
226
|
-
type CustomFilterConfig<T> = FilterControlConfig & {
|
|
240
|
+
type CustomFilterConfig<T, G extends PersistGroupId | undefined = undefined> = FilterControlConfig<G> & {
|
|
227
241
|
/** Any unique string identifying this filter. Not required to be a real field, since `filterFn`
|
|
228
242
|
* reads the row directly. */
|
|
229
243
|
id: string;
|
|
@@ -236,8 +250,11 @@ type CustomFilterConfig<T> = FilterControlConfig & {
|
|
|
236
250
|
* {@link PathFilterConfig} — pass `key` (a real dot path). The common case: flat or nested fields.
|
|
237
251
|
* {@link CustomFilterConfig} — pass `id` + `filterFn`. For arrays of objects or multi field matches.
|
|
238
252
|
* Either way the filtering runs through TanStack's model and AND combines; you never edit `columns`.
|
|
253
|
+
*
|
|
254
|
+
* `G` — the table's persist group, for narrowing `shared`'s autocomplete to that one group's
|
|
255
|
+
* slots. Left to its default almost everywhere; see `DataTableProps` for where it's actually set.
|
|
239
256
|
*/
|
|
240
|
-
type FilterConfig<T> = PathFilterConfig<T> | CustomFilterConfig<T>;
|
|
257
|
+
type FilterConfig<T, G extends PersistGroupId | undefined = undefined> = PathFilterConfig<T, G> | CustomFilterConfig<T, G>;
|
|
241
258
|
type PaginationConfig = {
|
|
242
259
|
/** Rows per page initially. @default 10 */
|
|
243
260
|
pageSize?: number;
|
|
@@ -494,7 +511,19 @@ type GroupColumnDef<TData> = ColumnDef<TData> & {
|
|
|
494
511
|
*/
|
|
495
512
|
pinIndex?: number;
|
|
496
513
|
};
|
|
497
|
-
|
|
514
|
+
/**
|
|
515
|
+
* `G` — this table's persist group, ONLY relevant for narrowing `filters[].shared`'s
|
|
516
|
+
* autocomplete/type-check to that one group's own slots (see `PersistSlotFor`). You never set it
|
|
517
|
+
* explicitly for an inline `<DataTable persist={{group:"QC"}} filters={[...]} />` call: TS infers
|
|
518
|
+
* it from `persist.group` and checks `filters` against it in the same pass, same as `TData`
|
|
519
|
+
* infers from `data`/`columns`.
|
|
520
|
+
*
|
|
521
|
+
* It DOES need spelling out when `filters` is a separately declared `const` (the common pattern —
|
|
522
|
+
* `const filters: DataTableProps<Row>["filters"] = [...]`), because that array gets its type at
|
|
523
|
+
* its own declaration, independent of a `persist` prop written later in the same file. Add the
|
|
524
|
+
* group there too: `DataTableProps<Row, "QC">["filters"]`.
|
|
525
|
+
*/
|
|
526
|
+
type DataTableProps<TData, G extends PersistGroupId | undefined = undefined> = {
|
|
498
527
|
/** Row data. Rendered client-side (filter/sort/paginate all in-memory unless server-driven). */
|
|
499
528
|
data: TData[];
|
|
500
529
|
/** Column definitions. TanStack `ColumnDef` plus a few extras; see {@link GroupColumnDef}. */
|
|
@@ -502,7 +531,7 @@ type DataTableProps<TData> = {
|
|
|
502
531
|
/** Toolbar filter controls (see {@link FilterConfig}); place each on the bar or behind the global
|
|
503
532
|
* search's field picker via `FilterConfig.placement`. Debug: filters live in the toolbar, so none
|
|
504
533
|
* render unless `settings.showToolbar: true`. */
|
|
505
|
-
filters?: FilterConfig<TData>[];
|
|
534
|
+
filters?: FilterConfig<TData, G>[];
|
|
506
535
|
/** Pagination config — its presence enables pagination. Omit to render all rows. */
|
|
507
536
|
pagination?: PaginationConfig;
|
|
508
537
|
/** Feature and presentation toggles; see {@link TableSettings} for the full dependency map. */
|
|
@@ -603,13 +632,18 @@ type DataTableProps<TData> = {
|
|
|
603
632
|
* Restore is synchronous (seeded before first render — no unfiltered flash); external filters
|
|
604
633
|
* are replayed through `onExternalSearch` on mount (see `readPersistedExternal` to seed the
|
|
605
634
|
* page's own query instead). Selection is never persisted. See {@link PersistConfig}.
|
|
635
|
+
*
|
|
636
|
+
* Setting `group` here is also what narrows every filter's `shared` (in the SAME `filters`
|
|
637
|
+
* array literal) to just this group's own slots instead of every group's — see `DataTableProps`'s
|
|
638
|
+
* `G` type param doc above for the one case (a separately-declared `filters` const) where you
|
|
639
|
+
* have to spell `G` out yourself for that to kick in.
|
|
606
640
|
* @example persist="qc-completed"
|
|
607
641
|
* @example persist={{ key: "qc-completed", group: "inhouse", local: true }}
|
|
608
642
|
*/
|
|
609
|
-
persist?: string | PersistConfig
|
|
643
|
+
persist?: string | PersistConfig<G>;
|
|
610
644
|
};
|
|
611
645
|
|
|
612
|
-
declare function DataTable<T>({ data, columns: initialColumns, filters, pagination, settings, header, footer, className, maxHeight, loading, error, emptyMessage, onRowSelectionChange, onExport, onRefresh, onTableReady, children, isRowSelectable, getRowId, defaultSelectedRows, onExternalSearch, aggregations, onAggregationChange, rowClassName, persist: persistProp, }: DataTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
646
|
+
declare function DataTable<T, G extends PersistGroupId | undefined = undefined>({ data, columns: initialColumns, filters, pagination, settings, header, footer, className, maxHeight, loading, error, emptyMessage, onRowSelectionChange, onExport, onRefresh, onTableReady, children, isRowSelectable, getRowId, defaultSelectedRows, onExternalSearch, aggregations, onAggregationChange, rowClassName, persist: persistProp, }: DataTableProps<T, G>): react_jsx_runtime.JSX.Element;
|
|
613
647
|
|
|
614
648
|
declare const buttonVariants: (props?: ({
|
|
615
649
|
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
|
|
@@ -636,6 +670,42 @@ interface DataTableActionBarSelectionProps<TData> {
|
|
|
636
670
|
}
|
|
637
671
|
declare function DataTableActionBarSelection<TData>({ table }: DataTableActionBarSelectionProps<TData>): react_jsx_runtime.JSX.Element | null;
|
|
638
672
|
|
|
673
|
+
/** The union of every `key`/`id` declared in a `filters` array — same array you already pass
|
|
674
|
+
* to `<DataTable filters={...} />`, so there's nothing new to author or keep in sync. Accepts
|
|
675
|
+
* `| undefined` because `DataTableProps<T>["filters"]` (the type most call sites annotate their
|
|
676
|
+
* local `filters` const with) is optional. Deliberately structural (`key?`/`id?`) and a plain
|
|
677
|
+
* indexed access, NOT `FilterConfig<any>` + conditional inference: `PathFilterConfig.key` is the
|
|
678
|
+
* recursive `Paths<T>`, and inferring through it against a union pattern made the checker blow
|
|
679
|
+
* its instantiation-depth budget (TS2589) at real call sites. Indexed access reads the same keys
|
|
680
|
+
* without re-instantiating any of that machinery. */
|
|
681
|
+
type FilterKeys<F extends readonly {
|
|
682
|
+
key?: string;
|
|
683
|
+
id?: string;
|
|
684
|
+
}[] | undefined> = Extract<NonNullable<F>[number]["key" | "id"], string>;
|
|
685
|
+
/**
|
|
686
|
+
* Live, typed escape hatch onto a table's filter state — for the case DataTable itself can't
|
|
687
|
+
* cover: reading (or driving) a specific filter's CURRENT value from outside the table's own
|
|
688
|
+
* subtree, as if it were a controlled `useState`.
|
|
689
|
+
*
|
|
690
|
+
* DataTable keeps `columnFilters` as private internal state — there's no prop/ref that exposes
|
|
691
|
+
* it. But when the table's `persist` is on (the default now syncs filters to the URL, not just
|
|
692
|
+
* memory — see `use-table-persist.ts`), the URL itself becomes that bridge: any component
|
|
693
|
+
* anywhere can read or write a filter's value through it, live, without prop-drilling and
|
|
694
|
+
* without DataTable exposing anything new.
|
|
695
|
+
*
|
|
696
|
+
* Reuses `useSearchParams` (react-router) directly — no separate subscription/store to keep in
|
|
697
|
+
* sync, no effect, so no loop to guard against; `value` is a pure per-render derivation and
|
|
698
|
+
* `setValue` writes with `replace: true` so it doesn't spam browser history.
|
|
699
|
+
*
|
|
700
|
+
* @example
|
|
701
|
+
* const [lotNo, setLotNo] = useTableFilterParam(lotReportFilters, "LotNo")
|
|
702
|
+
*/
|
|
703
|
+
declare function useTableFilterParam<F extends readonly {
|
|
704
|
+
key?: string;
|
|
705
|
+
id?: string;
|
|
706
|
+
}[] | undefined, K extends FilterKeys<F>>(_filters: F, // not read at runtime — only anchors `K` to this table's real filter keys
|
|
707
|
+
key: K): readonly [string | undefined, (next: string | undefined) => void];
|
|
708
|
+
|
|
639
709
|
type DataTemplateField<T> = {
|
|
640
710
|
key: keyof T;
|
|
641
711
|
label: string;
|
|
@@ -848,4 +918,4 @@ declare const OfflineUI: () => react_jsx_runtime.JSX.Element;
|
|
|
848
918
|
|
|
849
919
|
declare const Unauthorized: () => react_jsx_runtime.JSX.Element;
|
|
850
920
|
|
|
851
|
-
export { AppContainer, type AppContainerProps, AppContent, AppContentFooter, AppContentHeader, type AppContentProps, AppFooter, type AppFooterProps, AppHeader, type AppHeaderProps, AppSheet, type AppSheetProps, CurrencyTransfer, DataTable, DataTableActionBar, DataTableActionBarAction, DataTableActionBarSelection, type DataTableProps, DataTemplate, DataTemplateActionBar, DataTemplateActionBarAction, DataTemplateActionBarSelection, type DataTemplateProps, ErrorComponent, type GroupColumnDef, Loader, NotFound, OfflineUI, type PersistConfig, type PersistGroupRegistry, type TableExportColumn, type TableExportView, Unauthorized, getTableExportView, readPersistedExternal };
|
|
921
|
+
export { AppContainer, type AppContainerProps, AppContent, AppContentFooter, AppContentHeader, type AppContentProps, AppFooter, type AppFooterProps, AppHeader, type AppHeaderProps, AppSheet, type AppSheetProps, CurrencyTransfer, DataTable, DataTableActionBar, DataTableActionBarAction, DataTableActionBarSelection, type DataTableProps, DataTemplate, DataTemplateActionBar, DataTemplateActionBarAction, DataTemplateActionBarSelection, type DataTemplateProps, ErrorComponent, type FilterKeys, type GroupColumnDef, Loader, NotFound, OfflineUI, type PersistConfig, type PersistGroupId, type PersistGroupRegistry, type PersistSlotFor, type PersistSlotId, type TableExportColumn, type TableExportView, Unauthorized, getTableExportView, readPersistedExternal, useTableFilterParam };
|