@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.d.cts
CHANGED
|
@@ -1127,32 +1127,49 @@ type FieldProps<TValues extends FieldValues = FieldValues, TName extends FieldPa
|
|
|
1127
1127
|
*/
|
|
1128
1128
|
declare function Field<TValues extends FieldValues = FieldValues, TName extends FieldPath<TValues> = FieldPath<TValues>>(props: FieldProps<TValues, TName>): ReactElement;
|
|
1129
1129
|
|
|
1130
|
+
interface FormPageLabels {
|
|
1131
|
+
/** Back button label (top-left). Direction-aware default: `"Back"` / `"رجوع"`. */
|
|
1132
|
+
back?: string;
|
|
1133
|
+
/** Cancel button label. Direction-aware default: `"Cancel"` / `"إلغاء"`. */
|
|
1134
|
+
cancel?: string;
|
|
1135
|
+
/** Save (submit) button label when idle. Direction-aware default: `"Save"` / `"حفظ"`. */
|
|
1136
|
+
save?: string;
|
|
1137
|
+
/** Save (submit) button label while `isSubmitting` is true. Direction-aware default: `"Saving…"` / `"جارٍ الحفظ…"`. */
|
|
1138
|
+
saving?: string;
|
|
1139
|
+
}
|
|
1130
1140
|
interface FormPageProps {
|
|
1131
1141
|
/** Page title (required). Rendered as an `<h1>` by `PageHeader`. */
|
|
1132
1142
|
title: ReactNode;
|
|
1133
1143
|
/** Optional secondary text under the title. */
|
|
1134
1144
|
description?: ReactNode;
|
|
1135
|
-
/** Optional back-button config — forwarded straight to `PageHeader.back`. */
|
|
1136
|
-
back?: PageHeaderBackProps;
|
|
1137
1145
|
/** Page-header bottom border separator. Defaults to `true` for form pages. */
|
|
1138
1146
|
bordered?: boolean;
|
|
1139
1147
|
/** Form-submit handler. Wire RHF via `form.handleSubmit(onSave)`. */
|
|
1140
1148
|
onSubmit: FormEventHandler<HTMLFormElement>;
|
|
1149
|
+
/** Cancel-button handler. Defaults to navigating back one history entry. */
|
|
1150
|
+
onCancel?: () => void;
|
|
1151
|
+
/**
|
|
1152
|
+
* Disables the submit button and swaps its label to `labels.saving`. When
|
|
1153
|
+
* omitted, `FormPage` reads `formState.isSubmitting` from the surrounding
|
|
1154
|
+
* `<FormProvider>` (if any). Pass an explicit boolean to override.
|
|
1155
|
+
*/
|
|
1156
|
+
isSubmitting?: boolean;
|
|
1157
|
+
/** Localized copy for the built-in Cancel / Save buttons. */
|
|
1158
|
+
labels?: FormPageLabels;
|
|
1141
1159
|
/**
|
|
1142
1160
|
* Show skeleton placeholders in the body while the initial record is being
|
|
1143
1161
|
* fetched (typical for the edit page). The action bar still renders so the
|
|
1144
|
-
*
|
|
1145
|
-
* disabling submit buttons while loading.
|
|
1162
|
+
* user can Cancel out; the Save button is disabled while loading.
|
|
1146
1163
|
*/
|
|
1147
1164
|
isLoading?: boolean;
|
|
1148
1165
|
/** Number of skeleton rows shown while loading. Defaults to `6`. */
|
|
1149
1166
|
loadingRowCount?: number;
|
|
1150
1167
|
/**
|
|
1151
|
-
*
|
|
1152
|
-
*
|
|
1153
|
-
*
|
|
1168
|
+
* Extra action buttons rendered inside the sticky bar **before** the
|
|
1169
|
+
* built-in Cancel / Save pair (e.g. "Save & continue", "Delete"). Most
|
|
1170
|
+
* forms can omit this — Cancel + Save are owned by `FormPage` itself.
|
|
1154
1171
|
*/
|
|
1155
|
-
actions
|
|
1172
|
+
actions?: ReactNode;
|
|
1156
1173
|
/** Form body. Compose `<Field>` + your chosen controls, grouped however you like. */
|
|
1157
1174
|
children: ReactNode;
|
|
1158
1175
|
/** Class applied to the outer wrapper. */
|
|
@@ -1166,36 +1183,30 @@ interface FormPageProps {
|
|
|
1166
1183
|
}
|
|
1167
1184
|
/**
|
|
1168
1185
|
* Declarative form-page template — composes `PageHeader` + a scrollable form
|
|
1169
|
-
* body + a sticky action bar
|
|
1170
|
-
*
|
|
1171
|
-
*
|
|
1186
|
+
* body + a sticky action bar (with built-in **Cancel** and **Save** buttons)
|
|
1187
|
+
* into a single component.
|
|
1188
|
+
*
|
|
1189
|
+
* **Zero-prop defaults** make the minimal call site small:
|
|
1190
|
+
* - Back & Cancel both default to `navigate(-1)`.
|
|
1191
|
+
* - `isSubmitting` is auto-detected from the surrounding `<FormProvider>`'s
|
|
1192
|
+
* `formState.isSubmitting` — no need to wire it manually.
|
|
1193
|
+
* - All button labels are direction-aware (EN / AR) and resolved from
|
|
1194
|
+
* `<html dir>` via `useDirection()`.
|
|
1195
|
+
*
|
|
1196
|
+
* Override any of these by passing the matching prop (`onCancel`,
|
|
1197
|
+
* `isSubmitting`, `labels`).
|
|
1172
1198
|
*
|
|
1173
1199
|
* The component expects its parent to provide the scroll context — in the
|
|
1174
1200
|
* default `<AppShell>` setup, that's `<DashboardContent>`. The sticky bar
|
|
1175
1201
|
* relies on `position: sticky` against that scroll container.
|
|
1176
1202
|
*
|
|
1177
|
-
* @example
|
|
1203
|
+
* @example Minimal usage inside a `<FormProvider>` (RHF + Zod)
|
|
1178
1204
|
* ```tsx
|
|
1179
1205
|
* const form = useForm<UserDraft>({ resolver: zodResolver(schema), defaultValues });
|
|
1180
1206
|
*
|
|
1181
1207
|
* return (
|
|
1182
1208
|
* <FormProvider {...form}>
|
|
1183
|
-
* <FormPage
|
|
1184
|
-
* title="New user"
|
|
1185
|
-
* description="Invite a teammate to your workspace."
|
|
1186
|
-
* back={{ to: '/users' }}
|
|
1187
|
-
* onSubmit={form.handleSubmit(onSave)}
|
|
1188
|
-
* actions={
|
|
1189
|
-
* <>
|
|
1190
|
-
* <Button type="button" variant="outline" onClick={() => navigate(-1)}>
|
|
1191
|
-
* Cancel
|
|
1192
|
-
* </Button>
|
|
1193
|
-
* <Button type="submit" disabled={form.formState.isSubmitting}>
|
|
1194
|
-
* Save
|
|
1195
|
-
* </Button>
|
|
1196
|
-
* </>
|
|
1197
|
-
* }
|
|
1198
|
-
* >
|
|
1209
|
+
* <FormPage title="New user" onSubmit={form.handleSubmit(onSave)}>
|
|
1199
1210
|
* <div className="grid gap-4 md:grid-cols-2">
|
|
1200
1211
|
* <Field name="name" label="Full name" required><Input /></Field>
|
|
1201
1212
|
* <Field name="email" label="Email" required><Input type="email" /></Field>
|
|
@@ -1205,14 +1216,26 @@ interface FormPageProps {
|
|
|
1205
1216
|
* );
|
|
1206
1217
|
* ```
|
|
1207
1218
|
*
|
|
1219
|
+
* @example Override Cancel + add an extra action button
|
|
1220
|
+
* ```tsx
|
|
1221
|
+
* <FormPage
|
|
1222
|
+
* title="مستخدم جديد"
|
|
1223
|
+
* onSubmit={form.handleSubmit(onSave)}
|
|
1224
|
+
* onCancel={() => form.reset()}
|
|
1225
|
+
* actions={<Button type="button" variant="outline" onClick={onSaveAndContinue}>Save & continue</Button>}
|
|
1226
|
+
* >
|
|
1227
|
+
* {…fields…}
|
|
1228
|
+
* </FormPage>
|
|
1229
|
+
* ```
|
|
1230
|
+
*
|
|
1208
1231
|
* @example Edit mode with `isLoading`
|
|
1209
1232
|
* ```tsx
|
|
1210
|
-
* <FormPage title="Edit user" isLoading={query.isLoading} onSubmit={…}
|
|
1233
|
+
* <FormPage title="Edit user" isLoading={query.isLoading} onSubmit={…}>
|
|
1211
1234
|
* {…fields…}
|
|
1212
1235
|
* </FormPage>
|
|
1213
1236
|
* ```
|
|
1214
1237
|
*/
|
|
1215
|
-
declare function FormPage({ title, description,
|
|
1238
|
+
declare function FormPage({ title, description, bordered, onSubmit, onCancel, isSubmitting, labels: labelsProp, isLoading, loadingRowCount, actions, children, className, formClassName, bodyClassName, actionsClassName, }: FormPageProps): react_jsx_runtime.JSX.Element;
|
|
1216
1239
|
|
|
1217
1240
|
/** Outermost wrapper of `FormPage` — vertical flex column that fills its parent. */
|
|
1218
1241
|
declare const formPageBaseClass = "flex w-full flex-col gap-6";
|
|
@@ -1443,8 +1466,21 @@ interface PaginationState {
|
|
|
1443
1466
|
}
|
|
1444
1467
|
/** Set of row ids (returned from `getRowId`) that are currently selected. */
|
|
1445
1468
|
type RowSelectionState = ReadonlySet<string>;
|
|
1446
|
-
type SortableValue = string | number | bigint | boolean | Date | null | undefined;
|
|
1447
1469
|
type ColumnAlign = 'start' | 'center' | 'end';
|
|
1470
|
+
/**
|
|
1471
|
+
* Translatable strings rendered inside Table's chrome (paginator labels +
|
|
1472
|
+
* aria-labels). All optional; English defaults are used when omitted.
|
|
1473
|
+
*/
|
|
1474
|
+
interface TableLabels {
|
|
1475
|
+
/** "Rows per page" label next to the page-size select. */
|
|
1476
|
+
rowsPerPage?: string;
|
|
1477
|
+
/** Connector word in the range readout — e.g. "of" in `1–10 of 100`. */
|
|
1478
|
+
pageRangeOf?: string;
|
|
1479
|
+
/** aria-label on the Previous-page button. */
|
|
1480
|
+
previousPage?: string;
|
|
1481
|
+
/** aria-label on the Next-page button. */
|
|
1482
|
+
nextPage?: string;
|
|
1483
|
+
}
|
|
1448
1484
|
interface Column<T> {
|
|
1449
1485
|
/** Stable column id. Used for sort state and React keys. */
|
|
1450
1486
|
id: string;
|
|
@@ -1456,43 +1492,55 @@ interface Column<T> {
|
|
|
1456
1492
|
render?: (row: T, rowIndex: number) => ReactNode;
|
|
1457
1493
|
/** Enable click-to-sort UI on the header. */
|
|
1458
1494
|
sortable?: boolean;
|
|
1459
|
-
/** Optional override for the value used to compare during sorting. */
|
|
1460
|
-
sortAccessor?: (row: T) => SortableValue;
|
|
1461
1495
|
/** Tailwind classes applied to both <th> and <td>. */
|
|
1462
1496
|
className?: string;
|
|
1463
1497
|
/** Inline alignment hint. Defaults to 'start'. */
|
|
1464
1498
|
align?: ColumnAlign;
|
|
1465
1499
|
}
|
|
1466
1500
|
interface TableProps<T> {
|
|
1467
|
-
/**
|
|
1501
|
+
/**
|
|
1502
|
+
* Current page rows. Server-driven: the consumer's data layer slices
|
|
1503
|
+
* `data` for the active sort + pagination + filter query, and Table
|
|
1504
|
+
* renders it as-is. Table never sorts or paginates `data` locally.
|
|
1505
|
+
*/
|
|
1468
1506
|
data: readonly T[];
|
|
1469
1507
|
/** Column definitions. */
|
|
1470
1508
|
columns: ReadonlyArray<Column<T>>;
|
|
1471
1509
|
/**
|
|
1472
|
-
* Stable id for each row.
|
|
1473
|
-
*
|
|
1474
|
-
*
|
|
1475
|
-
*
|
|
1476
|
-
*
|
|
1477
|
-
* time the list can reorder — index-based ids break selection across
|
|
1478
|
-
* reorders.
|
|
1510
|
+
* Stable id for each row. **Optional with a default**: when omitted,
|
|
1511
|
+
* Table reads `row.id` (most APIs use it) and falls back to the row
|
|
1512
|
+
* index. Provide this explicitly for records that use a different
|
|
1513
|
+
* identifier (`_id`, `uuid`) or any time the list can reorder —
|
|
1514
|
+
* index-based ids break selection across reorders.
|
|
1479
1515
|
*/
|
|
1480
1516
|
getRowId?: (row: T, index: number) => string;
|
|
1481
1517
|
/**
|
|
1482
|
-
* Total row count
|
|
1483
|
-
*
|
|
1518
|
+
* Total row count on the server. Pair with `pagination` +
|
|
1519
|
+
* `onPaginationChange` to drive the paginator. Falls back to
|
|
1520
|
+
* `data.length` when omitted (small lists with no paginator).
|
|
1484
1521
|
*/
|
|
1485
1522
|
totalCount?: number;
|
|
1486
|
-
|
|
1523
|
+
/** Current sort state — the consumer's data layer is the source of truth. */
|
|
1487
1524
|
sort?: SortState;
|
|
1525
|
+
/**
|
|
1526
|
+
* Fires when the user clicks a sortable column header. Pair with `sort` to
|
|
1527
|
+
* drive sorting through your data layer. Without `onSortChange`, sortable
|
|
1528
|
+
* column buttons render but do nothing.
|
|
1529
|
+
*/
|
|
1488
1530
|
onSortChange?: (next: SortState) => void;
|
|
1489
|
-
|
|
1531
|
+
/** Current page state — the consumer's data layer is the source of truth. */
|
|
1490
1532
|
pagination?: PaginationState;
|
|
1533
|
+
/** Fires when the user changes the page or page size. */
|
|
1491
1534
|
onPaginationChange?: (next: PaginationState) => void;
|
|
1492
1535
|
/** Page size dropdown options. Defaults to [10, 25, 50]. */
|
|
1493
1536
|
pageSizeOptions?: readonly number[];
|
|
1494
|
-
/** Force the paginator to render even when
|
|
1537
|
+
/** Force the paginator to render even when totalCount <= pageSize. */
|
|
1495
1538
|
showPagination?: boolean;
|
|
1539
|
+
/**
|
|
1540
|
+
* Translatable strings rendered inside Table itself (paginator labels +
|
|
1541
|
+
* aria-labels). Pass only the keys you need to override.
|
|
1542
|
+
*/
|
|
1543
|
+
labels?: TableLabels;
|
|
1496
1544
|
/** Adds the selection column + header checkbox. */
|
|
1497
1545
|
enableRowSelection?: boolean;
|
|
1498
1546
|
defaultSelectedRowIds?: ReadonlySet<string>;
|
|
@@ -1532,23 +1580,26 @@ interface TableProps<T> {
|
|
|
1532
1580
|
caption?: ReactNode;
|
|
1533
1581
|
}
|
|
1534
1582
|
|
|
1583
|
+
/**
|
|
1584
|
+
* Server-driven data table. `data` is rendered as-is — the consumer's data
|
|
1585
|
+
* layer is responsible for slicing rows for the active sort + pagination
|
|
1586
|
+
* query. Table just reports user input (sort clicks, page changes,
|
|
1587
|
+
* selection) through callbacks and lets the consumer refetch.
|
|
1588
|
+
*/
|
|
1535
1589
|
declare function Table<T>(props: TableProps<T>): react_jsx_runtime.JSX.Element;
|
|
1536
1590
|
|
|
1537
1591
|
/**
|
|
1538
|
-
* One filter dropdown definition for `<ListPage>`.
|
|
1539
|
-
*
|
|
1592
|
+
* One filter dropdown definition for `<ListPage>`. Server owns the actual
|
|
1593
|
+
* filtering — the consumer keeps `filterValues` in state and ListPage just
|
|
1594
|
+
* renders the Select + reports changes.
|
|
1540
1595
|
*/
|
|
1541
|
-
interface ListPageFilter
|
|
1542
|
-
/** Unique key
|
|
1596
|
+
interface ListPageFilter {
|
|
1597
|
+
/** Unique key — used in the `filterValues` record and as aria-label fallback. */
|
|
1543
1598
|
key: string;
|
|
1544
|
-
/**
|
|
1545
|
-
|
|
1546
|
-
/** Returns the row value to match against the filter selection. */
|
|
1547
|
-
accessor: (row: T) => string;
|
|
1599
|
+
/** Display label. Falls back to `key` for the Select's aria-label. */
|
|
1600
|
+
label?: ReactNode;
|
|
1548
1601
|
/** Options to choose from. The first option's value is treated as "no filter / show all". */
|
|
1549
1602
|
options: SelectOption[];
|
|
1550
|
-
/** Override the "no filter" default. Defaults to the first option's `value`. */
|
|
1551
|
-
defaultValue?: string;
|
|
1552
1603
|
/** Width of the Select. Defaults to `'default'` (~11rem). */
|
|
1553
1604
|
width?: 'narrow' | 'default' | 'wide';
|
|
1554
1605
|
}
|
|
@@ -1559,168 +1610,142 @@ interface ListPageEmptyState {
|
|
|
1559
1610
|
/** Override the default action button. Pass `null` to hide entirely. */
|
|
1560
1611
|
action?: ReactNode | null;
|
|
1561
1612
|
}
|
|
1562
|
-
|
|
1563
|
-
|
|
1613
|
+
/**
|
|
1614
|
+
* Translatable strings for `<ListPage>`. Extends {@link TableLabels} so the
|
|
1615
|
+
* four paginator keys (`rowsPerPage` / `pageRangeOf` / `previousPage` /
|
|
1616
|
+
* `nextPage`) flow through to the inner Table without re-declaration.
|
|
1617
|
+
*/
|
|
1618
|
+
interface ListPageLabels extends TableLabels {
|
|
1619
|
+
/** Search input placeholder. */
|
|
1564
1620
|
searchPlaceholder?: string;
|
|
1565
|
-
/**
|
|
1621
|
+
/** Search input aria-label. Falls back to the placeholder. */
|
|
1566
1622
|
searchAriaLabel?: string;
|
|
1567
|
-
/**
|
|
1623
|
+
/** "Reset filters" button label. */
|
|
1568
1624
|
reset?: string;
|
|
1569
|
-
/**
|
|
1625
|
+
/** "No results matching filters" title. */
|
|
1570
1626
|
emptyTitle?: string;
|
|
1571
|
-
/**
|
|
1627
|
+
/** "No results matching filters" description. */
|
|
1572
1628
|
emptyDescription?: string;
|
|
1573
|
-
/**
|
|
1629
|
+
/** "No data yet" title (data empty, no filters active). */
|
|
1574
1630
|
noDataTitle?: string;
|
|
1575
|
-
/**
|
|
1631
|
+
/** "No data yet" description. */
|
|
1576
1632
|
noDataDescription?: string;
|
|
1577
1633
|
}
|
|
1578
1634
|
interface ListPageProps<T> {
|
|
1579
1635
|
title: ReactNode;
|
|
1580
1636
|
description?: ReactNode;
|
|
1581
|
-
/** Page-header bordered separator. Defaults to `true
|
|
1637
|
+
/** Page-header bordered separator. Defaults to `true`. */
|
|
1582
1638
|
bordered?: boolean;
|
|
1583
1639
|
/** Header action slot — primary "Add" button, etc. */
|
|
1584
1640
|
actions?: ReactNode;
|
|
1585
|
-
data: T[];
|
|
1586
|
-
columns: Column<T
|
|
1641
|
+
data: readonly T[];
|
|
1642
|
+
columns: ReadonlyArray<Column<T>>;
|
|
1587
1643
|
/**
|
|
1588
|
-
* Stable id for each row.
|
|
1589
|
-
* for
|
|
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.
|
|
1644
|
+
* Stable id for each row. Forwarded to Table; defaults to `row.id` then
|
|
1645
|
+
* the row index. Provide explicitly for records that use a different
|
|
1646
|
+
* identifier or any time the list can reorder.
|
|
1595
1647
|
*/
|
|
1596
|
-
getRowId?: (row: T) => string;
|
|
1648
|
+
getRowId?: (row: T, index: number) => string;
|
|
1597
1649
|
/** Show skeleton rows in the table area while data is fetching. */
|
|
1598
1650
|
isLoading?: boolean;
|
|
1599
1651
|
/** Number of skeleton rows rendered while loading. Defaults to the table page size. */
|
|
1600
1652
|
loadingRowCount?: number;
|
|
1601
|
-
/**
|
|
1602
|
-
|
|
1653
|
+
/** Current search query — the consumer's state. */
|
|
1654
|
+
searchValue?: string;
|
|
1603
1655
|
/**
|
|
1604
|
-
*
|
|
1605
|
-
*
|
|
1606
|
-
* provided, ListPage **stops filtering `data` locally** for search —
|
|
1607
|
-
* `data` is trusted to already match the query.
|
|
1656
|
+
* Fires on every keystroke. Providing this **renders the search input**.
|
|
1657
|
+
* Wire it to your data layer (and reset pagination to page 0 on change).
|
|
1608
1658
|
*/
|
|
1609
|
-
searchValue?: string;
|
|
1610
|
-
/** Fires on every search input change. Pair with `searchValue` for controlled mode. */
|
|
1611
1659
|
onSearchChange?: (value: string) => void;
|
|
1612
|
-
filters?: ListPageFilter<T>[];
|
|
1613
1660
|
/**
|
|
1614
|
-
*
|
|
1615
|
-
* `
|
|
1616
|
-
* is trusted to already match the active filter selections.
|
|
1661
|
+
* Filter definitions. Renders one `<Select>` per entry. Pair with
|
|
1662
|
+
* `filterValues` + `onFilterChange` to drive them.
|
|
1617
1663
|
*/
|
|
1664
|
+
filters?: ListPageFilter[];
|
|
1665
|
+
/** Current filter selections, keyed by `filter.key`. */
|
|
1618
1666
|
filterValues?: Record<string, string>;
|
|
1619
|
-
/** Fires when any filter Select changes.
|
|
1667
|
+
/** Fires when any filter Select changes. */
|
|
1620
1668
|
onFilterChange?: (key: string, value: string) => void;
|
|
1621
1669
|
enableRowSelection?: boolean;
|
|
1622
1670
|
bulkActions?: (selected: T[]) => ReactNode;
|
|
1623
|
-
/**
|
|
1624
|
-
* Controlled pagination state. Pair with `onPaginationChange` and `totalCount`
|
|
1625
|
-
* for server-side pagination — the consumer's data-fetching layer becomes
|
|
1626
|
-
* the source of truth for `pageIndex` / `pageSize`.
|
|
1627
|
-
*/
|
|
1671
|
+
/** Current page state from the consumer's data layer. */
|
|
1628
1672
|
pagination?: PaginationState;
|
|
1629
|
-
/** Uncontrolled initial pagination state. Ignored when `pagination` is set. */
|
|
1630
|
-
defaultPagination?: PaginationState;
|
|
1631
1673
|
/** Fires when the user changes the page or page size. */
|
|
1632
1674
|
onPaginationChange?: (next: PaginationState) => void;
|
|
1633
|
-
/**
|
|
1634
|
-
* Total row count across all pages on the server. Setting this flips the
|
|
1635
|
-
* inner Table into server-side mode — it stops slicing `data` locally and
|
|
1636
|
-
* trusts `data` to be the current page already.
|
|
1637
|
-
*
|
|
1638
|
-
* In server-side mode the consumer also typically skips `searchKeys` /
|
|
1639
|
-
* `filters` (those would filter only the current page) and drives search /
|
|
1640
|
-
* filter from the data-fetching layer instead.
|
|
1641
|
-
*/
|
|
1675
|
+
/** Total row count across all pages on the server. */
|
|
1642
1676
|
totalCount?: number;
|
|
1643
1677
|
/** Page-size dropdown options. Defaults to `[10, 25, 50]`. */
|
|
1644
1678
|
pageSizeOptions?: readonly number[];
|
|
1645
1679
|
/**
|
|
1646
|
-
* Shown when
|
|
1647
|
-
* "No results
|
|
1648
|
-
* with a reset button.
|
|
1680
|
+
* Shown when search / filters are active but match zero rows. Defaults to
|
|
1681
|
+
* a "No results" prompt with a Reset button.
|
|
1649
1682
|
*/
|
|
1650
1683
|
emptyState?: ListPageEmptyState;
|
|
1651
1684
|
/**
|
|
1652
|
-
* Shown when `data` is empty AND
|
|
1653
|
-
* state).
|
|
1654
|
-
* icon. When `actions` is set, you typically want to encourage creation
|
|
1655
|
-
* via this slot's `action`.
|
|
1685
|
+
* Shown when `data` is empty AND nothing is being searched / filtered
|
|
1686
|
+
* (first-run state). Defaults to an Inbox + "No data yet" message.
|
|
1656
1687
|
*/
|
|
1657
1688
|
noDataState?: ListPageEmptyState;
|
|
1658
1689
|
labels?: ListPageLabels;
|
|
1659
1690
|
className?: string;
|
|
1660
1691
|
}
|
|
1661
1692
|
/**
|
|
1662
|
-
* Declarative list-page template — composes `PageHeader + search
|
|
1663
|
-
* filter selects + Table + EmptyState` into a single
|
|
1693
|
+
* Declarative server-driven list-page template — composes `PageHeader + search
|
|
1694
|
+
* input + filter selects + Table + EmptyState` into a single component.
|
|
1664
1695
|
*
|
|
1665
|
-
* **
|
|
1666
|
-
* `data`
|
|
1667
|
-
*
|
|
1668
|
-
*
|
|
1696
|
+
* **All data-shaping is server-side.** ListPage does not filter / search /
|
|
1697
|
+
* paginate `data` locally; it renders whatever the consumer's data layer
|
|
1698
|
+
* returned for the current `searchValue` + `filterValues` + `pagination`
|
|
1699
|
+
* query. ListPage's job is the UI: render the controls, report user input
|
|
1700
|
+
* back through callbacks, and pick the right empty state.
|
|
1669
1701
|
*
|
|
1670
1702
|
* **Three rendering branches in the table area:**
|
|
1671
|
-
* - `isLoading` → Table with skeleton rows
|
|
1672
|
-
* - `data` empty AND
|
|
1673
|
-
* - filters
|
|
1703
|
+
* - `isLoading` → Table with skeleton rows.
|
|
1704
|
+
* - `data` empty AND nothing being searched / filtered → `noDataState` (first-run).
|
|
1705
|
+
* - search / filters active but `data` empty → `emptyState` (no results) with a Reset button.
|
|
1674
1706
|
*
|
|
1675
|
-
* @example
|
|
1707
|
+
* @example Server-driven list with TanStack Query
|
|
1676
1708
|
* ```tsx
|
|
1677
|
-
*
|
|
1678
|
-
*
|
|
1679
|
-
*
|
|
1680
|
-
* actions={<Button onClick={openCreate}>Add user</Button>}
|
|
1681
|
-
* data={users}
|
|
1682
|
-
* isLoading={query.isLoading}
|
|
1683
|
-
* columns={USER_COLUMNS}
|
|
1684
|
-
* getRowId={(u) => u.id}
|
|
1685
|
-
* searchKeys={['name', 'email']}
|
|
1686
|
-
* filters={[
|
|
1687
|
-
* {
|
|
1688
|
-
* key: 'status',
|
|
1689
|
-
* ariaLabel: 'Status',
|
|
1690
|
-
* accessor: (u) => u.status,
|
|
1691
|
-
* options: [
|
|
1692
|
-
* { value: 'all', label: 'All statuses' },
|
|
1693
|
-
* { value: 'active', label: 'Active' },
|
|
1694
|
-
* { value: 'invited', label: 'Invited' },
|
|
1695
|
-
* ],
|
|
1696
|
-
* },
|
|
1697
|
-
* ]}
|
|
1698
|
-
* enableRowSelection
|
|
1699
|
-
* bulkActions={(rows) => <Button variant="destructive">Delete ({rows.length})</Button>}
|
|
1700
|
-
* noDataState={{
|
|
1701
|
-
* title: 'No users yet',
|
|
1702
|
-
* description: 'Invite your first team member to get started.',
|
|
1703
|
-
* action: <Button onClick={openCreate}>Add user</Button>,
|
|
1704
|
-
* }}
|
|
1705
|
-
* />
|
|
1706
|
-
* ```
|
|
1709
|
+
* const [search, setSearch] = useState('');
|
|
1710
|
+
* const [filters, setFilters] = useState({ status: 'all' });
|
|
1711
|
+
* const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
|
|
1707
1712
|
*
|
|
1708
|
-
*
|
|
1709
|
-
*
|
|
1710
|
-
*
|
|
1711
|
-
*
|
|
1712
|
-
*
|
|
1713
|
-
*
|
|
1714
|
-
*
|
|
1715
|
-
*
|
|
1716
|
-
*
|
|
1717
|
-
*
|
|
1718
|
-
*
|
|
1719
|
-
*
|
|
1720
|
-
*
|
|
1713
|
+
* const { data, isLoading } = useQuery({
|
|
1714
|
+
* queryKey: ['users', search, filters, pagination],
|
|
1715
|
+
* queryFn: () => fetchUsers({ search, ...filters, ...pagination }),
|
|
1716
|
+
* });
|
|
1717
|
+
*
|
|
1718
|
+
* return (
|
|
1719
|
+
* <ListPage
|
|
1720
|
+
* title="Users"
|
|
1721
|
+
* actions={<Button onClick={openCreate}>Add user</Button>}
|
|
1722
|
+
* data={data?.rows ?? []}
|
|
1723
|
+
* totalCount={data?.total ?? 0}
|
|
1724
|
+
* isLoading={isLoading}
|
|
1725
|
+
* columns={USER_COLUMNS}
|
|
1726
|
+
*
|
|
1727
|
+
* searchValue={search}
|
|
1728
|
+
* onSearchChange={(v) => {
|
|
1729
|
+
* setSearch(v);
|
|
1730
|
+
* setPagination((p) => ({ ...p, pageIndex: 0 }));
|
|
1731
|
+
* }}
|
|
1732
|
+
*
|
|
1733
|
+
* filters={[
|
|
1734
|
+
* { key: 'status', label: 'Status', options: STATUS_OPTIONS },
|
|
1735
|
+
* ]}
|
|
1736
|
+
* filterValues={filters}
|
|
1737
|
+
* onFilterChange={(key, value) => {
|
|
1738
|
+
* setFilters((prev) => ({ ...prev, [key]: value }));
|
|
1739
|
+
* setPagination((p) => ({ ...p, pageIndex: 0 }));
|
|
1740
|
+
* }}
|
|
1741
|
+
*
|
|
1742
|
+
* pagination={pagination}
|
|
1743
|
+
* onPaginationChange={setPagination}
|
|
1744
|
+
* />
|
|
1745
|
+
* );
|
|
1721
1746
|
* ```
|
|
1722
1747
|
*/
|
|
1723
|
-
declare function ListPage<T>({ title, description, bordered, actions, data, columns, getRowId, isLoading, loadingRowCount,
|
|
1748
|
+
declare function ListPage<T>({ title, description, bordered, actions, data, columns, getRowId, isLoading, loadingRowCount, searchValue, onSearchChange, filters, filterValues, onFilterChange, enableRowSelection, bulkActions, pagination, onPaginationChange, totalCount, pageSizeOptions, emptyState, noDataState, labels: labelsProp, className, }: ListPageProps<T>): react_jsx_runtime.JSX.Element;
|
|
1724
1749
|
|
|
1725
1750
|
type RadioGroupSize = 'sm' | 'md' | 'lg';
|
|
1726
1751
|
/** Outer circle (radio button itself) — sized + bordered. */
|
|
@@ -2113,4 +2138,4 @@ declare function useDirection(): Direction;
|
|
|
2113
2138
|
|
|
2114
2139
|
declare function cn(...inputs: ClassValue[]): string;
|
|
2115
2140
|
|
|
2116
|
-
export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, type AlertDialogContentProps, AlertDialogDescription, type AlertDialogDescriptionProps, AlertDialogFooter, type AlertDialogFooterProps, AlertDialogHeader, type AlertDialogHeaderProps, AlertDialogOverlay, type AlertDialogOverlayProps, AlertDialogPortal, AlertDialogTitle, type AlertDialogTitleProps, AlertDialogTrigger, AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellProps, Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, type ConfirmDialogLabels, ConfirmDialogProvider, type ConfirmDialogProviderProps, type ConfirmOptions, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, DatePicker, type DatePickerProps, type DatePickerSize, type DatePickerVariant, DetailPage, type DetailPageLabels, type DetailPageNotFoundState, type DetailPageProps, Dialog, DialogClose, DialogContent, type DialogContentProps, DialogDescription, type DialogDescriptionProps, DialogFooter, type DialogFooterProps, DialogHeader, type DialogHeaderProps, DialogOverlay, type DialogOverlayProps, DialogPortal, DialogTitle, type DialogTitleProps, DialogTrigger, type Direction, DropdownMenu, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuItem, type DropdownMenuItemProps, type DropdownMenuItemVariant, DropdownMenuLabel, type DropdownMenuLabelProps, DropdownMenuPortal, DropdownMenuSeparator, type DropdownMenuSeparatorProps, DropdownMenuShortcut, type DropdownMenuShortcutProps, DropdownMenuTrigger, EmptyState, type EmptyStateProps, type EmptyStateSize, Field, type FieldOrientation, type FieldProps, type FieldRHFProps, FormPage, type FormPageProps, HeaderActions, type HeaderActionsProps, HeaderCollapseTrigger, type HeaderCollapseTriggerProps, HeaderMobileTrigger, type HeaderMobileTriggerProps, HeaderSearch, type HeaderSearchProps, HeaderTitle, type HeaderTitleProps, Input, type InputProps, type InputSize, type InputVariant, type LanguageOption, LanguageSwitcher, type LanguageSwitcherProps, ListPage, type ListPageEmptyState, type ListPageFilter, type ListPageLabels, type ListPageProps, PageHeader, type PageHeaderBackProps, type PageHeaderBackRenderProps, type PageHeaderHeadingLevel, type PageHeaderProps, type PaginationState, RadioGroup, RadioGroupItem, type RadioGroupOption, type RadioGroupOrientation, type RadioGroupProps, type RadioGroupSize, type RowSelectionState, Select, type SelectOption, type SelectProps, type SelectSize, type SelectVariant, Sidebar, SidebarFooter, type SidebarFooterProps, SidebarGroup, type SidebarGroupProps, SidebarHeader, type SidebarHeaderProps, SidebarNav, SidebarNavGroup, type SidebarNavGroupProps, SidebarNavItem, type SidebarNavItemProps, type SidebarNavItemRenderProps, type SidebarNavProps, type SidebarProps, type SortDirection, type SortState,
|
|
2141
|
+
export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, type AlertDialogContentProps, AlertDialogDescription, type AlertDialogDescriptionProps, AlertDialogFooter, type AlertDialogFooterProps, AlertDialogHeader, type AlertDialogHeaderProps, AlertDialogOverlay, type AlertDialogOverlayProps, AlertDialogPortal, AlertDialogTitle, type AlertDialogTitleProps, AlertDialogTrigger, AppShell, type AppShellBrand, type AppShellNavGroup, type AppShellNavItem, type AppShellProps, Avatar, type AvatarProps, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, Button, type ButtonProps, type ButtonSize, type ButtonVariant, Checkbox, type CheckboxProps, type CheckboxSize, type Column, type ColumnAlign, type ConfirmDialogLabels, ConfirmDialogProvider, type ConfirmDialogProviderProps, type ConfirmOptions, DashboardContent, type DashboardContentProps, DashboardHeader, type DashboardHeaderProps, DashboardLayout, type DashboardLayoutContextValue, type DashboardLayoutProps, DashboardMain, type DashboardMainProps, DatePicker, type DatePickerProps, type DatePickerSize, type DatePickerVariant, DetailPage, type DetailPageLabels, type DetailPageNotFoundState, type DetailPageProps, Dialog, DialogClose, DialogContent, type DialogContentProps, DialogDescription, type DialogDescriptionProps, DialogFooter, type DialogFooterProps, DialogHeader, type DialogHeaderProps, DialogOverlay, type DialogOverlayProps, DialogPortal, DialogTitle, type DialogTitleProps, DialogTrigger, type Direction, DropdownMenu, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuGroup, DropdownMenuItem, type DropdownMenuItemProps, type DropdownMenuItemVariant, DropdownMenuLabel, type DropdownMenuLabelProps, DropdownMenuPortal, DropdownMenuSeparator, type DropdownMenuSeparatorProps, DropdownMenuShortcut, type DropdownMenuShortcutProps, DropdownMenuTrigger, EmptyState, type EmptyStateProps, type EmptyStateSize, Field, type FieldOrientation, type FieldProps, type FieldRHFProps, FormPage, type FormPageLabels, type FormPageProps, HeaderActions, type HeaderActionsProps, HeaderCollapseTrigger, type HeaderCollapseTriggerProps, HeaderMobileTrigger, type HeaderMobileTriggerProps, HeaderSearch, type HeaderSearchProps, HeaderTitle, type HeaderTitleProps, Input, type InputProps, type InputSize, type InputVariant, type LanguageOption, LanguageSwitcher, type LanguageSwitcherProps, ListPage, type ListPageEmptyState, type ListPageFilter, type ListPageLabels, type ListPageProps, PageHeader, type PageHeaderBackProps, type PageHeaderBackRenderProps, type PageHeaderHeadingLevel, type PageHeaderProps, type PaginationState, RadioGroup, RadioGroupItem, type RadioGroupOption, type RadioGroupOrientation, type RadioGroupProps, type RadioGroupSize, type RowSelectionState, Select, type SelectOption, type SelectProps, type SelectSize, type SelectVariant, Sidebar, SidebarFooter, type SidebarFooterProps, SidebarGroup, type SidebarGroupProps, SidebarHeader, type SidebarHeaderProps, SidebarNav, SidebarNavGroup, type SidebarNavGroupProps, SidebarNavItem, type SidebarNavItemProps, type SidebarNavItemRenderProps, type SidebarNavProps, type SidebarProps, type SortDirection, type SortState, Switch, type SwitchProps, type SwitchSize, Table, type TableLabels, type TableProps, type TableSize, type TableSizeClasses, Textarea, type TextareaProps, type TextareaResize, type TextareaSize, type TextareaVariant, Toaster, type ToasterProps, Tooltip, type TooltipProps, TooltipProvider, type TooltipProviderProps, badgeBaseClass, badgeDotSizeClass, badgeSizeClass, badgeVariantClass, buttonBaseClass, buttonSizeClass, buttonVariantClass, cn, datePickerCalendarClass, datePickerCaptionClass, datePickerContentClass, datePickerDayBaseClass, datePickerDayWrapperClass, datePickerDisabledClass, datePickerMonthClass, datePickerMonthGridClass, datePickerMonthsClass, datePickerNavButtonClass, datePickerNavClass, datePickerOutsideClass, datePickerPlaceholderClass, datePickerSelectedClass, datePickerTodayClass, datePickerTriggerBaseClass, datePickerTriggerSizeClass, datePickerTriggerVariantClass, datePickerValueClass, datePickerWeekClass, datePickerWeekdayClass, datePickerWeekdaysClass, detailPageBaseClass, detailPageBodyClass, detailPageEmptyClass, detailPageSkeletonRowClass, dialogCloseButtonClass, dialogContentClass, dialogDescriptionClass, dialogFooterClass, dialogHeaderClass, dialogOverlayClass, dialogTitleClass, dropdownMenuContentClass, dropdownMenuItemBaseClass, dropdownMenuItemInsetClass, dropdownMenuItemVariantClass, dropdownMenuLabelClass, dropdownMenuSeparatorClass, dropdownMenuShortcutClass, emptyStateActionsSpacingClass, emptyStateBaseClass, emptyStateContainerSizeClass, emptyStateDescriptionSizeClass, emptyStateIconWrapperBaseClass, emptyStateIconWrapperSizeClass, emptyStateTitleSizeClass, formPageActionsBarClass, formPageBaseClass, formPageBodyClass, formPageSkeletonRowClass, inputBaseClass, inputSizeClass, inputVariantClass, pageHeaderActionsClass, pageHeaderBackClass, pageHeaderBackIconClass, pageHeaderBaseClass, pageHeaderBorderedClass, pageHeaderBreadcrumbsClass, pageHeaderDescriptionClass, pageHeaderTitleBlockClass, pageHeaderTitleClass, pageHeaderTitleRowClass, radioGroupBaseClass, radioGroupOrientationClass, radioIndicatorBaseClass, radioIndicatorDotClass, radioIndicatorSizeClass, radioItemBaseClass, radioItemSizeClass, radioLabelSizeClass, radioOptionRowClass, selectBaseClass, selectSizeClass, selectVariantClass, switchThumbBaseClass, switchThumbClass, switchTrackBaseClass, switchTrackClass, alignClass as tableAlignClass, tableBaseClass, selectedRowClass as tableSelectedRowClass, tableSizeClass, sortIconClass as tableSortIconClass, textareaBaseClass, textareaResizeClass, textareaSizeClass, textareaVariantClass, toastClassNames, tooltipArrowClass, tooltipContentClass, useConfirm, useDashboardLayout, useDirection };
|