@marktiderman/genesis-ui 1.3.0 → 2.1.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/LICENSE +21 -0
- package/dist/AppShell-sQT0UbXg.d.ts +198 -0
- package/dist/{chunk-NJMO3VPA.js → chunk-22XB3Q6H.js} +8 -8
- package/dist/chunk-22XB3Q6H.js.map +1 -0
- package/dist/{chunk-2MXMWBDV.js → chunk-27ELYTGE.js} +6 -6
- package/dist/chunk-27ELYTGE.js.map +1 -0
- package/dist/chunk-46TZGMFW.js +159 -0
- package/dist/chunk-46TZGMFW.js.map +1 -0
- package/dist/chunk-4CQHPWJD.js +117 -0
- package/dist/chunk-4CQHPWJD.js.map +1 -0
- package/dist/{chunk-ZDAT5JDH.js → chunk-65SPT7EA.js} +24 -6
- package/dist/chunk-65SPT7EA.js.map +1 -0
- package/dist/chunk-6KHY647C.js +67 -0
- package/dist/chunk-6KHY647C.js.map +1 -0
- package/dist/chunk-6M4NHHKG.js +51 -0
- package/dist/chunk-6M4NHHKG.js.map +1 -0
- package/dist/chunk-6Q6CLLJ4.js +9 -0
- package/dist/chunk-6Q6CLLJ4.js.map +1 -0
- package/dist/{chunk-UGHQFQOE.js → chunk-6TVMQH6M.js} +28 -28
- package/dist/chunk-6TVMQH6M.js.map +1 -0
- package/dist/{chunk-6VVVGYKS.js → chunk-6XPMU65K.js} +5 -5
- package/dist/{chunk-6VVVGYKS.js.map → chunk-6XPMU65K.js.map} +1 -1
- package/dist/{chunk-YZEA5TGK.js → chunk-7XMZVISM.js} +16 -16
- package/dist/chunk-7XMZVISM.js.map +1 -0
- package/dist/chunk-A7AHVDG7.js +52 -0
- package/dist/chunk-A7AHVDG7.js.map +1 -0
- package/dist/chunk-AFZ76Q26.js +84 -0
- package/dist/chunk-AFZ76Q26.js.map +1 -0
- package/dist/{chunk-4V4H2ZM7.js → chunk-AL5TMEZQ.js} +31 -31
- package/dist/chunk-AL5TMEZQ.js.map +1 -0
- package/dist/{chunk-AUECDWP2.js → chunk-AOZGQM6W.js} +3 -3
- package/dist/chunk-AOZGQM6W.js.map +1 -0
- package/dist/chunk-ARJI2JUV.js +122 -0
- package/dist/chunk-ARJI2JUV.js.map +1 -0
- package/dist/chunk-AVFZ4P4B.js +25 -0
- package/dist/chunk-AVFZ4P4B.js.map +1 -0
- package/dist/chunk-B2GIBUQD.js +11 -0
- package/dist/chunk-B2GIBUQD.js.map +1 -0
- package/dist/{chunk-JXI2MYL3.js → chunk-C46ITXE4.js} +5 -5
- package/dist/chunk-C46ITXE4.js.map +1 -0
- package/dist/{chunk-A2OXCNNY.js → chunk-CNTWQSUT.js} +3 -3
- package/dist/{chunk-A2OXCNNY.js.map → chunk-CNTWQSUT.js.map} +1 -1
- package/dist/chunk-D2LIXA2Y.js +65 -0
- package/dist/chunk-D2LIXA2Y.js.map +1 -0
- package/dist/{chunk-T5VX5DYO.js → chunk-F47U5KNW.js} +5 -5
- package/dist/chunk-F47U5KNW.js.map +1 -0
- package/dist/chunk-FEJAZFP3.js +1100 -0
- package/dist/chunk-FEJAZFP3.js.map +1 -0
- package/dist/{chunk-2B3MFHBQ.js → chunk-FK42ZGGV.js} +21 -21
- package/dist/chunk-FK42ZGGV.js.map +1 -0
- package/dist/{chunk-XISSLIMH.js → chunk-FTTNGGLA.js} +2 -2
- package/dist/{chunk-XISSLIMH.js.map → chunk-FTTNGGLA.js.map} +1 -1
- package/dist/chunk-G5YKBPBF.js +74 -0
- package/dist/chunk-G5YKBPBF.js.map +1 -0
- package/dist/{chunk-QLCDAFS7.js → chunk-GDFNAHI4.js} +10 -6
- package/dist/chunk-GDFNAHI4.js.map +1 -0
- package/dist/{chunk-KB5T5LWM.js → chunk-IJCT5IJD.js} +3 -3
- package/dist/{chunk-KB5T5LWM.js.map → chunk-IJCT5IJD.js.map} +1 -1
- package/dist/{chunk-44TULYGG.js → chunk-J6FBA7PH.js} +3 -3
- package/dist/{chunk-44TULYGG.js.map → chunk-J6FBA7PH.js.map} +1 -1
- package/dist/chunk-JAMLFMDS.js +12 -0
- package/dist/chunk-JAMLFMDS.js.map +1 -0
- package/dist/{chunk-C6H7AMO4.js → chunk-LNFF2RBD.js} +9 -9
- package/dist/chunk-LNFF2RBD.js.map +1 -0
- package/dist/{chunk-QBZMY2AF.js → chunk-M62CHO3N.js} +18 -18
- package/dist/chunk-M62CHO3N.js.map +1 -0
- package/dist/{chunk-5Q4FABZQ.js → chunk-NUXW6NPP.js} +8 -8
- package/dist/chunk-NUXW6NPP.js.map +1 -0
- package/dist/{chunk-ZJFSZFPI.js → chunk-NWSCYLPT.js} +77 -18
- package/dist/chunk-NWSCYLPT.js.map +1 -0
- package/dist/{chunk-63FW5ZUA.js → chunk-P3ZL6FGR.js} +7 -7
- package/dist/chunk-P3ZL6FGR.js.map +1 -0
- package/dist/chunk-P64MFQXZ.js +191 -0
- package/dist/chunk-P64MFQXZ.js.map +1 -0
- package/dist/chunk-PLIYF6KI.js +52 -0
- package/dist/chunk-PLIYF6KI.js.map +1 -0
- package/dist/chunk-PSR47JRA.js +26 -0
- package/dist/chunk-PSR47JRA.js.map +1 -0
- package/dist/{chunk-SBJV3K4G.js → chunk-QJ6P2DW6.js} +28 -28
- package/dist/chunk-QJ6P2DW6.js.map +1 -0
- package/dist/{chunk-IP6TMT3D.js → chunk-R7QFP6EL.js} +3 -3
- package/dist/chunk-R7QFP6EL.js.map +1 -0
- package/dist/{chunk-WZWR2ELB.js → chunk-SEBU6JCK.js} +6 -6
- package/dist/chunk-SEBU6JCK.js.map +1 -0
- package/dist/{chunk-7OBL3H5P.js → chunk-SEFK4NZV.js} +3 -3
- package/dist/chunk-SEFK4NZV.js.map +1 -0
- package/dist/chunk-SRIT4NFQ.js +67 -0
- package/dist/chunk-SRIT4NFQ.js.map +1 -0
- package/dist/chunk-SY62XJFA.js +19 -0
- package/dist/chunk-SY62XJFA.js.map +1 -0
- package/dist/{chunk-SVXDWPLO.js → chunk-THD3YOOZ.js} +17 -17
- package/dist/chunk-THD3YOOZ.js.map +1 -0
- package/dist/chunk-VXFYETRK.js +58 -0
- package/dist/chunk-VXFYETRK.js.map +1 -0
- package/dist/chunk-XBX6QMR5.js +58 -0
- package/dist/chunk-XBX6QMR5.js.map +1 -0
- package/dist/{chunk-SCUT2ZCD.js → chunk-XCGZPFT7.js} +17 -17
- package/dist/chunk-XCGZPFT7.js.map +1 -0
- package/dist/chunk-XMK3T4TA.js +73 -0
- package/dist/chunk-XMK3T4TA.js.map +1 -0
- package/dist/chunk-YJ6MPS6U.js +226 -0
- package/dist/chunk-YJ6MPS6U.js.map +1 -0
- package/dist/chunk-YRYQXU3G.js +38 -0
- package/dist/chunk-YRYQXU3G.js.map +1 -0
- package/dist/{chunk-5J7BP5DI.js → chunk-YWFPMND7.js} +10 -10
- package/dist/chunk-YWFPMND7.js.map +1 -0
- package/dist/chunk-YYEGAFUE.js +94 -0
- package/dist/chunk-YYEGAFUE.js.map +1 -0
- package/dist/{chunk-TKA4LOMT.js → chunk-ZZ7H7VVX.js} +8 -8
- package/dist/chunk-ZZ7H7VVX.js.map +1 -0
- package/dist/components/data/index.d.ts +318 -228
- package/dist/components/data/index.js +591 -1394
- package/dist/components/data/index.js.map +1 -1
- package/dist/components/layout/dashboard-page.d.ts +4 -0
- package/dist/components/layout/dashboard-page.js +5 -0
- package/dist/components/layout/dashboard-page.js.map +1 -0
- package/dist/components/layout/detail-page.d.ts +91 -0
- package/dist/components/layout/detail-page.js +6 -0
- package/dist/components/layout/detail-page.js.map +1 -0
- package/dist/components/layout/form-page.d.ts +82 -0
- package/dist/components/layout/form-page.js +5 -0
- package/dist/components/layout/form-page.js.map +1 -0
- package/dist/components/layout/index.d.ts +14 -0
- package/dist/components/layout/index.js +21 -0
- package/dist/components/layout/index.js.map +1 -0
- package/dist/components/layout/settings-page.d.ts +114 -0
- package/dist/components/layout/settings-page.js +6 -0
- package/dist/components/layout/settings-page.js.map +1 -0
- package/dist/components/patterns/empty-state.d.ts +73 -0
- package/dist/components/{ui → patterns}/empty-state.js +2 -1
- package/dist/components/{ui → patterns}/form-field.d.ts +5 -6
- package/dist/components/{ui → patterns}/form-field.js +2 -2
- package/dist/components/patterns/index.d.ts +17 -0
- package/dist/components/patterns/index.js +18 -0
- package/dist/components/patterns/index.js.map +1 -0
- package/dist/components/patterns/page-loading.d.ts +25 -0
- package/dist/components/patterns/page-loading.js +5 -0
- package/dist/components/patterns/page-loading.js.map +1 -0
- package/dist/components/patterns/settings-row.d.ts +41 -0
- package/dist/components/patterns/settings-row.js +6 -0
- package/dist/components/patterns/settings-row.js.map +1 -0
- package/dist/components/patterns/status-badge.d.ts +37 -0
- package/dist/components/patterns/status-badge.js +4 -0
- package/dist/components/patterns/status-badge.js.map +1 -0
- package/dist/components/patterns/toggle-row.d.ts +35 -0
- package/dist/components/patterns/toggle-row.js +8 -0
- package/dist/components/patterns/toggle-row.js.map +1 -0
- package/dist/components/patterns/user-avatar.d.ts +34 -0
- package/dist/components/patterns/user-avatar.js +5 -0
- package/dist/components/patterns/user-avatar.js.map +1 -0
- package/dist/components/ui/accessible-icon.d.ts +47 -0
- package/dist/components/ui/accessible-icon.js +3 -0
- package/dist/components/ui/accessible-icon.js.map +1 -0
- package/dist/components/ui/accordion.d.ts +5 -5
- package/dist/components/ui/accordion.js +1 -1
- package/dist/components/ui/alert-dialog.d.ts +12 -13
- package/dist/components/ui/alert-dialog.js +1 -1
- package/dist/components/ui/aspect-ratio.d.ts +2 -2
- package/dist/components/ui/aspect-ratio.js +1 -1
- package/dist/components/ui/avatar.d.ts +4 -4
- package/dist/components/ui/avatar.js +1 -1
- package/dist/components/ui/badge.d.ts +1 -2
- package/dist/components/ui/breadcrumb.d.ts +2 -3
- package/dist/components/ui/button-group.d.ts +1 -2
- package/dist/components/ui/button.d.ts +73 -8
- package/dist/components/ui/button.js +1 -1
- package/dist/components/ui/calendar.d.ts +2 -3
- package/dist/components/ui/calendar.js +2 -2
- package/dist/components/ui/card.d.ts +6 -7
- package/dist/components/ui/carousel.d.ts +4 -4
- package/dist/components/ui/carousel.js +2 -2
- package/dist/components/ui/chart.d.ts +4 -5
- package/dist/components/ui/checkbox.d.ts +2 -2
- package/dist/components/ui/checkbox.js +1 -1
- package/dist/components/ui/collapsible.d.ts +4 -4
- package/dist/components/ui/collapsible.js +1 -1
- package/dist/components/ui/command-palette.d.ts +1 -2
- package/dist/components/ui/command-palette.js +3 -3
- package/dist/components/ui/command.d.ts +11 -12
- package/dist/components/ui/command.js +2 -2
- package/dist/components/ui/context-menu.d.ts +16 -17
- package/dist/components/ui/context-menu.js +1 -1
- package/dist/components/ui/date-picker.d.ts +2 -2
- package/dist/components/ui/date-picker.js +4 -4
- package/dist/components/ui/dialog.d.ts +11 -12
- package/dist/components/ui/dialog.js +1 -1
- package/dist/components/ui/drawer.d.ts +10 -11
- package/dist/components/ui/dropdown-menu.d.ts +16 -17
- package/dist/components/ui/dropdown-menu.js +1 -1
- package/dist/components/ui/hover-card.d.ts +4 -4
- package/dist/components/ui/hover-card.js +1 -1
- package/dist/components/ui/input-otp.d.ts +2 -2
- package/dist/components/ui/kbd.d.ts +1 -2
- package/dist/components/ui/label.d.ts +2 -2
- package/dist/components/ui/label.js +1 -1
- package/dist/components/ui/menubar.d.ts +17 -18
- package/dist/components/ui/menubar.js +1 -1
- package/dist/components/ui/navigation-menu.d.ts +9 -9
- package/dist/components/ui/navigation-menu.js +1 -1
- package/dist/components/ui/pagination.d.ts +5 -6
- package/dist/components/ui/pagination.js +2 -2
- package/dist/components/ui/password-toggle-field.d.ts +120 -0
- package/dist/components/ui/password-toggle-field.js +4 -0
- package/dist/components/ui/password-toggle-field.js.map +1 -0
- package/dist/components/ui/popover.d.ts +4 -4
- package/dist/components/ui/popover.js +1 -1
- package/dist/components/ui/progress.d.ts +1 -2
- package/dist/components/ui/radio-group.d.ts +3 -3
- package/dist/components/ui/radio-group.js +1 -1
- package/dist/components/ui/resizable.d.ts +3 -4
- package/dist/components/ui/scroll-area.d.ts +60 -3
- package/dist/components/ui/scroll-area.js +1 -1
- package/dist/components/ui/select.d.ts +9 -9
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/separator.d.ts +1 -2
- package/dist/components/ui/sheet.d.ts +13 -12
- package/dist/components/ui/sheet.js +1 -1
- package/dist/components/ui/skeleton.d.ts +1 -2
- package/dist/components/ui/slider.d.ts +2 -2
- package/dist/components/ui/slider.js +1 -1
- package/dist/components/ui/sonner.d.ts +1 -2
- package/dist/components/ui/spinner.d.ts +1 -2
- package/dist/components/ui/switch.d.ts +2 -2
- package/dist/components/ui/switch.js +1 -1
- package/dist/components/ui/tabs.d.ts +29 -14
- package/dist/components/ui/tabs.js +1 -1
- package/dist/components/ui/toggle-group.d.ts +3 -3
- package/dist/components/ui/toggle-group.js +2 -2
- package/dist/components/ui/toggle.d.ts +2 -2
- package/dist/components/ui/toggle.js +1 -1
- package/dist/components/ui/toolbar.d.ts +104 -0
- package/dist/components/ui/toolbar.js +6 -0
- package/dist/components/ui/toolbar.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +46 -5
- package/dist/components/ui/tooltip.js +1 -1
- package/dist/components/ui/typography.d.ts +9 -10
- package/dist/components/ui/visually-hidden.d.ts +48 -0
- package/dist/components/ui/visually-hidden.js +4 -0
- package/dist/components/ui/visually-hidden.js.map +1 -0
- package/dist/dashboard-page-C0TihRl5.d.ts +107 -0
- package/dist/hooks/index.d.ts +2 -3
- package/dist/hooks/index.js +6 -6
- package/dist/hooks/use-keyboard-navigation.d.ts +58 -2
- package/dist/hooks/use-keyboard-navigation.js +1 -1
- package/dist/hooks/use-resource-page.d.ts +2 -3
- package/dist/hooks/use-resource-page.js +2 -2
- package/dist/hooks/use-view-preference.d.ts +2 -2
- package/dist/hooks/use-view-preference.js +1 -1
- package/dist/index.d.ts +22 -25
- package/dist/index.js +54 -38
- package/dist/spacing-BS6qECD4.d.ts +191 -0
- package/dist/split-Dk9f4Mi0.d.ts +57 -0
- package/dist/{use-resource-page-BXBv_Xah.d.ts → use-resource-page-DTQS011Q.d.ts} +18 -6
- package/dist/view-settings-kHKCHMjj.d.ts +12 -0
- package/dist/{ViewToggle-DDe_Luj2.d.ts → view-toggle-CahQ87PW.d.ts} +2 -2
- package/package.json +80 -39
- package/dist/chunk-2B3MFHBQ.js.map +0 -1
- package/dist/chunk-2MXMWBDV.js.map +0 -1
- package/dist/chunk-4V4H2ZM7.js.map +0 -1
- package/dist/chunk-5J7BP5DI.js.map +0 -1
- package/dist/chunk-5Q4FABZQ.js.map +0 -1
- package/dist/chunk-63FW5ZUA.js.map +0 -1
- package/dist/chunk-7OBL3H5P.js.map +0 -1
- package/dist/chunk-AUECDWP2.js.map +0 -1
- package/dist/chunk-C6H7AMO4.js.map +0 -1
- package/dist/chunk-EI5EGKHL.js +0 -32
- package/dist/chunk-EI5EGKHL.js.map +0 -1
- package/dist/chunk-IP6TMT3D.js.map +0 -1
- package/dist/chunk-JJ4NOMMI.js +0 -73
- package/dist/chunk-JJ4NOMMI.js.map +0 -1
- package/dist/chunk-JXI2MYL3.js.map +0 -1
- package/dist/chunk-KBS4BHME.js +0 -11
- package/dist/chunk-KBS4BHME.js.map +0 -1
- package/dist/chunk-LRXDZBV2.js +0 -26
- package/dist/chunk-LRXDZBV2.js.map +0 -1
- package/dist/chunk-NJMO3VPA.js.map +0 -1
- package/dist/chunk-OCTV3S4I.js +0 -29
- package/dist/chunk-OCTV3S4I.js.map +0 -1
- package/dist/chunk-QBZMY2AF.js.map +0 -1
- package/dist/chunk-QLCDAFS7.js.map +0 -1
- package/dist/chunk-SBJV3K4G.js.map +0 -1
- package/dist/chunk-SCUT2ZCD.js.map +0 -1
- package/dist/chunk-SVXDWPLO.js.map +0 -1
- package/dist/chunk-T465NJRL.js +0 -134
- package/dist/chunk-T465NJRL.js.map +0 -1
- package/dist/chunk-T5VX5DYO.js.map +0 -1
- package/dist/chunk-TKA4LOMT.js.map +0 -1
- package/dist/chunk-UGHQFQOE.js.map +0 -1
- package/dist/chunk-WALXVR6V.js +0 -9
- package/dist/chunk-WALXVR6V.js.map +0 -1
- package/dist/chunk-WZWR2ELB.js.map +0 -1
- package/dist/chunk-YZEA5TGK.js.map +0 -1
- package/dist/chunk-ZDAT5JDH.js.map +0 -1
- package/dist/chunk-ZJFSZFPI.js.map +0 -1
- package/dist/components/ui/empty-state.d.ts +0 -22
- /package/dist/components/{ui → patterns}/empty-state.js.map +0 -0
- /package/dist/components/{ui → patterns}/form-field.js.map +0 -0
|
@@ -1,84 +1,25 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
1
|
import * as React from 'react';
|
|
3
2
|
import { ReactNode, RefObject } from 'react';
|
|
3
|
+
import { c as PageHeaderOptions, A as AppShell$1, P as PageHeader$1 } from '../../AppShell-sQT0UbXg.js';
|
|
4
|
+
export { a as AppShellOptions, b as AppShellProps, N as NavItem, d as PageHeaderProps } from '../../AppShell-sQT0UbXg.js';
|
|
5
|
+
import { V as ViewMode } from '../../view-toggle-CahQ87PW.js';
|
|
6
|
+
export { a as ViewToggle } from '../../view-toggle-CahQ87PW.js';
|
|
4
7
|
import { LucideIcon } from 'lucide-react';
|
|
5
|
-
import { V as ViewMode } from '../../ViewToggle-DDe_Luj2.js';
|
|
6
|
-
export { a as ViewToggle } from '../../ViewToggle-DDe_Luj2.js';
|
|
7
8
|
import { Density } from '../../hooks/use-view-settings.js';
|
|
8
|
-
import { a as ResourceColumnDef } from '../../use-resource-page-
|
|
9
|
-
export { D as DataTable, c as DataTableColumn, d as DataTableProps, L as LinkCell,
|
|
9
|
+
import { R as ResourceActions, a as ResourceColumnDef } from '../../use-resource-page-DTQS011Q.js';
|
|
10
|
+
export { D as DataTable, c as DataTableColumn, d as DataTableProps, L as LinkCell, T as ThumbnailCell } from '../../use-resource-page-DTQS011Q.js';
|
|
11
|
+
export { EmptyState } from '../patterns/empty-state.js';
|
|
12
|
+
export { V as ViewSettings } from '../../view-settings-kHKCHMjj.js';
|
|
10
13
|
import { L as LinkComponent, N as NavigateFn } from '../../navigation-CpOEyUSb.js';
|
|
11
14
|
export { D as DefaultLink, G as GenesisLinkProps, d as defaultNavigate, i as isPathActive } from '../../navigation-CpOEyUSb.js';
|
|
12
15
|
import { UseFormReturn, Control, FieldErrors } from 'react-hook-form';
|
|
13
16
|
import { WizardStep, UseResourceOptions } from '@marktiderman/genesis-core/hooks';
|
|
14
|
-
import { FilterParam } from '@marktiderman/genesis-core/provider';
|
|
17
|
+
import { FilterParam, SortParam, BaseRecord, Identifier } from '@marktiderman/genesis-core/provider';
|
|
15
18
|
import { ResourceFormFieldDef } from '@marktiderman/genesis-core';
|
|
16
19
|
export { FieldType, ResourceFormFieldDef, SelectOption } from '@marktiderman/genesis-core';
|
|
17
20
|
export { CommandPalette, CommandPaletteItem, CommandPaletteProps, useCommandPaletteHotkey } from '../ui/command-palette.js';
|
|
18
21
|
export { UseSavedViewsReturn, useSavedViews } from '../../hooks/use-saved-views.js';
|
|
19
22
|
|
|
20
|
-
/**
|
|
21
|
-
* Declarative chrome for PageHeader — developer defaults + optional
|
|
22
|
-
* in-header user toggles (Notion/Linear “customize view” pattern).
|
|
23
|
-
*
|
|
24
|
-
* @stability Beta
|
|
25
|
-
*/
|
|
26
|
-
interface PageHeaderOptions {
|
|
27
|
-
showIcon?: boolean;
|
|
28
|
-
showSubtitle?: boolean;
|
|
29
|
-
showCount?: boolean;
|
|
30
|
-
showViewToggle?: boolean;
|
|
31
|
-
showViewSettings?: boolean;
|
|
32
|
-
showCreate?: boolean;
|
|
33
|
-
/** Ghost ListFilter control in the actions cluster */
|
|
34
|
-
showDetailsToggle?: boolean;
|
|
35
|
-
/** Quiet hint beside actions while details are collapsed */
|
|
36
|
-
showDetailsHint?: boolean;
|
|
37
|
-
/** Move subtitle into the details panel (default true when details exist) */
|
|
38
|
-
subtitleInDetails?: boolean;
|
|
39
|
-
defaultDetailsOpen?: boolean;
|
|
40
|
-
detailsLabel?: string;
|
|
41
|
-
/**
|
|
42
|
-
* Show the in-header Header options popover so users can customize chrome.
|
|
43
|
-
* Default true when the header has more than one chrome affordance.
|
|
44
|
-
*/
|
|
45
|
-
configurable?: boolean;
|
|
46
|
-
}
|
|
47
|
-
interface PageHeaderProps {
|
|
48
|
-
title: string;
|
|
49
|
-
subtitle?: string;
|
|
50
|
-
icon?: LucideIcon;
|
|
51
|
-
/**
|
|
52
|
-
* Header chrome config (developer defaults). Merged under user picks from
|
|
53
|
-
* the in-header options menu when `options.configurable` / storage is on.
|
|
54
|
-
*/
|
|
55
|
-
options?: PageHeaderOptions;
|
|
56
|
-
/** Persist user header-option overrides (localStorage) */
|
|
57
|
-
optionsStorageKey?: string;
|
|
58
|
-
/** Extra trailing actions (after create); prefer first-class slots below */
|
|
59
|
-
actions?: ReactNode;
|
|
60
|
-
/** Collapsible details region below the title row */
|
|
61
|
-
details?: ReactNode;
|
|
62
|
-
detailsOpen?: boolean;
|
|
63
|
-
onDetailsOpenChange?: (open: boolean) => void;
|
|
64
|
-
detailsActive?: boolean;
|
|
65
|
-
detailsHint?: ReactNode;
|
|
66
|
-
/** Count badge */
|
|
67
|
-
count?: number;
|
|
68
|
-
totalCount?: number;
|
|
69
|
-
/** Singular entity for “N rows” copy when unfiltered */
|
|
70
|
-
entityName?: string;
|
|
71
|
-
countActive?: boolean;
|
|
72
|
-
viewMode?: ViewMode;
|
|
73
|
-
onViewModeChange?: (mode: ViewMode) => void;
|
|
74
|
-
pageSize?: number;
|
|
75
|
-
onPageSizeChange?: (size: number) => void;
|
|
76
|
-
density?: Density;
|
|
77
|
-
onDensityChange?: (density: Density) => void;
|
|
78
|
-
createAction?: ReactNode;
|
|
79
|
-
}
|
|
80
|
-
declare function PageHeader({ title, subtitle, icon: Icon, options: optionsProp, optionsStorageKey, actions, details, detailsOpen, onDetailsOpenChange, detailsActive, detailsHint, count, totalCount, entityName, countActive, viewMode, onViewModeChange, pageSize, onPageSizeChange, density, onDensityChange, createAction, }: PageHeaderProps): react_jsx_runtime.JSX.Element;
|
|
81
|
-
|
|
82
23
|
interface DataPageShellProps {
|
|
83
24
|
/** Display title for the page */
|
|
84
25
|
title: string;
|
|
@@ -132,7 +73,7 @@ interface DataPageShellProps {
|
|
|
132
73
|
headerOptionsStorageKey?: string;
|
|
133
74
|
children: ReactNode;
|
|
134
75
|
}
|
|
135
|
-
declare function DataPageShell({ title, icon, entityName, subtitle, createAction, isLoading, isEmpty, emptyIcon, emptyMessage, emptyAction, hasError, errorMessage, onRetry, count, totalCount, viewMode, onViewModeChange, pageSize, onPageSizeChange, density, onDensityChange, filters, hasActiveFilters, onClearFilters, filtersCollapsible, defaultFiltersOpen, filtersOpen, onFiltersOpenChange, filtersLabel, filtersHint, headerOptions, headerOptionsStorageKey, children, }: DataPageShellProps):
|
|
76
|
+
declare function DataPageShell({ title, icon, entityName, subtitle, createAction, isLoading, isEmpty, emptyIcon, emptyMessage, emptyAction, hasError, errorMessage, onRetry, count, totalCount, viewMode, onViewModeChange, pageSize, onPageSizeChange, density, onDensityChange, filters, hasActiveFilters, onClearFilters, filtersCollapsible, defaultFiltersOpen, filtersOpen, onFiltersOpenChange, filtersLabel, filtersHint, headerOptions, headerOptionsStorageKey, children, }: DataPageShellProps): React.JSX.Element;
|
|
136
77
|
|
|
137
78
|
interface FilterOption {
|
|
138
79
|
value: string;
|
|
@@ -150,7 +91,7 @@ interface FilterComboboxProps {
|
|
|
150
91
|
/** Optional map of value -> display label */
|
|
151
92
|
labelMap?: Record<string, string>;
|
|
152
93
|
}
|
|
153
|
-
declare function FilterCombobox({ label, icon: Icon, options, selected, onChange, searchPlaceholder, allLabel, labelMap, }: FilterComboboxProps):
|
|
94
|
+
declare function FilterCombobox({ label, icon: Icon, options, selected, onChange, searchPlaceholder, allLabel, labelMap, }: FilterComboboxProps): React.JSX.Element;
|
|
154
95
|
|
|
155
96
|
interface DataFilterConfig {
|
|
156
97
|
key: string;
|
|
@@ -200,7 +141,7 @@ interface DataFiltersProps {
|
|
|
200
141
|
/** Expose the search input ref for keyboard nav "/" shortcut */
|
|
201
142
|
searchInputRef?: React.RefObject<HTMLInputElement | null>;
|
|
202
143
|
}
|
|
203
|
-
declare function DataFilters({ search, onSearchChange, searchPlaceholder, sort, onSortChange, sortOptions, filters, statusChips, savedViews, onLoadView, onSaveView, onDeleteView, canSaveViews, onViewSaved, onClearAll, searchInputRef, }: DataFiltersProps):
|
|
144
|
+
declare function DataFilters({ search, onSearchChange, searchPlaceholder, sort, onSortChange, sortOptions, filters, statusChips, savedViews, onLoadView, onSaveView, onDeleteView, canSaveViews, onViewSaved, onClearAll, searchInputRef, }: DataFiltersProps): React.JSX.Element;
|
|
204
145
|
|
|
205
146
|
interface DataGridProps<T> {
|
|
206
147
|
items: T[];
|
|
@@ -224,7 +165,7 @@ interface DataGridProps<T> {
|
|
|
224
165
|
/** Keyboard navigation: container ref for scroll management */
|
|
225
166
|
keyboardContainerRef?: RefObject<HTMLDivElement | null>;
|
|
226
167
|
}
|
|
227
|
-
declare function DataGrid<T>({ items, viewMode, batchSize, gridCols, renderCard, renderTable, renderListItem, staggerAnimation, getKey, focusedIndex, keyboardContainerRef, }: DataGridProps<T>):
|
|
168
|
+
declare function DataGrid<T>({ items, viewMode, batchSize, gridCols, renderCard, renderTable, renderListItem, staggerAnimation, getKey, focusedIndex, keyboardContainerRef, }: DataGridProps<T>): React.JSX.Element;
|
|
228
169
|
|
|
229
170
|
interface BulkAction {
|
|
230
171
|
label: string;
|
|
@@ -239,7 +180,7 @@ interface DataBulkBarProps {
|
|
|
239
180
|
onClearSelection: () => void;
|
|
240
181
|
actions: BulkAction[];
|
|
241
182
|
}
|
|
242
|
-
declare function DataBulkBar({ selected, totalCount, onToggleAll, onClearSelection, actions, }: DataBulkBarProps):
|
|
183
|
+
declare function DataBulkBar({ selected, totalCount, onToggleAll, onClearSelection, actions, }: DataBulkBarProps): React.JSX.Element | null;
|
|
243
184
|
|
|
244
185
|
/**
|
|
245
186
|
* DateCell -- shows relative date by default, formatted date otherwise.
|
|
@@ -260,25 +201,7 @@ declare function CurrencyCell(currency?: string, locale?: string): (_item: unkno
|
|
|
260
201
|
/**
|
|
261
202
|
* BadgeCell -- status badge with configurable color map.
|
|
262
203
|
*/
|
|
263
|
-
declare function BadgeCell(colorMap?: Record<string, "default" | "secondary" | "destructive" | "outline" | "success" | "warning" | "info" | "muted">): (_item: unknown, value: unknown) =>
|
|
264
|
-
|
|
265
|
-
interface EmptyStateProps {
|
|
266
|
-
icon?: LucideIcon;
|
|
267
|
-
message?: string;
|
|
268
|
-
action?: ReactNode;
|
|
269
|
-
/** If true, shows a "no results" message with clear button */
|
|
270
|
-
hasFilters?: boolean;
|
|
271
|
-
onClearFilters?: () => void;
|
|
272
|
-
}
|
|
273
|
-
declare function EmptyState({ icon: Icon, message, action, hasFilters, onClearFilters, }: EmptyStateProps): react_jsx_runtime.JSX.Element;
|
|
274
|
-
|
|
275
|
-
interface ViewSettingsProps {
|
|
276
|
-
pageSize: number;
|
|
277
|
-
onPageSizeChange: (size: number) => void;
|
|
278
|
-
density: Density;
|
|
279
|
-
onDensityChange: (density: Density) => void;
|
|
280
|
-
}
|
|
281
|
-
declare function ViewSettings({ pageSize, onPageSizeChange, density, onDensityChange, }: ViewSettingsProps): react_jsx_runtime.JSX.Element;
|
|
204
|
+
declare function BadgeCell(colorMap?: Record<string, "default" | "secondary" | "destructive" | "outline" | "success" | "warning" | "info" | "muted">): (_item: unknown, value: unknown) => React.JSX.Element | "—";
|
|
282
205
|
|
|
283
206
|
type StatCardColor = "primary" | "success" | "warning" | "info" | "destructive" | "muted";
|
|
284
207
|
interface StatCardProps {
|
|
@@ -300,7 +223,7 @@ interface StatCardProps {
|
|
|
300
223
|
};
|
|
301
224
|
className?: string;
|
|
302
225
|
}
|
|
303
|
-
declare function StatCard({ label, value, icon: Icon, color, href, linkComponent: Link, trend, className, }: StatCardProps):
|
|
226
|
+
declare function StatCard({ label, value, icon: Icon, color, href, linkComponent: Link, trend, className, }: StatCardProps): React.JSX.Element;
|
|
304
227
|
|
|
305
228
|
type ColumnStatus = "neutral" | "warning" | "success" | "info" | "destructive" | "primary";
|
|
306
229
|
interface KanbanColumn<T> {
|
|
@@ -320,7 +243,7 @@ interface KanbanBoardProps<T> {
|
|
|
320
243
|
emptyMessage?: string;
|
|
321
244
|
className?: string;
|
|
322
245
|
}
|
|
323
|
-
declare function KanbanBoard<T>({ columns, renderCard, emptyMessage, className, }: KanbanBoardProps<T>):
|
|
246
|
+
declare function KanbanBoard<T>({ columns, renderCard, emptyMessage, className, }: KanbanBoardProps<T>): React.JSX.Element;
|
|
324
247
|
|
|
325
248
|
interface DataListProps<T> {
|
|
326
249
|
items: T[];
|
|
@@ -328,8 +251,15 @@ interface DataListProps<T> {
|
|
|
328
251
|
emptyMessage?: string;
|
|
329
252
|
className?: string;
|
|
330
253
|
}
|
|
331
|
-
declare function DataList<T>({ items, renderItem, emptyMessage, className, }: DataListProps<T>):
|
|
254
|
+
declare function DataList<T>({ items, renderItem, emptyMessage, className, }: DataListProps<T>): React.JSX.Element;
|
|
332
255
|
|
|
256
|
+
/**
|
|
257
|
+
* Props for {@link DetailPanel} — a shell-agnostic record detail view.
|
|
258
|
+
* `layout` selects only the surrounding shell (inline / dialog / sheet);
|
|
259
|
+
* the header and content below it render identically across all three.
|
|
260
|
+
*
|
|
261
|
+
* @stability Beta
|
|
262
|
+
*/
|
|
333
263
|
interface DetailPanelProps<T> {
|
|
334
264
|
/** The record to display */
|
|
335
265
|
item: T | null;
|
|
@@ -353,17 +283,93 @@ interface DetailPanelProps<T> {
|
|
|
353
283
|
label: string;
|
|
354
284
|
render?: (value: unknown, item: T) => ReactNode;
|
|
355
285
|
}>;
|
|
356
|
-
/**
|
|
286
|
+
/**
|
|
287
|
+
* Panel width. For `"sheet"` / `"inline"` this is a fixed pixel width
|
|
288
|
+
* (matching this component's original, pre-`layout` sizing exactly). For
|
|
289
|
+
* `"dialog"` it maps to Tailwind's modal max-width scale instead, since a
|
|
290
|
+
* centered modal has a different sizing idiom than an edge-anchored panel.
|
|
291
|
+
*/
|
|
357
292
|
width?: "sm" | "md" | "lg";
|
|
293
|
+
/**
|
|
294
|
+
* Rendering shell for the header + content below.
|
|
295
|
+
* - `"sheet"` (default): fixed, right-anchored slide-in panel, composed
|
|
296
|
+
* from the shared `Sheet` primitive. Matches this component's original
|
|
297
|
+
* (pre-`layout`-prop) behavior — existing consumers that don't pass
|
|
298
|
+
* `layout` see no change, other than an overlay now present at all
|
|
299
|
+
* breakpoints (previously mobile-only) since it's a real `Sheet`.
|
|
300
|
+
* - `"dialog"`: centered modal overlay, composed from the shared `Dialog`
|
|
301
|
+
* primitive.
|
|
302
|
+
* - `"inline"`: plain in-flow panel — no overlay, backdrop, or fixed
|
|
303
|
+
* positioning — for master-detail / split-pane layouts.
|
|
304
|
+
*/
|
|
305
|
+
layout?: "inline" | "dialog" | "sheet";
|
|
358
306
|
}
|
|
359
|
-
declare function DetailPanel<T extends Record<string, unknown>>({ item, open, onClose, title, subtitle, onEdit, onDelete, children, fields, width, }: DetailPanelProps<T>):
|
|
307
|
+
declare function DetailPanel<T extends Record<string, unknown>>({ item, open, onClose, title, subtitle, onEdit, onDelete, children, fields, width, layout, }: DetailPanelProps<T>): React.JSX.Element | null;
|
|
360
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Row-bound actions handed to `renderCard`, on top of the resource-wide
|
|
311
|
+
* `ResourceActions`. `open` is per-row, which is why it lives here rather
|
|
312
|
+
* than on `ResourceActions` — that object is built once and shared by every
|
|
313
|
+
* row and column, so it cannot carry a row-specific callback.
|
|
314
|
+
*
|
|
315
|
+
* @stability Beta
|
|
316
|
+
*/
|
|
317
|
+
interface ResourceCardActions<T> extends ResourceActions<T> {
|
|
318
|
+
/**
|
|
319
|
+
* Activate this row — opens the configured detail panel / modal / route,
|
|
320
|
+
* exactly as clicking the built-in card does. Wire it to your card's
|
|
321
|
+
* `onClick` (and call `stopPropagation` on any nested control that should
|
|
322
|
+
* not also activate the row).
|
|
323
|
+
*/
|
|
324
|
+
open: () => void;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Config-driven resource page: wires data-fetching (or a pre-fetched `data`
|
|
328
|
+
* array), search/filter/sort, table/grid/list views, and a detail
|
|
329
|
+
* panel/modal/route around a `DataProvider` resource — the CRUD page most
|
|
330
|
+
* apps hand-roll, expressed as one component tree. `renderCard` lets a
|
|
331
|
+
* consumer fully own item presentation while ResourcePage keeps handling
|
|
332
|
+
* data-fetching, filtering, and layout; see also the built-in
|
|
333
|
+
* `useKeyboardNavigation` wiring (`keyboardNavigation` prop) and `gridCols`.
|
|
334
|
+
*
|
|
335
|
+
* Three levels of control, and each option is available at all three:
|
|
336
|
+
*
|
|
337
|
+
* 1. **The primitive offers it** — table / grid / list views, search, sort,
|
|
338
|
+
* status chips, column visibility and resizing, density, page size,
|
|
339
|
+
* detail panel / modal / route, built-in create and edit forms.
|
|
340
|
+
* 2. **The instance turns it on or off** — every one of those is a prop, so
|
|
341
|
+
* a given page decides which affordances it offers at all.
|
|
342
|
+
* 3. **The end user picks their own, and it sticks** — for the options left
|
|
343
|
+
* on at level 2, the user's choice persists to their own storage:
|
|
344
|
+
* `viewSettingsKey` for page size and density, `columnVisibilityKey` and
|
|
345
|
+
* `resizeKey` for column layout, `savedViews` (pair with `useSavedViews`)
|
|
346
|
+
* for named filter sets. Persistence needs a key; without one the choice
|
|
347
|
+
* lasts only for the session.
|
|
348
|
+
*
|
|
349
|
+
* A server-paginated list drives the same component through the controlled
|
|
350
|
+
* props (`page`, `perPage`, `onPageChange`, `onSortChange`, `onSearchChange`
|
|
351
|
+
* and friends) — supplying any of them stops ResourcePage from searching,
|
|
352
|
+
* sorting or paging the `data` a second time. See that block in
|
|
353
|
+
* {@link ResourcePageProps}.
|
|
354
|
+
*
|
|
355
|
+
* @stability Beta
|
|
356
|
+
*/
|
|
361
357
|
interface ResourcePageProps<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
362
358
|
/** Client-side mode: resource name passed to useResource / DataProvider. */
|
|
363
359
|
resource?: string;
|
|
364
360
|
/** Server-data mode: pre-fetched data array. */
|
|
365
361
|
data?: T[];
|
|
366
|
-
/**
|
|
362
|
+
/**
|
|
363
|
+
* Server-data mode: total record count (before client-side filtering).
|
|
364
|
+
*
|
|
365
|
+
* Required whenever `onPageChange` is supplied. It cannot be derived from
|
|
366
|
+
* `data`, which holds only the current page. Omitted, `displayTotal` falls
|
|
367
|
+
* back to `0`, so the range span reads "No records" and `Next` stays
|
|
368
|
+
* disabled while the rows render directly below it. Rather than show a
|
|
369
|
+
* pager that contradicts the list, the component refuses to render the
|
|
370
|
+
* pager and shows an error instead. See {@link perPage} and
|
|
371
|
+
* {@link onPageChange}.
|
|
372
|
+
*/
|
|
367
373
|
total?: number;
|
|
368
374
|
title: string;
|
|
369
375
|
/** Page subtitle shown below the title. */
|
|
@@ -381,6 +387,16 @@ interface ResourcePageProps<T extends Record<string, unknown> = Record<string, u
|
|
|
381
387
|
label: string;
|
|
382
388
|
render?: (value: unknown, item: T) => ReactNode;
|
|
383
389
|
}>;
|
|
390
|
+
/**
|
|
391
|
+
* Adds a status-chip filter. There is no dedicated status-change
|
|
392
|
+
* callback: chip clicks update the same filter state that already
|
|
393
|
+
* reports through `onFiltersChange`, whether or not the page is in
|
|
394
|
+
* server-controlled mode. A caller combining `statusFilter` with server
|
|
395
|
+
* pagination (`onPageChange` et al.) must supply `onFiltersChange` — see
|
|
396
|
+
* that prop — or status changes will update the chip UI without ever
|
|
397
|
+
* reaching the server. In server-controlled mode a status change also
|
|
398
|
+
* resets to page 1 via `onPageChange(1)` — see {@link onPageChange}.
|
|
399
|
+
*/
|
|
384
400
|
statusFilter?: string | {
|
|
385
401
|
field: string;
|
|
386
402
|
options?: string[];
|
|
@@ -389,6 +405,74 @@ interface ResourcePageProps<T extends Record<string, unknown> = Record<string, u
|
|
|
389
405
|
searchPlaceholder?: string;
|
|
390
406
|
initialFilters?: FilterParam[];
|
|
391
407
|
onFiltersChange?: (filters: FilterParam[]) => void;
|
|
408
|
+
/** Current page, 1-based. Server-controlled mode only. */
|
|
409
|
+
page?: number;
|
|
410
|
+
/**
|
|
411
|
+
* Rows per page the server was asked for. Required whenever
|
|
412
|
+
* `onPageChange` is supplied: pager math (total pages, range start, Next)
|
|
413
|
+
* cannot be inferred from `data.length`, because a short final page is
|
|
414
|
+
* smaller than the real page size. Wins over the per-user page size
|
|
415
|
+
* persisted by `viewSettingsKey` — an explicit prop always beats a stored
|
|
416
|
+
* preference.
|
|
417
|
+
*
|
|
418
|
+
* Required whenever `onPageChange` is supplied. A short final page (the
|
|
419
|
+
* server's last page returning fewer rows than its page size) is
|
|
420
|
+
* indistinguishable from a small page size — there is no correct way to
|
|
421
|
+
* infer the divisor from the rows handed back. Rather than guess and
|
|
422
|
+
* render a wrong range or a stuck Next button, the component refuses to
|
|
423
|
+
* render the pager and shows an error instead when `onPageChange` is
|
|
424
|
+
* present without `perPage`.
|
|
425
|
+
*
|
|
426
|
+
* `total` is required on the same terms — see {@link total}. The error
|
|
427
|
+
* names every missing prop, not just the first.
|
|
428
|
+
*/
|
|
429
|
+
perPage?: number;
|
|
430
|
+
/**
|
|
431
|
+
* Called with the next 1-based page number. The pager only renders when
|
|
432
|
+
* this is supplied AND both `perPage` and `total` are supplied — see
|
|
433
|
+
* {@link perPage} and {@link total}. Supplying this without either one
|
|
434
|
+
* renders an error naming the missing props instead of a pager.
|
|
435
|
+
*
|
|
436
|
+
* Status changes reach the server through `onFiltersChange` — not a
|
|
437
|
+
* dedicated callback here — because `statusFilter` state is tracked by
|
|
438
|
+
* the same filter machinery that already calls `onFiltersChange`
|
|
439
|
+
* regardless of controlled mode (see {@link statusFilter}). In
|
|
440
|
+
* server-controlled mode a status change also calls `onPageChange(1)`
|
|
441
|
+
* directly, since the previous page number is meaningless against a new
|
|
442
|
+
* filtered result set.
|
|
443
|
+
*/
|
|
444
|
+
onPageChange?: (page: number) => void;
|
|
445
|
+
/** Called when the user picks a different page size in the header's view settings. */
|
|
446
|
+
onPerPageChange?: (perPage: number) => void;
|
|
447
|
+
/** Called when the user changes the sort, with `null` when the sort is cleared. */
|
|
448
|
+
onSortChange?: (sort: SortParam | null) => void;
|
|
449
|
+
/** Called when the user changes the search text (including clearing it). */
|
|
450
|
+
onSearchChange?: (search: string) => void;
|
|
451
|
+
/** Saved filter views to offer. Pair with `useSavedViews` for per-user storage. */
|
|
452
|
+
savedViews?: SavedViewItem[];
|
|
453
|
+
onLoadView?: (filters: Record<string, unknown>) => void;
|
|
454
|
+
onSaveView?: (name: string) => void;
|
|
455
|
+
onDeleteView?: (id: string) => void;
|
|
456
|
+
/** Show the "save current view" affordance. */
|
|
457
|
+
canSaveViews?: boolean;
|
|
458
|
+
/** Show the column-visibility dropdown. DataTable's default is `true`. */
|
|
459
|
+
columnVisibility?: boolean;
|
|
460
|
+
/** Persist key for the user's column-visibility picks. */
|
|
461
|
+
columnVisibilityKey?: string;
|
|
462
|
+
/** Allow drag-resizing columns. DataTable's default is `true`. */
|
|
463
|
+
resizableColumns?: boolean;
|
|
464
|
+
/** Persist key for the user's column widths. */
|
|
465
|
+
resizeKey?: string;
|
|
466
|
+
/** Keep the table header visible while scrolling. DataTable's default is `true`. */
|
|
467
|
+
stickyHeader?: boolean;
|
|
468
|
+
/** Keep the first column visible while scrolling horizontally. */
|
|
469
|
+
stickyFirstColumn?: boolean;
|
|
470
|
+
/**
|
|
471
|
+
* Page-size choices offered by `DataTable`'s own pager. Client-side mode
|
|
472
|
+
* only — server-controlled mode switches that pager off. (The header's
|
|
473
|
+
* view-settings popover has its own fixed 10/25/50/100 list.)
|
|
474
|
+
*/
|
|
475
|
+
pageSizeOptions?: number[];
|
|
392
476
|
onCreate?: () => void;
|
|
393
477
|
onEdit?: (item: T) => void;
|
|
394
478
|
onDelete?: (item: T) => void;
|
|
@@ -413,6 +497,46 @@ interface ResourcePageProps<T extends Record<string, unknown> = Record<string, u
|
|
|
413
497
|
variant?: "default" | "destructive";
|
|
414
498
|
onAction: (ids: string[]) => void | Promise<void>;
|
|
415
499
|
}>;
|
|
500
|
+
/**
|
|
501
|
+
* Override the default card renderer used for grid view (and, absent a
|
|
502
|
+
* dedicated list layout, list view too — DataGrid falls back to the same
|
|
503
|
+
* renderer there). ResourcePage still owns data-fetching, filtering,
|
|
504
|
+
* sorting, and layout (grid columns, infinite-scroll batching, stagger
|
|
505
|
+
* animation) — this only swaps what's rendered inside each item slot.
|
|
506
|
+
*
|
|
507
|
+
* Receives `ResourceCardActions`: the row's `update`/`remove`/`refetch`
|
|
508
|
+
* plus `open()` to activate the row (opening the configured detail
|
|
509
|
+
* panel/modal/route). Row activation is *not* applied automatically to a
|
|
510
|
+
* custom card — wrapping it would double-fire against cards that bring
|
|
511
|
+
* their own click handling and would hijack clicks on nested buttons — so
|
|
512
|
+
* call `actions.open()` from wherever your card should activate.
|
|
513
|
+
*/
|
|
514
|
+
renderCard?: (item: T, index: number, actions: ResourceCardActions<T>) => ReactNode;
|
|
515
|
+
/**
|
|
516
|
+
* Tailwind grid-column classes for the card grid, passed through to
|
|
517
|
+
* `DataGrid`'s `gridCols` — e.g. `"grid-cols-1 sm:grid-cols-2 lg:grid-cols-3"`.
|
|
518
|
+
* Defaults to DataGrid's own responsive 1/2/3/4-column ramp.
|
|
519
|
+
*/
|
|
520
|
+
gridCols?: string;
|
|
521
|
+
/**
|
|
522
|
+
* Built-in list keyboard navigation via `useKeyboardNavigation`: j/k (or
|
|
523
|
+
* Arrow Up/Down) move a focus cursor, Enter opens the focused item,
|
|
524
|
+
* Backspace (⌫) closes an open detail view, and x toggles the focused
|
|
525
|
+
* item's selection when `bulkActions` are configured. Set to `false` to
|
|
526
|
+
* opt out.
|
|
527
|
+
*
|
|
528
|
+
* Default-on, and scoped so that being on by default stays safe:
|
|
529
|
+
* - Only while the grid or list view is showing. Table view keeps its own
|
|
530
|
+
* independent sort/pagination, so a flat focus index can't reliably map
|
|
531
|
+
* onto its visible rows.
|
|
532
|
+
* - Cursor keys suspend while a detail panel/modal or the built-in form
|
|
533
|
+
* is open, so they can't drive the list behind the overlay; ⌫ stays
|
|
534
|
+
* live there so it can close it.
|
|
535
|
+
* - Backspace is only intercepted while there's an open detail to close.
|
|
536
|
+
* - Modified chords (Ctrl/Cmd/Alt) are never captured, so an app's
|
|
537
|
+
* Cmd+K-style shortcuts keep working.
|
|
538
|
+
*/
|
|
539
|
+
keyboardNavigation?: boolean;
|
|
416
540
|
toolbar?: ReactNode;
|
|
417
541
|
emptyState?: ReactNode;
|
|
418
542
|
/**
|
|
@@ -430,7 +554,86 @@ interface ResourcePageProps<T extends Record<string, unknown> = Record<string, u
|
|
|
430
554
|
*/
|
|
431
555
|
viewSettingsKey?: string;
|
|
432
556
|
}
|
|
433
|
-
declare function ResourcePage<T extends Record<string, unknown> = Record<string, unknown>>(props: ResourcePageProps<T>):
|
|
557
|
+
declare function ResourcePage<T extends Record<string, unknown> = Record<string, unknown>>(props: ResourcePageProps<T>): React.JSX.Element;
|
|
558
|
+
|
|
559
|
+
interface ResourceDetailPageProps<T extends BaseRecord = BaseRecord> {
|
|
560
|
+
/** Resource name, resolved through the mounted `DataProvider`. */
|
|
561
|
+
resource: string;
|
|
562
|
+
/**
|
|
563
|
+
* Record id. Nullish means "not resolved yet" — no request goes out and the
|
|
564
|
+
* page shows its loading state, which is what a route param that hasn't
|
|
565
|
+
* arrived should look like. It is deliberately NOT the not-found state:
|
|
566
|
+
* nothing has been asked, so nothing is missing.
|
|
567
|
+
*/
|
|
568
|
+
id: Identifier | undefined | null;
|
|
569
|
+
/**
|
|
570
|
+
* Field used as the page title. Defaults to `name`, then `title`, then the
|
|
571
|
+
* id — the same fallback chain `ResourcePage` uses for a row's label.
|
|
572
|
+
*/
|
|
573
|
+
titleField?: string;
|
|
574
|
+
/** Field used as the line under the title. */
|
|
575
|
+
subtitleField?: string;
|
|
576
|
+
/** Provider select/join syntax, e.g. `"*, owner:profiles(name)"`. */
|
|
577
|
+
select?: string;
|
|
578
|
+
/** Slot above the title: a `Breadcrumb`, a back link, a `StatusBadge`. */
|
|
579
|
+
breadcrumb?: ReactNode;
|
|
580
|
+
/** Record-scoped controls, built from the loaded record. */
|
|
581
|
+
actions?: (record: T) => ReactNode;
|
|
582
|
+
/** Metadata column, built from the loaded record. */
|
|
583
|
+
sidebar?: (record: T) => ReactNode;
|
|
584
|
+
/** The primary content region. */
|
|
585
|
+
children: (record: T) => ReactNode;
|
|
586
|
+
className?: string;
|
|
587
|
+
/** Stable test/automation selector (emitted as `data-testid`). */
|
|
588
|
+
testID?: string;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* ResourceDetailPage — `DetailPage` with a record bound to it: fetches one
|
|
592
|
+
* record by id through the mounted `DataProvider` and hands it to the title,
|
|
593
|
+
* the actions, the sidebar and the content.
|
|
594
|
+
*
|
|
595
|
+
* ```tsx
|
|
596
|
+
* <ResourceDetailPage
|
|
597
|
+
* resource="people"
|
|
598
|
+
* id={params.id}
|
|
599
|
+
* subtitleField="role"
|
|
600
|
+
* actions={(person) => <Button testID="edit">Edit {person.name}</Button>}
|
|
601
|
+
* sidebar={(person) => <StatCard label="Sessions" value={person.session_count} />}
|
|
602
|
+
* >
|
|
603
|
+
* {(person) => <Section title="Timeline"><Timeline personId={person.id} /></Section>}
|
|
604
|
+
* </ResourceDetailPage>
|
|
605
|
+
* ```
|
|
606
|
+
*
|
|
607
|
+
* This is the detail-route counterpart to `ResourcePage`, which is the list
|
|
608
|
+
* one. Both are **data-bound**, not layouts: they need a resource contract
|
|
609
|
+
* to be useful, which is the layers table's admission test for this tier.
|
|
610
|
+
* The structure they render is a layout and lives one layer down —
|
|
611
|
+
* `DetailPage` in `@marktiderman/genesis-ui/layout` — so an app with its own
|
|
612
|
+
* fetching keeps the page shape without inheriting the provider. That
|
|
613
|
+
* layout/data-bound pairing is the same one `AppShell` and `ResourcePage`
|
|
614
|
+
* already have.
|
|
615
|
+
*
|
|
616
|
+
* The three non-record states are rendered here rather than left to the
|
|
617
|
+
* caller, because a per-app "loading…" is exactly the hand-written code a
|
|
618
|
+
* template exists to remove:
|
|
619
|
+
* - loading, or no id yet -> `PageLoading`
|
|
620
|
+
* - absent -> `EmptyState` saying so, distinct from the error state, since a
|
|
621
|
+
* deleted record and a broken query need different words. Every provider
|
|
622
|
+
* Genesis ships signals "no such row" by throwing rather than by resolving
|
|
623
|
+
* empty, so this state is reached by classifying the error (see
|
|
624
|
+
* `isNotFoundError`) as well as by a falsy `data`
|
|
625
|
+
* - any other failure -> `EmptyState` carrying the provider's message, which
|
|
626
|
+
* is kept verbatim: an error state that hides what went wrong is the one
|
|
627
|
+
* nobody can act on
|
|
628
|
+
*
|
|
629
|
+
* `titleField` is exact: name a field and you get that field, empty string
|
|
630
|
+
* included. The `name` -> `title` -> id chain is the DEFAULT, not a fallback
|
|
631
|
+
* layered under an explicit choice — a page silently titled by a different
|
|
632
|
+
* column than the one asked for is worse than a blank one.
|
|
633
|
+
*
|
|
634
|
+
* @stability Beta
|
|
635
|
+
*/
|
|
636
|
+
declare function ResourceDetailPage<T extends BaseRecord = BaseRecord>({ resource, id, titleField, subtitleField, select, breadcrumb, actions, sidebar, children, className, testID, }: ResourceDetailPageProps<T>): React.JSX.Element;
|
|
434
637
|
|
|
435
638
|
interface ResourceFormProps {
|
|
436
639
|
resource: string;
|
|
@@ -454,7 +657,7 @@ interface ResourceFormProps {
|
|
|
454
657
|
/** Number of columns for the form layout. Default 1. */
|
|
455
658
|
columns?: 1 | 2;
|
|
456
659
|
}
|
|
457
|
-
declare function ResourceForm(props: ResourceFormProps):
|
|
660
|
+
declare function ResourceForm(props: ResourceFormProps): React.JSX.Element | null;
|
|
458
661
|
|
|
459
662
|
interface RelationFieldProps {
|
|
460
663
|
field: ResourceFormFieldDef;
|
|
@@ -462,7 +665,7 @@ interface RelationFieldProps {
|
|
|
462
665
|
onChange: (value: string) => void;
|
|
463
666
|
disabled?: boolean;
|
|
464
667
|
}
|
|
465
|
-
declare function RelationField({ field, value, onChange, disabled, }: RelationFieldProps):
|
|
668
|
+
declare function RelationField({ field, value, onChange, disabled, }: RelationFieldProps): React.JSX.Element;
|
|
466
669
|
|
|
467
670
|
interface FileUploadFieldProps {
|
|
468
671
|
field: ResourceFormFieldDef;
|
|
@@ -470,14 +673,14 @@ interface FileUploadFieldProps {
|
|
|
470
673
|
onChange: (value: File | File[] | null) => void;
|
|
471
674
|
disabled?: boolean;
|
|
472
675
|
}
|
|
473
|
-
declare function FileUploadField({ field, value, onChange, disabled, }: FileUploadFieldProps):
|
|
676
|
+
declare function FileUploadField({ field, value, onChange, disabled, }: FileUploadFieldProps): React.JSX.Element;
|
|
474
677
|
|
|
475
678
|
declare function FieldArrayRenderer({ field, control, action, watchedValues, }: {
|
|
476
679
|
field: ResourceFormFieldDef;
|
|
477
680
|
control: Control<Record<string, unknown>>;
|
|
478
681
|
action: "create" | "edit";
|
|
479
682
|
watchedValues?: Record<string, unknown>;
|
|
480
|
-
}):
|
|
683
|
+
}): React.JSX.Element;
|
|
481
684
|
|
|
482
685
|
interface WizardFormProps {
|
|
483
686
|
steps: WizardStep[];
|
|
@@ -489,134 +692,21 @@ interface WizardFormProps {
|
|
|
489
692
|
action: "create" | "edit";
|
|
490
693
|
onInvalid?: (errors: FieldErrors) => void;
|
|
491
694
|
}
|
|
492
|
-
declare function WizardForm({ steps, form, fields, onSubmit, isSaving, renderField, action, onInvalid, }: WizardFormProps):
|
|
695
|
+
declare function WizardForm({ steps, form, fields, onSubmit, isSaving, renderField, action, onInvalid, }: WizardFormProps): React.JSX.Element;
|
|
493
696
|
|
|
494
|
-
interface NavItem {
|
|
495
|
-
to: string;
|
|
496
|
-
icon: LucideIcon;
|
|
497
|
-
label: string;
|
|
498
|
-
/** Nested items — rendered as a collapsible group when the rail is expanded */
|
|
499
|
-
children?: NavItem[];
|
|
500
|
-
badge?: string | number;
|
|
501
|
-
disabled?: boolean;
|
|
502
|
-
/** Exact-match active state (e.g. overview `/`) */
|
|
503
|
-
end?: boolean;
|
|
504
|
-
}
|
|
505
697
|
/**
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
* @stability
|
|
698
|
+
* @deprecated Import `AppShell` from `@marktiderman/genesis-ui/layout` instead.
|
|
699
|
+
* `AppShell` is a layout, not a data-bound component. This `/data` alias is
|
|
700
|
+
* removed in the next major — see docs/FRAMEWORK.md rule 5.
|
|
701
|
+
* @stability Deprecated
|
|
510
702
|
*/
|
|
511
|
-
|
|
512
|
-
showLogo?: boolean;
|
|
513
|
-
showAppName?: boolean;
|
|
514
|
-
showThemeToggle?: boolean;
|
|
515
|
-
/** Desktop rail collapse control */
|
|
516
|
-
showCollapse?: boolean;
|
|
517
|
-
showUserSlot?: boolean;
|
|
518
|
-
showFooter?: boolean;
|
|
519
|
-
showSecondaryNav?: boolean;
|
|
520
|
-
/** Mobile fixed bottom tab bar */
|
|
521
|
-
showMobileBottomNav?: boolean;
|
|
522
|
-
defaultCollapsed?: boolean;
|
|
523
|
-
/**
|
|
524
|
-
* Show the in-sidebar Sidebar options popover so users can customize chrome.
|
|
525
|
-
* Default true when collapse / secondary / theme / slots are available.
|
|
526
|
-
*/
|
|
527
|
-
configurable?: boolean;
|
|
528
|
-
/**
|
|
529
|
-
* Toggle keys the developer has decided on and users may not override —
|
|
530
|
-
* e.g. hiding `showThemeToggle` for a brand that manages theme elsewhere.
|
|
531
|
-
* Locked keys are dropped from the options popover and any stored user
|
|
532
|
-
* override for them is ignored on resolve.
|
|
533
|
-
*/
|
|
534
|
-
lockedOptions?: (keyof AppShellOptions)[];
|
|
535
|
-
/** Comfortable (default) vs compact row padding */
|
|
536
|
-
density?: "comfortable" | "compact";
|
|
537
|
-
/** Expanded rail width in rem-ish tokens: narrow ≈ 13rem, wide ≈ 16rem */
|
|
538
|
-
railWidth?: "narrow" | "wide";
|
|
539
|
-
/**
|
|
540
|
-
* Where page content scrolls.
|
|
541
|
-
* - `container` (default): main panel scrolls — classic app-shell chrome.
|
|
542
|
-
* - `window`: document/window scrolls with a sticky rail so React Router
|
|
543
|
-
* `ScrollRestoration` keeps working (dashboard dogfood).
|
|
544
|
-
*/
|
|
545
|
-
scrollRoot?: "container" | "window";
|
|
546
|
-
}
|
|
703
|
+
declare const AppShell: typeof AppShell$1;
|
|
547
704
|
/**
|
|
548
|
-
* @
|
|
705
|
+
* @deprecated Import `PageHeader` from `@marktiderman/genesis-ui/layout`
|
|
706
|
+
* instead. `PageHeader` is a layout, not a data-bound component. This `/data`
|
|
707
|
+
* alias is removed in the next major — see docs/FRAMEWORK.md rule 5.
|
|
708
|
+
* @stability Deprecated
|
|
549
709
|
*/
|
|
550
|
-
|
|
551
|
-
/** App name shown in sidebar header */
|
|
552
|
-
appName: string;
|
|
553
|
-
/** App logo letter or short text (ignored when `logo` is set) */
|
|
554
|
-
appLogo?: string;
|
|
555
|
-
/** Custom logo node — preferred over `appLogo` letter tile */
|
|
556
|
-
logo?: ReactNode;
|
|
557
|
-
/** Primary navigation items */
|
|
558
|
-
navItems: NavItem[];
|
|
559
|
-
/** Secondary nav (e.g. “More”) — rendered below a divider when shown */
|
|
560
|
-
secondaryNavItems?: NavItem[];
|
|
561
|
-
/** Label above secondary nav (default “More”) */
|
|
562
|
-
secondaryNavLabel?: string;
|
|
563
|
-
/**
|
|
564
|
-
* Items for the mobile bottom tab bar. Defaults to top-level `navItems`
|
|
565
|
-
* (no children). Pass a short list for apps with large sidebars; pass `[]`
|
|
566
|
-
* and set `options.showMobileBottomNav: false` to hide.
|
|
567
|
-
*/
|
|
568
|
-
mobileNavItems?: NavItem[];
|
|
569
|
-
/** Slot below the logo row (product switcher, workspace picker, …) */
|
|
570
|
-
headerSlot?: ReactNode;
|
|
571
|
-
/**
|
|
572
|
-
* Compact slot shown in the **collapsed** desktop rail, where `headerSlot`
|
|
573
|
-
* is hidden for space. Use it to keep a core affordance reachable without
|
|
574
|
-
* expanding — e.g. an icon-only product switcher. Omit to hide the header
|
|
575
|
-
* region entirely while collapsed.
|
|
576
|
-
*/
|
|
577
|
-
collapsedHeaderSlot?: ReactNode;
|
|
578
|
-
/** Footer region above the user slot (version, links) */
|
|
579
|
-
footer?: ReactNode;
|
|
580
|
-
/**
|
|
581
|
-
* User / account block at the bottom of the sidebar. When the rail is
|
|
582
|
-
* collapsed, AppShell hides any descendant carrying the
|
|
583
|
-
* `data-shell-user-detail` attribute (e.g. name/email text) so only a
|
|
584
|
-
* compact element (avatar, initial) remains — tag the detail wrapper you
|
|
585
|
-
* want hidden in the collapsed rail with that attribute.
|
|
586
|
-
*/
|
|
587
|
-
userSlot?: ReactNode;
|
|
588
|
-
/** Page content */
|
|
589
|
-
children: ReactNode;
|
|
590
|
-
/**
|
|
591
|
-
* @deprecated Prefer `options.showThemeToggle`. Kept for sample-app
|
|
592
|
-
* back-compat; merges into resolved options when `options` omits it.
|
|
593
|
-
*/
|
|
594
|
-
showThemeToggle?: boolean;
|
|
595
|
-
/** Chrome config (developer defaults + optional in-sidebar menu) */
|
|
596
|
-
options?: AppShellOptions;
|
|
597
|
-
/** Persist user sidebar-option overrides + collapse state (localStorage) */
|
|
598
|
-
optionsStorageKey?: string;
|
|
599
|
-
/** Controlled collapse (desktop rail) */
|
|
600
|
-
collapsed?: boolean;
|
|
601
|
-
onCollapsedChange?: (collapsed: boolean) => void;
|
|
602
|
-
/**
|
|
603
|
-
* Injectable link component. Defaults to a plain `<a>` (no router). Pass a
|
|
604
|
-
* router adapter — e.g. React Router `({ href, ...p }) => <Link to={href} {...p} />`
|
|
605
|
-
* or Next.js `next/link` — to get client-side navigation.
|
|
606
|
-
*/
|
|
607
|
-
linkComponent?: LinkComponent;
|
|
608
|
-
/**
|
|
609
|
-
* Current path used to highlight the active nav item. Router consumers pass
|
|
610
|
-
* `useLocation().pathname` (RR) or `usePathname()` (Next). Omit to disable
|
|
611
|
-
* active highlighting.
|
|
612
|
-
*/
|
|
613
|
-
activePath?: string;
|
|
614
|
-
/**
|
|
615
|
-
* Optional custom active-state matcher. Defaults to a prefix match (with `/`
|
|
616
|
-
* treated as exact), mirroring React Router `NavLink`.
|
|
617
|
-
*/
|
|
618
|
-
isActive?: (to: string, activePath?: string) => boolean;
|
|
619
|
-
}
|
|
620
|
-
declare function AppShell({ appName, appLogo, logo, navItems, secondaryNavItems, secondaryNavLabel, mobileNavItems, headerSlot, collapsedHeaderSlot, footer, userSlot, children, showThemeToggle: showThemeToggleProp, options: optionsProp, optionsStorageKey, collapsed: collapsedProp, onCollapsedChange, linkComponent, activePath, isActive, }: AppShellProps): react_jsx_runtime.JSX.Element;
|
|
710
|
+
declare const PageHeader: typeof PageHeader$1;
|
|
621
711
|
|
|
622
|
-
export { AppShell,
|
|
712
|
+
export { AppShell, BadgeCell, type BulkAction, type ColumnStatus, CurrencyCell, DataBulkBar, type DataFilterConfig, DataFilters, DataGrid, DataList, type DataListProps, DataPageShell, type DataPageShellProps, DateCell, Density, DetailPanel, type DetailPanelProps, FieldArrayRenderer, FileUploadField, FilterCombobox, type FilterOption, KanbanBoard, type KanbanBoardProps, type KanbanColumn, LinkComponent, NavigateFn, NumberCell, PageHeader, PageHeaderOptions, RelationField, ResourceActions, type ResourceCardActions, ResourceColumnDef, ResourceDetailPage, type ResourceDetailPageProps, ResourceForm, type ResourceFormProps, ResourcePage, type ResourcePageProps, type SavedViewItem, StatCard, type StatCardColor, type StatCardProps, ViewMode, WizardForm };
|