@marktiderman/genesis-ui 2.4.0 → 2.6.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/data/DataPageShell.tsx","../../../src/components/data/FilterCombobox.tsx","../../../src/components/data/DataFilters.tsx","../../../src/components/data/DataGrid.tsx","../../../src/components/data/DataTable.tsx","../../../src/components/data/DataBulkBar.tsx","../../../src/components/data/cell-formatters.tsx","../../../src/components/data/StatCard.tsx","../../../src/components/data/KanbanBoard.tsx","../../../src/components/data/DataList.tsx","../../../src/components/data/DetailPanel.tsx","../../../src/components/data/RelationField.tsx","../../../src/components/data/FileUploadField.tsx","../../../src/components/data/FieldArrayRenderer.tsx","../../../src/components/data/ResourceFormField.tsx","../../../src/components/data/WizardForm.tsx","../../../src/components/data/ResourceForm.tsx","../../../src/components/data/ResourcePage.tsx","../../../src/components/data/ResourceDetailPage.tsx","../../../src/components/data/index.ts"],"names":["jsxs","jsx","useState","ChevronDown","Fragment","useRef","useEffect","ArrowUpDown","colorMap","Trash2","X","Loader2","Check","useMemo","useCallback","useWatch","useResource","AlertTriangle","ChevronLeft","ChevronRight","AppShell","PageHeader"],"mappings":"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","file":"index.js","sourcesContent":["import type { ComponentProps, ComponentType, ReactNode } from \"react\";\nimport { cn } from \"../../utils\";\nimport { Button } from \"../ui/button\";\nimport { Skeleton } from \"../ui/skeleton\";\nimport { EmptyState } from \"./EmptyState\";\nimport {\n PageHeader,\n type PageHeaderOptions,\n type PageHeaderAction,\n} from \"../layout/PageHeader\";\nimport type { ViewMode } from \"../patterns/view-toggle\";\nimport { AlertTriangle, RefreshCw } from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport type { Density } from \"../../hooks/use-view-settings\";\n\nexport interface DataPageShellProps {\n /** Display title for the page */\n title: string;\n icon?: LucideIcon;\n /** Singular entity name for generated text, e.g. \"session\" */\n entityName?: string;\n /** Subtitle text */\n subtitle?: string;\n createAction?: ReactNode;\n /** Extra actions, rendered in the header's one overflow menu. */\n secondaryActions?: PageHeaderAction[];\n isLoading?: boolean;\n isEmpty?: boolean;\n emptyIcon?: LucideIcon;\n emptyMessage?: string;\n emptyAction?: ReactNode;\n /** Error state */\n hasError?: boolean;\n errorMessage?: string;\n onRetry?: () => void;\n /** Number of filtered/visible items */\n count?: number;\n /** Total items before filtering */\n totalCount?: number;\n viewMode?: ViewMode;\n onViewModeChange?: (mode: ViewMode) => void;\n /** View settings */\n pageSize?: number;\n onPageSizeChange?: (size: number) => void;\n density?: Density;\n onDensityChange?: (density: Density) => void;\n /**\n * Slot for a stat cards row. Forwarded to the header, which renders it\n * full width under the title block and above the filters — but only when\n * `headerOptions.showStats` is on (default off), so a page that gains\n * `stats` shows nothing new until the developer or user opts in.\n */\n stats?: ReactNode;\n /** Slot for filter bar */\n filters?: ReactNode;\n /** Whether filters are currently active */\n hasActiveFilters?: boolean;\n onClearFilters?: () => void;\n /**\n * When true, filters render inside PageHeader details (collapsed by default).\n * Default false preserves always-visible filters on existing boards.\n */\n filtersCollapsible?: boolean;\n defaultFiltersOpen?: boolean;\n filtersOpen?: boolean;\n onFiltersOpenChange?: (open: boolean) => void;\n filtersLabel?: string;\n filtersHint?: ReactNode;\n /**\n * PageHeader chrome config — developer defaults; users can further\n * customize via the in-header Header options menu.\n */\n headerOptions?: PageHeaderOptions;\n /** Persist user header-option overrides (localStorage) */\n headerOptionsStorageKey?: string;\n children: ReactNode;\n /** Merged onto the root, not replacing its layout. */\n className?: string;\n /**\n * Replace the header outright. It receives exactly the props\n * `DataPageShell` would have given `PageHeader`, so the common case is a\n * wrapper that renders `PageHeader` with one thing added — an overflow\n * menu, a status strip, a second row — rather than a reimplementation.\n *\n * `null` ejects it: shell layout, states and filter row, no header.\n */\n header?: ComponentType<ComponentProps<typeof PageHeader>> | null;\n}\n\nexport function DataPageShell({\n title,\n icon,\n entityName,\n subtitle,\n createAction,\n secondaryActions,\n isLoading = false,\n isEmpty = false,\n emptyIcon,\n emptyMessage,\n emptyAction,\n hasError = false,\n errorMessage,\n onRetry,\n count,\n totalCount,\n viewMode,\n onViewModeChange,\n pageSize,\n onPageSizeChange,\n density,\n onDensityChange,\n stats,\n filters,\n hasActiveFilters = false,\n onClearFilters,\n filtersCollapsible = false,\n defaultFiltersOpen = false,\n filtersOpen,\n onFiltersOpenChange,\n filtersLabel,\n filtersHint,\n headerOptions,\n headerOptionsStorageKey,\n children,\n className,\n header,\n}: DataPageShellProps) {\n const entity = entityName || title.toLowerCase();\n // `header === null` ejects the header, and the doc on `header` promises the\n // filter row survives that. It only does in the standard branch, where\n // `filters` renders as an independent sibling. In the collapsible branch the\n // filter row reaches the DOM ONLY as the header's `details` prop, so an\n // ejected header takes the filters down with it — silently, which is the\n // worst version. Collapsing needs a header to collapse INTO; without one we\n // fall through to the standard branch and the filter row renders on its own.\n const collapseFilters =\n filtersCollapsible && filters != null && header !== null;\n\n const mergedOptions: PageHeaderOptions = {\n defaultDetailsOpen: defaultFiltersOpen,\n detailsLabel: filtersLabel,\n subtitleInDetails: collapseFilters ? true : undefined,\n ...headerOptions,\n };\n\n const sharedHeaderProps = {\n title,\n subtitle,\n icon,\n entityName: entity,\n count,\n totalCount,\n countActive: hasActiveFilters,\n viewMode,\n onViewModeChange,\n pageSize,\n onPageSizeChange,\n density,\n onDensityChange,\n createAction,\n secondaryActions,\n stats,\n optionsStorageKey: headerOptionsStorageKey,\n };\n\n const Header =\n header === null ? (() => null) : (header ?? PageHeader);\n\n return (\n <div className={cn(\"space-y-6\", className)}>\n {collapseFilters ? (\n <Header\n {...sharedHeaderProps}\n details={filters}\n detailsOpen={filtersOpen}\n onDetailsOpenChange={onFiltersOpenChange}\n detailsActive={hasActiveFilters}\n detailsHint={filtersHint}\n options={mergedOptions}\n />\n ) : (\n <>\n <Header {...sharedHeaderProps} options={headerOptions} />\n {filters}\n </>\n )}\n\n {/* Content */}\n {isLoading ? (\n <div\n data-testid=\"page-loader\"\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4\"\n >\n {Array.from({ length: 8 }).map((_, i) => (\n <Skeleton\n key={i}\n className=\"h-40 rounded-xl\"\n style={{ animationDelay: `${i * 75}ms` }}\n />\n ))}\n </div>\n ) : hasError ? (\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <AlertTriangle className=\"h-10 w-10 text-destructive mb-3\" />\n <p className=\"mb-1 text-sm font-medium text-foreground\">\n Something went wrong\n </p>\n <p className=\"mb-4 text-sm text-muted-foreground\">\n {errorMessage || `Failed to load ${entity}s. Please try again.`}\n </p>\n {onRetry && (\n <Button variant=\"outline\" size=\"sm\" onClick={onRetry}>\n <RefreshCw className=\"mr-1 h-4 w-4\" /> Retry\n </Button>\n )}\n </div>\n ) : isEmpty ? (\n <EmptyState\n icon={emptyIcon}\n title={emptyMessage}\n action={emptyAction}\n hasFilters={hasActiveFilters}\n onClearFilters={onClearFilters}\n />\n ) : (\n children\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../ui/popover\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"../ui/command\";\nimport { Button } from \"../ui/button\";\nimport { Check, ChevronDown } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport type { LucideIcon } from \"lucide-react\";\n\nexport interface FilterOption {\n value: string;\n label?: string;\n count?: number;\n}\n\ninterface FilterComboboxProps {\n label: string;\n icon: LucideIcon;\n options: FilterOption[];\n selected: string[];\n onChange: (selected: string[]) => void;\n searchPlaceholder?: string;\n allLabel?: string;\n /** Optional map of value -> display label */\n labelMap?: Record<string, string>;\n}\n\nexport function FilterCombobox({\n label,\n icon: Icon,\n options,\n selected,\n onChange,\n searchPlaceholder,\n allLabel,\n labelMap,\n}: FilterComboboxProps) {\n const [open, setOpen] = useState(false);\n\n const toggle = (value: string) => {\n onChange(\n selected.includes(value)\n ? selected.filter((v) => v !== value)\n : [...selected, value],\n );\n };\n\n const getDisplayLabel = (value: string) => labelMap?.[value] || value;\n\n const triggerLabel =\n selected.length === 0\n ? allLabel || `All ${label}`\n : selected.length === 1\n ? getDisplayLabel(selected[0])\n : `${selected.length} ${label.toLowerCase()}`;\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant={selected.length > 0 ? \"default\" : \"outline\"}\n size=\"sm\"\n className=\"text-xs h-7 gap-1.5\"\n >\n <Icon className=\"h-3 w-3\" />\n {triggerLabel}\n <ChevronDown className=\"h-3 w-3 ml-0.5 opacity-60\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-[220px] max-w-[calc(100vw-2rem)] p-0 bg-popover z-50\"\n align=\"start\"\n >\n <Command>\n <CommandInput\n placeholder={searchPlaceholder || `Search ${label.toLowerCase()}...`}\n />\n <CommandList>\n <CommandEmpty>No {label.toLowerCase()} found.</CommandEmpty>\n <CommandGroup>\n <CommandItem\n value={`__all_${label.toLowerCase()}__`}\n onSelect={() => onChange([])}\n >\n <Check\n className={cn(\n \"mr-2 h-3.5 w-3.5\",\n selected.length === 0 ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n {allLabel || `All ${label}`}\n </CommandItem>\n {options.map((opt) => (\n <CommandItem\n key={opt.value}\n value={opt.label || getDisplayLabel(opt.value)}\n onSelect={() => toggle(opt.value)}\n >\n <Check\n className={cn(\n \"mr-2 h-3.5 w-3.5\",\n selected.includes(opt.value)\n ? \"opacity-100\"\n : \"opacity-0\",\n )}\n />\n <span className=\"flex-1\">\n {opt.label || getDisplayLabel(opt.value)}\n </span>\n {opt.count !== undefined && (\n <span className=\"text-[10px] text-muted-foreground ml-2\">\n {opt.count}\n </span>\n )}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { useState, useRef } from \"react\";\nimport { Input } from \"../ui/input\";\nimport { Button } from \"../ui/button\";\nimport { Badge } from \"../ui/badge\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../ui/select\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from \"../ui/dialog\";\nimport {\n Search,\n X,\n ArrowUpDown,\n Bookmark,\n BookmarkPlus,\n Trash2,\n ChevronDown,\n} from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport { FilterCombobox, type FilterOption } from \"./FilterCombobox\";\nimport type { LucideIcon } from \"lucide-react\";\n\nexport interface DataFilterConfig {\n key: string;\n label: string;\n icon: LucideIcon;\n options: FilterOption[];\n selected: string[];\n onChange: (values: string[]) => void;\n searchPlaceholder?: string;\n allLabel?: string;\n labelMap?: Record<string, string>;\n}\n\nexport interface SavedViewItem {\n id: string;\n name: string;\n filters: Record<string, unknown>;\n}\n\n/**\n * One status chip. A plain string is shorthand for `{ value, label: value }`.\n * `count` renders as a muted number after the label.\n */\nexport interface StatusChipOption {\n value: string;\n label?: string;\n count?: number;\n}\n\n/** Rendering of the status chips — a row of pills, or one segmented strip. */\nexport type StatusChipsVariant = \"chips\" | \"tabs\";\n\ninterface DataFiltersProps {\n search: string;\n onSearchChange: (value: string) => void;\n searchPlaceholder?: string;\n sort: string;\n onSortChange: (sort: string) => void;\n sortOptions: Array<{ value: string; label: string }>;\n filters?: DataFilterConfig[];\n /** Status chip toggles */\n statusChips?: {\n options: Array<string | StatusChipOption>;\n selected: string[];\n onChange: (values: string[]) => void;\n /**\n * `\"chips\"` (default) renders pills inside the filter row. `\"tabs\"`\n * renders a segmented strip on its own row above the search row —\n * the same border-and-fill look as `ViewToggle`. Selection is\n * multi-select in both.\n */\n variant?: StatusChipsVariant;\n };\n /** Saved views */\n savedViews?: SavedViewItem[];\n onLoadView?: (filters: Record<string, unknown>) => void;\n onSaveView?: (name: string) => void;\n onDeleteView?: (id: string) => void;\n canSaveViews?: boolean;\n /** Called after a view is saved successfully */\n onViewSaved?: (name: string) => void;\n /** Called when an error occurs */\n onError?: (message: string) => void;\n /** Called when \"Clear all\" is clicked */\n onClearAll?: () => void;\n /** Expose the search input ref for keyboard nav \"/\" shortcut */\n searchInputRef?: React.RefObject<HTMLInputElement | null>;\n}\n\nexport function DataFilters({\n search,\n onSearchChange,\n searchPlaceholder = \"Search...\",\n sort,\n onSortChange,\n sortOptions,\n filters = [],\n statusChips,\n savedViews = [],\n onLoadView,\n onSaveView,\n onDeleteView,\n canSaveViews = false,\n onViewSaved,\n onClearAll,\n searchInputRef,\n}: DataFiltersProps) {\n const internalSearchRef = useRef<HTMLInputElement>(null);\n const effectiveSearchRef = searchInputRef || internalSearchRef;\n const [viewsOpen, setViewsOpen] = useState(false);\n const [saveDialogOpen, setSaveDialogOpen] = useState(false);\n const [newViewName, setNewViewName] = useState(\"\");\n\n const hasFilters =\n filters.some((f) => f.selected.length > 0) ||\n (statusChips?.selected.length ?? 0) > 0;\n\n // Plain strings and option objects normalise to one shape so both render\n // paths below read `value`/`label`/`count` without re-checking.\n const statusOptions: Array<{ value: string; label: string; count?: number }> =\n (statusChips?.options ?? []).map((o) =>\n typeof o === \"string\"\n ? { value: o, label: o }\n : { value: o.value, label: o.label ?? o.value, count: o.count },\n );\n const statusVariant: StatusChipsVariant = statusChips?.variant ?? \"chips\";\n\n const toggleStatus = (status: string) => {\n if (!statusChips) return;\n const { selected, onChange } = statusChips;\n onChange(\n selected.includes(status)\n ? selected.filter((s) => s !== status)\n : [...selected, status],\n );\n };\n\n const handleSaveView = () => {\n if (!newViewName.trim()) return;\n onSaveView?.(newViewName.trim());\n setNewViewName(\"\");\n setSaveDialogOpen(false);\n onViewSaved?.(newViewName.trim());\n };\n\n return (\n <div className=\"space-y-3\">\n {/* Status tabs row — a segmented strip above everything else */}\n {statusChips && statusVariant === \"tabs\" && (\n <div\n className=\"flex items-center border rounded-lg overflow-x-auto w-fit max-w-full\"\n role=\"group\"\n aria-label=\"Status\"\n data-testid=\"status-tabs\"\n >\n {statusOptions.map((o) => {\n const pressed = statusChips.selected.includes(o.value);\n return (\n <Button\n key={o.value}\n type=\"button\"\n variant={pressed ? \"default\" : \"ghost\"}\n size=\"sm\"\n className=\"h-8 rounded-none gap-1.5\"\n onClick={() => toggleStatus(o.value)}\n aria-pressed={pressed}\n testID={`status-tab-${o.value}`}\n >\n {o.label}\n {o.count !== undefined && (\n <span className=\"text-[10px] tabular-nums opacity-70\">\n {o.count}\n </span>\n )}\n </Button>\n );\n })}\n </div>\n )}\n\n {/* Search + Sort row */}\n <div className=\"flex flex-col sm:flex-row gap-2\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground\" />\n <Input\n ref={effectiveSearchRef}\n placeholder={searchPlaceholder}\n value={search}\n onChange={(e) => onSearchChange(e.target.value)}\n className=\"pl-9\"\n />\n {search && (\n <button\n onClick={() => onSearchChange(\"\")}\n className=\"absolute right-3 top-1/2 -translate-y-1/2\"\n >\n <X className=\"h-3.5 w-3.5 text-muted-foreground\" />\n </button>\n )}\n </div>\n <Select value={sort} onValueChange={onSortChange}>\n <SelectTrigger className=\"w-full sm:w-[180px] shrink-0\">\n <ArrowUpDown className=\"h-3.5 w-3.5 mr-1.5 text-muted-foreground\" />\n <SelectValue placeholder=\"Sort by...\" />\n </SelectTrigger>\n <SelectContent className=\"bg-popover z-50\">\n {sortOptions.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {/* Filter chips row */}\n <div className=\"flex flex-wrap items-center gap-2\">\n {/* Saved Views */}\n {(savedViews.length > 0 || canSaveViews) && (\n <Popover open={viewsOpen} onOpenChange={setViewsOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"text-xs h-7 gap-1.5\"\n >\n <Bookmark className=\"h-3 w-3\" />\n Views\n {savedViews.length > 0 && (\n <span className=\"text-[10px] text-muted-foreground ml-0.5\">\n ({savedViews.length})\n </span>\n )}\n <ChevronDown className=\"h-3 w-3 ml-0.5 opacity-60\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-[240px] p-2 bg-popover z-50\"\n align=\"start\"\n >\n <div className=\"space-y-1\">\n {savedViews.map((view) => (\n <div key={view.id} className=\"flex items-center gap-1 group\">\n <button\n className=\"flex-1 text-left text-sm px-2 py-1.5 rounded hover:bg-accent truncate\"\n onClick={() => {\n onLoadView?.(view.filters);\n setViewsOpen(false);\n }}\n >\n {view.name}\n </button>\n {onDeleteView && (\n <button\n className=\"opacity-0 group-hover:opacity-100 p-1 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive transition-opacity\"\n onClick={() => onDeleteView(view.id)}\n >\n <Trash2 className=\"h-3 w-3\" />\n </button>\n )}\n </div>\n ))}\n {savedViews.length === 0 && (\n <p className=\"text-xs text-muted-foreground px-2 py-1\">\n No saved views yet\n </p>\n )}\n {canSaveViews && (\n <>\n <div className=\"border-t my-1\" />\n <button\n className=\"w-full flex items-center gap-1.5 text-sm px-2 py-1.5 rounded hover:bg-accent text-primary\"\n onClick={() => {\n setViewsOpen(false);\n setSaveDialogOpen(true);\n }}\n >\n <BookmarkPlus className=\"h-3.5 w-3.5\" />\n Save current view\n </button>\n </>\n )}\n </div>\n </PopoverContent>\n </Popover>\n )}\n\n {/* Status chips */}\n {statusChips && statusVariant === \"chips\" && (\n <div className=\"flex items-center gap-1 mr-1\">\n {statusOptions.map((o) => {\n const pressed = statusChips.selected.includes(o.value);\n return (\n <button\n key={o.value}\n type=\"button\"\n onClick={() => toggleStatus(o.value)}\n aria-pressed={pressed}\n data-testid={`status-chip-${o.value}`}\n className={cn(\n \"text-xs px-2.5 py-1 rounded-full border transition-all font-medium\",\n pressed\n ? \"bg-primary text-primary-foreground border-primary\"\n : \"bg-background text-muted-foreground border-border hover:border-primary/40\",\n )}\n >\n {o.label}\n {o.count !== undefined && (\n <span className=\"ml-1 text-[10px] tabular-nums opacity-70\">\n {o.count}\n </span>\n )}\n </button>\n );\n })}\n </div>\n )}\n\n {/* Filter comboboxes */}\n {filters.map((f) =>\n f.options.length > 0 ? (\n <FilterCombobox\n key={f.key}\n label={f.label}\n icon={f.icon}\n options={f.options}\n selected={f.selected}\n onChange={f.onChange}\n searchPlaceholder={f.searchPlaceholder}\n allLabel={f.allLabel}\n labelMap={f.labelMap}\n />\n ) : null,\n )}\n\n {/* Active filter badges */}\n {filters.flatMap((f) =>\n f.selected.map((val) => (\n <Badge\n key={`${f.key}-${val}`}\n variant=\"secondary\"\n className=\"text-xs cursor-pointer gap-1\"\n onClick={() => f.onChange(f.selected.filter((v) => v !== val))}\n >\n {f.labelMap?.[val] || val}\n <X className=\"h-2.5 w-2.5\" />\n </Badge>\n )),\n )}\n\n {/* Clear all */}\n {hasFilters && onClearAll && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs h-7 text-muted-foreground\"\n onClick={onClearAll}\n >\n <X className=\"h-3 w-3 mr-1\" />\n Clear all\n </Button>\n )}\n </div>\n\n {/* Save View Dialog */}\n <Dialog open={saveDialogOpen} onOpenChange={setSaveDialogOpen}>\n <DialogContent className=\"sm:max-w-sm\">\n <DialogHeader>\n <DialogTitle className=\"font-display\">\n Save Current View\n </DialogTitle>\n </DialogHeader>\n <div className=\"space-y-3\">\n <Input\n placeholder=\"View name (e.g. 'Active Sessions')\"\n value={newViewName}\n onChange={(e) => setNewViewName(e.target.value)}\n onKeyDown={(e) => e.key === \"Enter\" && handleSaveView()}\n autoFocus\n />\n <div className=\"flex justify-end gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setSaveDialogOpen(false)}\n >\n Cancel\n </Button>\n <Button\n size=\"sm\"\n onClick={handleSaveView}\n disabled={!newViewName.trim()}\n >\n Save\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n </div>\n );\n}\n","\"use client\";\n\nimport {\n useState,\n useEffect,\n useRef,\n type ReactNode,\n type RefObject,\n} from \"react\";\nimport { cn } from \"../../utils\";\nimport { Loader2 } from \"lucide-react\";\nimport type { ViewMode } from \"../patterns/view-toggle\";\n\nconst DEFAULT_BATCH_SIZE = 48;\n\ninterface DataGridProps<T> {\n items: T[];\n viewMode: ViewMode;\n /** Items per infinite scroll batch (grid only). Default 48 */\n batchSize?: number;\n /** Tailwind grid column classes */\n gridCols?: string;\n /** Render a single card in grid mode */\n renderCard: (item: T, index: number) => ReactNode;\n /** Render the table view (receives currently visible items) */\n renderTable?: (items: T[]) => ReactNode;\n /** Render a compact list row */\n renderListItem?: (item: T, index: number) => ReactNode;\n /** Animate cards with staggered fade-in. Default true */\n staggerAnimation?: boolean;\n /** Unique key extractor. Defaults to (item as any).id */\n getKey?: (item: T) => string;\n /** Keyboard navigation: focused item index (-1 = none) */\n focusedIndex?: number;\n /** Keyboard navigation: container ref for scroll management */\n keyboardContainerRef?: RefObject<HTMLDivElement | null>;\n}\n\nexport function DataGrid<T>({\n items,\n viewMode,\n batchSize = DEFAULT_BATCH_SIZE,\n gridCols = \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\",\n renderCard,\n renderTable,\n renderListItem,\n staggerAnimation = true,\n getKey,\n focusedIndex = -1,\n keyboardContainerRef,\n}: DataGridProps<T>) {\n const [visibleCount, setVisibleCount] = useState(batchSize);\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n // Reset visible count when items change\n useEffect(() => {\n setVisibleCount(batchSize);\n }, [items.length, batchSize]);\n\n // Infinite scroll observer (grid mode only)\n useEffect(() => {\n if (viewMode !== \"grid\") return;\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries[0]?.isIntersecting && visibleCount < items.length) {\n setVisibleCount((prev) =>\n Math.min(prev + batchSize, items.length),\n );\n }\n },\n { rootMargin: \"200px\" },\n );\n if (sentinelRef.current) observer.observe(sentinelRef.current);\n return () => observer.disconnect();\n }, [viewMode, visibleCount, items.length, batchSize]);\n\n if (viewMode === \"table\" && renderTable) {\n return <>{renderTable(items)}</>;\n }\n\n if (viewMode === \"list\" && renderListItem) {\n const keyFnList =\n getKey ||\n ((item: T) => (item as Record<string, unknown>).id as string);\n return (\n <div\n ref={keyboardContainerRef}\n className=\"divide-y divide-border rounded-lg border\"\n >\n {items.map((item, i) => (\n <div\n key={keyFnList(item)}\n data-nav-item\n className={cn(\n \"px-4 py-3 transition-colors hover:bg-accent/50\",\n focusedIndex === i &&\n \"ring-2 ring-inset ring-primary bg-accent/50\",\n )}\n >\n {renderListItem(item, i)}\n </div>\n ))}\n </div>\n );\n }\n\n const visible = items.slice(0, visibleCount);\n const keyFn =\n getKey ||\n ((item: T) => (item as Record<string, unknown>).id as string);\n\n return (\n <>\n <div ref={keyboardContainerRef} className={`grid ${gridCols} gap-4`}>\n {visible.map((item, i) => (\n <div\n key={keyFn(item)}\n data-nav-item\n className={cn(\n staggerAnimation && \"animate-fade-in\",\n focusedIndex === i &&\n \"ring-2 ring-primary ring-offset-2 ring-offset-background rounded-xl transition-shadow duration-150\",\n )}\n style={\n staggerAnimation\n ? {\n animationDelay: `${(i % batchSize) * 30}ms`,\n animationFillMode: \"both\",\n }\n : undefined\n }\n >\n {renderCard(item, i)}\n </div>\n ))}\n </div>\n {visibleCount < items.length && (\n <div\n ref={sentinelRef}\n className=\"h-12 flex items-center justify-center\"\n >\n <Loader2 className=\"h-6 w-6 animate-spin text-muted-foreground\" />\n </div>\n )}\n </>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport {\n useState,\n useCallback,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"../ui/table\";\nimport { Checkbox } from \"../ui/checkbox\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../ui/select\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuCheckboxItem,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../ui/dropdown-menu\";\nimport {\n ArrowUp,\n ArrowDown,\n ArrowUpDown,\n ExternalLink,\n Columns3,\n ChevronLeft,\n ChevronRight,\n} from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport type { Density } from \"../../hooks/use-view-settings\";\n\n/* ── Density row / cell rhythm ── */\n\nconst DENSITY_CELL: Record<Density, string> = {\n compact: \"py-1 h-8\",\n comfortable: \"py-2\",\n spacious: \"py-3\",\n};\n\nconst DENSITY_HEAD: Record<Density, string> = {\n compact: \"h-8 py-1\",\n comfortable: \"h-10\",\n spacious: \"h-12 py-3\",\n};\n\n/* ── Column definition ── */\n\nexport interface DataTableColumn<T> {\n key: string;\n header: string;\n width?: string;\n hideBelow?: \"sm\" | \"md\" | \"lg\" | \"xl\";\n sortable?: boolean;\n render?: (item: T, value: unknown) => ReactNode;\n accessor?: (item: T) => unknown;\n editable?: {\n type: \"text\" | \"select\";\n options?: string[];\n onSave: (item: T, newValue: string) => void;\n };\n /** Whether column is visible by default (default true) */\n defaultVisible?: boolean;\n /** Minimum width in px for resizing */\n minWidth?: number;\n}\n\n/* ── Component props ── */\n\nexport interface DataTableProps<T> {\n items: T[];\n columns: DataTableColumn<T>[];\n getKey: (item: T) => string;\n onRowClick?: (item: T) => void;\n selectable?: boolean;\n selected?: Set<string>;\n onToggleSelect?: (id: string) => void;\n onToggleAll?: () => void;\n renderActions?: (item: T) => ReactNode;\n emptyMessage?: string;\n /** Enable column visibility toggle dropdown */\n columnVisibility?: boolean;\n /** localStorage key for persisting column visibility */\n columnVisibilityKey?: string;\n /** Enable column resizing via drag */\n resizableColumns?: boolean;\n /** Enable pagination */\n pagination?: boolean;\n /** Initial page size (default 25) */\n pageSize?: number;\n /** Page size options (default [10, 25, 50, 100]) */\n pageSizeOptions?: number[];\n /** Sticky header on scroll */\n stickyHeader?: boolean;\n /** localStorage key for persisting column resize widths */\n resizeKey?: string;\n /** Make the first column sticky when scrolling horizontally */\n stickyFirstColumn?: boolean;\n /**\n * Row height / padding rhythm.\n * - compact: ~32px (py-1 / h-8)\n * - comfortable: default (py-2)\n * - spacious: taller (py-3)\n */\n density?: Density;\n}\n\n/* ── Helpers ── */\n\ntype SortEntry = { key: string; dir: \"asc\" | \"desc\" };\n\nfunction getCellClasses(col: DataTableColumn<unknown>) {\n const hide = col.hideBelow\n ? col.hideBelow === \"sm\"\n ? \"hidden sm:table-cell\"\n : col.hideBelow === \"md\"\n ? \"hidden md:table-cell\"\n : col.hideBelow === \"lg\"\n ? \"hidden lg:table-cell\"\n : \"hidden xl:table-cell\"\n : \"\";\n return cn(col.width, hide);\n}\n\n/* ── Inline edit cell ── */\n\nfunction EditableCell<T>({\n item,\n column,\n value,\n}: {\n item: T;\n column: DataTableColumn<T>;\n value: unknown;\n}) {\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState(String(value ?? \"\"));\n const editable = column.editable!;\n\n const commit = useCallback(\n (v: string) => {\n editable.onSave(item, v);\n setEditing(false);\n },\n [editable, item],\n );\n\n if (!editing) {\n return (\n <span\n className=\"cursor-pointer hover:underline decoration-dashed underline-offset-4 decoration-muted-foreground/40\"\n onClick={(e) => {\n e.stopPropagation();\n setDraft(String(value ?? \"\"));\n setEditing(true);\n }}\n >\n {column.render ? column.render(item, value) : String(value ?? \"\\u2014\")}\n </span>\n );\n }\n\n if (editable.type === \"select\" && editable.options) {\n return (\n <div onClick={(e) => e.stopPropagation()}>\n <Select defaultValue={draft} onValueChange={(v) => commit(v)}>\n <SelectTrigger className=\"h-7 text-xs w-28\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {editable.options.map((opt) => (\n <SelectItem key={opt} value={opt}>\n {opt}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n );\n }\n\n return (\n <div onClick={(e) => e.stopPropagation()}>\n <Input\n autoFocus\n className=\"h-7 text-xs w-full\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={() => commit(draft)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") commit(draft);\n if (e.key === \"Escape\") setEditing(false);\n }}\n />\n </div>\n );\n}\n\n/* ── Column resize handle ── */\n\nfunction ResizeHandle({\n onResize,\n onResizeEnd,\n}: {\n onResize: (delta: number) => void;\n onResizeEnd?: () => void;\n}) {\n const startX = useRef(0);\n const [isResizing, setIsResizing] = useState(false);\n\n const handlePointerDown = useCallback(\n (e: React.PointerEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startX.current = e.clientX;\n setIsResizing(true);\n document.body.style.cursor = \"col-resize\";\n const target = e.currentTarget as HTMLElement;\n target.setPointerCapture(e.pointerId);\n\n const onMove = (ev: PointerEvent) => {\n const delta = ev.clientX - startX.current;\n startX.current = ev.clientX;\n onResize(delta);\n };\n const onUp = () => {\n target.removeEventListener(\"pointermove\", onMove);\n target.removeEventListener(\"pointerup\", onUp);\n setIsResizing(false);\n document.body.style.cursor = \"\";\n onResizeEnd?.();\n };\n target.addEventListener(\"pointermove\", onMove);\n target.addEventListener(\"pointerup\", onUp);\n },\n [onResize, onResizeEnd],\n );\n\n return (\n <div\n className={cn(\n \"absolute right-0 top-0 bottom-0 cursor-col-resize transition-colors\",\n isResizing\n ? \"w-1.5 bg-primary/50\"\n : \"w-1 hover:bg-primary/30\",\n )}\n onPointerDown={handlePointerDown}\n onClick={(e) => e.stopPropagation()}\n />\n );\n}\n\n/* ── Main component ── */\n\nexport function DataTable<T>({\n items,\n columns,\n getKey,\n onRowClick,\n selectable,\n selected,\n onToggleSelect,\n onToggleAll,\n renderActions,\n emptyMessage = \"No records found\",\n columnVisibility = true,\n columnVisibilityKey,\n resizableColumns = true,\n pagination = true,\n pageSize: initialPageSize = 25,\n pageSizeOptions = [10, 25, 50, 100],\n stickyHeader = true,\n resizeKey,\n stickyFirstColumn,\n density = \"comfortable\",\n}: DataTableProps<T>) {\n const cellDensity = DENSITY_CELL[density];\n const headDensity = DENSITY_HEAD[density];\n // ── Multi-column sort ──\n const [sorts, setSorts] = useState<SortEntry[]>([]);\n\n const handleSort = useCallback(\n (key: string, shiftKey: boolean) => {\n setSorts((prev) => {\n const existing = prev.findIndex((s) => s.key === key);\n if (existing >= 0) {\n const entry = prev[existing];\n if (entry.dir === \"asc\") {\n const next = [...prev];\n next[existing] = { key, dir: \"desc\" };\n return next;\n }\n // Remove on third click\n return prev.filter((_, i) => i !== existing);\n }\n if (shiftKey) return [...prev, { key, dir: \"asc\" }];\n return [{ key, dir: \"asc\" }];\n });\n },\n [],\n );\n\n // ── Column visibility ──\n // SSR-safe: start from column defaults, restore localStorage after mount,\n // and only persist once hydrated — otherwise the defaults write would wipe\n // saved prefs on every full page load.\n const [visibleCols, setVisibleCols] = useState<Record<string, boolean>>(\n () => {\n const initial: Record<string, boolean> = {};\n columns.forEach((c) => {\n initial[c.key] = c.defaultVisible !== false;\n });\n return initial;\n },\n );\n const [visibilityHydrated, setVisibilityHydrated] = useState(false);\n\n useEffect(() => {\n if (!columnVisibilityKey) {\n setVisibilityHydrated(true);\n return;\n }\n try {\n const saved = localStorage.getItem(`dt-vis-${columnVisibilityKey}`);\n if (saved) {\n const parsed = JSON.parse(saved) as Record<string, boolean>;\n setVisibleCols((prev) => {\n const next = { ...prev };\n for (const [k, v] of Object.entries(parsed)) {\n if (k in next || columns.some((c) => c.key === k)) {\n next[k] = v;\n }\n }\n // Keep defaults for any column not in the saved map\n columns.forEach((c) => {\n if (!(c.key in next)) next[c.key] = c.defaultVisible !== false;\n });\n return next;\n });\n }\n } catch {\n // ignore corrupt prefs\n }\n setVisibilityHydrated(true);\n // Intentionally once-per-mount for this key (columns keys are stable)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [columnVisibilityKey]);\n\n useEffect(() => {\n if (!visibilityHydrated || !columnVisibilityKey) return;\n localStorage.setItem(\n `dt-vis-${columnVisibilityKey}`,\n JSON.stringify(visibleCols),\n );\n }, [visibleCols, columnVisibilityKey, visibilityHydrated]);\n\n const toggleColumnVisibility = useCallback((key: string) => {\n setVisibleCols((prev) => ({ ...prev, [key]: !prev[key] }));\n }, []);\n\n const resetColumnVisibility = useCallback(() => {\n const defaults: Record<string, boolean> = {};\n columns.forEach((c) => {\n defaults[c.key] = c.defaultVisible !== false;\n });\n setVisibleCols(defaults);\n if (columnVisibilityKey) {\n localStorage.removeItem(`dt-vis-${columnVisibilityKey}`);\n }\n }, [columns, columnVisibilityKey]);\n\n // Sync new columns that aren't in saved state\n useEffect(() => {\n setVisibleCols((prev) => {\n const updated = { ...prev };\n let changed = false;\n columns.forEach((c) => {\n if (!(c.key in updated)) {\n updated[c.key] = c.defaultVisible !== false;\n changed = true;\n }\n });\n return changed ? updated : prev;\n });\n }, [columns]);\n\n const activeColumns = columnVisibility\n ? columns.filter((c) => visibleCols[c.key] !== false)\n : columns;\n\n // ── Column resizing ──\n const [colWidths, setColWidths] = useState<Record<string, number>>(() => {\n // Restore from localStorage if resizeKey is provided\n if (resizeKey) {\n try {\n const saved = localStorage.getItem(`dt-resize-${resizeKey}`);\n if (saved) return JSON.parse(saved);\n } catch {\n // ignore\n }\n }\n // Initialize from column width definitions (parse px/rem values to px numbers)\n const initial: Record<string, number> = {};\n columns.forEach((c) => {\n if (c.width) {\n const px = parseInt(c.width, 10);\n if (!isNaN(px) && px > 0) initial[c.key] = px;\n }\n });\n return initial;\n });\n\n const handleResize = useCallback(\n (key: string, delta: number, minWidth: number) => {\n setColWidths((prev) => {\n const current = prev[key] || 150;\n return { ...prev, [key]: Math.max(minWidth, current + delta) };\n });\n },\n [],\n );\n\n const handleResizeEnd = useCallback(() => {\n if (resizeKey) {\n localStorage.setItem(`dt-resize-${resizeKey}`, JSON.stringify(colWidths));\n }\n }, [resizeKey, colWidths]);\n\n // ── Pagination ──\n const [currentPage, setCurrentPage] = useState(0);\n const [currentPageSize, setCurrentPageSize] = useState(initialPageSize);\n\n // Reset page when items change\n useEffect(() => {\n setCurrentPage(0);\n }, [items.length, currentPageSize]);\n\n // ── Sort items ──\n const sorted = (() => {\n if (sorts.length === 0) return items;\n return [...items].sort((a, b) => {\n for (const s of sorts) {\n const col = columns.find((c) => c.key === s.key);\n if (!col) continue;\n const acc =\n col.accessor ||\n ((item: T) => (item as Record<string, unknown>)[col.key]);\n const va = acc(a);\n const vb = acc(b);\n const sa = va == null ? \"\" : String(va);\n const sb = vb == null ? \"\" : String(vb);\n const cmp = sa.localeCompare(sb, undefined, {\n numeric: true,\n sensitivity: \"base\",\n });\n if (cmp !== 0) return s.dir === \"asc\" ? cmp : -cmp;\n }\n return 0;\n });\n })();\n\n // ── Paginate ──\n const totalItems = sorted.length;\n const totalPages = pagination\n ? Math.max(1, Math.ceil(totalItems / currentPageSize))\n : 1;\n const displayItems = pagination\n ? sorted.slice(\n currentPage * currentPageSize,\n (currentPage + 1) * currentPageSize,\n )\n : sorted;\n const showingFrom =\n totalItems === 0 ? 0 : currentPage * currentPageSize + 1;\n const showingTo = Math.min(\n (currentPage + 1) * currentPageSize,\n totalItems,\n );\n\n const totalCols =\n activeColumns.length + (selectable ? 1 : 0) + (renderActions ? 1 : 0);\n\n return (\n <div className=\"border rounded-lg animate-fade-in flex flex-col\">\n {/* ── Toolbar ── */}\n {columnVisibility && (\n <div className=\"flex items-center justify-end px-3 py-2 border-b bg-muted/30\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-7 text-xs gap-1.5\"\n >\n <Columns3 className=\"h-3.5 w-3.5\" />\n Columns\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"end\"\n className=\"w-44 bg-popover z-50\"\n >\n {columns.map((col) =>\n col.header ? (\n <DropdownMenuCheckboxItem\n key={col.key}\n checked={visibleCols[col.key] !== false}\n onCheckedChange={() => toggleColumnVisibility(col.key)}\n >\n {col.header}\n </DropdownMenuCheckboxItem>\n ) : null,\n )}\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={resetColumnVisibility}>\n Reset to defaults\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n )}\n\n {/* ── Table ── */}\n <div className=\"overflow-x-auto\">\n <Table style={{ tableLayout: \"fixed\" }}>\n <TableHeader\n className={\n stickyHeader ? \"sticky top-0 z-10 bg-background\" : \"\"\n }\n >\n <TableRow>\n {selectable && (\n <TableHead className={cn(\"w-10\", headDensity)}>\n <Checkbox\n checked={\n items.length > 0 && selected?.size === items.length\n }\n onCheckedChange={onToggleAll}\n />\n </TableHead>\n )}\n {activeColumns.map((col, colIndex) => {\n const sortIndex = sorts.findIndex((s) => s.key === col.key);\n const sortEntry =\n sortIndex >= 0 ? sorts[sortIndex] : null;\n const resizeWidth = colWidths[col.key];\n const isFirstCol = colIndex === 0 && stickyFirstColumn;\n\n return (\n <TableHead\n key={col.key}\n className={cn(\n getCellClasses(col as DataTableColumn<unknown>),\n headDensity,\n col.sortable && \"cursor-pointer select-none\",\n resizableColumns && \"relative\",\n isFirstCol && \"sticky left-0 bg-background\",\n isFirstCol && stickyHeader ? \"z-[15]\" : isFirstCol ? \"z-[5]\" : undefined,\n )}\n style={\n resizeWidth\n ? { width: resizeWidth, minWidth: resizeWidth }\n : undefined\n }\n onClick={\n col.sortable\n ? (e: React.MouseEvent) => handleSort(col.key, e.shiftKey)\n : undefined\n }\n >\n <span className=\"inline-flex items-center gap-1\">\n {col.header}\n {col.sortable &&\n (sortEntry ? (\n <>\n {sortEntry.dir === \"asc\" ? (\n <ArrowUp className=\"h-3 w-3 text-foreground\" />\n ) : (\n <ArrowDown className=\"h-3 w-3 text-foreground\" />\n )}\n {sorts.length > 1 && (\n <span className=\"text-[10px] text-muted-foreground font-mono\">\n {sortIndex + 1}\n </span>\n )}\n </>\n ) : (\n <ArrowUpDown className=\"h-3 w-3 text-muted-foreground/50\" />\n ))}\n </span>\n {resizableColumns && (\n <ResizeHandle\n onResize={(delta) =>\n handleResize(\n col.key,\n delta,\n col.minWidth ?? 60,\n )\n }\n onResizeEnd={handleResizeEnd}\n />\n )}\n </TableHead>\n );\n })}\n {renderActions && (\n <TableHead className={cn(\"w-10\", headDensity)} />\n )}\n </TableRow>\n </TableHeader>\n <TableBody>\n {displayItems.length === 0 ? (\n <TableRow>\n <TableCell\n colSpan={totalCols}\n className=\"text-center py-12 text-muted-foreground\"\n >\n {emptyMessage}\n </TableCell>\n </TableRow>\n ) : (\n displayItems.map((item) => {\n const id = getKey(item);\n return (\n <TableRow\n key={id}\n className={cn(onRowClick && \"cursor-pointer\")}\n data-state={\n selected?.has(id) ? \"selected\" : undefined\n }\n onClick={\n onRowClick ? () => onRowClick(item) : undefined\n }\n >\n {selectable && (\n <TableCell\n className={cellDensity}\n onClick={(e: React.MouseEvent) => e.stopPropagation()}\n >\n <Checkbox\n checked={selected?.has(id)}\n onCheckedChange={() => onToggleSelect?.(id)}\n />\n </TableCell>\n )}\n {activeColumns.map((col, colIndex) => {\n const acc =\n col.accessor ||\n ((it: T) =>\n (it as Record<string, unknown>)[col.key]);\n const value = acc(item);\n const isFirstCol = colIndex === 0 && stickyFirstColumn;\n return (\n <TableCell\n key={col.key}\n className={cn(\n getCellClasses(\n col as DataTableColumn<unknown>,\n ),\n cellDensity,\n isFirstCol && \"sticky left-0 z-[1] bg-background\",\n )}\n >\n {col.editable ? (\n <EditableCell\n item={item}\n column={col}\n value={value}\n />\n ) : col.render ? (\n col.render(item, value)\n ) : (\n <span className=\"truncate block max-w-[300px]\">\n {String(value ?? \"\\u2014\")}\n </span>\n )}\n </TableCell>\n );\n })}\n {renderActions && (\n <TableCell\n className={cellDensity}\n onClick={(e: React.MouseEvent) => e.stopPropagation()}\n >\n {renderActions(item)}\n </TableCell>\n )}\n </TableRow>\n );\n })\n )}\n </TableBody>\n </Table>\n </div>\n\n {/* ── Pagination footer ── */}\n {pagination && (\n <div className=\"sticky bottom-0 z-10 flex flex-col sm:flex-row items-center justify-between gap-2 px-4 py-3 border-t bg-muted/30 text-xs text-muted-foreground\">\n <span>\n {totalItems === 0\n ? \"No records\"\n : `Showing ${showingFrom}\\u2013${showingTo} of ${totalItems}`}\n </span>\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center gap-1.5\">\n <span>Rows:</span>\n <Select\n value={String(currentPageSize)}\n onValueChange={(v) => setCurrentPageSize(Number(v))}\n >\n <SelectTrigger className=\"h-7 w-16 text-xs\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent className=\"bg-popover z-50\">\n {pageSizeOptions.map((n) => (\n <SelectItem key={n} value={String(n)}>\n {n}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"h-7 w-7\"\n disabled={currentPage === 0}\n onClick={() => setCurrentPage((p) => p - 1)}\n >\n <ChevronLeft className=\"h-3.5 w-3.5\" />\n </Button>\n <span className=\"px-2 tabular-nums\">\n {currentPage + 1} / {totalPages}\n </span>\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"h-7 w-7\"\n disabled={currentPage >= totalPages - 1}\n onClick={() => setCurrentPage((p) => p + 1)}\n >\n <ChevronRight className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/* ── Pre-built cell renderers ── */\n\nexport function ThumbnailCell({\n src,\n alt,\n}: {\n src?: string | null;\n alt: string;\n}) {\n if (!src) {\n return (\n <div className=\"h-10 w-14 rounded bg-muted flex items-center justify-center text-[10px] text-muted-foreground\">\n &mdash;\n </div>\n );\n }\n return (\n <img\n src={src}\n alt={alt}\n className=\"h-10 w-14 rounded object-cover bg-muted\"\n loading=\"lazy\"\n />\n );\n}\n\nexport function LinkCell({\n href,\n label,\n}: {\n href?: string | null;\n label?: string;\n}) {\n if (!href) return <span className=\"text-muted-foreground\">&mdash;</span>;\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(e) => e.stopPropagation()}\n className=\"inline-flex items-center gap-1 text-xs text-primary hover:underline max-w-[200px] truncate\"\n >\n {label || new URL(href).hostname}\n <ExternalLink className=\"h-3 w-3 shrink-0\" />\n </a>\n );\n}\n","import { Checkbox } from \"../ui/checkbox\";\nimport { Badge } from \"../ui/badge\";\nimport { Button } from \"../ui/button\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { cn } from \"../../utils\";\n\n/**\n * One button in the bulk action bar.\n *\n * @stability Stable\n */\nexport interface BulkAction {\n label: string;\n icon: LucideIcon;\n onClick: () => void;\n variant?:\n | \"default\"\n | \"destructive\"\n | \"outline\"\n | \"secondary\"\n | \"ghost\"\n | \"link\";\n /**\n * Makes this action inert: it renders with the Button primitive's native\n * `disabled` attribute, so it is neither clickable nor focusable, and it\n * picks up the disabled styling.\n *\n * The case this exists for is an in-flight bulk mutation. A consumer that\n * fires a move/duplicate/delete over the selected ids wants every bulk\n * action dead until it settles, so a user cannot double-fire a destructive\n * operation on the same selection. Without this field the only guard\n * available is an early return inside `onClick` — which does stop the\n * second call, but leaves the button looking live, so the affordance lies\n * about what pressing it will do. Concretely, that is what blocks a real\n * consumer's hand-rolled bulk bar from migrating to `DataBulkBar`: it\n * would have to give up its double-submit guard to do so.\n *\n * Optional and defaulted off — omitting it behaves exactly as before.\n */\n disabled?: boolean;\n /**\n * `data-testid` on the rendered button.\n *\n * Without it, a consumer migrating a hand-rolled bulk bar to `DataBulkBar`\n * loses every selector its e2e suite uses to drive one — which is a real\n * reason not to migrate, and the kind of small missing affordance that\n * keeps a parallel implementation alive.\n */\n testId?: string;\n}\n\nexport interface DataBulkBarProps {\n selected: Set<string>;\n totalCount: number;\n onToggleAll: () => void;\n onClearSelection: () => void;\n actions: BulkAction[];\n /** Merged onto the bar, not replacing its positioning. */\n className?: string;\n}\n\nexport function DataBulkBar({\n selected,\n totalCount,\n onToggleAll,\n onClearSelection,\n actions,\n className,\n}: DataBulkBarProps) {\n if (selected.size === 0) return null;\n\n return (\n <div\n className={cn(\n \"flex items-center gap-2 p-3 rounded-lg border bg-muted/50 animate-fade-in\",\n className,\n )}\n >\n <Checkbox\n checked={selected.size === totalCount}\n onCheckedChange={onToggleAll}\n />\n <Badge variant=\"secondary\">{selected.size} selected</Badge>\n {actions.map((action) => {\n const ActionIcon = action.icon;\n return (\n <Button\n key={action.label}\n size=\"sm\"\n variant={action.variant || \"outline\"}\n onClick={action.onClick}\n disabled={action.disabled}\n data-testid={action.testId}\n >\n <ActionIcon className=\"h-3.5 w-3.5 mr-1\" />\n {action.label}\n </Button>\n );\n })}\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={onClearSelection}\n className=\"ml-auto text-xs text-muted-foreground\"\n >\n Clear\n </Button>\n </div>\n );\n}\n","import { Badge } from \"../ui/badge\";\nimport { formatDistanceToNow, format } from \"date-fns\";\n\n/**\n * DateCell -- shows relative date by default, formatted date otherwise.\n * Compatible with DataTableColumn<T>'s `render` prop.\n */\nexport function DateCell(options?: { relative?: boolean; format?: string }) {\n return (_item: unknown, value: unknown) => {\n if (!value) return \"\\u2014\";\n const date = new Date(String(value));\n if (isNaN(date.getTime())) return String(value);\n const relative = options?.relative !== false;\n const fmt = options?.format ?? \"MMM d, yyyy\";\n return relative\n ? formatDistanceToNow(date, { addSuffix: true })\n : format(date, fmt);\n };\n}\n\n/**\n * NumberCell -- locale-aware number formatting.\n */\nexport function NumberCell(options?: Intl.NumberFormatOptions) {\n const formatter = new Intl.NumberFormat(undefined, options);\n return (_item: unknown, value: unknown) => {\n if (value == null) return \"\\u2014\";\n const num = Number(value);\n return isNaN(num) ? String(value) : formatter.format(num);\n };\n}\n\n/**\n * CurrencyCell -- currency formatting with string-safe parsing.\n */\nexport function CurrencyCell(currency = \"USD\", locale?: string) {\n const formatter = new Intl.NumberFormat(locale, {\n style: \"currency\",\n currency,\n });\n return (_item: unknown, value: unknown) => {\n if (value == null) return \"\\u2014\";\n const str = String(value).replace(/[^0-9.-]/g, \"\");\n const num = Number(str);\n return isNaN(num) ? String(value) : formatter.format(num);\n };\n}\n\n/**\n * BadgeCell -- status badge with configurable color map.\n */\nexport function BadgeCell(\n colorMap?: Record<\n string,\n | \"default\"\n | \"secondary\"\n | \"destructive\"\n | \"outline\"\n | \"success\"\n | \"warning\"\n | \"info\"\n | \"muted\"\n >,\n) {\n return (_item: unknown, value: unknown) => {\n if (value == null) return \"\\u2014\";\n const str = String(value);\n const variant = colorMap?.[str] ?? \"outline\";\n return <Badge variant={variant}>{str}</Badge>;\n };\n}\n","import { cn } from \"../../utils\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { DefaultLink, type LinkComponent } from \"../../navigation\";\n\nexport type StatCardColor = \"primary\" | \"success\" | \"warning\" | \"info\" | \"destructive\" | \"muted\";\n\nconst colorMap: Record<StatCardColor, string> = {\n primary: \"text-primary\",\n success: \"text-success\",\n warning: \"text-warning\",\n info: \"text-info\",\n destructive: \"text-destructive\",\n muted: \"text-muted-foreground\",\n};\n\nexport interface StatCardProps {\n label: string;\n value: string | number;\n icon?: LucideIcon;\n /** Semantic color key or raw Tailwind class */\n color?: StatCardColor | string;\n /** When set, the card renders as a link to this path. */\n href?: string;\n /**\n * Injectable link component used when `href` is set. Defaults to a plain\n * `<a>` (no router). Pass a router adapter for client-side navigation.\n */\n linkComponent?: LinkComponent;\n trend?: { value: number; label: string };\n className?: string;\n}\n\nfunction resolveColor(color: string): string {\n return (colorMap as Record<string, string>)[color] ?? color;\n}\n\nexport function StatCard({\n label,\n value,\n icon: Icon,\n color = \"primary\",\n href,\n linkComponent: Link = DefaultLink,\n trend,\n className,\n}: StatCardProps) {\n const content = (\n <>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-muted-foreground\">{label}</span>\n {Icon && <Icon className={cn(\"h-4 w-4\", resolveColor(color))} />}\n </div>\n <p className=\"mt-2 text-2xl font-bold\">{value}</p>\n {trend && (\n <p\n className={cn(\n \"mt-1 text-xs font-medium\",\n trend.value >= 0\n ? \"text-primary\"\n : \"text-destructive\",\n )}\n >\n {trend.value >= 0 ? \"+\" : \"\"}\n {trend.value}% {trend.label}\n </p>\n )}\n </>\n );\n\n const cardClasses = cn(\n \"rounded-xl border border-border bg-card p-4 transition-all hover:shadow-md\",\n href && \"cursor-pointer hover:border-primary/30\",\n className,\n );\n\n if (href) {\n return (\n <Link href={href} className={cardClasses}>\n {content}\n </Link>\n );\n }\n\n return <div className={cardClasses}>{content}</div>;\n}\n","import type { ReactNode } from \"react\";\nimport { Badge } from \"../ui/badge\";\nimport { cn } from \"../../utils\";\n\nexport type ColumnStatus = \"neutral\" | \"warning\" | \"success\" | \"info\" | \"destructive\" | \"primary\";\n\nconst statusColorMap: Record<ColumnStatus, { color: string; bgColor: string }> = {\n neutral: { color: \"text-muted-foreground\", bgColor: \"bg-muted\" },\n warning: { color: \"text-warning\", bgColor: \"bg-warning/15\" },\n success: { color: \"text-success\", bgColor: \"bg-success/15\" },\n info: { color: \"text-info\", bgColor: \"bg-info/15\" },\n destructive: { color: \"text-destructive\", bgColor: \"bg-destructive/15\" },\n primary: { color: \"text-primary\", bgColor: \"bg-primary/15\" },\n};\n\nexport interface KanbanColumn<T> {\n key: string;\n label: string;\n /** Semantic status for automatic color mapping */\n status?: ColumnStatus;\n /** Raw color class (used if status not provided) */\n color?: string;\n /** Raw bg color class (used if status not provided) */\n bgColor?: string;\n items: T[];\n}\n\nexport interface KanbanBoardProps<T> {\n columns: KanbanColumn<T>[];\n renderCard: (item: T) => ReactNode;\n emptyMessage?: string;\n className?: string;\n}\n\nexport function KanbanBoard<T>({\n columns,\n renderCard,\n emptyMessage = \"No items\",\n className,\n}: KanbanBoardProps<T>) {\n return (\n <div\n className={cn(\n \"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\",\n className,\n )}\n >\n {columns.map((column) => {\n const resolved = column.status\n ? statusColorMap[column.status]\n : { color: column.color ?? \"\", bgColor: column.bgColor ?? \"\" };\n return (\n <div key={column.key} className=\"flex flex-col gap-3\">\n {/* Column header */}\n <div className=\"flex items-center gap-2\">\n <span className={cn(\"text-sm font-semibold\", resolved.color)}>\n {column.label}\n </span>\n <Badge\n variant=\"secondary\"\n className={cn(\"text-[10px] px-1.5 py-0\", resolved.bgColor)}\n >\n {column.items.length}\n </Badge>\n </div>\n\n {/* Cards */}\n <div className=\"flex flex-col gap-2 min-h-[80px]\">\n {column.items.length === 0 ? (\n <div className=\"flex items-center justify-center rounded-lg border border-dashed border-border p-6 text-xs text-muted-foreground\">\n {emptyMessage}\n </div>\n ) : (\n column.items.map((item, i) => (\n <div key={i} className=\"animate-fade-in\" style={{ animationDelay: `${i * 30}ms`, animationFillMode: \"both\" }}>\n {renderCard(item)}\n </div>\n ))\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils\";\n\nexport interface DataListProps<T> {\n items: T[];\n renderItem: (item: T, index: number) => ReactNode;\n emptyMessage?: string;\n className?: string;\n}\n\nexport function DataList<T>({\n items,\n renderItem,\n emptyMessage = \"No items found\",\n className,\n}: DataListProps<T>) {\n if (items.length === 0) {\n return (\n <div className=\"text-center py-12 text-sm text-muted-foreground\">\n {emptyMessage}\n </div>\n );\n }\n\n return (\n <div className={cn(\"divide-y divide-border rounded-lg border\", className)}>\n {items.map((item, i) => (\n <div\n key={i}\n className=\"px-4 py-3 transition-colors hover:bg-accent/50\"\n >\n {renderItem(item, i)}\n </div>\n ))}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Button } from \"../ui/button\";\nimport { Separator } from \"../ui/separator\";\nimport { Pencil, Trash2, X } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport { Dialog, DialogContent, DialogTitle, DialogDescription } from \"../ui/dialog\";\nimport { Sheet, SheetContent, SheetTitle, SheetDescription } from \"../ui/sheet\";\n\n/**\n * Props for {@link DetailPanel} — a shell-agnostic record detail view.\n * `layout` selects only the surrounding shell (inline / dialog / sheet);\n * the header and content below it render identically across all three.\n *\n * @stability Beta\n */\nexport interface DetailPanelProps<T> {\n /** The record to display */\n item: T | null;\n /** Whether panel is visible */\n open: boolean;\n /** Close handler */\n onClose: () => void;\n /** Header title */\n title?: string;\n /** Header subtitle */\n subtitle?: string;\n /** Shows edit button if provided */\n onEdit?: (item: T) => void;\n /** Shows delete button if provided */\n onDelete?: (item: T) => void;\n /** Custom content renderer */\n children?: (item: T) => ReactNode;\n /** Field definitions for auto-rendering */\n fields?: Array<{\n key: string;\n label: string;\n render?: (value: unknown, item: T) => ReactNode;\n }>;\n /**\n * Panel width. For `\"sheet\"` / `\"inline\"` this is a fixed pixel width\n * (matching this component's original, pre-`layout` sizing exactly). For\n * `\"dialog\"` it maps to Tailwind's modal max-width scale instead, since a\n * centered modal has a different sizing idiom than an edge-anchored panel.\n */\n width?: \"sm\" | \"md\" | \"lg\";\n /**\n * Rendering shell for the header + content below.\n * - `\"sheet\"` (default): fixed, right-anchored slide-in panel, composed\n * from the shared `Sheet` primitive. Matches this component's original\n * (pre-`layout`-prop) behavior — existing consumers that don't pass\n * `layout` see no change, other than an overlay now present at all\n * breakpoints (previously mobile-only) since it's a real `Sheet`.\n * - `\"dialog\"`: centered modal overlay, composed from the shared `Dialog`\n * primitive.\n * - `\"inline\"`: plain in-flow panel — no overlay, backdrop, or fixed\n * positioning — for master-detail / split-pane layouts.\n */\n layout?: \"inline\" | \"dialog\" | \"sheet\";\n}\n\nconst widthClasses = {\n sm: \"w-80\",\n md: \"w-96\",\n lg: \"w-[480px]\",\n} as const;\n\n/** `dialog` layout's width idiom: a centered modal, not an edge panel. */\nconst dialogMaxWidthClasses = {\n sm: \"sm:max-w-sm\",\n md: \"sm:max-w-lg\",\n lg: \"sm:max-w-2xl\",\n} as const;\n\n/** Convert a snake_case or camelCase key to Title Case label */\nfunction keyToLabel(key: string): string {\n return key\n .replace(/_/g, \" \")\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction formatValue(value: unknown): string {\n if (value === null || value === undefined) return \"—\";\n if (typeof value === \"boolean\") return value ? \"Yes\" : \"No\";\n if (value instanceof Date) return value.toLocaleDateString();\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/**\n * Title/subtitle block for the panel header. `\"dialog\"` / `\"sheet\"` render\n * through the composed primitive's own `Title`/`Description` so Radix's\n * accessibility wiring (`aria-labelledby` / `aria-describedby`) stays\n * correct — falling back to visually-hidden text when `title`/`subtitle`\n * are omitted so Radix always has something to point at, without changing\n * what's visibly shown. `\"inline\"` isn't a Radix primitive, so it renders\n * the original plain conditional markup.\n */\nfunction renderTitleBlock(\n layout: \"inline\" | \"dialog\" | \"sheet\",\n title: string | undefined,\n subtitle: string | undefined,\n) {\n const titleText = title || \"Detail panel\";\n\n if (layout === \"dialog\") {\n return (\n <>\n <DialogTitle className={cn(\"text-sm font-semibold truncate\", !title && \"sr-only\")}>\n {titleText}\n </DialogTitle>\n <DialogDescription\n className={cn(\"text-xs text-muted-foreground truncate\", !subtitle && \"sr-only\")}\n >\n {subtitle || titleText}\n </DialogDescription>\n </>\n );\n }\n\n if (layout === \"sheet\") {\n return (\n <>\n <SheetTitle className={cn(\"text-sm font-semibold truncate\", !title && \"sr-only\")}>\n {titleText}\n </SheetTitle>\n <SheetDescription\n className={cn(\"text-xs text-muted-foreground truncate\", !subtitle && \"sr-only\")}\n >\n {subtitle || titleText}\n </SheetDescription>\n </>\n );\n }\n\n return (\n <>\n {title && <h2 className=\"text-sm font-semibold truncate\">{title}</h2>}\n {subtitle && <p className=\"text-xs text-muted-foreground truncate\">{subtitle}</p>}\n </>\n );\n}\n\nexport function DetailPanel<T extends Record<string, unknown>>({\n item,\n open,\n onClose,\n title,\n subtitle,\n onEdit,\n onDelete,\n children,\n fields,\n width = \"md\",\n layout = \"sheet\",\n}: DetailPanelProps<T>) {\n if (!open || !item) return null;\n\n const renderContent = () => {\n if (children) {\n return children(item);\n }\n\n if (fields) {\n return (\n <dl className=\"space-y-0\">\n {fields.map((field, index) => (\n <div key={field.key}>\n {index > 0 && <Separator />}\n <div className=\"py-3\">\n <dt className=\"text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {field.label}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {field.render\n ? field.render(item[field.key], item)\n : formatValue(item[field.key])}\n </dd>\n </div>\n </div>\n ))}\n </dl>\n );\n }\n\n // Auto-render all fields except \"id\"\n const entries = Object.entries(item).filter(([key]) => key !== \"id\");\n return (\n <dl className=\"space-y-0\">\n {entries.map(([key, value], index) => (\n <div key={key}>\n {index > 0 && <Separator />}\n <div className=\"py-3\">\n <dt className=\"text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {keyToLabel(key)}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {formatValue(value)}\n </dd>\n </div>\n </div>\n ))}\n </dl>\n );\n };\n\n const header = (\n <div className=\"flex items-center justify-between gap-2 border-b border-border px-4 py-3\">\n <div className=\"min-w-0\">{renderTitleBlock(layout, title, subtitle)}</div>\n <div className=\"flex items-center gap-1 shrink-0\">\n {onEdit && (\n <Button\n testID=\"detail-panel-edit\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => onEdit(item)}\n aria-label=\"Edit\"\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n )}\n {onDelete && (\n <Button\n testID=\"detail-panel-delete\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive hover:text-destructive\"\n onClick={() => onDelete(item)}\n aria-label=\"Delete\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n )}\n <Button\n testID=\"detail-panel-close\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={onClose}\n aria-label=\"Close\"\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n\n const content = (\n <div className=\"flex-1 overflow-y-auto px-4 py-3\">{renderContent()}</div>\n );\n\n // ── \"dialog\": centered modal overlay, composed from the shared Dialog ──\n if (layout === \"dialog\") {\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n if (!next) onClose();\n }}\n >\n <DialogContent\n showCloseButton={false}\n className={cn(\n \"flex max-h-[85vh] flex-col gap-0 overflow-hidden p-0\",\n dialogMaxWidthClasses[width],\n )}\n >\n {header}\n {content}\n </DialogContent>\n </Dialog>\n );\n }\n\n // ── \"sheet\" (default): fixed right-anchored slide-in, composed from the\n // shared Sheet primitive — this is the original DetailPanel look. ──\n if (layout === \"sheet\") {\n return (\n <Sheet\n open={open}\n onOpenChange={(next) => {\n if (!next) onClose();\n }}\n >\n <SheetContent\n side=\"right\"\n showCloseButton={false}\n className={cn(\n \"flex flex-col gap-0 overflow-hidden p-0 max-w-[90vw] sm:max-w-[90vw]\",\n widthClasses[width],\n )}\n >\n {header}\n {content}\n </SheetContent>\n </Sheet>\n );\n }\n\n // ── \"inline\": plain in-flow panel, no overlay/backdrop/fixed position ──\n return (\n <div\n role=\"region\"\n aria-label={title || \"Detail panel\"}\n className={cn(\n \"flex flex-col rounded-lg border border-border bg-card\",\n widthClasses[width],\n )}\n >\n {header}\n {content}\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useMemo } from \"react\";\nimport { Check, ChevronsUpDown, Loader2 } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport { useResource } from \"@marktiderman/genesis-core/hooks\";\nimport { useDataProvider, type BaseRecord } from \"@marktiderman/genesis-core/provider\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from \"../ui/command\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n} from \"../ui/dialog\";\nimport { Input } from \"../ui/input\";\nimport { Button } from \"../ui/button\";\nimport type { ResourceFormFieldDef } from \"./ResourceFormField\";\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface RelationFieldProps {\n field: ResourceFormFieldDef;\n value: string;\n onChange: (value: string) => void;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function RelationField({\n field,\n value,\n onChange,\n disabled,\n}: RelationFieldProps) {\n const [open, setOpen] = useState(false);\n const [createOpen, setCreateOpen] = useState(false);\n const [createValue, setCreateValue] = useState(\"\");\n const [createError, setCreateError] = useState<string | null>(null);\n const [isCreating, setIsCreating] = useState(false);\n const [extraOptions, setExtraOptions] = useState<{ value: string; label: string }[]>([]);\n const relation = field.relation!;\n const valueField = relation.valueField ?? \"id\";\n const provider = useDataProvider();\n\n const { list } = useResource(relation.resource, {\n defaultPerPage: 100,\n });\n\n const options = useMemo(() => {\n const base = list.data?.data\n ? list.data.data.map((item) => {\n const record = item as Record<string, unknown>;\n return {\n value: String(record[valueField] ?? \"\"),\n label: String(record[relation.labelField] ?? \"\"),\n };\n })\n : [];\n return [...base, ...extraOptions];\n }, [list.data?.data, valueField, relation.labelField, extraOptions]);\n\n const handleCreate = async () => {\n if (!createValue.trim() || isCreating) return;\n setIsCreating(true);\n try {\n const res = await provider.create<BaseRecord>(relation.resource, {\n data: { [relation.labelField]: createValue.trim() },\n });\n const record = res.data;\n const newValue = String(record[valueField] ?? \"\");\n const newLabel = String(record[relation.labelField] ?? \"\");\n setExtraOptions((prev) => [...prev, { value: newValue, label: newLabel }]);\n onChange(newValue);\n setCreateOpen(false);\n setCreateValue(\"\");\n } catch (err) {\n console.error(`Failed to create ${relation.resource}:`, err);\n setCreateError(err instanceof Error ? err.message : \"Failed to create record\");\n } finally {\n setIsCreating(false);\n }\n };\n\n const showSearch =\n relation.searchable ?? options.length > 10;\n\n const selectedLabel = useMemo(() => {\n if (!value) return null;\n const match = options.find((opt) => opt.value === value);\n return match?.label ?? null;\n }, [value, options]);\n\n const isLoading = list.isLoading;\n\n return (\n <>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className=\"w-full justify-between font-normal\"\n disabled={disabled || isLoading}\n >\n {isLoading ? (\n <span className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Loading...\n </span>\n ) : selectedLabel ? (\n selectedLabel\n ) : (\n <span className=\"text-muted-foreground\">\n {field.placeholder ?? \"Select...\"}\n </span>\n )}\n <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[--radix-popover-trigger-width] p-0\" align=\"start\">\n <Command>\n {showSearch && <CommandInput placeholder=\"Search...\" />}\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n {options.map((opt) => (\n <CommandItem\n key={opt.value}\n value={opt.label}\n onSelect={() => {\n onChange(opt.value === value ? \"\" : opt.value);\n setOpen(false);\n }}\n >\n <Check\n className={cn(\n \"mr-2 h-4 w-4\",\n value === opt.value ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n {opt.label}\n </CommandItem>\n ))}\n </CommandGroup>\n {relation.allowCreate && (\n <>\n <CommandSeparator />\n <CommandGroup>\n <CommandItem\n onSelect={() => {\n setOpen(false);\n setCreateOpen(true);\n }}\n >\n + Create new...\n </CommandItem>\n </CommandGroup>\n </>\n )}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n\n {relation.allowCreate && (\n <Dialog open={createOpen} onOpenChange={setCreateOpen}>\n <DialogContent className=\"sm:max-w-[400px]\">\n <DialogHeader>\n <DialogTitle>Create new {relation.resource.replace(/s$/, \"\")}</DialogTitle>\n </DialogHeader>\n <Input\n placeholder={`Enter ${relation.labelField}...`}\n value={createValue}\n onChange={(e) => { setCreateValue(e.target.value); setCreateError(null); }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n void handleCreate();\n }\n }}\n autoFocus\n />\n {createError && (\n <p className=\"text-sm text-destructive\">{createError}</p>\n )}\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setCreateOpen(false)} disabled={isCreating}>\n Cancel\n </Button>\n <Button onClick={() => void handleCreate()} disabled={isCreating || !createValue.trim()}>\n {isCreating ? \"Creating...\" : \"Create\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { useState, useMemo, useCallback, useEffect } from \"react\";\nimport { useDropzone, type FileRejection } from \"react-dropzone\";\nimport { Upload, X, FileIcon, ImageIcon, AlertCircle } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport type { ResourceFormFieldDef } from \"./ResourceFormField\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_MAX_SIZE = 10 * 1024 * 1024; // 10MB\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction parseAcceptProp(accept?: string): Record<string, string[]> | undefined {\n if (!accept) return undefined;\n // Convert shorthand like \"image/*\", \".pdf,.doc\" into react-dropzone accept format\n const result: Record<string, string[]> = {};\n const parts = accept.split(\",\").map((s) => s.trim());\n for (const part of parts) {\n if (part.includes(\"/\")) {\n // MIME type like \"image/*\"\n result[part] = [];\n } else if (part.startsWith(\".\")) {\n // Extension like \".pdf\"\n // Group under a generic key — react-dropzone matches by extension\n const key = \"application/octet-stream\";\n if (!result[key]) result[key] = [];\n result[key].push(part);\n }\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface FileUploadFieldProps {\n field: ResourceFormFieldDef;\n value: File | File[] | null;\n onChange: (value: File | File[] | null) => void;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function FileUploadField({\n field,\n value,\n onChange,\n disabled,\n}: FileUploadFieldProps) {\n const multiple = field.multiple ?? false;\n const maxSize = field.maxSize ?? DEFAULT_MAX_SIZE;\n const isImage = field.type === \"image\";\n const acceptObj = useMemo(\n () => parseAcceptProp(field.accept ?? (isImage ? \"image/*\" : undefined)),\n [field.accept, isImage],\n );\n\n const [errors, setErrors] = useState<string[]>([]);\n\n // Normalise value to an array for display\n const files: File[] = useMemo(() => {\n if (!value) return [];\n return Array.isArray(value) ? value : [value];\n }, [value]);\n\n // Preview URLs for image files\n const [previews, setPreviews] = useState<string[]>([]);\n\n useEffect(() => {\n const urls = files\n .filter((f) => f.type.startsWith(\"image/\"))\n .map((f) => URL.createObjectURL(f));\n setPreviews(urls);\n return () => urls.forEach((u) => URL.revokeObjectURL(u));\n }, [files]);\n\n const onDrop = useCallback(\n (accepted: File[], rejected: FileRejection[]) => {\n const newErrors: string[] = [];\n for (const rej of rejected) {\n for (const err of rej.errors) {\n if (err.code === \"file-too-large\") {\n newErrors.push(\n `\"${rej.file.name}\" exceeds ${formatFileSize(maxSize)} limit`,\n );\n } else if (err.code === \"file-invalid-type\") {\n newErrors.push(`\"${rej.file.name}\" is not an accepted file type`);\n } else {\n newErrors.push(`\"${rej.file.name}\": ${err.message}`);\n }\n }\n }\n setErrors(newErrors);\n\n if (accepted.length === 0) return;\n\n if (multiple) {\n const merged = [...files, ...accepted];\n onChange(merged);\n } else {\n onChange(accepted[0]);\n }\n },\n [files, maxSize, multiple, onChange],\n );\n\n const removeFile = useCallback(\n (index: number) => {\n const next = files.filter((_, i) => i !== index);\n if (next.length === 0) {\n onChange(null);\n } else if (multiple) {\n onChange(next);\n } else {\n onChange(null);\n }\n setErrors([]);\n },\n [files, multiple, onChange],\n );\n\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\n onDrop,\n accept: acceptObj,\n maxSize,\n multiple,\n disabled,\n });\n\n const hasFiles = files.length > 0;\n\n return (\n <div className=\"space-y-2\">\n {/* Drop zone */}\n <div\n {...getRootProps()}\n className={cn(\n \"flex cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed px-6 py-8 text-center transition-colors\",\n isDragActive\n ? \"border-primary bg-primary/5\"\n : \"border-muted-foreground/25 hover:border-muted-foreground/50\",\n disabled && \"pointer-events-none opacity-50\",\n hasFiles && \"py-4\",\n )}\n >\n <input {...getInputProps()} />\n {isImage ? (\n <ImageIcon className=\"mb-2 h-8 w-8 text-muted-foreground\" />\n ) : (\n <Upload className=\"mb-2 h-8 w-8 text-muted-foreground\" />\n )}\n <p className=\"text-sm text-muted-foreground\">\n {isDragActive\n ? \"Drop files here...\"\n : \"Drag & drop or click to upload\"}\n </p>\n <p className=\"mt-1 text-xs text-muted-foreground/70\">\n Max {formatFileSize(maxSize)}\n {field.accept ? ` -- ${field.accept}` : \"\"}\n </p>\n </div>\n\n {/* Error messages */}\n {errors.length > 0 && (\n <div className=\"space-y-1\">\n {errors.map((err, i) => (\n <p key={i} className=\"flex items-center gap-1 text-sm text-destructive\">\n <AlertCircle className=\"h-3.5 w-3.5 shrink-0\" />\n {err}\n </p>\n ))}\n </div>\n )}\n\n {/* File previews */}\n {hasFiles && (\n <ul className=\"space-y-2\">\n {files.map((file, index) => {\n const isImg = file.type.startsWith(\"image/\");\n const previewUrl = isImg ? previews[\n files.filter((f, i) => i <= index && f.type.startsWith(\"image/\")).length - 1\n ] : undefined;\n\n return (\n <li\n key={`${file.name}-${index}`}\n className=\"flex items-center gap-3 rounded-md border bg-muted/30 p-2\"\n >\n {isImg && previewUrl ? (\n <img\n src={previewUrl}\n alt={file.name}\n className=\"h-10 w-10 rounded object-cover\"\n />\n ) : (\n <FileIcon className=\"h-10 w-10 shrink-0 text-muted-foreground p-1\" />\n )}\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium\">{file.name}</p>\n <p className=\"text-xs text-muted-foreground\">\n {formatFileSize(file.size)}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n removeFile(index);\n }}\n className=\"shrink-0 rounded-md p-1 text-muted-foreground hover:bg-muted hover:text-foreground\"\n aria-label={`Remove ${file.name}`}\n >\n <X className=\"h-4 w-4\" />\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useFieldArray, type Control } from \"react-hook-form\";\nimport { Card, CardContent } from \"../ui/card\";\nimport { Button } from \"../ui/button\";\nimport { FormField, FormLabel, FormError } from \"../patterns/form-field\";\nimport { titleCase } from \"../../hooks/use-resource-page\";\nimport { buildArrayItemDefaults } from \"@marktiderman/genesis-core/hooks\";\nimport { ResourceFormFieldRenderer, type ResourceFormFieldDef } from \"./ResourceFormField\";\n\n// ---------------------------------------------------------------------------\n// FieldArrayRenderer\n// ---------------------------------------------------------------------------\n\nexport function FieldArrayRenderer({\n field,\n control,\n action,\n watchedValues,\n}: {\n field: ResourceFormFieldDef;\n control: Control<Record<string, unknown>>;\n action: \"create\" | \"edit\";\n watchedValues?: Record<string, unknown>;\n}) {\n const { fields: items, append, remove } = useFieldArray({\n control: control as unknown as Control,\n name: field.key,\n });\n\n const subFields = field.arrayFields ?? [];\n const label = field.label ?? titleCase(field.key);\n const canAdd = field.arrayMax == null || items.length < field.arrayMax;\n const canRemove = field.arrayMin == null || items.length > field.arrayMin;\n\n const handleAdd = () => {\n append(buildArrayItemDefaults(subFields));\n };\n\n return (\n <FormField>\n <FormLabel required={field.required}>{label}</FormLabel>\n {field.description && (\n <p className=\"text-sm text-muted-foreground\">{field.description}</p>\n )}\n\n <div className=\"space-y-3\">\n {items.map((item, index) => (\n <Card key={item.id} className=\"relative\">\n <CardContent className=\"pt-4 pb-3 px-4\">\n <div className=\"flex items-center justify-between mb-3\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Item {index + 1}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2 text-destructive hover:text-destructive\"\n disabled={!canRemove}\n onClick={() => remove(index)}\n aria-label={`Remove item ${index + 1}`}\n >\n <TrashIcon className=\"h-4 w-4\" />\n </Button>\n </div>\n <div className=\"space-y-3\">\n {subFields.map((subField) => (\n <ResourceFormFieldRenderer\n key={subField.key}\n field={{\n ...subField,\n key: `${field.key}.${index}.${subField.key}`,\n }}\n control={control}\n action={action}\n watchedValues={watchedValues}\n />\n ))}\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-2\"\n disabled={!canAdd}\n onClick={handleAdd}\n >\n <PlusIcon className=\"h-4 w-4 mr-1\" />\n Add {label.replace(/s$/, \"\")}\n </Button>\n\n <FormError id={`${field.key}-error`}>\n {/* Array-level error from zod min/max */}\n </FormError>\n </FormField>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Inline icons (avoids lucide-react hard dependency)\n// ---------------------------------------------------------------------------\n\nfunction TrashIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M3 6h18\" />\n <path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\" />\n <path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\" />\n <line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\" />\n <line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\" />\n </svg>\n );\n}\n\nfunction PlusIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n );\n}\n","\"use client\";\n\nimport { Controller, type Control } from \"react-hook-form\";\nimport type { ResourceFormFieldDef } from \"@marktiderman/genesis-core\";\nimport { Input } from \"../ui/input\";\nimport { Textarea } from \"../ui/textarea\";\nimport { Switch } from \"../ui/switch\";\nimport { Checkbox } from \"../ui/checkbox\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../ui/select\";\nimport { FormField, FormLabel, FormError, FormDescription } from \"../patterns/form-field\";\nimport { titleCase } from \"../../hooks/use-resource-page\";\nimport { RelationField } from \"./RelationField\";\nimport { FileUploadField } from \"./FileUploadField\";\nimport { FieldArrayRenderer } from \"./FieldArrayRenderer\";\n\n// ---------------------------------------------------------------------------\n// Types — single source of truth is @marktiderman/genesis-core/form-types\n// ---------------------------------------------------------------------------\n\nexport type { FieldType, SelectOption, ResourceFormFieldDef } from \"@marktiderman/genesis-core\";\n\n// ---------------------------------------------------------------------------\n// Renderer\n// ---------------------------------------------------------------------------\n\nexport function ResourceFormFieldRenderer({\n field,\n control,\n action,\n autoFocus,\n watchedValues,\n}: {\n field: ResourceFormFieldDef;\n control: Control<Record<string, unknown>>;\n action: \"create\" | \"edit\";\n autoFocus?: boolean;\n watchedValues?: Record<string, unknown>;\n}) {\n const label = field.label ?? titleCase(field.key);\n const fieldType = field.type ?? \"text\";\n const isReadOnly = action === \"edit\" && field.readOnlyOnEdit;\n const isDisabled = isReadOnly || (watchedValues ? field.disabled?.(watchedValues) === true : false);\n\n // Array fields use useFieldArray — rendered outside of Controller\n if (fieldType === \"array\" && field.arrayFields) {\n return (\n <FieldArrayRenderer\n field={field}\n control={control}\n action={action}\n watchedValues={watchedValues}\n />\n );\n }\n\n if (field.hidden || fieldType === \"hidden\") {\n return (\n <Controller\n name={field.key}\n control={control}\n render={({ field: f }) => <input type=\"hidden\" {...f} value={String(f.value ?? \"\")} />}\n />\n );\n }\n\n return (\n <Controller\n name={field.key}\n control={control}\n render={({ field: f, fieldState }) => {\n const errorMessage = fieldState.error?.message;\n const ariaProps = {\n \"aria-invalid\": !!errorMessage || undefined,\n \"aria-describedby\": errorMessage\n ? `${field.key}-error`\n : field.description\n ? `${field.key}-desc`\n : undefined,\n \"aria-required\": field.required || undefined,\n };\n\n // Switch\n if (fieldType === \"switch\") {\n return (\n <FormField className=\"flex flex-row items-center justify-between rounded-lg border p-4\">\n <div className=\"space-y-0.5\">\n <FormLabel error={!!errorMessage}>{label}</FormLabel>\n </div>\n <Switch\n checked={!!f.value}\n onCheckedChange={f.onChange}\n disabled={isDisabled}\n {...ariaProps}\n />\n </FormField>\n );\n }\n\n // Checkbox\n if (fieldType === \"checkbox\") {\n return (\n <FormField className=\"flex flex-row items-start space-x-3 space-y-0\">\n <Checkbox\n checked={!!f.value}\n onCheckedChange={f.onChange}\n disabled={isDisabled}\n {...ariaProps}\n />\n <div className=\"space-y-1 leading-none\">\n <FormLabel error={!!errorMessage}>{label}</FormLabel>\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </div>\n </FormField>\n );\n }\n\n // Select\n if (fieldType === \"select\" && field.options) {\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <Select\n value={f.value != null ? String(f.value) : \"\"}\n onValueChange={f.onChange}\n disabled={isDisabled}\n >\n <SelectTrigger\n {...ariaProps}\n >\n <SelectValue placeholder={field.placeholder ?? `Select ${label.toLowerCase()}...`} />\n </SelectTrigger>\n <SelectContent>\n {field.options.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }\n\n // Relation\n if (fieldType === \"relation\" && field.relation) {\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <RelationField\n field={field}\n value={f.value != null ? String(f.value) : \"\"}\n onChange={f.onChange}\n disabled={isDisabled}\n />\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }\n\n // File / Image\n if (fieldType === \"file\" || fieldType === \"image\") {\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <FileUploadField\n field={field}\n value={f.value as File | File[] | null}\n onChange={f.onChange}\n disabled={isDisabled}\n />\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }\n\n // Textarea\n if (fieldType === \"textarea\") {\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <Textarea\n placeholder={field.placeholder}\n rows={field.rows ?? 3}\n value={f.value != null ? String(f.value) : \"\"}\n onChange={(e) => f.onChange(e.target.value)}\n disabled={isDisabled}\n autoFocus={autoFocus}\n {...ariaProps}\n />\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }\n\n // Number\n if (fieldType === \"number\") {\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <Input\n type=\"number\"\n placeholder={field.placeholder}\n min={field.min}\n max={field.max}\n value={f.value != null ? String(f.value) : \"\"}\n onChange={(e) => {\n const val = e.target.value;\n f.onChange(val === \"\" ? undefined : Number(val));\n }}\n disabled={isDisabled}\n autoFocus={autoFocus}\n {...ariaProps}\n />\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }\n\n // Text, email, url, date\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <Input\n type={fieldType}\n placeholder={field.placeholder}\n value={f.value != null ? String(f.value) : \"\"}\n onChange={(e) => f.onChange(e.target.value)}\n disabled={isDisabled}\n autoFocus={autoFocus}\n {...ariaProps}\n />\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }}\n />\n );\n}\n","\"use client\";\n\nimport { type ReactNode } from \"react\";\nimport type { UseFormReturn, FieldErrors } from \"react-hook-form\";\nimport { useWatch } from \"react-hook-form\";\nimport { Button } from \"../ui/button\";\nimport { Progress } from \"../ui/progress\";\nimport { Spinner } from \"../ui/spinner\";\nimport { useWizard, type WizardStep } from \"@marktiderman/genesis-core/hooks\";\nimport { ResourceFormFieldRenderer, type ResourceFormFieldDef } from \"./ResourceFormField\";\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface WizardFormProps {\n steps: WizardStep[];\n form: UseFormReturn<Record<string, unknown>>;\n fields: ResourceFormFieldDef[];\n onSubmit: (data: Record<string, unknown>) => Promise<void>;\n isSaving: boolean;\n renderField?: (\n field: ResourceFormFieldDef,\n control: UseFormReturn<Record<string, unknown>>[\"control\"],\n action: \"create\" | \"edit\",\n watchedValues: Record<string, unknown>,\n ) => ReactNode;\n action: \"create\" | \"edit\";\n onInvalid?: (errors: FieldErrors) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function WizardForm({\n steps,\n form,\n fields,\n onSubmit,\n isSaving,\n renderField,\n action,\n onInvalid,\n}: WizardFormProps) {\n const wizard = useWizard(steps, form);\n const watchedValues = useWatch({ control: form.control }) as Record<string, unknown>;\n\n // Get fields for the current step\n const stepFieldKeys = new Set(wizard.currentStepDef.fields);\n const stepFields = fields.filter(\n (f) => stepFieldKeys.has(f.key) && f.visible?.(watchedValues) !== false,\n );\n\n const handleNext = async () => {\n if (wizard.isLast) {\n // Submit the form\n await form.handleSubmit(onSubmit, onInvalid)();\n } else {\n await wizard.next();\n }\n };\n\n return (\n <div className=\"space-y-6\">\n {/* Progress */}\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between text-sm text-muted-foreground\">\n <span>\n Step {wizard.currentStep + 1} of {wizard.totalSteps}\n </span>\n <span>{Math.round(wizard.progress * 100)}%</span>\n </div>\n <Progress value={wizard.progress * 100} />\n </div>\n\n {/* Step header */}\n <div className=\"space-y-1\">\n <h3 className=\"text-lg font-semibold\">{wizard.currentStepDef.title}</h3>\n {wizard.currentStepDef.description && (\n <p className=\"text-sm text-muted-foreground\">\n {wizard.currentStepDef.description}\n </p>\n )}\n </div>\n\n {/* Step fields with transition */}\n <div\n key={wizard.currentStep}\n className=\"animate-in fade-in slide-in-from-right-2 duration-200\"\n >\n <div className=\"space-y-4\">\n {stepFields.map((field) =>\n renderField ? (\n <div key={field.key}>\n {renderField(field, form.control, action, watchedValues)}\n </div>\n ) : (\n <ResourceFormFieldRenderer\n key={field.key}\n field={field}\n control={form.control}\n action={action}\n watchedValues={watchedValues}\n />\n ),\n )}\n </div>\n </div>\n\n {/* Navigation buttons */}\n <div className=\"flex justify-between pt-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={wizard.back}\n disabled={wizard.isFirst || isSaving}\n >\n Back\n </Button>\n <Button\n type=\"button\"\n onClick={handleNext}\n disabled={isSaving}\n >\n {isSaving && <Spinner size=\"sm\" className=\"mr-2\" />}\n {wizard.isLast ? (action === \"create\" ? \"Create\" : \"Save\") : \"Next\"}\n </Button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { type ReactNode } from \"react\";\nimport type { UseFormReturn, FieldErrors } from \"react-hook-form\";\nimport { useWatch } from \"react-hook-form\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n} from \"../ui/dialog\";\nimport {\n Sheet,\n SheetContent,\n SheetHeader,\n SheetTitle,\n SheetDescription,\n} from \"../ui/sheet\";\nimport { Card, CardHeader, CardTitle, CardContent } from \"../ui/card\";\nimport { Button } from \"../ui/button\";\nimport { Spinner } from \"../ui/spinner\";\nimport { useIsMobile } from \"../../hooks/use-mobile\";\nimport { useResourceForm, type UseResourceFormOptions } from \"@marktiderman/genesis-core/hooks\";\nimport { ResourceFormFieldRenderer, type ResourceFormFieldDef } from \"./ResourceFormField\";\nimport { WizardForm } from \"./WizardForm\";\nimport type { WizardStep } from \"@marktiderman/genesis-core/hooks\";\nimport { titleCase } from \"../../hooks/use-resource-page\";\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface ResourceFormProps {\n resource: string;\n action: \"create\" | \"edit\";\n item?: Record<string, unknown>;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title?: string;\n fields?: ResourceFormFieldDef[];\n /** Full dataset used to auto-detect select fields from unique values. */\n listData?: Record<string, unknown>[];\n renderForm?: (\n form: UseFormReturn<Record<string, unknown>>,\n fields: ResourceFormFieldDef[],\n ) => ReactNode;\n onSuccess?: (data: Record<string, unknown>) => void;\n onError?: (error: Error) => void;\n /** Layout mode for the form container. Default \"dialog\". */\n layout?: \"dialog\" | \"sheet\" | \"page\";\n /** Form presentation mode. Default \"standard\". */\n mode?: \"standard\" | \"wizard\";\n /** Wizard step definitions. Required when mode is \"wizard\". */\n steps?: WizardStep[];\n /** Number of columns for the form layout. Default 1. */\n columns?: 1 | 2;\n}\n\n// ---------------------------------------------------------------------------\n// Internal: shared form body\n// ---------------------------------------------------------------------------\n\nfunction FormBody({\n form,\n resolvedFields,\n renderForm,\n action,\n isSaving,\n isLoading,\n onOpenChange,\n handleSave,\n mode = \"standard\",\n steps,\n columns = 1,\n}: {\n form: UseFormReturn<Record<string, unknown>>;\n resolvedFields: ResourceFormFieldDef[];\n renderForm?: ResourceFormProps[\"renderForm\"];\n action: \"create\" | \"edit\";\n isSaving: boolean;\n isLoading: boolean;\n onOpenChange: (open: boolean) => void;\n handleSave: (data: Record<string, unknown>) => Promise<void>;\n mode?: \"standard\" | \"wizard\";\n steps?: WizardStep[];\n columns?: 1 | 2;\n}) {\n // Only watch all values when conditional fields exist (performance optimization)\n const hasConditionalFields = resolvedFields.some((f: ResourceFormFieldDef) => f.visible || f.disabled);\n const watchedValues = useWatch({\n control: form.control,\n disabled: !hasConditionalFields,\n }) as Record<string, unknown>;\n\n const onInvalid = (errors: FieldErrors) => {\n const firstErrorKey = Object.keys(errors)[0];\n if (firstErrorKey) form.setFocus(firstErrorKey);\n };\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center py-8\">\n <Spinner />\n </div>\n );\n }\n\n // Wizard mode\n if (mode === \"wizard\" && steps) {\n return (\n <WizardForm\n steps={steps}\n form={form}\n fields={resolvedFields}\n onSubmit={handleSave}\n isSaving={isSaving}\n action={action}\n onInvalid={onInvalid}\n />\n );\n }\n\n // Filter fields by visibility\n const visibleFields = resolvedFields.filter(\n (field) => field.visible?.(watchedValues) !== false,\n );\n\n let autoFocusAssigned = false;\n\n // Group fields by their `group` property\n const groups: { name: string | null; fields: ResourceFormFieldDef[] }[] = [];\n const groupMap = new Map<string | null, ResourceFormFieldDef[]>();\n\n for (const field of visibleFields) {\n const groupKey = field.group ?? null;\n if (!groupMap.has(groupKey)) {\n const arr: ResourceFormFieldDef[] = [];\n groupMap.set(groupKey, arr);\n groups.push({ name: groupKey, fields: arr });\n }\n groupMap.get(groupKey)!.push(field);\n }\n\n /** Render a list of fields with optional 2-column grid */\n function renderFields(fields: ResourceFormFieldDef[]) {\n const useGrid = columns === 2;\n return (\n <div className={useGrid ? \"grid grid-cols-2 gap-4\" : \"space-y-4\"}>\n {fields.map((field) => {\n const isHidden = field.hidden || field.type === \"hidden\";\n const shouldAutoFocus = !isHidden && !autoFocusAssigned;\n if (shouldAutoFocus) autoFocusAssigned = true;\n // Auto-span 2 columns for textarea and array fields in 2-column mode\n const autoSpan =\n useGrid && (field.type === \"textarea\" || field.type === \"array\") ? 2 : undefined;\n const span = useGrid ? (field.colSpan ?? autoSpan ?? 1) : undefined;\n return (\n <div key={field.key} className={span === 2 ? \"col-span-2\" : \"\"}>\n <ResourceFormFieldRenderer\n field={field}\n control={form.control}\n action={action}\n autoFocus={shouldAutoFocus}\n watchedValues={watchedValues}\n />\n </div>\n );\n })}\n </div>\n );\n }\n\n return (\n <form\n onSubmit={(e) => {\n e.preventDefault();\n void form.handleSubmit(handleSave, onInvalid)(e);\n }}\n className=\"space-y-4\"\n >\n <div className=\"max-h-[60vh] overflow-y-auto px-1\">\n {renderForm ? (\n renderForm(form, visibleFields)\n ) : (\n <div className=\"space-y-4\">\n {groups.map((group, idx) => (\n <div key={group.name ?? \"__default\"}>\n {group.name && (\n <div className=\"pt-2\">\n {idx > 0 && <div className=\"border-t mb-3\" />}\n <h3 className=\"text-sm font-medium text-muted-foreground mb-3\">\n {group.name}\n </h3>\n </div>\n )}\n {renderFields(group.fields)}\n </div>\n ))}\n </div>\n )}\n </div>\n\n <div className=\"flex justify-end gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n disabled={isSaving}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={isSaving}>\n {isSaving && <Spinner size=\"sm\" className=\"mr-2\" />}\n {action === \"create\" ? \"Create\" : \"Save\"}\n </Button>\n </div>\n </form>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function ResourceForm(props: ResourceFormProps) {\n const {\n resource,\n action,\n item,\n open,\n onOpenChange,\n title: titleProp,\n fields: fieldsProp,\n listData,\n renderForm,\n onSuccess,\n onError,\n layout: layoutProp = \"dialog\",\n mode = \"standard\",\n steps,\n columns = 1,\n } = props;\n\n const isMobile = useIsMobile();\n const effectiveLayout = isMobile ? \"sheet\" : layoutProp;\n\n const resourceLabel = titleCase(resource.replace(/s$/, \"\"));\n const formTitle =\n titleProp ?? (action === \"create\" ? `Create ${resourceLabel}` : `Edit ${resourceLabel}`);\n const formDescription =\n `${action === \"create\" ? \"Fill in the details to create a new\" : \"Update the\"} ${resourceLabel.toLowerCase()} record.`;\n\n const hookOptions: UseResourceFormOptions = {\n resource,\n action,\n id: item ? String(item.id ?? \"\") : undefined,\n initialData: item ?? undefined,\n fields: fieldsProp,\n listData,\n onSuccess: (data) => {\n onOpenChange(false);\n onSuccess?.(data);\n },\n onError,\n };\n\n const { form, resolvedFields, handleSave, isSaving, isLoading } =\n useResourceForm(hookOptions);\n\n const bodyProps = {\n form,\n resolvedFields,\n renderForm,\n action,\n isSaving,\n isLoading,\n onOpenChange,\n handleSave,\n mode,\n steps,\n columns,\n };\n\n // ── Dialog layout ──\n if (effectiveLayout === \"dialog\") {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-[560px]\">\n <DialogHeader>\n <DialogTitle>{formTitle}</DialogTitle>\n <DialogDescription className=\"sr-only\">\n {formDescription}\n </DialogDescription>\n </DialogHeader>\n <FormBody {...bodyProps} />\n </DialogContent>\n </Dialog>\n );\n }\n\n // ── Sheet layout ──\n if (effectiveLayout === \"sheet\") {\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent side=\"right\" className=\"sm:max-w-[480px] overflow-y-auto\">\n <SheetHeader>\n <SheetTitle>{formTitle}</SheetTitle>\n <SheetDescription className=\"sr-only\">\n {formDescription}\n </SheetDescription>\n </SheetHeader>\n <FormBody {...bodyProps} />\n </SheetContent>\n </Sheet>\n );\n }\n\n // ── Page layout ──\n if (!open) return null;\n\n return (\n <Card className=\"mx-auto max-w-[560px]\">\n <CardHeader>\n <CardTitle>{formTitle}</CardTitle>\n </CardHeader>\n <CardContent>\n <FormBody {...bodyProps} />\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport {\n Fragment,\n type KeyboardEvent as ReactKeyboardEvent,\n type ComponentProps,\n type ComponentType,\n type ReactNode,\n useMemo,\n useState,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport type { UseFormReturn } from \"react-hook-form\";\nimport {\n AlertTriangle,\n ChevronLeft,\n ChevronRight,\n Plus,\n Trash2,\n} from \"lucide-react\";\nimport { Button } from \"../ui/button\";\nimport { cn } from \"../../utils\";\nimport { DataPageShell } from \"./DataPageShell\";\nimport type { PageHeaderAction } from \"../layout/PageHeader\";\nimport {\n DataFilters,\n type SavedViewItem,\n type DataFilterConfig,\n} from \"./DataFilters\";\nimport { DataTable } from \"./DataTable\";\nimport { DataBulkBar } from \"./DataBulkBar\";\nimport { DataGrid } from \"./DataGrid\";\nimport { DetailPanel } from \"./DetailPanel\";\nimport { ResourceForm } from \"./ResourceForm\";\nimport {\n renderSlot,\n type Slots,\n type SlotPropsFor,\n} from \"../../slots\";\nimport { Card, CardHeader, CardTitle, CardContent } from \"../ui/card\";\nimport type { ViewMode } from \"../patterns/view-toggle\";\nimport {\n useResource,\n type UseResourceOptions,\n} from \"@marktiderman/genesis-core/hooks\";\nimport {\n useResourcePage,\n type ResourceColumnDef,\n type ResourceActions,\n} from \"../../hooks/use-resource-page\";\nimport { useViewSettings } from \"../../hooks/use-view-settings\";\nimport { useKeyboardNavigation } from \"../../hooks/use-keyboard-navigation\";\nimport type {\n BaseRecord,\n FilterParam,\n SortParam,\n} from \"@marktiderman/genesis-core/provider\";\nimport type { ResourceFormFieldDef } from \"./ResourceFormField\";\nimport type { WizardStep } from \"@marktiderman/genesis-core/hooks\";\nimport { defaultNavigate, type NavigateFn } from \"../../navigation\";\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\n/**\n * Row-bound actions handed to `renderCard`, on top of the resource-wide\n * `ResourceActions`. `open` is per-row, which is why it lives here rather\n * than on `ResourceActions` — that object is built once and shared by every\n * row and column, so it cannot carry a row-specific callback.\n *\n * @stability Beta\n */\nexport interface ResourceCardActions<T> extends ResourceActions<T> {\n /**\n * Activate this row — opens the configured detail panel / modal / route,\n * exactly as clicking the built-in card does. Wire it to your card's\n * `onClick` (and call `stopPropagation` on any nested control that should\n * not also activate the row).\n */\n open: () => void;\n}\n\n/**\n * Config-driven resource page: wires data-fetching (or a pre-fetched `data`\n * array), search/filter/sort, table/grid/list views, and a detail\n * panel/modal/route around a `DataProvider` resource — the CRUD page most\n * apps hand-roll, expressed as one component tree. `renderCard` lets a\n * consumer fully own item presentation while ResourcePage keeps handling\n * data-fetching, filtering, and layout; see also the built-in\n * `useKeyboardNavigation` wiring (`keyboardNavigation` prop) and `gridCols`.\n *\n * Three levels of control, and each option is available at all three:\n *\n * 1. **The primitive offers it** — table / grid / list views, search, sort,\n * status chips, column visibility and resizing, density, page size,\n * detail panel / modal / route, built-in create and edit forms.\n * 2. **The instance turns it on or off** — every one of those is a prop, so\n * a given page decides which affordances it offers at all.\n * 3. **The end user picks their own, and it sticks** — for the options left\n * on at level 2, the user's choice persists to their own storage:\n * `viewSettingsKey` for page size and density, `columnVisibilityKey` and\n * `resizeKey` for column layout, `savedViews` (pair with `useSavedViews`)\n * for named filter sets. Persistence needs a key; without one the choice\n * lasts only for the session.\n *\n * A server-paginated list drives the same component through the controlled\n * props (`page`, `perPage`, `onPageChange`, `onSortChange`, `onSearchChange`\n * and friends) — supplying any of them stops ResourcePage from searching,\n * sorting or paging the `data` a second time. See that block in\n * {@link ResourcePageProps}.\n *\n * @stability Beta\n */\n/**\n * Every interior part `ResourcePage` composes, with the props it composes it\n * with. Each key is a slot: replace it via `slots`, feed it more props via\n * `slotProps`, or eject it with `null`.\n *\n * The map is the contract. A part that is not named here cannot be reached,\n * so adding a part to the render tree means adding it here in the same\n * change — otherwise the next surface that needs it forks the whole page.\n */\nexport type ResourcePageSlotMap<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** The page shell: header, count pill, loading / empty / error states. */\n shell: ComponentProps<typeof DataPageShell>;\n /** The filter row — search, sort, facets, saved views. */\n filters: ComponentProps<typeof DataFilters>;\n /** The selection bar. Ejecting it leaves selection working, just unshown. */\n bulkBar: ComponentProps<typeof DataBulkBar>;\n /** The card/table switch. */\n grid: ComponentProps<typeof DataGrid<T>>;\n /** The table inside the grid. `renderTable` stays the terser way to swap. */\n table: ComponentProps<typeof DataTable<T>>;\n /** The detail peek. */\n detail: ComponentProps<typeof DetailPanel<T>>;\n /** The create / edit form. */\n form: ComponentProps<typeof ResourceForm>;\n};\n\n/**\n * `slots` for {@link ResourcePage}, with one asymmetry the map cannot express:\n * every part may be ejected with `null` EXCEPT `shell`.\n *\n * The shell is not an interior part, it is the page — `Shell` is what the\n * render returns, so ejecting it does not remove a piece, it removes the\n * component (`const Shell = slots?.shell ?? DataPageShell` would become\n * `null`, and React throws on the element). A caller who wants no shell wants\n * rung 3 of the ladder, not a `null` here. Replacing it stays supported, which\n * is the way to wrap it and change one thing.\n */\nexport type ResourcePageSlots<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = Omit<Slots<ResourcePageSlotMap<T>>, \"shell\"> & {\n shell?: ComponentType<ComponentProps<typeof DataPageShell>>;\n};\n\nexport interface ResourcePageProps<\n T extends Record<string, unknown> = Record<string, unknown>,\n> {\n // Data source — one or the other\n /** Client-side mode: resource name passed to useResource / DataProvider. */\n resource?: string;\n /** Server-data mode: pre-fetched data array. */\n data?: T[];\n /**\n * Server-data mode: total record count (before client-side filtering).\n *\n * Required whenever `onPageChange` is supplied. It cannot be derived from\n * `data`, which holds only the current page. Omitted, `displayTotal` falls\n * back to `0`, so the range span reads \"No records\" and `Next` stays\n * disabled while the rows render directly below it. Rather than show a\n * pager that contradicts the list, the component refuses to render the\n * pager and shows an error instead. See {@link perPage} and\n * {@link onPageChange}.\n */\n total?: number;\n\n // Page chrome\n title: string;\n /** Page subtitle shown below the title. */\n subtitle?: string;\n icon?: LucideIcon;\n\n // Columns — optional, string shorthand supported\n columns?: Array<string | ResourceColumnDef<T>>;\n\n // Detail view\n /** How row-click detail is shown. Default \"panel\". */\n detail?: \"panel\" | \"modal\" | \"route\" | \"none\";\n detailWidth?: \"sm\" | \"md\" | \"lg\";\n titleField?: string;\n subtitleField?: string;\n renderDetail?: (item: T) => ReactNode;\n detailFields?: Array<{\n key: string;\n label: string;\n render?: (value: unknown, item: T) => ReactNode;\n }>;\n\n // Filters\n /**\n * Adds a status-chip filter. There is no dedicated status-change\n * callback: chip clicks update the same filter state that already\n * reports through `onFiltersChange`, whether or not the page is in\n * server-controlled mode. A caller combining `statusFilter` with server\n * pagination (`onPageChange` et al.) must supply `onFiltersChange` — see\n * that prop — or status changes will update the chip UI without ever\n * reaching the server. In server-controlled mode a status change also\n * resets to page 1 via `onPageChange(1)` — see {@link onPageChange}.\n */\n statusFilter?: string | { field: string; options?: string[] };\n searchFields?: string[];\n searchPlaceholder?: string;\n initialFilters?: FilterParam[];\n onFiltersChange?: (filters: FilterParam[]) => void;\n /**\n * Extra multi-select filter comboboxes, handed straight to `DataFilters`\n * and rendered beside the status chips. Each config owns its own\n * `selected` array and `onChange` — ResourcePage never reads or writes\n * them, because it cannot know what a caller's \"Grade\" or \"Subject\"\n * combobox means against the row shape. That is deliberate rather than a\n * gap: the built-in machinery (`searchFields`, `statusFilter`) covers the\n * two shapes it *can* interpret, and this prop covers everything else by\n * getting out of the way.\n *\n * Two consequences of that hands-off stance, stated rather than hidden:\n * - These selections are invisible to `page.hasActiveFilters`, so the\n * header's \"Clear filters\" affordance does not appear for them alone,\n * and `onClearFilters` does not reset them. DataFilters' own \"Clear all\"\n * does call each config's `onChange([])`, so wire real clearing there.\n * - In client-side mode the rows are NOT re-filtered by these selections.\n * A caller using them is expected to filter its own `data` (or ask the\n * server to), exactly as it already does in server-controlled mode.\n */\n filters?: DataFilterConfig[];\n\n // ─────────────────────────────────────────────────────────────────────────\n // Server-controlled list (opt-in, additive)\n //\n // Supplying ANY prop in this block puts the page in server-controlled\n // mode, in which ResourcePage renders `data` exactly as given: it does not\n // search it, sort it or paginate it a second time. That double-work is the\n // reason a server-paginated list could not previously adopt ResourcePage —\n // page 3 of 40 would be re-filtered and re-sorted against only its own 25\n // rows, and then re-paged on top of that.\n //\n // Consequences, stated rather than hidden:\n // - Table column headers stop being sort triggers (a header click could\n // only reorder the current page, which would be a lie about the sort).\n // The sort control in `DataFilters` drives `onSortChange` instead.\n // - `DataTable`'s own pagination is switched off; the pager below the list\n // is driven by `page` / `perPage` / `total` / `onPageChange`, and is only\n // rendered when `onPageChange` is supplied. BOTH `perPage` AND `total`\n // are required for that pager's math, and neither can be derived from\n // the rows: a short final page is smaller than the real page size, so\n // `data.length` must not be used as the divisor, and `data` holds only\n // the current page, so it cannot supply the total either.\n // - Changing search or sort calls `onPageChange(1)` as well, so the caller\n // is never left requesting page 7 of a one-page result.\n // - Grid and list views are NOT forced to table view, and they render\n // cards for the current server page only. That is accepted rather than\n // worked around, because it is not actually wrong here: the pager is\n // rendered OUTSIDE DataGrid precisely so it pages grid and list too, so\n // \"this view shows one page, and there is a pager under it\" is the same\n // contract the table view has. Forcing `viewMode=\"table\"` would instead\n // silently discard a `renderCard` the caller supplied, and silently\n // overriding a user's own view choice is the worse failure. The one real\n // caveat: DataGrid's infinite-scroll batching (48 at a time) tops out at\n // the page size, so a server page smaller than 48 never scroll-loads —\n // harmless, but it means infinite scroll and server paging do not\n // compose into an endless list.\n // ─────────────────────────────────────────────────────────────────────────\n\n /** Current page, 1-based. Server-controlled mode only. */\n page?: number;\n /**\n * Rows per page the server was asked for. Required whenever\n * `onPageChange` is supplied: pager math (total pages, range start, Next)\n * cannot be inferred from `data.length`, because a short final page is\n * smaller than the real page size. Wins over the per-user page size\n * persisted by `viewSettingsKey` — an explicit prop always beats a stored\n * preference.\n *\n * Required whenever `onPageChange` is supplied. A short final page (the\n * server's last page returning fewer rows than its page size) is\n * indistinguishable from a small page size — there is no correct way to\n * infer the divisor from the rows handed back. Rather than guess and\n * render a wrong range or a stuck Next button, the component refuses to\n * render the pager and shows an error instead when `onPageChange` is\n * present without `perPage`.\n *\n * `total` is required on the same terms — see {@link total}. The error\n * names every missing prop, not just the first.\n */\n perPage?: number;\n /**\n * Called with the next 1-based page number. The pager only renders when\n * this is supplied AND both `perPage` and `total` are supplied — see\n * {@link perPage} and {@link total}. Supplying this without either one\n * renders an error naming the missing props instead of a pager.\n *\n * Status changes reach the server through `onFiltersChange` — not a\n * dedicated callback here — because `statusFilter` state is tracked by\n * the same filter machinery that already calls `onFiltersChange`\n * regardless of controlled mode (see {@link statusFilter}). In\n * server-controlled mode a status change also calls `onPageChange(1)`\n * directly, since the previous page number is meaningless against a new\n * filtered result set.\n */\n onPageChange?: (page: number) => void;\n /** Called when the user picks a different page size in the header's view settings. */\n onPerPageChange?: (perPage: number) => void;\n /** Called when the user changes the sort, with `null` when the sort is cleared. */\n onSortChange?: (sort: SortParam | null) => void;\n /** Called when the user changes the search text (including clearing it). */\n onSearchChange?: (search: string) => void;\n\n // ── Fetch state for server-data mode ──\n //\n // In client-side mode ResourcePage owns the fetch, so it knows on its own\n // when the list is in flight or has failed and renders the shell's spinner\n // or error panel accordingly. In server-data mode the caller owns the\n // fetch, and ResourcePage sees only the `data` array that comes out the\n // far end — which means a request that is still in flight and a request\n // that failed both arrive as `data={[]}`, indistinguishable from a\n // genuinely empty result. Left alone that renders a failed fetch as an\n // ordinary \"no records\" table: the page shows nothing and says nothing is\n // wrong, which is the worst of the three outcomes. These props let the\n // caller say which of the three it is. They are read only outside\n // client-side mode, so a `resource`-driven page behaves exactly as before\n // whether or not they are supplied.\n\n /**\n * Server-data mode: the caller's fetch is in flight, so render the shell's\n * loading skeleton instead of the (as yet meaningless) `data`. Ignored in\n * client-side mode, where `useResource`'s own loading state is used.\n */\n loading?: boolean;\n /**\n * Server-data mode: the caller's fetch failed, so render the shell's error\n * panel instead of an empty table. Takes effect even when `data` is\n * non-empty — stale rows beside no indication of failure are exactly the\n * silent-failure this prop exists to prevent. Ignored in client-side mode,\n * where `useResource`'s own error state is used.\n */\n error?: boolean;\n /**\n * Message shown in the error panel, in place of the shell's generic\n * \"Failed to load …\". Forwarded in both modes — it is inert unless an\n * error state is actually showing — so a client-side page can also give\n * its failure a human sentence.\n */\n errorMessage?: string;\n /**\n * Server-data mode: invoked by the error panel's Retry button. The button\n * only appears when this is supplied, so a caller with no way to retry\n * simply omits it and gets an error panel without a dead control. In\n * client-side mode the button is already wired to `useResource`'s own\n * `refetch` and this prop is ignored.\n */\n onRetry?: () => void;\n\n // ── Saved views — passed straight through to DataFilters ──\n /** Saved filter views to offer. Pair with `useSavedViews` for per-user storage. */\n savedViews?: SavedViewItem[];\n onLoadView?: (filters: Record<string, unknown>) => void;\n onSaveView?: (name: string) => void;\n onDeleteView?: (id: string) => void;\n /** Show the \"save current view\" affordance. */\n canSaveViews?: boolean;\n\n // ── Table chrome — passed straight through to DataTable ──\n /** Show the column-visibility dropdown. DataTable's default is `true`. */\n columnVisibility?: boolean;\n /** Persist key for the user's column-visibility picks. */\n columnVisibilityKey?: string;\n /** Allow drag-resizing columns. DataTable's default is `true`. */\n resizableColumns?: boolean;\n /** Persist key for the user's column widths. */\n resizeKey?: string;\n /** Keep the table header visible while scrolling. DataTable's default is `true`. */\n stickyHeader?: boolean;\n /** Keep the first column visible while scrolling horizontally. */\n stickyFirstColumn?: boolean;\n /**\n * Page-size choices offered by `DataTable`'s own pager. Client-side mode\n * only — server-controlled mode switches that pager off. (The header's\n * view-settings popover has its own fixed 10/25/50/100 list.)\n */\n pageSizeOptions?: number[];\n\n // CRUD — presence enables the action\n onCreate?: () => void;\n onEdit?: (item: T) => void;\n onDelete?: (item: T) => void;\n createLabel?: string;\n /**\n * Extra header actions beyond the create button, in one overflow menu.\n * See {@link PageHeaderAction} — the budget is one primary, the rest here.\n */\n secondaryActions?: PageHeaderAction[];\n\n // Built-in form support (Phase 2)\n /** Enable built-in create form (ignored if onCreate callback is provided). */\n allowCreate?: boolean;\n /** Enable built-in edit form (ignored if onEdit callback is provided). */\n allowEdit?: boolean;\n /** Field definitions for the built-in form. */\n formFields?: ResourceFormFieldDef[];\n /** Custom form renderer — receives form instance and resolved fields. */\n renderForm?: (\n form: UseFormReturn<Record<string, unknown>>,\n fields: ResourceFormFieldDef[],\n ) => ReactNode;\n\n /** Form presentation mode. Default \"standard\". */\n formMode?: \"standard\" | \"wizard\";\n /** Wizard step definitions. Required when formMode is \"wizard\". */\n formSteps?: WizardStep[];\n /** Layout mode for the built-in form container. If not set, defaults to sheet for edit, dialog for create. */\n formLayout?: \"dialog\" | \"sheet\" | \"page\";\n\n // Bulk actions\n bulkActions?: Array<{\n label: string;\n icon?: LucideIcon;\n variant?: \"default\" | \"destructive\";\n onAction: (ids: string[]) => void | Promise<void>;\n /**\n * Forwarded straight to the rendered bulk button (see `BulkAction`).\n * Exists so a consumer can kill every bulk action while one of them is\n * in flight — an early return inside `onAction` blocks the second call\n * but leaves the button looking live, which misstates what it will do.\n */\n disabled?: boolean;\n /** `data-testid` on the rendered bulk button, so e2e can drive it. */\n testId?: string;\n }>;\n\n // Grid/list rendering + keyboard nav\n /**\n * Override the default card renderer used for grid view (and, absent a\n * dedicated list layout, list view too — DataGrid falls back to the same\n * renderer there). ResourcePage still owns data-fetching, filtering,\n * sorting, and layout (grid columns, infinite-scroll batching, stagger\n * animation) — this only swaps what's rendered inside each item slot.\n *\n * Receives `ResourceCardActions`: the row's `update`/`remove`/`refetch`\n * plus `open()` to activate the row (opening the configured detail\n * panel/modal/route). Row activation is *not* applied automatically to a\n * custom card — wrapping it would double-fire against cards that bring\n * their own click handling and would hijack clicks on nested buttons — so\n * call `actions.open()` from wherever your card should activate.\n */\n renderCard?: (\n item: T,\n index: number,\n actions: ResourceCardActions<T>,\n ) => ReactNode;\n /**\n * Replace the built-in `DataTable` that table view renders, keeping every\n * other piece of the page — header, counts, view settings, filters,\n * bulk bar, detail panel, form, pager — exactly as it is. The counterpart\n * to `renderCard`, which does the same for grid and list view.\n *\n * Receives the rows for the current view, which in server-controlled mode\n * is precisely the page the server returned. Ownership is total: row\n * click-through, selection, density, column visibility and resizing are\n * all things the built-in table wires for you and a custom table must\n * wire for itself. That is the trade this prop makes, and it is why\n * `renderCard` remains the lighter option when only the *cells* need to\n * change — a `ResourceColumnDef.render` is lighter still.\n *\n * Omitted, the default `DataTable` render is used unchanged.\n */\n renderTable?: (items: T[]) => ReactNode;\n /**\n * Tailwind grid-column classes for the card grid, passed through to\n * `DataGrid`'s `gridCols` — e.g. `\"grid-cols-1 sm:grid-cols-2 lg:grid-cols-3\"`.\n * Defaults to DataGrid's own responsive 1/2/3/4-column ramp.\n */\n gridCols?: string;\n /**\n * Built-in list keyboard navigation via `useKeyboardNavigation`: j/k (or\n * Arrow Up/Down) move a focus cursor, Enter opens the focused item,\n * Backspace (⌫) closes an open detail view, and x toggles the focused\n * item's selection when `bulkActions` are configured. Set to `false` to\n * opt out.\n *\n * Default-on, and scoped so that being on by default stays safe:\n * - Only while the grid or list view is showing. Table view keeps its own\n * independent sort/pagination, so a flat focus index can't reliably map\n * onto its visible rows.\n * - Cursor keys suspend while a detail panel/modal or the built-in form\n * is open, so they can't drive the list behind the overlay; ⌫ stays\n * live there so it can close it.\n * - Backspace is only intercepted while there's an open detail to close.\n * - Modified chords (Ctrl/Cmd/Alt) are never captured, so an app's\n * Cmd+K-style shortcuts keep working.\n */\n keyboardNavigation?: boolean;\n\n // Slots\n toolbar?: ReactNode;\n emptyState?: ReactNode;\n\n /**\n * Imperative navigation used only when `detail=\"route\"` (navigates to\n * `/{resource}/{id}` on row click). Defaults to a full-page navigation.\n * Router consumers pass their navigate fn — e.g. RR `useNavigate()` or\n * Next `router.push`.\n */\n onNavigate?: NavigateFn;\n\n // Data options (client-side mode only)\n resourceOptions?: UseResourceOptions<T>;\n defaultView?: ViewMode;\n /**\n * Persist key for density / page size via `useViewSettings`.\n * Defaults to `resource` or a slug of `title`.\n */\n viewSettingsKey?: string;\n\n /**\n * The interior parts `ResourcePage` composes, by name. Replace one with your\n * own component, or pass `null` to eject it entirely — see\n * {@link ResourcePageSlots}.\n *\n * This is the reason a surface that needs one part to differ does not have\n * to drop to the primitives and re-derive the pagination, selection and\n * detail wiring that were already correct.\n */\n slots?: ResourcePageSlots<T>;\n /** Extra props merged into a part you are KEEPING. Wins over ours. */\n slotProps?: SlotPropsFor<ResourcePageSlotMap<T>>;\n /** Merged onto the page shell's root. */\n className?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function ResourcePage<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(props: ResourcePageProps<T>) {\n const {\n resource: resourceName,\n data: dataProp,\n total: totalProp,\n title,\n subtitle,\n icon,\n columns: columnsProp,\n detail = \"panel\",\n detailWidth = \"md\",\n titleField: titleFieldProp,\n subtitleField: subtitleFieldProp,\n renderDetail: renderDetailProp,\n detailFields,\n statusFilter,\n searchFields,\n searchPlaceholder,\n initialFilters,\n onFiltersChange,\n filters: filtersProp,\n page: pageProp,\n perPage: perPageProp,\n onPageChange,\n onPerPageChange,\n onSortChange,\n onSearchChange,\n loading: loadingProp,\n error: errorProp,\n errorMessage,\n onRetry: onRetryProp,\n savedViews,\n onLoadView,\n onSaveView,\n onDeleteView,\n canSaveViews,\n columnVisibility,\n columnVisibilityKey,\n resizableColumns,\n resizeKey,\n stickyHeader,\n stickyFirstColumn,\n pageSizeOptions,\n onCreate,\n onEdit,\n onDelete,\n createLabel = \"New\",\n secondaryActions,\n allowCreate,\n allowEdit,\n formFields,\n renderForm: renderFormProp,\n formMode,\n formSteps,\n formLayout: formLayoutProp,\n bulkActions,\n renderCard: renderCardProp,\n renderTable: renderTableProp,\n gridCols: gridColsProp,\n keyboardNavigation = true,\n toolbar,\n emptyState,\n resourceOptions,\n defaultView = \"table\",\n onNavigate = defaultNavigate,\n viewSettingsKey: viewSettingsKeyProp,\n slots,\n slotProps,\n className,\n } = props;\n\n // ── Determine mode ──\n const isClientMode = !!resourceName;\n\n /**\n * Server-controlled mode is entered by supplying ANY of the controlled\n * props — presence is the switch, so a caller that only pages (no server\n * search) still gets its `data` left alone.\n */\n const isServerControlled =\n pageProp !== undefined ||\n perPageProp !== undefined ||\n onPageChange !== undefined ||\n onPerPageChange !== undefined ||\n onSortChange !== undefined ||\n onSearchChange !== undefined;\n\n const viewSettingsKey =\n viewSettingsKeyProp ??\n resourceName ??\n title.toLowerCase().replace(/\\s+/g, \"-\");\n const { settings, updateSetting } = useViewSettings(viewSettingsKey);\n\n /** Explicit prop beats the per-user stored preference. */\n const effectivePageSize = perPageProp ?? settings.pageSize;\n\n // ── Client-side mode: call useResource (hook is always called for rules-of-hooks) ──\n // Core's useResource constrains its row type to BaseRecord (rows carry an\n // `id`), which is stricter than ResourcePage's public `T extends\n // Record<string, unknown>`. Intersect at the call site so the public\n // ResourcePageProps<T> generic stays unchanged while satisfying the hook.\n const resourceHook = useResource<T & BaseRecord>(\n resourceName ?? \"__noop__\",\n isClientMode ? resourceOptions : { enabled: false },\n );\n\n // ── Resolve display data ──\n const displayData: T[] = isClientMode\n ? (resourceHook.list.data?.data ?? [])\n : (dataProp ?? []);\n const displayTotal: number = isClientMode\n ? (resourceHook.list.data?.total ?? 0)\n : (totalProp ?? 0);\n // Client-side mode reads the hook it owns; server-data mode reads the\n // caller's `loading` / `error` props, defaulting to false so a page that\n // supplies neither renders exactly as it did before they existed.\n const isLoading = isClientMode\n ? resourceHook.list.isLoading\n : (loadingProp ?? false);\n const hasError = isClientMode\n ? resourceHook.list.isError\n : (errorProp ?? false);\n\n // ── Call useResourcePage ──\n const page = useResourcePage<T>({\n resource: resourceName,\n data: displayData,\n total: displayTotal,\n columns: columnsProp,\n statusFilter,\n searchFields,\n initialFilters,\n onFiltersChange,\n defaultView,\n detail,\n titleField: titleFieldProp,\n subtitleField: subtitleFieldProp,\n controlled: isServerControlled,\n });\n\n // ── Build ResourceActions for column render functions ──\n const actions: ResourceActions<T> = useMemo(() => {\n if (isClientMode) {\n return {\n update: resourceHook.update as ResourceActions<T>[\"update\"],\n remove: resourceHook.remove,\n refetch: () => resourceHook.list.refetch(),\n };\n }\n return {\n update: async () => {\n throw new Error(\n \"ResourceActions.update not available in server-data mode\",\n );\n },\n remove: async () => {\n throw new Error(\n \"ResourceActions.remove not available in server-data mode\",\n );\n },\n refetch: () => {\n /* no-op in server-data mode */\n },\n };\n }, [\n isClientMode,\n resourceHook.update,\n resourceHook.remove,\n resourceHook.list,\n ]);\n\n // ── Bulk selection ──\n const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());\n\n const handleToggleSelect = useCallback((id: string) => {\n setSelectedIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }, []);\n\n const handleToggleAll = useCallback(() => {\n setSelectedIds((prev) => {\n if (prev.size === page.data.length) return new Set();\n return new Set(\n page.data.map((item) =>\n String((item as Record<string, unknown>).id ?? \"\"),\n ),\n );\n });\n }, [page.data]);\n\n const handleClearSelection = useCallback(() => {\n setSelectedIds(new Set());\n }, []);\n\n // ── Built-in form state ──\n const [formOpen, setFormOpen] = useState(false);\n const [formAction, setFormAction] = useState<\"create\" | \"edit\">(\"create\");\n const [formItem, setFormItem] = useState<T | null>(null);\n\n // Determine if built-in form should handle create/edit\n const useBuiltInCreate = allowCreate && !onCreate && isClientMode;\n const useBuiltInEdit = allowEdit && !onEdit && isClientMode;\n\n const handleCreate = useCallback(() => {\n if (useBuiltInCreate) {\n setFormAction(\"create\");\n setFormItem(null);\n setFormOpen(true);\n } else if (onCreate) {\n onCreate();\n }\n }, [useBuiltInCreate, onCreate]);\n\n const handleEdit = useCallback(\n (item: T) => {\n if (useBuiltInEdit) {\n setFormAction(\"edit\");\n setFormItem(item);\n setFormOpen(true);\n } else if (onEdit) {\n onEdit(item);\n }\n },\n [useBuiltInEdit, onEdit],\n );\n\n // ── Patch tableColumns to use real actions (client-side mode) ──\n const tableColumns = useMemo(() => {\n const base = isClientMode\n ? page.columns.map((col) => ({\n key: col.key,\n header: col.header ?? col.key,\n sortable: col.sortable ?? true,\n hideBelow: col.hideBelow,\n render: col.render\n ? (item: T, value: unknown) => col.render!(item, value, actions)\n : undefined,\n }))\n : page.tableColumns;\n if (!isServerControlled) return base;\n // The server owns the ordering. DataTable's header sort is client-side\n // and would only reorder the rows of the current page — a visibly wrong\n // answer presented as a sort — so the affordance is withdrawn rather\n // than left to lie. The DataFilters sort control drives `onSortChange`.\n return base.map((col) => ({ ...col, sortable: false }));\n }, [\n isClientMode,\n isServerControlled,\n page.columns,\n page.tableColumns,\n actions,\n ]);\n\n // ── Server-driven pager state, needed above for handleSearchChange's\n // already-on-page-1 check. ──\n const currentPage = pageProp ?? 1;\n\n // ── Filter changes: keep the controlled UI state, and tell the server ──\n // In client-side mode these are exactly the hook's own setters; in\n // server-controlled mode they additionally notify the caller and reset to\n // page 1, since the previous page number is meaningless against a new\n // query. The reset is skipped when already on page 1 — nothing changed,\n // so there is nothing for the caller to do.\n const handleSearchChange = useCallback(\n (value: string) => {\n page.filterConfig.onSearchChange(value);\n if (!isServerControlled) return;\n onSearchChange?.(value);\n if (currentPage !== 1) onPageChange?.(1);\n },\n [\n page.filterConfig,\n isServerControlled,\n onSearchChange,\n onPageChange,\n currentPage,\n ],\n );\n\n const handleSortSelect = useCallback(\n (value: string) => {\n page.filterConfig.onSortChange(value);\n if (!isServerControlled) return;\n const [field, order] = value.split(\":\");\n onSortChange?.(\n field && (order === \"asc\" || order === \"desc\")\n ? { field, order }\n : null,\n );\n onPageChange?.(1);\n },\n [page.filterConfig, isServerControlled, onSortChange, onPageChange],\n );\n\n const handleClearFilters = useCallback(() => {\n page.clearFilters();\n if (!isServerControlled) return;\n // Clearing has to reach the server too — otherwise \"Clear all\" empties\n // the controls and leaves the same rows on screen.\n onSearchChange?.(\"\");\n onSortChange?.(null);\n onPageChange?.(1);\n }, [page, isServerControlled, onSearchChange, onSortChange, onPageChange]);\n\n // ── Status-chip changes: same page-1 reset as search/sort ──\n // In server-controlled mode `useResourcePage` skips client-side status\n // filtering, so a status change only reaches the caller through\n // `onFiltersChange`. Nothing else calls `onPageChange(1)` for it, so\n // selecting a more restrictive status while on page 3 could otherwise\n // fetch page 3 of the new result set and render an empty page while the\n // matching rows sit on page 1. Guarded the same way as\n // `handleSearchChange`, and not reachable from `handleClearFilters`\n // (which already does its own single reset).\n const handleStatusChange = useCallback(\n (values: string[]) => {\n page.filterConfig.statusChips?.onChange(values);\n if (!isServerControlled) return;\n if (currentPage !== 1) onPageChange?.(1);\n },\n [page.filterConfig, isServerControlled, onPageChange, currentPage],\n );\n\n const statusChipsConfig = useMemo(() => {\n const base = page.filterConfig.statusChips;\n if (!base) return undefined;\n return { ...base, onChange: handleStatusChange };\n }, [page.filterConfig.statusChips, handleStatusChange]);\n\n const handlePageSizeChange = useCallback(\n (size: number) => {\n updateSetting(\"pageSize\", size);\n onPerPageChange?.(size);\n if (isServerControlled) onPageChange?.(1);\n },\n [updateSetting, onPerPageChange, isServerControlled, onPageChange],\n );\n\n // ── Pagination-config error ──\n // `perPage` AND `total` are both required whenever `onPageChange` is\n // supplied. Neither can be derived from the other, and neither can be\n // derived from the rows:\n // - `perPage`: see the prop doc on `perPage`. A short final page has\n // fewer rows than the page size, so the row count of a page cannot\n // stand in for the page size.\n // - `total`: `displayTotal` falls back to `0` (Line 453). With `total`\n // omitted the range span reads \"No records\" and `Next` stays\n // disabled, while `page.data` renders rows directly below it. A\n // surface that says \"no records\" above visible records is a lie, not\n // a degraded view.\n // Rather than silently guess either one, the pager below refuses to\n // render and shows the error instead. Logged once per mount (not on\n // every render) so it's visible in a console without spamming it.\n const missingPerPage =\n isServerControlled && !!onPageChange && perPageProp === undefined;\n const missingTotal =\n isServerControlled && !!onPageChange && totalProp === undefined;\n const pagerMisconfigured = missingPerPage || missingTotal;\n const missingPagerProps = [\n ...(missingPerPage ? [\"perPage\"] : []),\n ...(missingTotal ? [\"total\"] : []),\n ];\n const loggedMissingPerPageRef = useRef(false);\n useEffect(() => {\n if (!pagerMisconfigured) return;\n if (loggedMissingPerPageRef.current) return;\n loggedMissingPerPageRef.current = true;\n console.error(\n `ResourcePage: ${missingPagerProps\n .map((name) => `\\`${name}\\``)\n .join(\" and \")} ${\n missingPagerProps.length > 1 ? \"are\" : \"is\"\n } required when \\`onPageChange\\` is supplied.`,\n );\n // `missingPagerProps` is derived from `pagerMisconfigured`'s own inputs\n // and the ref makes this run at most once, so it is not a dependency.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pagerMisconfigured]);\n\n // ── Server-driven pager math ──\n // By the time the pager renders, `pagerMisconfigured` has already gated\n // it off, so `perPageProp` and `totalProp` are both present here.\n const pagerPageSize = perPageProp ?? effectivePageSize;\n const totalPages = Math.max(\n 1,\n Math.ceil(displayTotal / Math.max(1, pagerPageSize)),\n );\n const rangeFrom =\n page.data.length === 0 ? 0 : (currentPage - 1) * pagerPageSize + 1;\n const rangeTo = rangeFrom === 0 ? 0 : rangeFrom + page.data.length - 1;\n\n // ── Detail title/subtitle values ──\n const detailTitle = page.selectedItem\n ? String(\n (page.selectedItem as Record<string, unknown>)[page.titleField] ?? \"\",\n )\n : \"\";\n const detailSubtitle =\n page.selectedItem && page.subtitleField\n ? String(\n (page.selectedItem as Record<string, unknown>)[page.subtitleField] ??\n \"\",\n )\n : undefined;\n\n // ── Row click handler (route mode navigates) ──\n const handleRowClick = (item: T) => {\n if (detail === \"route\") {\n // Navigate to /{resource}/{id}\n const id = (item as Record<string, unknown>).id;\n if (resourceName && id) {\n onNavigate(`/${resourceName}/${id}`);\n }\n return;\n }\n page.handleRowClick(item);\n };\n\n // ── Keyboard navigation (j/k, Enter, Backspace, x) ──\n // Only engaged for grid/list views: table view runs its own independent\n // client-side sort + pagination (DataTable), so a flat index into\n // `page.data` can't reliably be mapped back onto its currently-visible,\n // possibly differently-ordered rows.\n const hasBulkSelect = !!bulkActions && bulkActions.length > 0;\n // A detail panel/modal or the built-in form is covering the list. Cursor\n // keys suspend (they'd otherwise drive the list behind the overlay, and\n // Enter would re-open the row instead of activating the focused control);\n // ⌫ stays live so it can dismiss the overlay.\n const overlayOpen = page.detailOpen || formOpen;\n const keyboardNav = useKeyboardNavigation({\n itemCount: page.data.length,\n enabled: keyboardNavigation && page.viewMode !== \"table\",\n overlayOpen,\n onOpen: (index) => {\n const item = page.data[index];\n if (item) handleRowClick(item);\n },\n onToggleSelect: hasBulkSelect\n ? (index) => {\n const item = page.data[index];\n if (item) {\n handleToggleSelect(\n String((item as Record<string, unknown>).id ?? \"\"),\n );\n }\n }\n : undefined,\n // Supplied only while there is an open detail to close — the hook\n // suppresses Backspace's default whenever this is present, so leaving it\n // wired up permanently would swallow the browser/app's Backspace on\n // every grid/list page (including detail=\"none\" and detail=\"route\",\n // which never open one). `detailOpen` is only ever true for the panel\n // and modal modes, so it is the precise precondition here.\n onBack: page.detailOpen\n ? () => {\n page.setDetailOpen(false);\n page.setSelectedItem(null);\n }\n : undefined,\n });\n\n // ── Create button ──\n const showCreateButton = onCreate || useBuiltInCreate;\n const createButton = showCreateButton ? (\n <Button size=\"sm\" onClick={handleCreate}>\n <Plus className=\"h-4 w-4 mr-1\" />\n {createLabel}\n </Button>\n ) : null;\n\n const createAction =\n toolbar || createButton ? (\n <div className=\"flex items-center gap-2\">\n {toolbar}\n {createButton}\n </div>\n ) : undefined;\n\n // ── Empty state ──\n const isEmpty = !isLoading && !hasError && page.data.length === 0;\n\n /**\n * Row-bound actions for a custom `renderCard`. The shared `actions` object\n * is memoized once for the whole resource, so the per-row `open()` is bound\n * here instead. Without it a custom card has no way to open the detail\n * panel/modal/route by pointer — the built-in cards get that from their own\n * onClick, which a custom card replaces.\n */\n const cardActionsFor = (item: T): ResourceCardActions<T> => ({\n ...actions,\n open: () => handleRowClick(item),\n });\n\n /**\n * Props that turn a plain `div`/`Card` into a real activatable row: a tab\n * stop, a button role, and Enter/Space activation to match the pointer\n * click. Without these the default card is reachable by mouse and by the\n * j/k cursor but not by Tab, which is the one path a keyboard-only user\n * actually has.\n *\n * Enter does not double-fire against the list cursor: `useKeyboardNavigation`\n * bails out whenever the event target owns its own keys, and `role=\"button\"`\n * is one of the roles it checks (covered by a test in\n * `resource-page-render-card-keyboard-nav.test.tsx`).\n */\n const rowActivationProps = (item: T, label: string, testId: string) => ({\n role: \"button\",\n tabIndex: 0,\n \"aria-label\": label || undefined,\n \"data-testid\": testId,\n onClick: () => handleRowClick(item),\n onKeyDown: (e: ReactKeyboardEvent<HTMLElement>) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleRowClick(item);\n }\n },\n });\n\n /** Default card renderer (grid view) — used unless `renderCard` is given. */\n const renderDefaultCard = (item: T): ReactNode => {\n const cols = page.columns;\n const titleCol = cols[0];\n const titleVal = titleCol\n ? String((item as Record<string, unknown>)[titleCol.key] ?? \"\")\n : \"\";\n // Second column is typically the status badge\n const badgeCol = cols[1];\n const badgeVal = badgeCol\n ? (item as Record<string, unknown>)[badgeCol.key]\n : null;\n // Find a numeric-looking column for the price position\n const priceCol = cols.find(\n (c, i) => i > 1 && /price|cost|amount|total/i.test(c.key),\n );\n const priceVal = priceCol\n ? (item as Record<string, unknown>)[priceCol.key]\n : null;\n // Remaining metadata columns (skip title, badge, price)\n const metaCols = cols.filter(\n (c) => c !== titleCol && c !== badgeCol && c !== priceCol,\n );\n return (\n <Card\n {...rowActivationProps(item, titleVal, \"resource-card\")}\n className=\"h-full cursor-pointer hover:shadow-md motion-safe:transition-shadow focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n >\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-base truncate\">{titleVal}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n {badgeCol && (\n <span>\n {badgeCol.render\n ? badgeCol.render(item, badgeVal, actions)\n : badgeVal != null\n ? String(badgeVal)\n : \"—\"}\n </span>\n )}\n {priceVal != null && (\n <span className=\"text-sm font-semibold\">\n {String(priceVal)}\n </span>\n )}\n </div>\n {metaCols.map((col) => {\n const val = (item as Record<string, unknown>)[col.key];\n return (\n <p\n key={col.key}\n className=\"text-xs text-muted-foreground truncate\"\n >\n {col.render\n ? col.render(item, val, actions)\n : val != null\n ? String(val)\n : \"—\"}\n </p>\n );\n })}\n </div>\n </CardContent>\n </Card>\n );\n };\n\n /** Default list-row renderer (list view) — used unless `renderCard` is given. */\n const renderDefaultListItem = (item: T): ReactNode => {\n const cols = page.columns;\n const titleCol = cols[0];\n const titleVal = titleCol\n ? String((item as Record<string, unknown>)[titleCol.key] ?? \"\")\n : \"\";\n return (\n <div\n {...rowActivationProps(item, titleVal, \"resource-list-row\")}\n className=\"flex items-center justify-between px-3 py-2 border-b cursor-pointer hover:bg-muted/50 motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\"\n >\n <span className=\"font-medium text-sm truncate\">{titleVal}</span>\n <div className=\"flex items-center gap-3 text-xs text-muted-foreground\">\n {cols.slice(1, 4).map((col) => {\n const val = (item as Record<string, unknown>)[col.key];\n return (\n <span key={col.key}>\n {col.render\n ? col.render(item, val, actions)\n : val != null\n ? String(val)\n : \"—\"}\n </span>\n );\n })}\n </div>\n </div>\n );\n };\n\n // The root slot. Unlike the interior parts it cannot be ejected — a page\n // with no shell is not a page — so it resolves to a component, never null.\n // `slotProps.shell` merges last and wins, except `className`, which is\n // merged rather than replaced so a consumer adding a class does not\n // silently drop the shell's own layout.\n const Shell = slots?.shell ?? DataPageShell;\n const shellSlotProps = slotProps?.shell;\n\n return (\n <Shell\n title={title}\n subtitle={subtitle}\n icon={icon}\n count={page.data.length}\n totalCount={displayTotal}\n isLoading={isLoading}\n hasError={hasError}\n isEmpty={isEmpty}\n errorMessage={errorMessage}\n onRetry={isClientMode ? () => resourceHook.list.refetch() : onRetryProp}\n viewMode={page.viewMode}\n onViewModeChange={page.setViewMode}\n pageSize={effectivePageSize}\n onPageSizeChange={handlePageSizeChange}\n density={settings.density}\n onDensityChange={(d) => updateSetting(\"density\", d)}\n createAction={createAction}\n secondaryActions={secondaryActions}\n hasActiveFilters={page.hasActiveFilters}\n onClearFilters={handleClearFilters}\n emptyAction={emptyState}\n filters={renderSlot(\n DataFilters,\n slots?.filters,\n {\n search: page.filterConfig.search,\n onSearchChange: handleSearchChange,\n searchPlaceholder,\n sort: page.filterConfig.sort,\n onSortChange: handleSortSelect,\n sortOptions: page.filterConfig.sortOptions,\n filters: filtersProp,\n statusChips: statusChipsConfig,\n savedViews,\n onLoadView,\n onSaveView,\n onDeleteView,\n canSaveViews,\n onClearAll: page.hasActiveFilters ? handleClearFilters : undefined,\n },\n slotProps?.filters,\n )}\n {...shellSlotProps}\n className={cn(className, shellSlotProps?.className)}\n >\n {bulkActions &&\n bulkActions.length > 0 &&\n renderSlot(\n DataBulkBar,\n slots?.bulkBar,\n {\n selected: selectedIds,\n totalCount: page.data.length,\n onToggleAll: handleToggleAll,\n onClearSelection: handleClearSelection,\n actions: bulkActions.map((a) => ({\n label: a.label,\n icon: a.icon ?? Trash2,\n variant: a.variant,\n disabled: a.disabled,\n testId: a.testId,\n onClick: () => {\n void a.onAction(Array.from(selectedIds));\n },\n })),\n },\n slotProps?.bulkBar,\n )}\n\n {renderSlot(\n DataGrid<T>,\n slots?.grid,\n {\n items: page.data,\n viewMode: page.viewMode,\n gridCols: gridColsProp,\n getKey: (item: T) =>\n String((item as Record<string, unknown>).id ?? \"\"),\n focusedIndex: keyboardNav.focusedIndex,\n keyboardContainerRef: keyboardNav.containerRef,\n renderTable: (items: T[]) =>\n renderTableProp ? (\n renderTableProp(items)\n ) : (\n renderSlot(\n DataTable<T>,\n slots?.table,\n {\n items,\n columns: tableColumns,\n getKey: (item: T) =>\n String((item as Record<string, unknown>).id ?? \"\"),\n onRowClick: detail !== \"none\" ? handleRowClick : undefined,\n selectable: !!bulkActions && bulkActions.length > 0,\n selected: selectedIds,\n onToggleSelect: handleToggleSelect,\n onToggleAll: handleToggleAll,\n density: settings.density,\n pageSize: effectivePageSize,\n pageSizeOptions,\n columnVisibility,\n columnVisibilityKey,\n resizableColumns,\n resizeKey,\n stickyHeader,\n stickyFirstColumn,\n // The server already cut the page window; DataTable's own\n // pagination would slice the slice.\n pagination: isServerControlled ? false : undefined,\n },\n slotProps?.table,\n )\n )\n ,\n renderCard: (item: T, index: number) =>\n renderCardProp\n ? renderCardProp(item, index, cardActionsFor(item))\n : renderDefaultCard(item),\n renderListItem: (item: T, index: number) =>\n renderCardProp\n ? renderCardProp(item, index, cardActionsFor(item))\n : renderDefaultListItem(item),\n },\n slotProps?.grid,\n )}\n\n {/* Server-driven pager. Rendered only when `onPageChange` is supplied —\n without a handler the buttons would be decoration, and a control\n that does nothing is worse than no control. It sits outside\n DataGrid so it pages the grid and list views too, not just the\n table.\n\n When `onPageChange` is supplied without `perPage`, this renders an\n error instead of a pager computed from a guess — see the\n `pagerMisconfigured` comment above. A pager reporting the wrong range\n with a Next button that never disables is worse than one that\n says why it can't render. */}\n {isServerControlled && onPageChange && pagerMisconfigured && (\n <div\n className=\"flex items-center gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive\"\n data-testid=\"resource-page-pagination-error\"\n role=\"alert\"\n >\n <AlertTriangle className=\"h-4 w-4 shrink-0\" aria-hidden=\"true\" />\n <span>\n Pagination unavailable:{\" \"}\n {missingPagerProps.map((name, index) => (\n <Fragment key={name}>\n {index > 0 ? \" and \" : null}\n <code>{name}</code>\n </Fragment>\n ))}{\" \"}\n {missingPagerProps.length > 1 ? \"are\" : \"is\"} required when{\" \"}\n <code>onPageChange</code> is supplied.\n </span>\n </div>\n )}\n {isServerControlled && onPageChange && !pagerMisconfigured && (\n <nav\n aria-label=\"Pagination\"\n className=\"flex flex-col sm:flex-row items-center justify-between gap-2 px-3 py-2 text-sm\"\n data-testid=\"resource-page-pagination\"\n >\n <span\n className=\"text-muted-foreground\"\n data-testid=\"resource-page-range\"\n aria-live=\"polite\"\n >\n {displayTotal === 0\n ? \"No records\"\n : `Showing ${rangeFrom}-${rangeTo} of ${displayTotal}`}\n </span>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={currentPage <= 1}\n onClick={() => onPageChange(currentPage - 1)}\n testID=\"resource-page-prev\"\n >\n <ChevronLeft className=\"h-4 w-4 mr-1\" aria-hidden=\"true\" />\n Previous\n </Button>\n <span\n className=\"text-muted-foreground\"\n data-testid=\"resource-page-indicator\"\n >\n Page {currentPage} of {totalPages}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={currentPage >= totalPages}\n onClick={() => onPageChange(currentPage + 1)}\n testID=\"resource-page-next\"\n >\n Next\n <ChevronRight className=\"h-4 w-4 ml-1\" aria-hidden=\"true\" />\n </Button>\n </div>\n </nav>\n )}\n\n {/* Detail panel / modal — DetailPanel's `layout` prop picks the shell;\n \"panel\" gets its default fixed slide-in sheet, \"modal\" gets a\n centered dialog. Both share one implementation (header, content,\n edit/delete affordances) instead of ResourcePage hand-rolling a\n second Dialog. */}\n {(detail === \"panel\" || detail === \"modal\") && (\n renderSlot(\n DetailPanel<T>,\n slots?.detail,\n {\n item: page.selectedItem,\n open: page.detailOpen,\n onClose: () => {\n page.setDetailOpen(false);\n page.setSelectedItem(null);\n },\n title: detailTitle,\n subtitle: detailSubtitle,\n onEdit: onEdit ?? (useBuiltInEdit ? handleEdit : undefined),\n onDelete,\n fields: detailFields,\n width: detailWidth,\n layout: detail === \"modal\" ? \"dialog\" : \"sheet\",\n children: renderDetailProp\n ? (item: T) => renderDetailProp(item)\n : undefined,\n },\n slotProps?.detail,\n )\n )}\n {/* Built-in create/edit form */}\n {(useBuiltInCreate || useBuiltInEdit) && resourceName && (\n renderSlot(\n ResourceForm,\n slots?.form,\n {\n resource: resourceName,\n action: formAction,\n layout:\n formLayoutProp ?? (formAction === \"edit\" ? \"sheet\" : \"dialog\"),\n mode: formMode,\n steps: formSteps,\n item:\n formAction === \"edit\"\n ? ((formItem as Record<string, unknown> | null) ?? undefined)\n : page.data.length > 0\n ? Object.fromEntries(\n Object.keys(page.data[0] as Record<string, unknown>)\n .filter((k) => k !== \"id\")\n .map((k) => [k, \"\"]),\n )\n : undefined,\n open: formOpen,\n onOpenChange: setFormOpen,\n fields: formFields,\n listData: page.data as Record<string, unknown>[],\n renderForm: renderFormProp,\n onSuccess: () => {\n // Data auto-refreshes via TanStack Query invalidation in useResourceForm\n page.setDetailOpen(false);\n page.setSelectedItem(null);\n },\n },\n slotProps?.form,\n )\n )}\n </Shell>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { AlertTriangle } from \"lucide-react\";\nimport { useOne } from \"@marktiderman/genesis-core/hooks\";\nimport type { BaseRecord, Identifier } from \"@marktiderman/genesis-core/provider\";\nimport { DetailPage } from \"../layout/detail-page\";\nimport { EmptyState } from \"../patterns/empty-state\";\nimport { PageLoading } from \"../patterns/page-loading\";\n\nexport interface ResourceDetailPageProps<T extends BaseRecord = BaseRecord> {\n /** Resource name, resolved through the mounted `DataProvider`. */\n resource: string;\n /**\n * Record id. Nullish means \"not resolved yet\" — no request goes out and the\n * page shows its loading state, which is what a route param that hasn't\n * arrived should look like. It is deliberately NOT the not-found state:\n * nothing has been asked, so nothing is missing.\n */\n id: Identifier | undefined | null;\n /**\n * Field used as the page title. Defaults to `name`, then `title`, then the\n * id — the same fallback chain `ResourcePage` uses for a row's label.\n */\n titleField?: string;\n /** Field used as the line under the title. */\n subtitleField?: string;\n /** Provider select/join syntax, e.g. `\"*, owner:profiles(name)\"`. */\n select?: string;\n /** Slot above the title: a `Breadcrumb`, a back link, a `StatusBadge`. */\n breadcrumb?: ReactNode;\n /** Record-scoped controls, built from the loaded record. */\n actions?: (record: T) => ReactNode;\n /** Metadata column, built from the loaded record. */\n sidebar?: (record: T) => ReactNode;\n /** The primary content region. */\n children: (record: T) => ReactNode;\n className?: string;\n /** Stable test/automation selector (emitted as `data-testid`). */\n testID?: string;\n}\n\n/** `name` -> `title` -> id. Mirrors `ResourcePage`'s row-label fallback. */\nfunction pick(record: BaseRecord, field: string | undefined): string {\n const value = field ? record[field] : record.name ?? record.title ?? record.id;\n return value == null ? \"\" : String(value);\n}\n\n/**\n * Does this error mean \"no such row\" rather than \"the request failed\"?\n *\n * Every provider Genesis ships reports a missing record by THROWING, not by\n * resolving with empty data, so without this the not-found state would be\n * dead code and a deleted record would show a generic failure carrying a raw\n * database string. Verified against each provider's `getOne` rather than\n * assumed:\n *\n * - `packages/core/src/provider/supabase-provider.ts` — `.single()`, whose\n * PostgREST error for zero rows is code `PGRST116`; `throwIfError` copies\n * `code` onto the thrown Error.\n * - `packages/core/src/provider/mock-provider.ts` — throws\n * `[MockProvider] Record not found: <resource>#<id>`.\n * - `packages/data-switchboard/src/data-provider.ts` — throws\n * `switchboard-data-provider: no \"<resource>\" row with id \"<id>\".`\n *\n * Deliberately narrow: anything it does not recognise falls through to the\n * error state, which is the safe direction. A custom provider that instead\n * resolves with no data is also handled — see the `!data` branch below.\n */\n/** The absent-record state, reached from two directions — see below. */\nfunction NotFound() {\n return (\n <EmptyState\n title=\"Not found\"\n description=\"This record no longer exists, or you don't have access to it.\"\n />\n );\n}\n\nfunction isNotFoundError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n if ((error as { code?: unknown }).code === \"PGRST116\") return true;\n return (\n /\\[MockProvider\\] Record not found/i.test(error.message) ||\n /switchboard-data-provider: no \".*\" row with id/i.test(error.message)\n );\n}\n\n/**\n * ResourceDetailPage — `DetailPage` with a record bound to it: fetches one\n * record by id through the mounted `DataProvider` and hands it to the title,\n * the actions, the sidebar and the content.\n *\n * ```tsx\n * <ResourceDetailPage\n * resource=\"people\"\n * id={params.id}\n * subtitleField=\"role\"\n * actions={(person) => <Button testID=\"edit\">Edit {person.name}</Button>}\n * sidebar={(person) => <StatCard label=\"Sessions\" value={person.session_count} />}\n * >\n * {(person) => <Section title=\"Timeline\"><Timeline personId={person.id} /></Section>}\n * </ResourceDetailPage>\n * ```\n *\n * This is the detail-route counterpart to `ResourcePage`, which is the list\n * one. Both are **data-bound**, not layouts: they need a resource contract\n * to be useful, which is the layers table's admission test for this tier.\n * The structure they render is a layout and lives one layer down —\n * `DetailPage` in `@marktiderman/genesis-ui/layout` — so an app with its own\n * fetching keeps the page shape without inheriting the provider. That\n * layout/data-bound pairing is the same one `AppShell` and `ResourcePage`\n * already have.\n *\n * The three non-record states are rendered here rather than left to the\n * caller, because a per-app \"loading…\" is exactly the hand-written code a\n * template exists to remove:\n * - loading, or no id yet -> `PageLoading`\n * - absent -> `EmptyState` saying so, distinct from the error state, since a\n * deleted record and a broken query need different words. Every provider\n * Genesis ships signals \"no such row\" by throwing rather than by resolving\n * empty, so this state is reached by classifying the error (see\n * `isNotFoundError`) as well as by a falsy `data`\n * - any other failure -> `EmptyState` carrying the provider's message, which\n * is kept verbatim: an error state that hides what went wrong is the one\n * nobody can act on\n *\n * `titleField` is exact: name a field and you get that field, empty string\n * included. The `name` -> `title` -> id chain is the DEFAULT, not a fallback\n * layered under an explicit choice — a page silently titled by a different\n * column than the one asked for is worse than a blank one.\n *\n * @stability Beta\n */\nexport function ResourceDetailPage<T extends BaseRecord = BaseRecord>({\n resource,\n id,\n titleField,\n subtitleField,\n select,\n breadcrumb,\n actions,\n sidebar,\n children,\n className,\n testID,\n}: ResourceDetailPageProps<T>) {\n const { data, isLoading, isError, error } = useOne<T>(resource, id, {\n select,\n // `useOne` defaults to `enabled: !!id`, which is wrong for a numeric\n // primary key: id `0` is falsy, so the query would never run and the page\n // would report a record that exists as missing, without ever asking the\n // provider. `Identifier` is `string | number`, so this is reachable.\n // Presence is the question, not truthiness.\n enabled: id != null,\n });\n\n // A disabled query reports neither loading nor error nor data, so the\n // \"no id yet\" case has to be named explicitly or it falls through to\n // not-found — nothing was asked, so nothing is missing.\n if (id == null || isLoading) {\n return <PageLoading testID={testID ? `${testID}-loading` : undefined} />;\n }\n\n // Order matters: `isError` implies `data` is undefined, so testing `!data`\n // first would swallow every failure into the not-found state.\n if (isError) {\n if (isNotFoundError(error)) return <NotFound />;\n return (\n <EmptyState\n icon={AlertTriangle}\n title=\"Couldn't load this record\"\n description={error instanceof Error ? error.message : undefined}\n />\n );\n }\n\n // A provider that answers successfully with nothing. None of the three\n // Genesis ships does this, but the `DataProvider` contract permits it and\n // a custom adapter is free to.\n if (!data) return <NotFound />;\n\n return (\n <DetailPage\n className={className}\n testID={testID}\n breadcrumb={breadcrumb}\n title={pick(data, titleField)}\n subtitle={subtitleField ? pick(data, subtitleField) : undefined}\n actions={actions?.(data)}\n sidebar={sidebar?.(data)}\n >\n {children(data)}\n </DetailPage>\n );\n}\n","export { DataPageShell, type DataPageShellProps } from \"./DataPageShell\";\nexport {\n DataFilters,\n type DataFilterConfig,\n type SavedViewItem,\n type StatusChipOption,\n type StatusChipsVariant,\n} from \"./DataFilters\";\nexport { DataGrid } from \"./DataGrid\";\nexport {\n DataTable,\n ThumbnailCell,\n LinkCell,\n type DataTableColumn,\n type DataTableProps,\n} from \"./DataTable\";\nexport { DataBulkBar, type BulkAction } from \"./DataBulkBar\";\nexport { FilterCombobox, type FilterOption } from \"./FilterCombobox\";\nexport { DateCell, NumberCell, CurrencyCell, BadgeCell } from \"./cell-formatters\";\nexport { EmptyState } from \"./EmptyState\";\nexport { ViewToggle, type ViewMode } from \"../patterns/view-toggle\";\nexport { ViewSettings } from \"../patterns/view-settings\";\nexport { StatCard, type StatCardProps, type StatCardColor } from \"./StatCard\";\nexport { KanbanBoard, type KanbanColumn, type KanbanBoardProps, type ColumnStatus } from \"./KanbanBoard\";\nexport { DataList, type DataListProps } from \"./DataList\";\nexport { DetailPanel, type DetailPanelProps } from \"./DetailPanel\";\nexport {\n ResourcePage,\n type ResourcePageProps,\n type ResourceCardActions,\n} from \"./ResourcePage\";\nexport {\n ResourceDetailPage,\n type ResourceDetailPageProps,\n} from \"./ResourceDetailPage\";\nexport { ResourceForm, type ResourceFormProps } from \"./ResourceForm\";\nexport { type ResourceFormFieldDef, type FieldType, type SelectOption } from \"./ResourceFormField\";\nexport { RelationField } from \"./RelationField\";\nexport { FileUploadField } from \"./FileUploadField\";\nexport { FieldArrayRenderer } from \"./FieldArrayRenderer\";\nexport { WizardForm } from \"./WizardForm\";\nexport type { ResourceColumnDef, ResourceActions } from \"../../hooks/use-resource-page\";\n// `AppShell` and `PageHeader` are layouts, not data-bound components — neither\n// takes a `DataProvider`. They stay re-exported here for one deprecation window\n// per docs/FRAMEWORK.md rule 5, and leave `/data` in the next major.\n//\n// These are LOCAL RE-BINDINGS rather than `export { X } from \"../layout/X\"`,\n// and that is load-bearing, not style. TypeScript does not attach a JSDoc\n// `@deprecated` on an `export ... from` statement to the symbol a consumer\n// imports: hovering the import shows no tag and no migration note, so the\n// deprecation is invisible exactly where it needs to be read. Only a local\n// binding carries the tag through to the emitted `.d.ts` and to the consumer's\n// editor. Verified against the TypeScript language service — the regression\n// test in `src/components/data/__tests__/deprecated-aliases.test.ts` asserts it\n// on the real build output, so this cannot silently rot back.\nimport {\n AppShell as AppShellImpl,\n type AppShellProps,\n type AppShellOptions,\n type NavItem,\n} from \"../layout/AppShell\";\nimport {\n PageHeader as PageHeaderImpl,\n type PageHeaderProps,\n type PageHeaderOptions,\n} from \"../layout/PageHeader\";\n\n/**\n * @deprecated Import `AppShell` from `@marktiderman/genesis-ui/layout` instead.\n * `AppShell` is a layout, not a data-bound component. This `/data` alias is\n * removed in the next major — see docs/FRAMEWORK.md rule 5.\n * @stability Deprecated\n */\nexport const AppShell = AppShellImpl;\n/**\n * @deprecated Import `PageHeader` from `@marktiderman/genesis-ui/layout`\n * instead. `PageHeader` is a layout, not a data-bound component. This `/data`\n * alias is removed in the next major — see docs/FRAMEWORK.md rule 5.\n * @stability Deprecated\n */\nexport const PageHeader = PageHeaderImpl;\nexport type { AppShellProps, AppShellOptions, NavItem };\nexport type { PageHeaderProps, PageHeaderOptions };\n\n// Router-agnostic navigation primitives (re-exported for `/data` consumers)\nexport {\n DefaultLink,\n isPathActive,\n resolveNavigation,\n defaultNavigate,\n type GenesisLinkProps,\n type IsPathActiveOptions,\n type NavigationNode,\n type ResolvedNavigation,\n type LinkComponent,\n type NavigateFn,\n} from \"../../navigation\";\n\n// Re-export Density for DataTable consumers who import from `/data`\nexport type { Density } from \"../../hooks/use-view-settings\";\nexport {\n CommandPalette,\n useCommandPaletteHotkey,\n type CommandPaletteProps,\n type CommandPaletteItem,\n} from \"../ui/command-palette\";\nexport { useSavedViews, type UseSavedViewsReturn } from \"../../hooks/use-saved-views\";\n"]}
1
+ {"version":3,"sources":["../../../src/components/data/DataPageShell.tsx","../../../src/components/data/FilterCombobox.tsx","../../../src/components/data/DataFilters.tsx","../../../src/components/data/DataGrid.tsx","../../../src/components/data/DataTable.tsx","../../../src/components/data/DataBulkBar.tsx","../../../src/components/data/cell-formatters.tsx","../../../src/components/data/StatCard.tsx","../../../src/components/data/KanbanBoard.tsx","../../../src/components/data/DataList.tsx","../../../src/components/data/DetailPanel.tsx","../../../src/components/data/RelationField.tsx","../../../src/components/data/FileUploadField.tsx","../../../src/components/data/FieldArrayRenderer.tsx","../../../src/components/data/ResourceFormField.tsx","../../../src/components/data/WizardForm.tsx","../../../src/components/data/ResourceForm.tsx","../../../src/components/data/ResourcePage.tsx","../../../src/components/data/ResourceDetailPage.tsx","../../../src/components/data/index.ts"],"names":["errorMessage","jsxs","jsx","useState","ChevronDown","Fragment","useRef","useEffect","ArrowUpDown","colorMap","Trash2","X","Loader2","Check","useMemo","useCallback","useWatch","useResource","AlertTriangle","ChevronLeft","ChevronRight","AppShell","PageHeader"],"mappings":"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","file":"index.js","sourcesContent":["import type { ComponentProps, ComponentType, ReactNode } from \"react\";\nimport { cn } from \"../../utils\";\nimport { Button } from \"../ui/button\";\nimport { Skeleton } from \"../ui/skeleton\";\nimport { EmptyState } from \"./EmptyState\";\nimport {\n PageHeader,\n type PageHeaderOptions,\n type PageHeaderAction,\n} from \"../layout/PageHeader\";\nimport type { ViewMode } from \"../patterns/view-toggle\";\nimport { AlertTriangle, RefreshCw } from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport type { Density } from \"../../hooks/use-view-settings\";\n\nexport interface DataPageShellProps {\n /** Display title for the page */\n title: string;\n icon?: LucideIcon;\n /** Singular entity name for generated text, e.g. \"session\" */\n entityName?: string;\n /** Subtitle text */\n subtitle?: string;\n createAction?: ReactNode;\n /** Extra actions, rendered in the header's one overflow menu. */\n secondaryActions?: PageHeaderAction[];\n isLoading?: boolean;\n isEmpty?: boolean;\n emptyIcon?: LucideIcon;\n emptyMessage?: string;\n emptyAction?: ReactNode;\n /** Error state */\n hasError?: boolean;\n errorMessage?: string;\n onRetry?: () => void;\n /** Number of filtered/visible items */\n count?: number;\n /** Total items before filtering */\n totalCount?: number;\n viewMode?: ViewMode;\n onViewModeChange?: (mode: ViewMode) => void;\n /** View settings */\n pageSize?: number;\n onPageSizeChange?: (size: number) => void;\n density?: Density;\n onDensityChange?: (density: Density) => void;\n /**\n * Slot for a stat cards row. Forwarded to the header, which renders it\n * full width under the title block and above the filters — but only when\n * `headerOptions.showStats` is on (default off), so a page that gains\n * `stats` shows nothing new until the developer or user opts in.\n */\n stats?: ReactNode;\n /** Slot for filter bar */\n filters?: ReactNode;\n /** Whether filters are currently active */\n hasActiveFilters?: boolean;\n onClearFilters?: () => void;\n /**\n * When true, filters render inside PageHeader details (collapsed by default).\n * Default false preserves always-visible filters on existing boards.\n */\n filtersCollapsible?: boolean;\n defaultFiltersOpen?: boolean;\n filtersOpen?: boolean;\n onFiltersOpenChange?: (open: boolean) => void;\n filtersLabel?: string;\n filtersHint?: ReactNode;\n /**\n * PageHeader chrome config — developer defaults; users can further\n * customize via the in-header Header options menu.\n */\n headerOptions?: PageHeaderOptions;\n /** Persist user header-option overrides (localStorage) */\n headerOptionsStorageKey?: string;\n children: ReactNode;\n /** Merged onto the root, not replacing its layout. */\n className?: string;\n /**\n * Replace the header outright. It receives exactly the props\n * `DataPageShell` would have given `PageHeader`, so the common case is a\n * wrapper that renders `PageHeader` with one thing added — an overflow\n * menu, a status strip, a second row — rather than a reimplementation.\n *\n * `null` ejects it: shell layout, states and filter row, no header.\n */\n header?: ComponentType<ComponentProps<typeof PageHeader>> | null;\n}\n\nexport function DataPageShell({\n title,\n icon,\n entityName,\n subtitle,\n createAction,\n secondaryActions,\n isLoading = false,\n isEmpty = false,\n emptyIcon,\n emptyMessage,\n emptyAction,\n hasError = false,\n errorMessage,\n onRetry,\n count,\n totalCount,\n viewMode,\n onViewModeChange,\n pageSize,\n onPageSizeChange,\n density,\n onDensityChange,\n stats,\n filters,\n hasActiveFilters = false,\n onClearFilters,\n filtersCollapsible = false,\n defaultFiltersOpen = false,\n filtersOpen,\n onFiltersOpenChange,\n filtersLabel,\n filtersHint,\n headerOptions,\n headerOptionsStorageKey,\n children,\n className,\n header,\n}: DataPageShellProps) {\n const entity = entityName || title.toLowerCase();\n // `header === null` ejects the header, and the doc on `header` promises the\n // filter row survives that. It only does in the standard branch, where\n // `filters` renders as an independent sibling. In the collapsible branch the\n // filter row reaches the DOM ONLY as the header's `details` prop, so an\n // ejected header takes the filters down with it — silently, which is the\n // worst version. Collapsing needs a header to collapse INTO; without one we\n // fall through to the standard branch and the filter row renders on its own.\n const collapseFilters =\n filtersCollapsible && filters != null && header !== null;\n\n const mergedOptions: PageHeaderOptions = {\n defaultDetailsOpen: defaultFiltersOpen,\n detailsLabel: filtersLabel,\n subtitleInDetails: collapseFilters ? true : undefined,\n ...headerOptions,\n };\n\n const sharedHeaderProps = {\n title,\n subtitle,\n icon,\n entityName: entity,\n count,\n totalCount,\n countActive: hasActiveFilters,\n viewMode,\n onViewModeChange,\n pageSize,\n onPageSizeChange,\n density,\n onDensityChange,\n createAction,\n secondaryActions,\n stats,\n optionsStorageKey: headerOptionsStorageKey,\n };\n\n const Header =\n header === null ? (() => null) : (header ?? PageHeader);\n\n return (\n <div className={cn(\"space-y-6\", className)}>\n {collapseFilters ? (\n <Header\n {...sharedHeaderProps}\n details={filters}\n detailsOpen={filtersOpen}\n onDetailsOpenChange={onFiltersOpenChange}\n detailsActive={hasActiveFilters}\n detailsHint={filtersHint}\n options={mergedOptions}\n />\n ) : (\n <>\n <Header {...sharedHeaderProps} options={headerOptions} />\n {filters}\n </>\n )}\n\n {/* Content */}\n {isLoading ? (\n <div\n data-testid=\"page-loader\"\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4\"\n >\n {Array.from({ length: 8 }).map((_, i) => (\n <Skeleton\n key={i}\n className=\"h-40 rounded-xl\"\n style={{ animationDelay: `${i * 75}ms` }}\n />\n ))}\n </div>\n ) : hasError ? (\n <div className=\"flex flex-col items-center justify-center py-16 text-center\">\n <AlertTriangle className=\"h-10 w-10 text-destructive mb-3\" />\n <p className=\"mb-1 text-sm font-medium text-foreground\">\n Something went wrong\n </p>\n <p className=\"mb-4 text-sm text-muted-foreground\">\n {errorMessage || `Failed to load ${entity}s. Please try again.`}\n </p>\n {onRetry && (\n <Button variant=\"outline\" size=\"sm\" onClick={onRetry}>\n <RefreshCw className=\"mr-1 h-4 w-4\" /> Retry\n </Button>\n )}\n </div>\n ) : isEmpty ? (\n <EmptyState\n icon={emptyIcon}\n title={emptyMessage}\n action={emptyAction}\n hasFilters={hasActiveFilters}\n onClearFilters={onClearFilters}\n />\n ) : (\n children\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../ui/popover\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"../ui/command\";\nimport { Button } from \"../ui/button\";\nimport { Check, ChevronDown } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport type { LucideIcon } from \"lucide-react\";\n\nexport interface FilterOption {\n value: string;\n label?: string;\n count?: number;\n}\n\ninterface FilterComboboxProps {\n label: string;\n icon: LucideIcon;\n options: FilterOption[];\n selected: string[];\n onChange: (selected: string[]) => void;\n searchPlaceholder?: string;\n allLabel?: string;\n /** Optional map of value -> display label */\n labelMap?: Record<string, string>;\n}\n\nexport function FilterCombobox({\n label,\n icon: Icon,\n options,\n selected,\n onChange,\n searchPlaceholder,\n allLabel,\n labelMap,\n}: FilterComboboxProps) {\n const [open, setOpen] = useState(false);\n\n const toggle = (value: string) => {\n onChange(\n selected.includes(value)\n ? selected.filter((v) => v !== value)\n : [...selected, value],\n );\n };\n\n const getDisplayLabel = (value: string) => labelMap?.[value] || value;\n\n const triggerLabel =\n selected.length === 0\n ? allLabel || `All ${label}`\n : selected.length === 1\n ? getDisplayLabel(selected[0])\n : `${selected.length} ${label.toLowerCase()}`;\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant={selected.length > 0 ? \"default\" : \"outline\"}\n size=\"sm\"\n className=\"text-xs h-7 gap-1.5\"\n >\n <Icon className=\"h-3 w-3\" />\n {triggerLabel}\n <ChevronDown className=\"h-3 w-3 ml-0.5 opacity-60\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-[220px] max-w-[calc(100vw-2rem)] p-0 bg-popover z-50\"\n align=\"start\"\n >\n <Command>\n <CommandInput\n placeholder={searchPlaceholder || `Search ${label.toLowerCase()}...`}\n />\n <CommandList>\n <CommandEmpty>No {label.toLowerCase()} found.</CommandEmpty>\n <CommandGroup>\n <CommandItem\n value={`__all_${label.toLowerCase()}__`}\n onSelect={() => onChange([])}\n >\n <Check\n className={cn(\n \"mr-2 h-3.5 w-3.5\",\n selected.length === 0 ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n {allLabel || `All ${label}`}\n </CommandItem>\n {options.map((opt) => (\n <CommandItem\n key={opt.value}\n value={opt.label || getDisplayLabel(opt.value)}\n onSelect={() => toggle(opt.value)}\n >\n <Check\n className={cn(\n \"mr-2 h-3.5 w-3.5\",\n selected.includes(opt.value)\n ? \"opacity-100\"\n : \"opacity-0\",\n )}\n />\n <span className=\"flex-1\">\n {opt.label || getDisplayLabel(opt.value)}\n </span>\n {opt.count !== undefined && (\n <span className=\"text-[10px] text-muted-foreground ml-2\">\n {opt.count}\n </span>\n )}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { useState, useRef } from \"react\";\nimport { Input } from \"../ui/input\";\nimport { Button } from \"../ui/button\";\nimport { Badge } from \"../ui/badge\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../ui/select\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\nimport { Dialog, DialogContent, DialogHeader, DialogTitle } from \"../ui/dialog\";\nimport {\n Search,\n X,\n ArrowUpDown,\n Bookmark,\n BookmarkPlus,\n Trash2,\n ChevronDown,\n} from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport { FilterCombobox, type FilterOption } from \"./FilterCombobox\";\nimport type { LucideIcon } from \"lucide-react\";\n\nexport interface DataFilterConfig {\n key: string;\n label: string;\n icon: LucideIcon;\n options: FilterOption[];\n selected: string[];\n onChange: (values: string[]) => void;\n searchPlaceholder?: string;\n allLabel?: string;\n labelMap?: Record<string, string>;\n}\n\nexport interface SavedViewItem {\n id: string;\n name: string;\n filters: Record<string, unknown>;\n}\n\n/**\n * One status chip. A plain string is shorthand for `{ value, label: value }`.\n * `count` renders as a muted number after the label.\n */\nexport interface StatusChipOption {\n value: string;\n label?: string;\n count?: number;\n}\n\n/** Rendering of the status chips — a row of pills, or one segmented strip. */\nexport type StatusChipsVariant = \"chips\" | \"tabs\";\n\ninterface DataFiltersProps {\n search: string;\n onSearchChange: (value: string) => void;\n searchPlaceholder?: string;\n sort: string;\n onSortChange: (sort: string) => void;\n sortOptions: Array<{ value: string; label: string }>;\n filters?: DataFilterConfig[];\n /** Status chip toggles */\n statusChips?: {\n options: Array<string | StatusChipOption>;\n selected: string[];\n onChange: (values: string[]) => void;\n /**\n * `\"chips\"` (default) renders pills inside the filter row. `\"tabs\"`\n * renders a segmented strip on its own row above the search row —\n * the same border-and-fill look as `ViewToggle`. Selection is\n * multi-select in both.\n */\n variant?: StatusChipsVariant;\n };\n /** Saved views */\n savedViews?: SavedViewItem[];\n onLoadView?: (filters: Record<string, unknown>) => void;\n onSaveView?: (name: string) => void;\n onDeleteView?: (id: string) => void;\n canSaveViews?: boolean;\n /** Called after a view is saved successfully */\n onViewSaved?: (name: string) => void;\n /** Called when an error occurs */\n onError?: (message: string) => void;\n /** Called when \"Clear all\" is clicked */\n onClearAll?: () => void;\n /** Expose the search input ref for keyboard nav \"/\" shortcut */\n searchInputRef?: React.RefObject<HTMLInputElement | null>;\n /** Show the search box. Default `true`; turn off when the data source can't search. */\n showSearch?: boolean;\n /** Show the sort select. Default `true`; turn off when the data source can't sort. */\n showSort?: boolean;\n}\n\nexport function DataFilters({\n search,\n onSearchChange,\n searchPlaceholder = \"Search...\",\n sort,\n onSortChange,\n sortOptions,\n filters = [],\n statusChips,\n savedViews = [],\n onLoadView,\n onSaveView,\n onDeleteView,\n canSaveViews = false,\n onViewSaved,\n onClearAll,\n searchInputRef,\n showSearch = true,\n showSort = true,\n}: DataFiltersProps) {\n const internalSearchRef = useRef<HTMLInputElement>(null);\n const effectiveSearchRef = searchInputRef || internalSearchRef;\n const [viewsOpen, setViewsOpen] = useState(false);\n const [saveDialogOpen, setSaveDialogOpen] = useState(false);\n const [newViewName, setNewViewName] = useState(\"\");\n\n const hasFilters =\n filters.some((f) => f.selected.length > 0) ||\n (statusChips?.selected.length ?? 0) > 0;\n\n // Plain strings and option objects normalise to one shape so both render\n // paths below read `value`/`label`/`count` without re-checking.\n const statusOptions: Array<{ value: string; label: string; count?: number }> =\n (statusChips?.options ?? []).map((o) =>\n typeof o === \"string\"\n ? { value: o, label: o }\n : { value: o.value, label: o.label ?? o.value, count: o.count },\n );\n const statusVariant: StatusChipsVariant = statusChips?.variant ?? \"chips\";\n\n const toggleStatus = (status: string) => {\n if (!statusChips) return;\n const { selected, onChange } = statusChips;\n onChange(\n selected.includes(status)\n ? selected.filter((s) => s !== status)\n : [...selected, status],\n );\n };\n\n const handleSaveView = () => {\n if (!newViewName.trim()) return;\n onSaveView?.(newViewName.trim());\n setNewViewName(\"\");\n setSaveDialogOpen(false);\n onViewSaved?.(newViewName.trim());\n };\n\n return (\n <div className=\"space-y-3\">\n {/* Status tabs row — a segmented strip above everything else */}\n {statusChips && statusVariant === \"tabs\" && (\n <div\n className=\"flex items-center border rounded-lg overflow-x-auto w-fit max-w-full\"\n role=\"group\"\n aria-label=\"Status\"\n data-testid=\"status-tabs\"\n >\n {statusOptions.map((o) => {\n const pressed = statusChips.selected.includes(o.value);\n return (\n <Button\n key={o.value}\n type=\"button\"\n variant={pressed ? \"default\" : \"ghost\"}\n size=\"sm\"\n className=\"h-8 rounded-none gap-1.5\"\n onClick={() => toggleStatus(o.value)}\n aria-pressed={pressed}\n testID={`status-tab-${o.value}`}\n >\n {o.label}\n {o.count !== undefined && (\n <span className=\"text-[10px] tabular-nums opacity-70\">\n {o.count}\n </span>\n )}\n </Button>\n );\n })}\n </div>\n )}\n\n {/* Search + Sort row */}\n {(showSearch || showSort) && (\n <div className=\"flex flex-col sm:flex-row gap-2\">\n {showSearch && (\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground\" />\n <Input\n ref={effectiveSearchRef}\n placeholder={searchPlaceholder}\n value={search}\n onChange={(e) => onSearchChange(e.target.value)}\n className=\"pl-9\"\n />\n {search && (\n <button\n onClick={() => onSearchChange(\"\")}\n className=\"absolute right-3 top-1/2 -translate-y-1/2\"\n >\n <X className=\"h-3.5 w-3.5 text-muted-foreground\" />\n </button>\n )}\n </div>\n )}\n {showSort && (\n <Select value={sort} onValueChange={onSortChange}>\n <SelectTrigger className=\"w-full sm:w-[180px] shrink-0\">\n <ArrowUpDown className=\"h-3.5 w-3.5 mr-1.5 text-muted-foreground\" />\n <SelectValue placeholder=\"Sort by...\" />\n </SelectTrigger>\n <SelectContent className=\"bg-popover z-50\">\n {sortOptions.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </div>\n )}\n\n {/* Filter chips row */}\n <div className=\"flex flex-wrap items-center gap-2\">\n {/* Saved Views */}\n {(savedViews.length > 0 || canSaveViews) && (\n <Popover open={viewsOpen} onOpenChange={setViewsOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"text-xs h-7 gap-1.5\"\n >\n <Bookmark className=\"h-3 w-3\" />\n Views\n {savedViews.length > 0 && (\n <span className=\"text-[10px] text-muted-foreground ml-0.5\">\n ({savedViews.length})\n </span>\n )}\n <ChevronDown className=\"h-3 w-3 ml-0.5 opacity-60\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent\n className=\"w-[240px] p-2 bg-popover z-50\"\n align=\"start\"\n >\n <div className=\"space-y-1\">\n {savedViews.map((view) => (\n <div key={view.id} className=\"flex items-center gap-1 group\">\n <button\n className=\"flex-1 text-left text-sm px-2 py-1.5 rounded hover:bg-accent truncate\"\n onClick={() => {\n onLoadView?.(view.filters);\n setViewsOpen(false);\n }}\n >\n {view.name}\n </button>\n {onDeleteView && (\n <button\n className=\"opacity-0 group-hover:opacity-100 p-1 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive transition-opacity\"\n onClick={() => onDeleteView(view.id)}\n >\n <Trash2 className=\"h-3 w-3\" />\n </button>\n )}\n </div>\n ))}\n {savedViews.length === 0 && (\n <p className=\"text-xs text-muted-foreground px-2 py-1\">\n No saved views yet\n </p>\n )}\n {canSaveViews && (\n <>\n <div className=\"border-t my-1\" />\n <button\n className=\"w-full flex items-center gap-1.5 text-sm px-2 py-1.5 rounded hover:bg-accent text-primary\"\n onClick={() => {\n setViewsOpen(false);\n setSaveDialogOpen(true);\n }}\n >\n <BookmarkPlus className=\"h-3.5 w-3.5\" />\n Save current view\n </button>\n </>\n )}\n </div>\n </PopoverContent>\n </Popover>\n )}\n\n {/* Status chips */}\n {statusChips && statusVariant === \"chips\" && (\n <div className=\"flex items-center gap-1 mr-1\">\n {statusOptions.map((o) => {\n const pressed = statusChips.selected.includes(o.value);\n return (\n <button\n key={o.value}\n type=\"button\"\n onClick={() => toggleStatus(o.value)}\n aria-pressed={pressed}\n data-testid={`status-chip-${o.value}`}\n className={cn(\n \"text-xs px-2.5 py-1 rounded-full border transition-all font-medium\",\n pressed\n ? \"bg-primary text-primary-foreground border-primary\"\n : \"bg-background text-muted-foreground border-border hover:border-primary/40\",\n )}\n >\n {o.label}\n {o.count !== undefined && (\n <span className=\"ml-1 text-[10px] tabular-nums opacity-70\">\n {o.count}\n </span>\n )}\n </button>\n );\n })}\n </div>\n )}\n\n {/* Filter comboboxes */}\n {filters.map((f) =>\n f.options.length > 0 ? (\n <FilterCombobox\n key={f.key}\n label={f.label}\n icon={f.icon}\n options={f.options}\n selected={f.selected}\n onChange={f.onChange}\n searchPlaceholder={f.searchPlaceholder}\n allLabel={f.allLabel}\n labelMap={f.labelMap}\n />\n ) : null,\n )}\n\n {/* Active filter badges */}\n {filters.flatMap((f) =>\n f.selected.map((val) => (\n <Badge\n key={`${f.key}-${val}`}\n variant=\"secondary\"\n className=\"text-xs cursor-pointer gap-1\"\n onClick={() => f.onChange(f.selected.filter((v) => v !== val))}\n >\n {f.labelMap?.[val] || val}\n <X className=\"h-2.5 w-2.5\" />\n </Badge>\n )),\n )}\n\n {/* Clear all */}\n {hasFilters && onClearAll && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"text-xs h-7 text-muted-foreground\"\n onClick={onClearAll}\n >\n <X className=\"h-3 w-3 mr-1\" />\n Clear all\n </Button>\n )}\n </div>\n\n {/* Save View Dialog */}\n <Dialog open={saveDialogOpen} onOpenChange={setSaveDialogOpen}>\n <DialogContent className=\"sm:max-w-sm\">\n <DialogHeader>\n <DialogTitle className=\"font-display\">\n Save Current View\n </DialogTitle>\n </DialogHeader>\n <div className=\"space-y-3\">\n <Input\n placeholder=\"View name (e.g. 'Active Sessions')\"\n value={newViewName}\n onChange={(e) => setNewViewName(e.target.value)}\n onKeyDown={(e) => e.key === \"Enter\" && handleSaveView()}\n autoFocus\n />\n <div className=\"flex justify-end gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setSaveDialogOpen(false)}\n >\n Cancel\n </Button>\n <Button\n size=\"sm\"\n onClick={handleSaveView}\n disabled={!newViewName.trim()}\n >\n Save\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n </div>\n );\n}\n","\"use client\";\n\nimport {\n useState,\n useEffect,\n useRef,\n type ReactNode,\n type RefObject,\n} from \"react\";\nimport { cn } from \"../../utils\";\nimport { Loader2 } from \"lucide-react\";\nimport type { ViewMode } from \"../patterns/view-toggle\";\n\nconst DEFAULT_BATCH_SIZE = 48;\n\ninterface DataGridProps<T> {\n items: T[];\n viewMode: ViewMode;\n /** Items per infinite scroll batch (grid only). Default 48 */\n batchSize?: number;\n /** Tailwind grid column classes */\n gridCols?: string;\n /** Render a single card in grid mode */\n renderCard: (item: T, index: number) => ReactNode;\n /** Render the table view (receives currently visible items) */\n renderTable?: (items: T[]) => ReactNode;\n /** Render a compact list row */\n renderListItem?: (item: T, index: number) => ReactNode;\n /** Animate cards with staggered fade-in. Default true */\n staggerAnimation?: boolean;\n /** Unique key extractor. Defaults to (item as any).id */\n getKey?: (item: T) => string;\n /** Keyboard navigation: focused item index (-1 = none) */\n focusedIndex?: number;\n /** Keyboard navigation: container ref for scroll management */\n keyboardContainerRef?: RefObject<HTMLDivElement | null>;\n}\n\nexport function DataGrid<T>({\n items,\n viewMode,\n batchSize = DEFAULT_BATCH_SIZE,\n gridCols = \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\",\n renderCard,\n renderTable,\n renderListItem,\n staggerAnimation = true,\n getKey,\n focusedIndex = -1,\n keyboardContainerRef,\n}: DataGridProps<T>) {\n const [visibleCount, setVisibleCount] = useState(batchSize);\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n // Reset visible count when items change\n useEffect(() => {\n setVisibleCount(batchSize);\n }, [items.length, batchSize]);\n\n // Infinite scroll observer (grid mode only)\n useEffect(() => {\n if (viewMode !== \"grid\") return;\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries[0]?.isIntersecting && visibleCount < items.length) {\n setVisibleCount((prev) =>\n Math.min(prev + batchSize, items.length),\n );\n }\n },\n { rootMargin: \"200px\" },\n );\n if (sentinelRef.current) observer.observe(sentinelRef.current);\n return () => observer.disconnect();\n }, [viewMode, visibleCount, items.length, batchSize]);\n\n if (viewMode === \"table\" && renderTable) {\n return <>{renderTable(items)}</>;\n }\n\n if (viewMode === \"list\" && renderListItem) {\n const keyFnList =\n getKey ||\n ((item: T) => (item as Record<string, unknown>).id as string);\n return (\n <div\n ref={keyboardContainerRef}\n className=\"divide-y divide-border rounded-lg border\"\n >\n {items.map((item, i) => (\n <div\n key={keyFnList(item)}\n data-nav-item\n className={cn(\n \"px-4 py-3 transition-colors hover:bg-accent/50\",\n focusedIndex === i &&\n \"ring-2 ring-inset ring-primary bg-accent/50\",\n )}\n >\n {renderListItem(item, i)}\n </div>\n ))}\n </div>\n );\n }\n\n const visible = items.slice(0, visibleCount);\n const keyFn =\n getKey ||\n ((item: T) => (item as Record<string, unknown>).id as string);\n\n return (\n <>\n <div ref={keyboardContainerRef} className={`grid ${gridCols} gap-4`}>\n {visible.map((item, i) => (\n <div\n key={keyFn(item)}\n data-nav-item\n className={cn(\n staggerAnimation && \"animate-fade-in\",\n focusedIndex === i &&\n \"ring-2 ring-primary ring-offset-2 ring-offset-background rounded-xl transition-shadow duration-150\",\n )}\n style={\n staggerAnimation\n ? {\n animationDelay: `${(i % batchSize) * 30}ms`,\n animationFillMode: \"both\",\n }\n : undefined\n }\n >\n {renderCard(item, i)}\n </div>\n ))}\n </div>\n {visibleCount < items.length && (\n <div\n ref={sentinelRef}\n className=\"h-12 flex items-center justify-center\"\n >\n <Loader2 className=\"h-6 w-6 animate-spin text-muted-foreground\" />\n </div>\n )}\n </>\n );\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport {\n useState,\n useCallback,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\";\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"../ui/table\";\nimport { Checkbox } from \"../ui/checkbox\";\nimport { Button } from \"../ui/button\";\nimport { Input } from \"../ui/input\";\nimport { Spinner } from \"../ui/spinner\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../ui/select\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuCheckboxItem,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../ui/dropdown-menu\";\nimport {\n ArrowUp,\n ArrowDown,\n ArrowUpDown,\n ExternalLink,\n Columns3,\n ChevronLeft,\n ChevronRight,\n} from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport type { Density } from \"../../hooks/use-view-settings\";\n\n/* ── Density row / cell rhythm ── */\n\nconst DENSITY_CELL: Record<Density, string> = {\n compact: \"py-1 h-8\",\n comfortable: \"py-2\",\n spacious: \"py-3\",\n};\n\nconst DENSITY_HEAD: Record<Density, string> = {\n compact: \"h-8 py-1\",\n comfortable: \"h-10\",\n spacious: \"h-12 py-3\",\n};\n\n/* ── Column definition ── */\n\nexport interface DataTableColumn<T> {\n key: string;\n header: string;\n width?: string;\n hideBelow?: \"sm\" | \"md\" | \"lg\" | \"xl\";\n sortable?: boolean;\n render?: (item: T, value: unknown) => ReactNode;\n accessor?: (item: T) => unknown;\n editable?: {\n type: \"text\" | \"select\";\n options?: string[];\n /**\n * Called with the new value. Return a promise to keep the cell in a\n * saving state until it settles: a fulfilled save closes the editor, and\n * a rejected one keeps it open with the error's message beneath it, so\n * nothing the user typed is lost and the reason is on screen. A plain\n * `void` return closes the editor at once, as before.\n */\n onSave: (item: T, newValue: string) => void | Promise<void>;\n };\n /** Whether column is visible by default (default true) */\n defaultVisible?: boolean;\n /** Minimum width in px for resizing */\n minWidth?: number;\n}\n\n/* ── Component props ── */\n\nexport interface DataTableProps<T> {\n items: T[];\n columns: DataTableColumn<T>[];\n getKey: (item: T) => string;\n onRowClick?: (item: T) => void;\n selectable?: boolean;\n selected?: Set<string>;\n onToggleSelect?: (id: string) => void;\n onToggleAll?: () => void;\n renderActions?: (item: T) => ReactNode;\n emptyMessage?: string;\n /** Enable column visibility toggle dropdown */\n columnVisibility?: boolean;\n /** localStorage key for persisting column visibility */\n columnVisibilityKey?: string;\n /** Enable column resizing via drag */\n resizableColumns?: boolean;\n /** Enable pagination */\n pagination?: boolean;\n /** Initial page size (default 25) */\n pageSize?: number;\n /** Page size options (default [10, 25, 50, 100]) */\n pageSizeOptions?: number[];\n /** Sticky header on scroll */\n stickyHeader?: boolean;\n /** localStorage key for persisting column resize widths */\n resizeKey?: string;\n /** Make the first column sticky when scrolling horizontally */\n stickyFirstColumn?: boolean;\n /**\n * Row height / padding rhythm.\n * - compact: ~32px (py-1 / h-8)\n * - comfortable: default (py-2)\n * - spacious: taller (py-3)\n */\n density?: Density;\n}\n\n/* ── Helpers ── */\n\ntype SortEntry = { key: string; dir: \"asc\" | \"desc\" };\n\nfunction getCellClasses(col: DataTableColumn<unknown>) {\n const hide = col.hideBelow\n ? col.hideBelow === \"sm\"\n ? \"hidden sm:table-cell\"\n : col.hideBelow === \"md\"\n ? \"hidden md:table-cell\"\n : col.hideBelow === \"lg\"\n ? \"hidden lg:table-cell\"\n : \"hidden xl:table-cell\"\n : \"\";\n return cn(col.width, hide);\n}\n\n/* ── Inline edit cell ── */\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction EditableCell<T>({\n item,\n column,\n value,\n}: {\n item: T;\n column: DataTableColumn<T>;\n value: unknown;\n}) {\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState(String(value ?? \"\"));\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n // A ref, not state: Enter and the blur that follows it land in the same\n // tick, and only the first may start a save.\n const inFlight = useRef(false);\n // The draft that last failed, so leaving the cell doesn't silently retry it.\n const failedDraft = useRef<string | null>(null);\n const editable = column.editable!;\n\n const close = useCallback(() => {\n setEditing(false);\n setError(null);\n failedDraft.current = null;\n }, []);\n\n const commit = useCallback(\n (v: string) => {\n if (inFlight.current) return;\n let result: void | Promise<void>;\n try {\n result = editable.onSave(item, v);\n } catch (e) {\n setError(errorMessage(e));\n failedDraft.current = v;\n return;\n }\n if (!result || typeof (result as Promise<void>).then !== \"function\") {\n close();\n return;\n }\n inFlight.current = true;\n setSaving(true);\n setError(null);\n (result as Promise<void>).then(\n () => {\n inFlight.current = false;\n setSaving(false);\n close();\n },\n (e: unknown) => {\n inFlight.current = false;\n setSaving(false);\n setError(errorMessage(e));\n failedDraft.current = v;\n },\n );\n },\n [editable, item, close],\n );\n\n if (!editing) {\n return (\n <span\n className=\"cursor-pointer hover:underline decoration-dashed underline-offset-4 decoration-muted-foreground/40\"\n onClick={(e) => {\n e.stopPropagation();\n setDraft(String(value ?? \"\"));\n setError(null);\n failedDraft.current = null;\n setEditing(true);\n }}\n >\n {column.render ? column.render(item, value) : String(value ?? \"\\u2014\")}\n </span>\n );\n }\n\n const feedback = error ? (\n <p role=\"alert\" className=\"mt-1 text-[11px] leading-snug text-destructive\">\n {error}\n </p>\n ) : null;\n\n if (editable.type === \"select\" && editable.options) {\n // Controlled, so what it shows is always the draft; and closable without\n // choosing again — Radix fires no change for the value already picked,\n // so after a failed save Escape or Cancel is the only way out.\n return (\n <div\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => {\n if (e.key === \"Escape\" && !inFlight.current) close();\n }}\n aria-busy={saving || undefined}\n >\n <Select\n value={draft}\n disabled={saving}\n onValueChange={(v) => {\n setDraft(v);\n commit(v);\n }}\n >\n <SelectTrigger className=\"h-7 text-xs w-28\" aria-invalid={error ? true : undefined}>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {editable.options.map((opt) => (\n <SelectItem key={opt} value={opt}>\n {opt}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {feedback}\n {error && (\n <button\n type=\"button\"\n className=\"mt-0.5 text-[11px] text-muted-foreground underline-offset-2 hover:underline\"\n onClick={close}\n >\n Cancel\n </button>\n )}\n </div>\n );\n }\n\n return (\n <div onClick={(e) => e.stopPropagation()} aria-busy={saving || undefined}>\n <div className=\"relative\">\n <Input\n autoFocus\n className={cn(\"h-7 text-xs w-full\", saving && \"pr-7 opacity-70\")}\n value={draft}\n // readOnly rather than disabled while saving: disabling would drop\n // focus, and the resulting blur would try to save a second time.\n readOnly={saving}\n aria-invalid={error ? true : undefined}\n onChange={(e) => setDraft(e.target.value)}\n onBlur={() => {\n if (inFlight.current) return;\n if (failedDraft.current === draft) close();\n else commit(draft);\n }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") commit(draft);\n if (e.key === \"Escape\" && !inFlight.current) close();\n }}\n />\n {saving && (\n <Spinner className=\"absolute right-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2\" aria-label=\"Saving\" />\n )}\n </div>\n {feedback}\n </div>\n );\n}\n\n/* ── Column resize handle ── */\n\nfunction ResizeHandle({\n onResize,\n onResizeEnd,\n}: {\n onResize: (delta: number) => void;\n onResizeEnd?: () => void;\n}) {\n const startX = useRef(0);\n const [isResizing, setIsResizing] = useState(false);\n\n const handlePointerDown = useCallback(\n (e: React.PointerEvent) => {\n e.preventDefault();\n e.stopPropagation();\n startX.current = e.clientX;\n setIsResizing(true);\n document.body.style.cursor = \"col-resize\";\n const target = e.currentTarget as HTMLElement;\n target.setPointerCapture(e.pointerId);\n\n const onMove = (ev: PointerEvent) => {\n const delta = ev.clientX - startX.current;\n startX.current = ev.clientX;\n onResize(delta);\n };\n const onUp = () => {\n target.removeEventListener(\"pointermove\", onMove);\n target.removeEventListener(\"pointerup\", onUp);\n setIsResizing(false);\n document.body.style.cursor = \"\";\n onResizeEnd?.();\n };\n target.addEventListener(\"pointermove\", onMove);\n target.addEventListener(\"pointerup\", onUp);\n },\n [onResize, onResizeEnd],\n );\n\n return (\n <div\n className={cn(\n \"absolute right-0 top-0 bottom-0 cursor-col-resize transition-colors\",\n isResizing\n ? \"w-1.5 bg-primary/50\"\n : \"w-1 hover:bg-primary/30\",\n )}\n onPointerDown={handlePointerDown}\n onClick={(e) => e.stopPropagation()}\n />\n );\n}\n\n/* ── Main component ── */\n\nexport function DataTable<T>({\n items,\n columns,\n getKey,\n onRowClick,\n selectable,\n selected,\n onToggleSelect,\n onToggleAll,\n renderActions,\n emptyMessage = \"No records found\",\n columnVisibility = true,\n columnVisibilityKey,\n resizableColumns = true,\n pagination = true,\n pageSize: initialPageSize = 25,\n pageSizeOptions = [10, 25, 50, 100],\n stickyHeader = true,\n resizeKey,\n stickyFirstColumn,\n density = \"comfortable\",\n}: DataTableProps<T>) {\n const cellDensity = DENSITY_CELL[density];\n const headDensity = DENSITY_HEAD[density];\n // ── Multi-column sort ──\n const [sorts, setSorts] = useState<SortEntry[]>([]);\n\n const handleSort = useCallback(\n (key: string, shiftKey: boolean) => {\n setSorts((prev) => {\n const existing = prev.findIndex((s) => s.key === key);\n if (existing >= 0) {\n const entry = prev[existing];\n if (entry.dir === \"asc\") {\n const next = [...prev];\n next[existing] = { key, dir: \"desc\" };\n return next;\n }\n // Remove on third click\n return prev.filter((_, i) => i !== existing);\n }\n if (shiftKey) return [...prev, { key, dir: \"asc\" }];\n return [{ key, dir: \"asc\" }];\n });\n },\n [],\n );\n\n // ── Column visibility ──\n // SSR-safe: start from column defaults, restore localStorage after mount,\n // and only persist once hydrated — otherwise the defaults write would wipe\n // saved prefs on every full page load.\n const [visibleCols, setVisibleCols] = useState<Record<string, boolean>>(\n () => {\n const initial: Record<string, boolean> = {};\n columns.forEach((c) => {\n initial[c.key] = c.defaultVisible !== false;\n });\n return initial;\n },\n );\n const [visibilityHydrated, setVisibilityHydrated] = useState(false);\n\n useEffect(() => {\n if (!columnVisibilityKey) {\n setVisibilityHydrated(true);\n return;\n }\n try {\n const saved = localStorage.getItem(`dt-vis-${columnVisibilityKey}`);\n if (saved) {\n const parsed = JSON.parse(saved) as Record<string, boolean>;\n setVisibleCols((prev) => {\n const next = { ...prev };\n for (const [k, v] of Object.entries(parsed)) {\n if (k in next || columns.some((c) => c.key === k)) {\n next[k] = v;\n }\n }\n // Keep defaults for any column not in the saved map\n columns.forEach((c) => {\n if (!(c.key in next)) next[c.key] = c.defaultVisible !== false;\n });\n return next;\n });\n }\n } catch {\n // ignore corrupt prefs\n }\n setVisibilityHydrated(true);\n // Intentionally once-per-mount for this key (columns keys are stable)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [columnVisibilityKey]);\n\n useEffect(() => {\n if (!visibilityHydrated || !columnVisibilityKey) return;\n localStorage.setItem(\n `dt-vis-${columnVisibilityKey}`,\n JSON.stringify(visibleCols),\n );\n }, [visibleCols, columnVisibilityKey, visibilityHydrated]);\n\n const toggleColumnVisibility = useCallback((key: string) => {\n setVisibleCols((prev) => ({ ...prev, [key]: !prev[key] }));\n }, []);\n\n const resetColumnVisibility = useCallback(() => {\n const defaults: Record<string, boolean> = {};\n columns.forEach((c) => {\n defaults[c.key] = c.defaultVisible !== false;\n });\n setVisibleCols(defaults);\n if (columnVisibilityKey) {\n localStorage.removeItem(`dt-vis-${columnVisibilityKey}`);\n }\n }, [columns, columnVisibilityKey]);\n\n // Sync new columns that aren't in saved state\n useEffect(() => {\n setVisibleCols((prev) => {\n const updated = { ...prev };\n let changed = false;\n columns.forEach((c) => {\n if (!(c.key in updated)) {\n updated[c.key] = c.defaultVisible !== false;\n changed = true;\n }\n });\n return changed ? updated : prev;\n });\n }, [columns]);\n\n const activeColumns = columnVisibility\n ? columns.filter((c) => visibleCols[c.key] !== false)\n : columns;\n\n // ── Column resizing ──\n const [colWidths, setColWidths] = useState<Record<string, number>>(() => {\n // Restore from localStorage if resizeKey is provided\n if (resizeKey) {\n try {\n const saved = localStorage.getItem(`dt-resize-${resizeKey}`);\n if (saved) return JSON.parse(saved);\n } catch {\n // ignore\n }\n }\n // Initialize from column width definitions (parse px/rem values to px numbers)\n const initial: Record<string, number> = {};\n columns.forEach((c) => {\n if (c.width) {\n const px = parseInt(c.width, 10);\n if (!isNaN(px) && px > 0) initial[c.key] = px;\n }\n });\n return initial;\n });\n\n const handleResize = useCallback(\n (key: string, delta: number, minWidth: number) => {\n setColWidths((prev) => {\n const current = prev[key] || 150;\n return { ...prev, [key]: Math.max(minWidth, current + delta) };\n });\n },\n [],\n );\n\n const handleResizeEnd = useCallback(() => {\n if (resizeKey) {\n localStorage.setItem(`dt-resize-${resizeKey}`, JSON.stringify(colWidths));\n }\n }, [resizeKey, colWidths]);\n\n // ── Pagination ──\n const [currentPage, setCurrentPage] = useState(0);\n const [currentPageSize, setCurrentPageSize] = useState(initialPageSize);\n\n // Reset page when items change\n useEffect(() => {\n setCurrentPage(0);\n }, [items.length, currentPageSize]);\n\n // ── Sort items ──\n const sorted = (() => {\n if (sorts.length === 0) return items;\n return [...items].sort((a, b) => {\n for (const s of sorts) {\n const col = columns.find((c) => c.key === s.key);\n if (!col) continue;\n const acc =\n col.accessor ||\n ((item: T) => (item as Record<string, unknown>)[col.key]);\n const va = acc(a);\n const vb = acc(b);\n const sa = va == null ? \"\" : String(va);\n const sb = vb == null ? \"\" : String(vb);\n const cmp = sa.localeCompare(sb, undefined, {\n numeric: true,\n sensitivity: \"base\",\n });\n if (cmp !== 0) return s.dir === \"asc\" ? cmp : -cmp;\n }\n return 0;\n });\n })();\n\n // ── Paginate ──\n const totalItems = sorted.length;\n const totalPages = pagination\n ? Math.max(1, Math.ceil(totalItems / currentPageSize))\n : 1;\n const displayItems = pagination\n ? sorted.slice(\n currentPage * currentPageSize,\n (currentPage + 1) * currentPageSize,\n )\n : sorted;\n const showingFrom =\n totalItems === 0 ? 0 : currentPage * currentPageSize + 1;\n const showingTo = Math.min(\n (currentPage + 1) * currentPageSize,\n totalItems,\n );\n\n const totalCols =\n activeColumns.length + (selectable ? 1 : 0) + (renderActions ? 1 : 0);\n\n return (\n <div className=\"border rounded-lg animate-fade-in flex flex-col\">\n {/* ── Toolbar ── */}\n {columnVisibility && (\n <div className=\"flex items-center justify-end px-3 py-2 border-b bg-muted/30\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-7 text-xs gap-1.5\"\n >\n <Columns3 className=\"h-3.5 w-3.5\" />\n Columns\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n align=\"end\"\n className=\"w-44 bg-popover z-50\"\n >\n {columns.map((col) =>\n col.header ? (\n <DropdownMenuCheckboxItem\n key={col.key}\n checked={visibleCols[col.key] !== false}\n onCheckedChange={() => toggleColumnVisibility(col.key)}\n >\n {col.header}\n </DropdownMenuCheckboxItem>\n ) : null,\n )}\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={resetColumnVisibility}>\n Reset to defaults\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n )}\n\n {/* ── Table ── */}\n <div className=\"overflow-x-auto\">\n <Table style={{ tableLayout: \"fixed\" }}>\n <TableHeader\n className={\n stickyHeader ? \"sticky top-0 z-10 bg-background\" : \"\"\n }\n >\n <TableRow>\n {selectable && (\n <TableHead className={cn(\"w-10\", headDensity)}>\n <Checkbox\n checked={\n items.length > 0 && selected?.size === items.length\n }\n onCheckedChange={onToggleAll}\n />\n </TableHead>\n )}\n {activeColumns.map((col, colIndex) => {\n const sortIndex = sorts.findIndex((s) => s.key === col.key);\n const sortEntry =\n sortIndex >= 0 ? sorts[sortIndex] : null;\n const resizeWidth = colWidths[col.key];\n const isFirstCol = colIndex === 0 && stickyFirstColumn;\n\n return (\n <TableHead\n key={col.key}\n className={cn(\n getCellClasses(col as DataTableColumn<unknown>),\n headDensity,\n col.sortable && \"cursor-pointer select-none\",\n resizableColumns && \"relative\",\n isFirstCol && \"sticky left-0 bg-background\",\n isFirstCol && stickyHeader ? \"z-[15]\" : isFirstCol ? \"z-[5]\" : undefined,\n )}\n style={\n resizeWidth\n ? { width: resizeWidth, minWidth: resizeWidth }\n : undefined\n }\n onClick={\n col.sortable\n ? (e: React.MouseEvent) => handleSort(col.key, e.shiftKey)\n : undefined\n }\n >\n <span className=\"inline-flex items-center gap-1\">\n {col.header}\n {col.sortable &&\n (sortEntry ? (\n <>\n {sortEntry.dir === \"asc\" ? (\n <ArrowUp className=\"h-3 w-3 text-foreground\" />\n ) : (\n <ArrowDown className=\"h-3 w-3 text-foreground\" />\n )}\n {sorts.length > 1 && (\n <span className=\"text-[10px] text-muted-foreground font-mono\">\n {sortIndex + 1}\n </span>\n )}\n </>\n ) : (\n <ArrowUpDown className=\"h-3 w-3 text-muted-foreground/50\" />\n ))}\n </span>\n {resizableColumns && (\n <ResizeHandle\n onResize={(delta) =>\n handleResize(\n col.key,\n delta,\n col.minWidth ?? 60,\n )\n }\n onResizeEnd={handleResizeEnd}\n />\n )}\n </TableHead>\n );\n })}\n {renderActions && (\n <TableHead className={cn(\"w-10\", headDensity)} />\n )}\n </TableRow>\n </TableHeader>\n <TableBody>\n {displayItems.length === 0 ? (\n <TableRow>\n <TableCell\n colSpan={totalCols}\n className=\"text-center py-12 text-muted-foreground\"\n >\n {emptyMessage}\n </TableCell>\n </TableRow>\n ) : (\n displayItems.map((item) => {\n const id = getKey(item);\n return (\n <TableRow\n key={id}\n className={cn(onRowClick && \"cursor-pointer\")}\n data-state={\n selected?.has(id) ? \"selected\" : undefined\n }\n onClick={\n onRowClick ? () => onRowClick(item) : undefined\n }\n >\n {selectable && (\n <TableCell\n className={cellDensity}\n onClick={(e: React.MouseEvent) => e.stopPropagation()}\n >\n <Checkbox\n checked={selected?.has(id)}\n onCheckedChange={() => onToggleSelect?.(id)}\n />\n </TableCell>\n )}\n {activeColumns.map((col, colIndex) => {\n const acc =\n col.accessor ||\n ((it: T) =>\n (it as Record<string, unknown>)[col.key]);\n const value = acc(item);\n const isFirstCol = colIndex === 0 && stickyFirstColumn;\n return (\n <TableCell\n key={col.key}\n className={cn(\n getCellClasses(\n col as DataTableColumn<unknown>,\n ),\n cellDensity,\n isFirstCol && \"sticky left-0 z-[1] bg-background\",\n )}\n >\n {col.editable ? (\n <EditableCell\n item={item}\n column={col}\n value={value}\n />\n ) : col.render ? (\n col.render(item, value)\n ) : (\n <span className=\"truncate block max-w-[300px]\">\n {String(value ?? \"\\u2014\")}\n </span>\n )}\n </TableCell>\n );\n })}\n {renderActions && (\n <TableCell\n className={cellDensity}\n onClick={(e: React.MouseEvent) => e.stopPropagation()}\n >\n {renderActions(item)}\n </TableCell>\n )}\n </TableRow>\n );\n })\n )}\n </TableBody>\n </Table>\n </div>\n\n {/* ── Pagination footer ── */}\n {pagination && (\n <div className=\"sticky bottom-0 z-10 flex flex-col sm:flex-row items-center justify-between gap-2 px-4 py-3 border-t bg-muted/30 text-xs text-muted-foreground\">\n <span>\n {totalItems === 0\n ? \"No records\"\n : `Showing ${showingFrom}\\u2013${showingTo} of ${totalItems}`}\n </span>\n <div className=\"flex items-center gap-3\">\n <div className=\"flex items-center gap-1.5\">\n <span>Rows:</span>\n <Select\n value={String(currentPageSize)}\n onValueChange={(v) => setCurrentPageSize(Number(v))}\n >\n <SelectTrigger className=\"h-7 w-16 text-xs\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent className=\"bg-popover z-50\">\n {pageSizeOptions.map((n) => (\n <SelectItem key={n} value={String(n)}>\n {n}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"h-7 w-7\"\n disabled={currentPage === 0}\n onClick={() => setCurrentPage((p) => p - 1)}\n >\n <ChevronLeft className=\"h-3.5 w-3.5\" />\n </Button>\n <span className=\"px-2 tabular-nums\">\n {currentPage + 1} / {totalPages}\n </span>\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"h-7 w-7\"\n disabled={currentPage >= totalPages - 1}\n onClick={() => setCurrentPage((p) => p + 1)}\n >\n <ChevronRight className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/* ── Pre-built cell renderers ── */\n\nexport function ThumbnailCell({\n src,\n alt,\n}: {\n src?: string | null;\n alt: string;\n}) {\n if (!src) {\n return (\n <div className=\"h-10 w-14 rounded bg-muted flex items-center justify-center text-[10px] text-muted-foreground\">\n &mdash;\n </div>\n );\n }\n return (\n <img\n src={src}\n alt={alt}\n className=\"h-10 w-14 rounded object-cover bg-muted\"\n loading=\"lazy\"\n />\n );\n}\n\nexport function LinkCell({\n href,\n label,\n}: {\n href?: string | null;\n label?: string;\n}) {\n if (!href) return <span className=\"text-muted-foreground\">&mdash;</span>;\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n onClick={(e) => e.stopPropagation()}\n className=\"inline-flex items-center gap-1 text-xs text-primary hover:underline max-w-[200px] truncate\"\n >\n {label || new URL(href).hostname}\n <ExternalLink className=\"h-3 w-3 shrink-0\" />\n </a>\n );\n}\n","import { Checkbox } from \"../ui/checkbox\";\nimport { Badge } from \"../ui/badge\";\nimport { Button } from \"../ui/button\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { cn } from \"../../utils\";\n\n/**\n * One button in the bulk action bar.\n *\n * @stability Stable\n */\nexport interface BulkAction {\n label: string;\n icon: LucideIcon;\n onClick: () => void;\n variant?:\n | \"default\"\n | \"destructive\"\n | \"outline\"\n | \"secondary\"\n | \"ghost\"\n | \"link\";\n /**\n * Makes this action inert: it renders with the Button primitive's native\n * `disabled` attribute, so it is neither clickable nor focusable, and it\n * picks up the disabled styling.\n *\n * The case this exists for is an in-flight bulk mutation. A consumer that\n * fires a move/duplicate/delete over the selected ids wants every bulk\n * action dead until it settles, so a user cannot double-fire a destructive\n * operation on the same selection. Without this field the only guard\n * available is an early return inside `onClick` — which does stop the\n * second call, but leaves the button looking live, so the affordance lies\n * about what pressing it will do. Concretely, that is what blocks a real\n * consumer's hand-rolled bulk bar from migrating to `DataBulkBar`: it\n * would have to give up its double-submit guard to do so.\n *\n * Optional and defaulted off — omitting it behaves exactly as before.\n */\n disabled?: boolean;\n /**\n * `data-testid` on the rendered button.\n *\n * Without it, a consumer migrating a hand-rolled bulk bar to `DataBulkBar`\n * loses every selector its e2e suite uses to drive one — which is a real\n * reason not to migrate, and the kind of small missing affordance that\n * keeps a parallel implementation alive.\n */\n testId?: string;\n}\n\nexport interface DataBulkBarProps {\n selected: Set<string>;\n totalCount: number;\n onToggleAll: () => void;\n onClearSelection: () => void;\n actions: BulkAction[];\n /** Merged onto the bar, not replacing its positioning. */\n className?: string;\n}\n\nexport function DataBulkBar({\n selected,\n totalCount,\n onToggleAll,\n onClearSelection,\n actions,\n className,\n}: DataBulkBarProps) {\n if (selected.size === 0) return null;\n\n return (\n <div\n className={cn(\n \"flex items-center gap-2 p-3 rounded-lg border bg-muted/50 animate-fade-in\",\n className,\n )}\n >\n <Checkbox\n checked={selected.size === totalCount}\n onCheckedChange={onToggleAll}\n />\n <Badge variant=\"secondary\">{selected.size} selected</Badge>\n {actions.map((action) => {\n const ActionIcon = action.icon;\n return (\n <Button\n key={action.label}\n size=\"sm\"\n variant={action.variant || \"outline\"}\n onClick={action.onClick}\n disabled={action.disabled}\n data-testid={action.testId}\n >\n <ActionIcon className=\"h-3.5 w-3.5 mr-1\" />\n {action.label}\n </Button>\n );\n })}\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={onClearSelection}\n className=\"ml-auto text-xs text-muted-foreground\"\n >\n Clear\n </Button>\n </div>\n );\n}\n","import { Badge } from \"../ui/badge\";\nimport { formatDistanceToNow, format } from \"date-fns\";\n\n/**\n * DateCell -- shows relative date by default, formatted date otherwise.\n * Compatible with DataTableColumn<T>'s `render` prop.\n */\nexport function DateCell(options?: { relative?: boolean; format?: string }) {\n return (_item: unknown, value: unknown) => {\n if (!value) return \"\\u2014\";\n const date = new Date(String(value));\n if (isNaN(date.getTime())) return String(value);\n const relative = options?.relative !== false;\n const fmt = options?.format ?? \"MMM d, yyyy\";\n return relative\n ? formatDistanceToNow(date, { addSuffix: true })\n : format(date, fmt);\n };\n}\n\n/**\n * NumberCell -- locale-aware number formatting.\n */\nexport function NumberCell(options?: Intl.NumberFormatOptions) {\n const formatter = new Intl.NumberFormat(undefined, options);\n return (_item: unknown, value: unknown) => {\n if (value == null) return \"\\u2014\";\n const num = Number(value);\n return isNaN(num) ? String(value) : formatter.format(num);\n };\n}\n\n/**\n * CurrencyCell -- currency formatting with string-safe parsing.\n */\nexport function CurrencyCell(currency = \"USD\", locale?: string) {\n const formatter = new Intl.NumberFormat(locale, {\n style: \"currency\",\n currency,\n });\n return (_item: unknown, value: unknown) => {\n if (value == null) return \"\\u2014\";\n const str = String(value).replace(/[^0-9.-]/g, \"\");\n const num = Number(str);\n return isNaN(num) ? String(value) : formatter.format(num);\n };\n}\n\n/**\n * BadgeCell -- status badge with configurable color map.\n */\nexport function BadgeCell(\n colorMap?: Record<\n string,\n | \"default\"\n | \"secondary\"\n | \"destructive\"\n | \"outline\"\n | \"success\"\n | \"warning\"\n | \"info\"\n | \"muted\"\n >,\n) {\n return (_item: unknown, value: unknown) => {\n if (value == null) return \"\\u2014\";\n const str = String(value);\n const variant = colorMap?.[str] ?? \"outline\";\n return <Badge variant={variant}>{str}</Badge>;\n };\n}\n","import { cn } from \"../../utils\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { DefaultLink, type LinkComponent } from \"../../navigation\";\n\nexport type StatCardColor = \"primary\" | \"success\" | \"warning\" | \"info\" | \"destructive\" | \"muted\";\n\nconst colorMap: Record<StatCardColor, string> = {\n primary: \"text-primary\",\n success: \"text-success\",\n warning: \"text-warning\",\n info: \"text-info\",\n destructive: \"text-destructive\",\n muted: \"text-muted-foreground\",\n};\n\nexport interface StatCardProps {\n label: string;\n value: string | number;\n icon?: LucideIcon;\n /** Semantic color key or raw Tailwind class */\n color?: StatCardColor | string;\n /** When set, the card renders as a link to this path. */\n href?: string;\n /**\n * Injectable link component used when `href` is set. Defaults to a plain\n * `<a>` (no router). Pass a router adapter for client-side navigation.\n */\n linkComponent?: LinkComponent;\n trend?: { value: number; label: string };\n className?: string;\n}\n\nfunction resolveColor(color: string): string {\n return (colorMap as Record<string, string>)[color] ?? color;\n}\n\nexport function StatCard({\n label,\n value,\n icon: Icon,\n color = \"primary\",\n href,\n linkComponent: Link = DefaultLink,\n trend,\n className,\n}: StatCardProps) {\n const content = (\n <>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-muted-foreground\">{label}</span>\n {Icon && <Icon className={cn(\"h-4 w-4\", resolveColor(color))} />}\n </div>\n <p className=\"mt-2 text-2xl font-bold\">{value}</p>\n {trend && (\n <p\n className={cn(\n \"mt-1 text-xs font-medium\",\n trend.value >= 0\n ? \"text-primary\"\n : \"text-destructive\",\n )}\n >\n {trend.value >= 0 ? \"+\" : \"\"}\n {trend.value}% {trend.label}\n </p>\n )}\n </>\n );\n\n const cardClasses = cn(\n \"rounded-xl border border-border bg-card p-4 transition-all hover:shadow-md\",\n href && \"cursor-pointer hover:border-primary/30\",\n className,\n );\n\n if (href) {\n return (\n <Link href={href} className={cardClasses}>\n {content}\n </Link>\n );\n }\n\n return <div className={cardClasses}>{content}</div>;\n}\n","import { useState, type DragEvent, type ReactNode } from \"react\";\nimport { ArrowRightLeft } from \"lucide-react\";\nimport { Badge } from \"../ui/badge\";\nimport { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuTrigger } from \"../ui/dropdown-menu\";\nimport { cn } from \"../../utils\";\n\nexport type ColumnStatus = \"neutral\" | \"warning\" | \"success\" | \"info\" | \"destructive\" | \"primary\";\n\nconst statusColorMap: Record<ColumnStatus, { color: string; bgColor: string }> = {\n neutral: { color: \"text-muted-foreground\", bgColor: \"bg-muted\" },\n warning: { color: \"text-warning\", bgColor: \"bg-warning/15\" },\n success: { color: \"text-success\", bgColor: \"bg-success/15\" },\n info: { color: \"text-info\", bgColor: \"bg-info/15\" },\n destructive: { color: \"text-destructive\", bgColor: \"bg-destructive/15\" },\n primary: { color: \"text-primary\", bgColor: \"bg-primary/15\" },\n};\n\nexport interface KanbanColumn<T> {\n key: string;\n label: string;\n /** Semantic status for automatic color mapping */\n status?: ColumnStatus;\n /** Raw color class (used if status not provided) */\n color?: string;\n /** Raw bg color class (used if status not provided) */\n bgColor?: string;\n items: T[];\n /** How many items the column holds in all, when `items` is one page of them. */\n total?: number;\n}\n\nexport interface KanbanBoardProps<T> {\n columns: KanbanColumn<T>[];\n renderCard: (item: T) => ReactNode;\n emptyMessage?: string;\n className?: string;\n /** A stable key per item. Without one, cards are keyed by position. */\n getKey?: (item: T) => string;\n /**\n * Move an item to another column. When set, cards can be dragged between\n * columns, and each card gets a \"Move to…\" menu that does the same from\n * the keyboard. A rejected promise leaves the card where it was.\n */\n onMoveItem?: (item: T, toColumn: string) => void | Promise<void>;\n /** A name for an item, for the move menu's label (\"Move Ana Ruiz\"). */\n getItemLabel?: (item: T) => string;\n /** Under a column's cards, e.g. a \"Load more\" button. */\n renderColumnFooter?: (column: KanbanColumn<T>) => ReactNode;\n}\n\nconst DRAG_TYPE = \"application/x-genesis-kanban-item\";\n\n/**\n * Columns of cards, optionally movable between columns.\n *\n * Why the keyboard path isn't Radix (docs/FRAMEWORK.md rule 3): Radix has no\n * drag and drop, and native drag and drop can't be done from a keyboard. The\n * \"Move to…\" menu (a Radix DropdownMenu) is the equivalent path for keyboard\n * and screen-reader users, so dragging is never the only way to move a card.\n */\nexport function KanbanBoard<T>({\n columns,\n renderCard,\n emptyMessage = \"No items\",\n className,\n getKey,\n onMoveItem,\n getItemLabel,\n renderColumnFooter,\n}: KanbanBoardProps<T>) {\n const [dragging, setDragging] = useState<{ key: string; from: string } | null>(null);\n const [over, setOver] = useState<string | null>(null);\n const keyOf = (item: T, index: number) => (getKey ? getKey(item) : String(index));\n\n const move = (item: T, to: string) => {\n void Promise.resolve(onMoveItem?.(item, to)).catch(() => {\n // The caller reports the failure; the card simply stays put.\n });\n };\n\n const onDrop = (event: DragEvent, to: string) => {\n event.preventDefault();\n setOver(null);\n const key = event.dataTransfer.getData(DRAG_TYPE) || dragging?.key;\n setDragging(null);\n if (!key || !getKey) return;\n for (const column of columns) {\n const item = column.items.find((i) => getKey(i) === key);\n if (item) {\n if (column.key !== to) move(item, to);\n return;\n }\n }\n };\n\n // Dragging needs stable keys to find the dropped item again.\n const movable = Boolean(onMoveItem && getKey);\n\n return (\n <div\n className={cn(\n \"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\",\n className,\n )}\n >\n {columns.map((column) => {\n const resolved = column.status\n ? statusColorMap[column.status]\n : { color: column.color ?? \"\", bgColor: column.bgColor ?? \"\" };\n return (\n <section\n key={column.key}\n aria-label={column.label}\n data-kanban-column={column.key}\n className={cn(\n \"flex flex-col gap-3 rounded-lg\",\n movable && over === column.key && dragging?.from !== column.key && \"bg-accent/40 ring-2 ring-primary/40\",\n )}\n onDragOver={movable ? (e) => {\n if (!dragging) return;\n e.preventDefault();\n e.dataTransfer.dropEffect = \"move\";\n if (over !== column.key) setOver(column.key);\n } : undefined}\n onDragLeave={movable ? (e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) setOver(null);\n } : undefined}\n onDrop={movable ? (e) => onDrop(e, column.key) : undefined}\n >\n {/* Column header */}\n <div className=\"flex items-center gap-2\">\n <span className={cn(\"text-sm font-semibold\", resolved.color)}>\n {column.label}\n </span>\n <Badge\n variant=\"secondary\"\n className={cn(\"text-[10px] px-1.5 py-0\", resolved.bgColor)}\n >\n {column.total ?? column.items.length}\n </Badge>\n </div>\n\n {/* Cards */}\n <div className=\"flex flex-col gap-2 min-h-[80px]\">\n {column.items.length === 0 ? (\n <div className=\"flex items-center justify-center rounded-lg border border-dashed border-border p-6 text-xs text-muted-foreground\">\n {emptyMessage}\n </div>\n ) : (\n column.items.map((item, i) => {\n const key = keyOf(item, i);\n return (\n <div\n key={key}\n className={cn(\"animate-fade-in\", movable && \"group relative\", dragging?.key === key && \"opacity-50\")}\n style={{ animationDelay: `${i * 30}ms`, animationFillMode: \"both\" }}\n draggable={movable || undefined}\n onDragStart={movable ? (e) => {\n e.dataTransfer.setData(DRAG_TYPE, key);\n e.dataTransfer.effectAllowed = \"move\";\n setDragging({ key, from: column.key });\n } : undefined}\n onDragEnd={movable ? () => {\n setDragging(null);\n setOver(null);\n } : undefined}\n >\n {renderCard(item)}\n {movable && columns.length > 1 && (\n <DropdownMenu>\n <DropdownMenuTrigger\n aria-label={`Move ${getItemLabel?.(item) ?? \"card\"}`}\n className=\"absolute right-1.5 top-1.5 rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ArrowRightLeft className=\"h-3.5 w-3.5\" aria-hidden />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Move to</DropdownMenuLabel>\n {columns\n .filter((c) => c.key !== column.key)\n .map((c) => (\n <DropdownMenuItem key={c.key} onSelect={() => move(item, c.key)}>\n {c.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n );\n })\n )}\n </div>\n {renderColumnFooter?.(column)}\n </section>\n );\n })}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils\";\n\nexport interface DataListProps<T> {\n items: T[];\n renderItem: (item: T, index: number) => ReactNode;\n emptyMessage?: string;\n className?: string;\n}\n\nexport function DataList<T>({\n items,\n renderItem,\n emptyMessage = \"No items found\",\n className,\n}: DataListProps<T>) {\n if (items.length === 0) {\n return (\n <div className=\"text-center py-12 text-sm text-muted-foreground\">\n {emptyMessage}\n </div>\n );\n }\n\n return (\n <div className={cn(\"divide-y divide-border rounded-lg border\", className)}>\n {items.map((item, i) => (\n <div\n key={i}\n className=\"px-4 py-3 transition-colors hover:bg-accent/50\"\n >\n {renderItem(item, i)}\n </div>\n ))}\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport { Button } from \"../ui/button\";\nimport { Separator } from \"../ui/separator\";\nimport { Pencil, Trash2, X } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport { Dialog, DialogContent, DialogTitle, DialogDescription } from \"../ui/dialog\";\nimport { Sheet, SheetContent, SheetTitle, SheetDescription } from \"../ui/sheet\";\n\n/**\n * Props for {@link DetailPanel} — a shell-agnostic record detail view.\n * `layout` selects only the surrounding shell (inline / dialog / sheet);\n * the header and content below it render identically across all three.\n *\n * @stability Beta\n */\nexport interface DetailPanelProps<T> {\n /** The record to display */\n item: T | null;\n /** Whether panel is visible */\n open: boolean;\n /** Close handler */\n onClose: () => void;\n /** Header title */\n title?: string;\n /** Header subtitle */\n subtitle?: string;\n /** Shows edit button if provided */\n onEdit?: (item: T) => void;\n /** Shows delete button if provided */\n onDelete?: (item: T) => void;\n /** Custom content renderer */\n children?: (item: T) => ReactNode;\n /** Field definitions for auto-rendering */\n fields?: Array<{\n key: string;\n label: string;\n render?: (value: unknown, item: T) => ReactNode;\n }>;\n /**\n * Panel width. For `\"sheet\"` / `\"inline\"` this is a fixed pixel width\n * (matching this component's original, pre-`layout` sizing exactly). For\n * `\"dialog\"` it maps to Tailwind's modal max-width scale instead, since a\n * centered modal has a different sizing idiom than an edge-anchored panel.\n */\n width?: \"sm\" | \"md\" | \"lg\";\n /**\n * Rendering shell for the header + content below.\n * - `\"sheet\"` (default): fixed, right-anchored slide-in panel, composed\n * from the shared `Sheet` primitive. Matches this component's original\n * (pre-`layout`-prop) behavior — existing consumers that don't pass\n * `layout` see no change, other than an overlay now present at all\n * breakpoints (previously mobile-only) since it's a real `Sheet`.\n * - `\"dialog\"`: centered modal overlay, composed from the shared `Dialog`\n * primitive.\n * - `\"inline\"`: plain in-flow panel — no overlay, backdrop, or fixed\n * positioning — for master-detail / split-pane layouts.\n */\n layout?: \"inline\" | \"dialog\" | \"sheet\";\n}\n\nconst widthClasses = {\n sm: \"w-80\",\n md: \"w-96\",\n lg: \"w-[480px]\",\n} as const;\n\n/** `dialog` layout's width idiom: a centered modal, not an edge panel. */\nconst dialogMaxWidthClasses = {\n sm: \"sm:max-w-sm\",\n md: \"sm:max-w-lg\",\n lg: \"sm:max-w-2xl\",\n} as const;\n\n/** Convert a snake_case or camelCase key to Title Case label */\nfunction keyToLabel(key: string): string {\n return key\n .replace(/_/g, \" \")\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction formatValue(value: unknown): string {\n if (value === null || value === undefined) return \"—\";\n if (typeof value === \"boolean\") return value ? \"Yes\" : \"No\";\n if (value instanceof Date) return value.toLocaleDateString();\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n\n/**\n * Title/subtitle block for the panel header. `\"dialog\"` / `\"sheet\"` render\n * through the composed primitive's own `Title`/`Description` so Radix's\n * accessibility wiring (`aria-labelledby` / `aria-describedby`) stays\n * correct — falling back to visually-hidden text when `title`/`subtitle`\n * are omitted so Radix always has something to point at, without changing\n * what's visibly shown. `\"inline\"` isn't a Radix primitive, so it renders\n * the original plain conditional markup.\n */\nfunction renderTitleBlock(\n layout: \"inline\" | \"dialog\" | \"sheet\",\n title: string | undefined,\n subtitle: string | undefined,\n) {\n const titleText = title || \"Detail panel\";\n\n if (layout === \"dialog\") {\n return (\n <>\n <DialogTitle className={cn(\"text-sm font-semibold truncate\", !title && \"sr-only\")}>\n {titleText}\n </DialogTitle>\n <DialogDescription\n className={cn(\"text-xs text-muted-foreground truncate\", !subtitle && \"sr-only\")}\n >\n {subtitle || titleText}\n </DialogDescription>\n </>\n );\n }\n\n if (layout === \"sheet\") {\n return (\n <>\n <SheetTitle className={cn(\"text-sm font-semibold truncate\", !title && \"sr-only\")}>\n {titleText}\n </SheetTitle>\n <SheetDescription\n className={cn(\"text-xs text-muted-foreground truncate\", !subtitle && \"sr-only\")}\n >\n {subtitle || titleText}\n </SheetDescription>\n </>\n );\n }\n\n return (\n <>\n {title && <h2 className=\"text-sm font-semibold truncate\">{title}</h2>}\n {subtitle && <p className=\"text-xs text-muted-foreground truncate\">{subtitle}</p>}\n </>\n );\n}\n\nexport function DetailPanel<T extends Record<string, unknown>>({\n item,\n open,\n onClose,\n title,\n subtitle,\n onEdit,\n onDelete,\n children,\n fields,\n width = \"md\",\n layout = \"sheet\",\n}: DetailPanelProps<T>) {\n if (!open || !item) return null;\n\n const renderContent = () => {\n if (children) {\n return children(item);\n }\n\n if (fields) {\n return (\n <dl className=\"space-y-0\">\n {fields.map((field, index) => (\n <div key={field.key}>\n {index > 0 && <Separator />}\n <div className=\"py-3\">\n <dt className=\"text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {field.label}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {field.render\n ? field.render(item[field.key], item)\n : formatValue(item[field.key])}\n </dd>\n </div>\n </div>\n ))}\n </dl>\n );\n }\n\n // Auto-render all fields except \"id\"\n const entries = Object.entries(item).filter(([key]) => key !== \"id\");\n return (\n <dl className=\"space-y-0\">\n {entries.map(([key, value], index) => (\n <div key={key}>\n {index > 0 && <Separator />}\n <div className=\"py-3\">\n <dt className=\"text-xs font-medium text-muted-foreground uppercase tracking-wider\">\n {keyToLabel(key)}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {formatValue(value)}\n </dd>\n </div>\n </div>\n ))}\n </dl>\n );\n };\n\n const header = (\n <div className=\"flex items-center justify-between gap-2 border-b border-border px-4 py-3\">\n <div className=\"min-w-0\">{renderTitleBlock(layout, title, subtitle)}</div>\n <div className=\"flex items-center gap-1 shrink-0\">\n {onEdit && (\n <Button\n testID=\"detail-panel-edit\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => onEdit(item)}\n aria-label=\"Edit\"\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n )}\n {onDelete && (\n <Button\n testID=\"detail-panel-delete\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8 text-destructive hover:text-destructive\"\n onClick={() => onDelete(item)}\n aria-label=\"Delete\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n )}\n <Button\n testID=\"detail-panel-close\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={onClose}\n aria-label=\"Close\"\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n\n const content = (\n <div className=\"flex-1 overflow-y-auto px-4 py-3\">{renderContent()}</div>\n );\n\n // ── \"dialog\": centered modal overlay, composed from the shared Dialog ──\n if (layout === \"dialog\") {\n return (\n <Dialog\n open={open}\n onOpenChange={(next) => {\n if (!next) onClose();\n }}\n >\n <DialogContent\n showCloseButton={false}\n className={cn(\n \"flex max-h-[85vh] flex-col gap-0 overflow-hidden p-0\",\n dialogMaxWidthClasses[width],\n )}\n >\n {header}\n {content}\n </DialogContent>\n </Dialog>\n );\n }\n\n // ── \"sheet\" (default): fixed right-anchored slide-in, composed from the\n // shared Sheet primitive — this is the original DetailPanel look. ──\n if (layout === \"sheet\") {\n return (\n <Sheet\n open={open}\n onOpenChange={(next) => {\n if (!next) onClose();\n }}\n >\n <SheetContent\n side=\"right\"\n showCloseButton={false}\n className={cn(\n \"flex flex-col gap-0 overflow-hidden p-0 max-w-[90vw] sm:max-w-[90vw]\",\n widthClasses[width],\n )}\n >\n {header}\n {content}\n </SheetContent>\n </Sheet>\n );\n }\n\n // ── \"inline\": plain in-flow panel, no overlay/backdrop/fixed position ──\n return (\n <div\n role=\"region\"\n aria-label={title || \"Detail panel\"}\n className={cn(\n \"flex flex-col rounded-lg border border-border bg-card\",\n widthClasses[width],\n )}\n >\n {header}\n {content}\n </div>\n );\n}\n","\"use client\";\n\nimport { useState, useMemo } from \"react\";\nimport { Check, ChevronsUpDown, Loader2 } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport { useResource } from \"@marktiderman/genesis-core/hooks\";\nimport { useDataProvider, type BaseRecord } from \"@marktiderman/genesis-core/provider\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../ui/popover\";\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n} from \"../ui/command\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n} from \"../ui/dialog\";\nimport { Input } from \"../ui/input\";\nimport { Button } from \"../ui/button\";\nimport type { ResourceFormFieldDef } from \"./ResourceFormField\";\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface RelationFieldProps {\n field: ResourceFormFieldDef;\n value: string;\n onChange: (value: string) => void;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function RelationField({\n field,\n value,\n onChange,\n disabled,\n}: RelationFieldProps) {\n const [open, setOpen] = useState(false);\n const [createOpen, setCreateOpen] = useState(false);\n const [createValue, setCreateValue] = useState(\"\");\n const [createError, setCreateError] = useState<string | null>(null);\n const [isCreating, setIsCreating] = useState(false);\n const [extraOptions, setExtraOptions] = useState<{ value: string; label: string }[]>([]);\n const relation = field.relation!;\n const valueField = relation.valueField ?? \"id\";\n const provider = useDataProvider();\n\n const { list } = useResource(relation.resource, {\n defaultPerPage: 100,\n });\n\n const options = useMemo(() => {\n const base = list.data?.data\n ? list.data.data.map((item) => {\n const record = item as Record<string, unknown>;\n return {\n value: String(record[valueField] ?? \"\"),\n label: String(record[relation.labelField] ?? \"\"),\n };\n })\n : [];\n return [...base, ...extraOptions];\n }, [list.data?.data, valueField, relation.labelField, extraOptions]);\n\n const handleCreate = async () => {\n if (!createValue.trim() || isCreating) return;\n setIsCreating(true);\n try {\n const res = await provider.create<BaseRecord>(relation.resource, {\n data: { [relation.labelField]: createValue.trim() },\n });\n const record = res.data;\n const newValue = String(record[valueField] ?? \"\");\n const newLabel = String(record[relation.labelField] ?? \"\");\n setExtraOptions((prev) => [...prev, { value: newValue, label: newLabel }]);\n onChange(newValue);\n setCreateOpen(false);\n setCreateValue(\"\");\n } catch (err) {\n console.error(`Failed to create ${relation.resource}:`, err);\n setCreateError(err instanceof Error ? err.message : \"Failed to create record\");\n } finally {\n setIsCreating(false);\n }\n };\n\n const showSearch =\n relation.searchable ?? options.length > 10;\n\n const selectedLabel = useMemo(() => {\n if (!value) return null;\n const match = options.find((opt) => opt.value === value);\n return match?.label ?? null;\n }, [value, options]);\n\n const isLoading = list.isLoading;\n\n return (\n <>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className=\"w-full justify-between font-normal\"\n disabled={disabled || isLoading}\n >\n {isLoading ? (\n <span className=\"flex items-center gap-2 text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Loading...\n </span>\n ) : selectedLabel ? (\n selectedLabel\n ) : (\n <span className=\"text-muted-foreground\">\n {field.placeholder ?? \"Select...\"}\n </span>\n )}\n <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-[--radix-popover-trigger-width] p-0\" align=\"start\">\n <Command>\n {showSearch && <CommandInput placeholder=\"Search...\" />}\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup>\n {options.map((opt) => (\n <CommandItem\n key={opt.value}\n value={opt.label}\n onSelect={() => {\n onChange(opt.value === value ? \"\" : opt.value);\n setOpen(false);\n }}\n >\n <Check\n className={cn(\n \"mr-2 h-4 w-4\",\n value === opt.value ? \"opacity-100\" : \"opacity-0\",\n )}\n />\n {opt.label}\n </CommandItem>\n ))}\n </CommandGroup>\n {relation.allowCreate && (\n <>\n <CommandSeparator />\n <CommandGroup>\n <CommandItem\n onSelect={() => {\n setOpen(false);\n setCreateOpen(true);\n }}\n >\n + Create new...\n </CommandItem>\n </CommandGroup>\n </>\n )}\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n\n {relation.allowCreate && (\n <Dialog open={createOpen} onOpenChange={setCreateOpen}>\n <DialogContent className=\"sm:max-w-[400px]\">\n <DialogHeader>\n <DialogTitle>Create new {relation.resource.replace(/s$/, \"\")}</DialogTitle>\n </DialogHeader>\n <Input\n placeholder={`Enter ${relation.labelField}...`}\n value={createValue}\n onChange={(e) => { setCreateValue(e.target.value); setCreateError(null); }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n void handleCreate();\n }\n }}\n autoFocus\n />\n {createError && (\n <p className=\"text-sm text-destructive\">{createError}</p>\n )}\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setCreateOpen(false)} disabled={isCreating}>\n Cancel\n </Button>\n <Button onClick={() => void handleCreate()} disabled={isCreating || !createValue.trim()}>\n {isCreating ? \"Creating...\" : \"Create\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { useState, useMemo, useCallback, useEffect } from \"react\";\nimport { useDropzone, type FileRejection } from \"react-dropzone\";\nimport { Upload, X, FileIcon, ImageIcon, AlertCircle } from \"lucide-react\";\nimport { cn } from \"../../utils\";\nimport type { ResourceFormFieldDef } from \"./ResourceFormField\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_MAX_SIZE = 10 * 1024 * 1024; // 10MB\n\nfunction formatFileSize(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction parseAcceptProp(accept?: string): Record<string, string[]> | undefined {\n if (!accept) return undefined;\n // Convert shorthand like \"image/*\", \".pdf,.doc\" into react-dropzone accept format\n const result: Record<string, string[]> = {};\n const parts = accept.split(\",\").map((s) => s.trim());\n for (const part of parts) {\n if (part.includes(\"/\")) {\n // MIME type like \"image/*\"\n result[part] = [];\n } else if (part.startsWith(\".\")) {\n // Extension like \".pdf\"\n // Group under a generic key — react-dropzone matches by extension\n const key = \"application/octet-stream\";\n if (!result[key]) result[key] = [];\n result[key].push(part);\n }\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface FileUploadFieldProps {\n field: ResourceFormFieldDef;\n value: File | File[] | null;\n onChange: (value: File | File[] | null) => void;\n disabled?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function FileUploadField({\n field,\n value,\n onChange,\n disabled,\n}: FileUploadFieldProps) {\n const multiple = field.multiple ?? false;\n const maxSize = field.maxSize ?? DEFAULT_MAX_SIZE;\n const isImage = field.type === \"image\";\n const acceptObj = useMemo(\n () => parseAcceptProp(field.accept ?? (isImage ? \"image/*\" : undefined)),\n [field.accept, isImage],\n );\n\n const [errors, setErrors] = useState<string[]>([]);\n\n // Normalise value to an array for display\n const files: File[] = useMemo(() => {\n if (!value) return [];\n return Array.isArray(value) ? value : [value];\n }, [value]);\n\n // Preview URLs for image files\n const [previews, setPreviews] = useState<string[]>([]);\n\n useEffect(() => {\n const urls = files\n .filter((f) => f.type.startsWith(\"image/\"))\n .map((f) => URL.createObjectURL(f));\n setPreviews(urls);\n return () => urls.forEach((u) => URL.revokeObjectURL(u));\n }, [files]);\n\n const onDrop = useCallback(\n (accepted: File[], rejected: FileRejection[]) => {\n const newErrors: string[] = [];\n for (const rej of rejected) {\n for (const err of rej.errors) {\n if (err.code === \"file-too-large\") {\n newErrors.push(\n `\"${rej.file.name}\" exceeds ${formatFileSize(maxSize)} limit`,\n );\n } else if (err.code === \"file-invalid-type\") {\n newErrors.push(`\"${rej.file.name}\" is not an accepted file type`);\n } else {\n newErrors.push(`\"${rej.file.name}\": ${err.message}`);\n }\n }\n }\n setErrors(newErrors);\n\n if (accepted.length === 0) return;\n\n if (multiple) {\n const merged = [...files, ...accepted];\n onChange(merged);\n } else {\n onChange(accepted[0]);\n }\n },\n [files, maxSize, multiple, onChange],\n );\n\n const removeFile = useCallback(\n (index: number) => {\n const next = files.filter((_, i) => i !== index);\n if (next.length === 0) {\n onChange(null);\n } else if (multiple) {\n onChange(next);\n } else {\n onChange(null);\n }\n setErrors([]);\n },\n [files, multiple, onChange],\n );\n\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\n onDrop,\n accept: acceptObj,\n maxSize,\n multiple,\n disabled,\n });\n\n const hasFiles = files.length > 0;\n\n return (\n <div className=\"space-y-2\">\n {/* Drop zone */}\n <div\n {...getRootProps()}\n className={cn(\n \"flex cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed px-6 py-8 text-center transition-colors\",\n isDragActive\n ? \"border-primary bg-primary/5\"\n : \"border-muted-foreground/25 hover:border-muted-foreground/50\",\n disabled && \"pointer-events-none opacity-50\",\n hasFiles && \"py-4\",\n )}\n >\n <input {...getInputProps()} />\n {isImage ? (\n <ImageIcon className=\"mb-2 h-8 w-8 text-muted-foreground\" />\n ) : (\n <Upload className=\"mb-2 h-8 w-8 text-muted-foreground\" />\n )}\n <p className=\"text-sm text-muted-foreground\">\n {isDragActive\n ? \"Drop files here...\"\n : \"Drag & drop or click to upload\"}\n </p>\n <p className=\"mt-1 text-xs text-muted-foreground/70\">\n Max {formatFileSize(maxSize)}\n {field.accept ? ` -- ${field.accept}` : \"\"}\n </p>\n </div>\n\n {/* Error messages */}\n {errors.length > 0 && (\n <div className=\"space-y-1\">\n {errors.map((err, i) => (\n <p key={i} className=\"flex items-center gap-1 text-sm text-destructive\">\n <AlertCircle className=\"h-3.5 w-3.5 shrink-0\" />\n {err}\n </p>\n ))}\n </div>\n )}\n\n {/* File previews */}\n {hasFiles && (\n <ul className=\"space-y-2\">\n {files.map((file, index) => {\n const isImg = file.type.startsWith(\"image/\");\n const previewUrl = isImg ? previews[\n files.filter((f, i) => i <= index && f.type.startsWith(\"image/\")).length - 1\n ] : undefined;\n\n return (\n <li\n key={`${file.name}-${index}`}\n className=\"flex items-center gap-3 rounded-md border bg-muted/30 p-2\"\n >\n {isImg && previewUrl ? (\n <img\n src={previewUrl}\n alt={file.name}\n className=\"h-10 w-10 rounded object-cover\"\n />\n ) : (\n <FileIcon className=\"h-10 w-10 shrink-0 text-muted-foreground p-1\" />\n )}\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium\">{file.name}</p>\n <p className=\"text-xs text-muted-foreground\">\n {formatFileSize(file.size)}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n removeFile(index);\n }}\n className=\"shrink-0 rounded-md p-1 text-muted-foreground hover:bg-muted hover:text-foreground\"\n aria-label={`Remove ${file.name}`}\n >\n <X className=\"h-4 w-4\" />\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useFieldArray, type Control } from \"react-hook-form\";\nimport { Card, CardContent } from \"../ui/card\";\nimport { Button } from \"../ui/button\";\nimport { FormField, FormLabel, FormError } from \"../patterns/form-field\";\nimport { titleCase } from \"../../hooks/use-resource-page\";\nimport { buildArrayItemDefaults } from \"@marktiderman/genesis-core/hooks\";\nimport { ResourceFormFieldRenderer, type ResourceFormFieldDef } from \"./ResourceFormField\";\n\n// ---------------------------------------------------------------------------\n// FieldArrayRenderer\n// ---------------------------------------------------------------------------\n\nexport function FieldArrayRenderer({\n field,\n control,\n action,\n watchedValues,\n}: {\n field: ResourceFormFieldDef;\n control: Control<Record<string, unknown>>;\n action: \"create\" | \"edit\";\n watchedValues?: Record<string, unknown>;\n}) {\n const { fields: items, append, remove } = useFieldArray({\n control: control as unknown as Control,\n name: field.key,\n });\n\n const subFields = field.arrayFields ?? [];\n const label = field.label ?? titleCase(field.key);\n const canAdd = field.arrayMax == null || items.length < field.arrayMax;\n const canRemove = field.arrayMin == null || items.length > field.arrayMin;\n\n const handleAdd = () => {\n append(buildArrayItemDefaults(subFields));\n };\n\n return (\n <FormField>\n <FormLabel required={field.required}>{label}</FormLabel>\n {field.description && (\n <p className=\"text-sm text-muted-foreground\">{field.description}</p>\n )}\n\n <div className=\"space-y-3\">\n {items.map((item, index) => (\n <Card key={item.id} className=\"relative\">\n <CardContent className=\"pt-4 pb-3 px-4\">\n <div className=\"flex items-center justify-between mb-3\">\n <span className=\"text-xs font-medium text-muted-foreground\">\n Item {index + 1}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-7 px-2 text-destructive hover:text-destructive\"\n disabled={!canRemove}\n onClick={() => remove(index)}\n aria-label={`Remove item ${index + 1}`}\n >\n <TrashIcon className=\"h-4 w-4\" />\n </Button>\n </div>\n <div className=\"space-y-3\">\n {subFields.map((subField) => (\n <ResourceFormFieldRenderer\n key={subField.key}\n field={{\n ...subField,\n key: `${field.key}.${index}.${subField.key}`,\n }}\n control={control}\n action={action}\n watchedValues={watchedValues}\n />\n ))}\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-2\"\n disabled={!canAdd}\n onClick={handleAdd}\n >\n <PlusIcon className=\"h-4 w-4 mr-1\" />\n Add {label.replace(/s$/, \"\")}\n </Button>\n\n <FormError id={`${field.key}-error`}>\n {/* Array-level error from zod min/max */}\n </FormError>\n </FormField>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Inline icons (avoids lucide-react hard dependency)\n// ---------------------------------------------------------------------------\n\nfunction TrashIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <path d=\"M3 6h18\" />\n <path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\" />\n <path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\" />\n <line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\" />\n <line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\" />\n </svg>\n );\n}\n\nfunction PlusIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n );\n}\n","\"use client\";\n\nimport { Controller, type Control } from \"react-hook-form\";\nimport type { ResourceFormFieldDef } from \"@marktiderman/genesis-core\";\nimport { Input } from \"../ui/input\";\nimport { Textarea } from \"../ui/textarea\";\nimport { Switch } from \"../ui/switch\";\nimport { Checkbox } from \"../ui/checkbox\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../ui/select\";\nimport { FormField, FormLabel, FormError, FormDescription } from \"../patterns/form-field\";\nimport { titleCase } from \"../../hooks/use-resource-page\";\nimport { RelationField } from \"./RelationField\";\nimport { FileUploadField } from \"./FileUploadField\";\nimport { FieldArrayRenderer } from \"./FieldArrayRenderer\";\n\n// ---------------------------------------------------------------------------\n// Types — single source of truth is @marktiderman/genesis-core/form-types\n// ---------------------------------------------------------------------------\n\nexport type { FieldType, SelectOption, ResourceFormFieldDef } from \"@marktiderman/genesis-core\";\n\n// ---------------------------------------------------------------------------\n// Renderer\n// ---------------------------------------------------------------------------\n\nexport function ResourceFormFieldRenderer({\n field,\n control,\n action,\n autoFocus,\n watchedValues,\n}: {\n field: ResourceFormFieldDef;\n control: Control<Record<string, unknown>>;\n action: \"create\" | \"edit\";\n autoFocus?: boolean;\n watchedValues?: Record<string, unknown>;\n}) {\n const label = field.label ?? titleCase(field.key);\n const fieldType = field.type ?? \"text\";\n const isReadOnly = action === \"edit\" && field.readOnlyOnEdit;\n const isDisabled = isReadOnly || (watchedValues ? field.disabled?.(watchedValues) === true : false);\n\n // Array fields use useFieldArray — rendered outside of Controller\n if (fieldType === \"array\" && field.arrayFields) {\n return (\n <FieldArrayRenderer\n field={field}\n control={control}\n action={action}\n watchedValues={watchedValues}\n />\n );\n }\n\n if (field.hidden || fieldType === \"hidden\") {\n return (\n <Controller\n name={field.key}\n control={control}\n render={({ field: f }) => <input type=\"hidden\" {...f} value={String(f.value ?? \"\")} />}\n />\n );\n }\n\n return (\n <Controller\n name={field.key}\n control={control}\n render={({ field: f, fieldState }) => {\n const errorMessage = fieldState.error?.message;\n const ariaProps = {\n \"aria-invalid\": !!errorMessage || undefined,\n \"aria-describedby\": errorMessage\n ? `${field.key}-error`\n : field.description\n ? `${field.key}-desc`\n : undefined,\n \"aria-required\": field.required || undefined,\n };\n\n // Switch\n if (fieldType === \"switch\") {\n return (\n <FormField className=\"flex flex-row items-center justify-between rounded-lg border p-4\">\n <div className=\"space-y-0.5\">\n <FormLabel error={!!errorMessage}>{label}</FormLabel>\n </div>\n <Switch\n checked={!!f.value}\n onCheckedChange={f.onChange}\n disabled={isDisabled}\n {...ariaProps}\n />\n </FormField>\n );\n }\n\n // Checkbox\n if (fieldType === \"checkbox\") {\n return (\n <FormField className=\"flex flex-row items-start space-x-3 space-y-0\">\n <Checkbox\n checked={!!f.value}\n onCheckedChange={f.onChange}\n disabled={isDisabled}\n {...ariaProps}\n />\n <div className=\"space-y-1 leading-none\">\n <FormLabel error={!!errorMessage}>{label}</FormLabel>\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </div>\n </FormField>\n );\n }\n\n // Select\n if (fieldType === \"select\" && field.options) {\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <Select\n value={f.value != null ? String(f.value) : \"\"}\n onValueChange={f.onChange}\n disabled={isDisabled}\n >\n <SelectTrigger\n {...ariaProps}\n >\n <SelectValue placeholder={field.placeholder ?? `Select ${label.toLowerCase()}...`} />\n </SelectTrigger>\n <SelectContent>\n {field.options.map((opt) => (\n <SelectItem key={opt.value} value={opt.value}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }\n\n // Relation\n if (fieldType === \"relation\" && field.relation) {\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <RelationField\n field={field}\n value={f.value != null ? String(f.value) : \"\"}\n onChange={f.onChange}\n disabled={isDisabled}\n />\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }\n\n // File / Image\n if (fieldType === \"file\" || fieldType === \"image\") {\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <FileUploadField\n field={field}\n value={f.value as File | File[] | null}\n onChange={f.onChange}\n disabled={isDisabled}\n />\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }\n\n // Textarea\n if (fieldType === \"textarea\") {\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <Textarea\n placeholder={field.placeholder}\n rows={field.rows ?? 3}\n value={f.value != null ? String(f.value) : \"\"}\n onChange={(e) => f.onChange(e.target.value)}\n disabled={isDisabled}\n autoFocus={autoFocus}\n {...ariaProps}\n />\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }\n\n // Number\n if (fieldType === \"number\") {\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <Input\n type=\"number\"\n placeholder={field.placeholder}\n min={field.min}\n max={field.max}\n value={f.value != null ? String(f.value) : \"\"}\n onChange={(e) => {\n const val = e.target.value;\n f.onChange(val === \"\" ? undefined : Number(val));\n }}\n disabled={isDisabled}\n autoFocus={autoFocus}\n {...ariaProps}\n />\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }\n\n // Text, email, url, date\n return (\n <FormField>\n <FormLabel error={!!errorMessage} required={field.required}>\n {label}\n </FormLabel>\n <Input\n type={fieldType}\n placeholder={field.placeholder}\n value={f.value != null ? String(f.value) : \"\"}\n onChange={(e) => f.onChange(e.target.value)}\n disabled={isDisabled}\n autoFocus={autoFocus}\n {...ariaProps}\n />\n {field.description && <FormDescription id={`${field.key}-desc`}>{field.description}</FormDescription>}\n <FormError id={`${field.key}-error`}>{errorMessage}</FormError>\n </FormField>\n );\n }}\n />\n );\n}\n","\"use client\";\n\nimport { type ReactNode } from \"react\";\nimport type { UseFormReturn, FieldErrors } from \"react-hook-form\";\nimport { useWatch } from \"react-hook-form\";\nimport { Button } from \"../ui/button\";\nimport { Progress } from \"../ui/progress\";\nimport { Spinner } from \"../ui/spinner\";\nimport { useWizard, type WizardStep } from \"@marktiderman/genesis-core/hooks\";\nimport { ResourceFormFieldRenderer, type ResourceFormFieldDef } from \"./ResourceFormField\";\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface WizardFormProps {\n steps: WizardStep[];\n form: UseFormReturn<Record<string, unknown>>;\n fields: ResourceFormFieldDef[];\n onSubmit: (data: Record<string, unknown>) => Promise<void>;\n isSaving: boolean;\n renderField?: (\n field: ResourceFormFieldDef,\n control: UseFormReturn<Record<string, unknown>>[\"control\"],\n action: \"create\" | \"edit\",\n watchedValues: Record<string, unknown>,\n ) => ReactNode;\n action: \"create\" | \"edit\";\n onInvalid?: (errors: FieldErrors) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function WizardForm({\n steps,\n form,\n fields,\n onSubmit,\n isSaving,\n renderField,\n action,\n onInvalid,\n}: WizardFormProps) {\n const wizard = useWizard(steps, form);\n const watchedValues = useWatch({ control: form.control }) as Record<string, unknown>;\n\n // Get fields for the current step\n const stepFieldKeys = new Set(wizard.currentStepDef.fields);\n const stepFields = fields.filter(\n (f) => stepFieldKeys.has(f.key) && f.visible?.(watchedValues) !== false,\n );\n\n const handleNext = async () => {\n if (wizard.isLast) {\n // Submit the form\n await form.handleSubmit(onSubmit, onInvalid)();\n } else {\n await wizard.next();\n }\n };\n\n return (\n <div className=\"space-y-6\">\n {/* Progress */}\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between text-sm text-muted-foreground\">\n <span>\n Step {wizard.currentStep + 1} of {wizard.totalSteps}\n </span>\n <span>{Math.round(wizard.progress * 100)}%</span>\n </div>\n <Progress value={wizard.progress * 100} />\n </div>\n\n {/* Step header */}\n <div className=\"space-y-1\">\n <h3 className=\"text-lg font-semibold\">{wizard.currentStepDef.title}</h3>\n {wizard.currentStepDef.description && (\n <p className=\"text-sm text-muted-foreground\">\n {wizard.currentStepDef.description}\n </p>\n )}\n </div>\n\n {/* Step fields with transition */}\n <div\n key={wizard.currentStep}\n className=\"animate-in fade-in slide-in-from-right-2 duration-200\"\n >\n <div className=\"space-y-4\">\n {stepFields.map((field) =>\n renderField ? (\n <div key={field.key}>\n {renderField(field, form.control, action, watchedValues)}\n </div>\n ) : (\n <ResourceFormFieldRenderer\n key={field.key}\n field={field}\n control={form.control}\n action={action}\n watchedValues={watchedValues}\n />\n ),\n )}\n </div>\n </div>\n\n {/* Navigation buttons */}\n <div className=\"flex justify-between pt-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={wizard.back}\n disabled={wizard.isFirst || isSaving}\n >\n Back\n </Button>\n <Button\n type=\"button\"\n onClick={handleNext}\n disabled={isSaving}\n >\n {isSaving && <Spinner size=\"sm\" className=\"mr-2\" />}\n {wizard.isLast ? (action === \"create\" ? \"Create\" : \"Save\") : \"Next\"}\n </Button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { type ReactNode } from \"react\";\nimport type { UseFormReturn, FieldErrors } from \"react-hook-form\";\nimport { useWatch } from \"react-hook-form\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n} from \"../ui/dialog\";\nimport {\n Sheet,\n SheetContent,\n SheetHeader,\n SheetTitle,\n SheetDescription,\n} from \"../ui/sheet\";\nimport { Card, CardHeader, CardTitle, CardContent } from \"../ui/card\";\nimport { Button } from \"../ui/button\";\nimport { Spinner } from \"../ui/spinner\";\nimport { useIsMobile } from \"../../hooks/use-mobile\";\nimport { useResourceForm, type UseResourceFormOptions } from \"@marktiderman/genesis-core/hooks\";\nimport { ResourceFormFieldRenderer, type ResourceFormFieldDef } from \"./ResourceFormField\";\nimport { WizardForm } from \"./WizardForm\";\nimport type { WizardStep } from \"@marktiderman/genesis-core/hooks\";\nimport { titleCase } from \"../../hooks/use-resource-page\";\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface ResourceFormProps {\n resource: string;\n action: \"create\" | \"edit\";\n item?: Record<string, unknown>;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title?: string;\n fields?: ResourceFormFieldDef[];\n /** Full dataset used to auto-detect select fields from unique values. */\n listData?: Record<string, unknown>[];\n renderForm?: (\n form: UseFormReturn<Record<string, unknown>>,\n fields: ResourceFormFieldDef[],\n ) => ReactNode;\n onSuccess?: (data: Record<string, unknown>) => void;\n onError?: (error: Error) => void;\n /** Layout mode for the form container. Default \"dialog\". */\n layout?: \"dialog\" | \"sheet\" | \"page\";\n /** Form presentation mode. Default \"standard\". */\n mode?: \"standard\" | \"wizard\";\n /** Wizard step definitions. Required when mode is \"wizard\". */\n steps?: WizardStep[];\n /** Number of columns for the form layout. Default 1. */\n columns?: 1 | 2;\n}\n\n// ---------------------------------------------------------------------------\n// Internal: shared form body\n// ---------------------------------------------------------------------------\n\nfunction FormBody({\n form,\n resolvedFields,\n renderForm,\n action,\n isSaving,\n isLoading,\n onOpenChange,\n handleSave,\n mode = \"standard\",\n steps,\n columns = 1,\n}: {\n form: UseFormReturn<Record<string, unknown>>;\n resolvedFields: ResourceFormFieldDef[];\n renderForm?: ResourceFormProps[\"renderForm\"];\n action: \"create\" | \"edit\";\n isSaving: boolean;\n isLoading: boolean;\n onOpenChange: (open: boolean) => void;\n handleSave: (data: Record<string, unknown>) => Promise<void>;\n mode?: \"standard\" | \"wizard\";\n steps?: WizardStep[];\n columns?: 1 | 2;\n}) {\n // Only watch all values when conditional fields exist (performance optimization)\n const hasConditionalFields = resolvedFields.some((f: ResourceFormFieldDef) => f.visible || f.disabled);\n const watchedValues = useWatch({\n control: form.control,\n disabled: !hasConditionalFields,\n }) as Record<string, unknown>;\n\n const onInvalid = (errors: FieldErrors) => {\n const firstErrorKey = Object.keys(errors)[0];\n if (firstErrorKey) form.setFocus(firstErrorKey);\n };\n\n if (isLoading) {\n return (\n <div className=\"flex items-center justify-center py-8\">\n <Spinner />\n </div>\n );\n }\n\n // Wizard mode\n if (mode === \"wizard\" && steps) {\n return (\n <WizardForm\n steps={steps}\n form={form}\n fields={resolvedFields}\n onSubmit={handleSave}\n isSaving={isSaving}\n action={action}\n onInvalid={onInvalid}\n />\n );\n }\n\n // Filter fields by visibility\n const visibleFields = resolvedFields.filter(\n (field) => field.visible?.(watchedValues) !== false,\n );\n\n let autoFocusAssigned = false;\n\n // Group fields by their `group` property\n const groups: { name: string | null; fields: ResourceFormFieldDef[] }[] = [];\n const groupMap = new Map<string | null, ResourceFormFieldDef[]>();\n\n for (const field of visibleFields) {\n const groupKey = field.group ?? null;\n if (!groupMap.has(groupKey)) {\n const arr: ResourceFormFieldDef[] = [];\n groupMap.set(groupKey, arr);\n groups.push({ name: groupKey, fields: arr });\n }\n groupMap.get(groupKey)!.push(field);\n }\n\n /** Render a list of fields with optional 2-column grid */\n function renderFields(fields: ResourceFormFieldDef[]) {\n const useGrid = columns === 2;\n return (\n <div className={useGrid ? \"grid grid-cols-2 gap-4\" : \"space-y-4\"}>\n {fields.map((field) => {\n const isHidden = field.hidden || field.type === \"hidden\";\n const shouldAutoFocus = !isHidden && !autoFocusAssigned;\n if (shouldAutoFocus) autoFocusAssigned = true;\n // Auto-span 2 columns for textarea and array fields in 2-column mode\n const autoSpan =\n useGrid && (field.type === \"textarea\" || field.type === \"array\") ? 2 : undefined;\n const span = useGrid ? (field.colSpan ?? autoSpan ?? 1) : undefined;\n return (\n <div key={field.key} className={span === 2 ? \"col-span-2\" : \"\"}>\n <ResourceFormFieldRenderer\n field={field}\n control={form.control}\n action={action}\n autoFocus={shouldAutoFocus}\n watchedValues={watchedValues}\n />\n </div>\n );\n })}\n </div>\n );\n }\n\n return (\n <form\n onSubmit={(e) => {\n e.preventDefault();\n void form.handleSubmit(handleSave, onInvalid)(e);\n }}\n className=\"space-y-4\"\n >\n <div className=\"max-h-[60vh] overflow-y-auto px-1\">\n {renderForm ? (\n renderForm(form, visibleFields)\n ) : (\n <div className=\"space-y-4\">\n {groups.map((group, idx) => (\n <div key={group.name ?? \"__default\"}>\n {group.name && (\n <div className=\"pt-2\">\n {idx > 0 && <div className=\"border-t mb-3\" />}\n <h3 className=\"text-sm font-medium text-muted-foreground mb-3\">\n {group.name}\n </h3>\n </div>\n )}\n {renderFields(group.fields)}\n </div>\n ))}\n </div>\n )}\n </div>\n\n <div className=\"flex justify-end gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n disabled={isSaving}\n >\n Cancel\n </Button>\n <Button type=\"submit\" disabled={isSaving}>\n {isSaving && <Spinner size=\"sm\" className=\"mr-2\" />}\n {action === \"create\" ? \"Create\" : \"Save\"}\n </Button>\n </div>\n </form>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function ResourceForm(props: ResourceFormProps) {\n const {\n resource,\n action,\n item,\n open,\n onOpenChange,\n title: titleProp,\n fields: fieldsProp,\n listData,\n renderForm,\n onSuccess,\n onError,\n layout: layoutProp = \"dialog\",\n mode = \"standard\",\n steps,\n columns = 1,\n } = props;\n\n const isMobile = useIsMobile();\n const effectiveLayout = isMobile ? \"sheet\" : layoutProp;\n\n const resourceLabel = titleCase(resource.replace(/s$/, \"\"));\n const formTitle =\n titleProp ?? (action === \"create\" ? `Create ${resourceLabel}` : `Edit ${resourceLabel}`);\n const formDescription =\n `${action === \"create\" ? \"Fill in the details to create a new\" : \"Update the\"} ${resourceLabel.toLowerCase()} record.`;\n\n const hookOptions: UseResourceFormOptions = {\n resource,\n action,\n id: item ? String(item.id ?? \"\") : undefined,\n initialData: item ?? undefined,\n fields: fieldsProp,\n listData,\n onSuccess: (data) => {\n onOpenChange(false);\n onSuccess?.(data);\n },\n onError,\n };\n\n const { form, resolvedFields, handleSave, isSaving, isLoading } =\n useResourceForm(hookOptions);\n\n const bodyProps = {\n form,\n resolvedFields,\n renderForm,\n action,\n isSaving,\n isLoading,\n onOpenChange,\n handleSave,\n mode,\n steps,\n columns,\n };\n\n // ── Dialog layout ──\n if (effectiveLayout === \"dialog\") {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-[560px]\">\n <DialogHeader>\n <DialogTitle>{formTitle}</DialogTitle>\n <DialogDescription className=\"sr-only\">\n {formDescription}\n </DialogDescription>\n </DialogHeader>\n <FormBody {...bodyProps} />\n </DialogContent>\n </Dialog>\n );\n }\n\n // ── Sheet layout ──\n if (effectiveLayout === \"sheet\") {\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent side=\"right\" className=\"sm:max-w-[480px] overflow-y-auto\">\n <SheetHeader>\n <SheetTitle>{formTitle}</SheetTitle>\n <SheetDescription className=\"sr-only\">\n {formDescription}\n </SheetDescription>\n </SheetHeader>\n <FormBody {...bodyProps} />\n </SheetContent>\n </Sheet>\n );\n }\n\n // ── Page layout ──\n if (!open) return null;\n\n return (\n <Card className=\"mx-auto max-w-[560px]\">\n <CardHeader>\n <CardTitle>{formTitle}</CardTitle>\n </CardHeader>\n <CardContent>\n <FormBody {...bodyProps} />\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport {\n Fragment,\n type KeyboardEvent as ReactKeyboardEvent,\n type ComponentProps,\n type ComponentType,\n type ReactNode,\n useMemo,\n useState,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport type { UseFormReturn } from \"react-hook-form\";\nimport {\n AlertTriangle,\n ChevronLeft,\n ChevronRight,\n Plus,\n Trash2,\n} from \"lucide-react\";\nimport { Button } from \"../ui/button\";\nimport { cn } from \"../../utils\";\nimport { DataPageShell } from \"./DataPageShell\";\nimport type { PageHeaderAction } from \"../layout/PageHeader\";\nimport {\n DataFilters,\n type SavedViewItem,\n type DataFilterConfig,\n} from \"./DataFilters\";\nimport { DataTable } from \"./DataTable\";\nimport { DataBulkBar } from \"./DataBulkBar\";\nimport { DataGrid } from \"./DataGrid\";\nimport { DetailPanel } from \"./DetailPanel\";\nimport { ResourceForm } from \"./ResourceForm\";\nimport {\n renderSlot,\n type Slots,\n type SlotPropsFor,\n} from \"../../slots\";\nimport { Card, CardHeader, CardTitle, CardContent } from \"../ui/card\";\nimport type { ViewMode } from \"../patterns/view-toggle\";\nimport {\n useResource,\n type UseResourceOptions,\n} from \"@marktiderman/genesis-core/hooks\";\nimport {\n useResourcePage,\n type ResourceColumnDef,\n type ResourceActions,\n} from \"../../hooks/use-resource-page\";\nimport { useViewSettings } from \"../../hooks/use-view-settings\";\nimport { useKeyboardNavigation } from \"../../hooks/use-keyboard-navigation\";\nimport type {\n BaseRecord,\n FilterParam,\n SortParam,\n} from \"@marktiderman/genesis-core/provider\";\nimport type { ResourceFormFieldDef } from \"./ResourceFormField\";\nimport type { WizardStep } from \"@marktiderman/genesis-core/hooks\";\nimport { defaultNavigate, type NavigateFn } from \"../../navigation\";\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\n/**\n * Row-bound actions handed to `renderCard`, on top of the resource-wide\n * `ResourceActions`. `open` is per-row, which is why it lives here rather\n * than on `ResourceActions` — that object is built once and shared by every\n * row and column, so it cannot carry a row-specific callback.\n *\n * @stability Beta\n */\nexport interface ResourceCardActions<T> extends ResourceActions<T> {\n /**\n * Activate this row — opens the configured detail panel / modal / route,\n * exactly as clicking the built-in card does. Wire it to your card's\n * `onClick` (and call `stopPropagation` on any nested control that should\n * not also activate the row).\n */\n open: () => void;\n}\n\n/**\n * Config-driven resource page: wires data-fetching (or a pre-fetched `data`\n * array), search/filter/sort, table/grid/list views, and a detail\n * panel/modal/route around a `DataProvider` resource — the CRUD page most\n * apps hand-roll, expressed as one component tree. `renderCard` lets a\n * consumer fully own item presentation while ResourcePage keeps handling\n * data-fetching, filtering, and layout; see also the built-in\n * `useKeyboardNavigation` wiring (`keyboardNavigation` prop) and `gridCols`.\n *\n * Three levels of control, and each option is available at all three:\n *\n * 1. **The primitive offers it** — table / grid / list views, search, sort,\n * status chips, column visibility and resizing, density, page size,\n * detail panel / modal / route, built-in create and edit forms.\n * 2. **The instance turns it on or off** — every one of those is a prop, so\n * a given page decides which affordances it offers at all.\n * 3. **The end user picks their own, and it sticks** — for the options left\n * on at level 2, the user's choice persists to their own storage:\n * `viewSettingsKey` for page size and density, `columnVisibilityKey` and\n * `resizeKey` for column layout, `savedViews` (pair with `useSavedViews`)\n * for named filter sets. Persistence needs a key; without one the choice\n * lasts only for the session.\n *\n * A server-paginated list drives the same component through the controlled\n * props (`page`, `perPage`, `onPageChange`, `onSortChange`, `onSearchChange`\n * and friends) — supplying any of them stops ResourcePage from searching,\n * sorting or paging the `data` a second time. See that block in\n * {@link ResourcePageProps}.\n *\n * @stability Beta\n */\n/**\n * Every interior part `ResourcePage` composes, with the props it composes it\n * with. Each key is a slot: replace it via `slots`, feed it more props via\n * `slotProps`, or eject it with `null`.\n *\n * The map is the contract. A part that is not named here cannot be reached,\n * so adding a part to the render tree means adding it here in the same\n * change — otherwise the next surface that needs it forks the whole page.\n */\nexport type ResourcePageSlotMap<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = {\n /** The page shell: header, count pill, loading / empty / error states. */\n shell: ComponentProps<typeof DataPageShell>;\n /** The filter row — search, sort, facets, saved views. */\n filters: ComponentProps<typeof DataFilters>;\n /** The selection bar. Ejecting it leaves selection working, just unshown. */\n bulkBar: ComponentProps<typeof DataBulkBar>;\n /** The card/table switch. */\n grid: ComponentProps<typeof DataGrid<T>>;\n /** The table inside the grid. `renderTable` stays the terser way to swap. */\n table: ComponentProps<typeof DataTable<T>>;\n /** The detail peek. */\n detail: ComponentProps<typeof DetailPanel<T>>;\n /** The create / edit form. */\n form: ComponentProps<typeof ResourceForm>;\n};\n\n/**\n * `slots` for {@link ResourcePage}, with one asymmetry the map cannot express:\n * every part may be ejected with `null` EXCEPT `shell`.\n *\n * The shell is not an interior part, it is the page — `Shell` is what the\n * render returns, so ejecting it does not remove a piece, it removes the\n * component (`const Shell = slots?.shell ?? DataPageShell` would become\n * `null`, and React throws on the element). A caller who wants no shell wants\n * rung 3 of the ladder, not a `null` here. Replacing it stays supported, which\n * is the way to wrap it and change one thing.\n */\nexport type ResourcePageSlots<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = Omit<Slots<ResourcePageSlotMap<T>>, \"shell\"> & {\n shell?: ComponentType<ComponentProps<typeof DataPageShell>>;\n};\n\nexport interface ResourcePageProps<\n T extends Record<string, unknown> = Record<string, unknown>,\n> {\n // Data source — one or the other\n /** Client-side mode: resource name passed to useResource / DataProvider. */\n resource?: string;\n /** Server-data mode: pre-fetched data array. */\n data?: T[];\n /**\n * Server-data mode: total record count (before client-side filtering).\n *\n * Required whenever `onPageChange` is supplied. It cannot be derived from\n * `data`, which holds only the current page. Omitted, `displayTotal` falls\n * back to `0`, so the range span reads \"No records\" and `Next` stays\n * disabled while the rows render directly below it. Rather than show a\n * pager that contradicts the list, the component refuses to render the\n * pager and shows an error instead. See {@link perPage} and\n * {@link onPageChange}.\n */\n total?: number;\n\n // Page chrome\n title: string;\n /** Page subtitle shown below the title. */\n subtitle?: string;\n icon?: LucideIcon;\n\n // Columns — optional, string shorthand supported\n columns?: Array<string | ResourceColumnDef<T>>;\n\n /**\n * A row's identity, for React keys and bulk selection. Defaults to\n * `String(item.id)`. Supply it for rows keyed some other way — a composite\n * key (`encodeRecordKey` from `@marktiderman/genesis-core/schema`), or a\n * table whose key column isn't called `id`. Detail `route` mode still\n * navigates by `item.id`.\n */\n getKey?: (item: T) => string;\n\n // Detail view\n /** How row-click detail is shown. Default \"panel\". */\n detail?: \"panel\" | \"modal\" | \"route\" | \"none\";\n detailWidth?: \"sm\" | \"md\" | \"lg\";\n titleField?: string;\n subtitleField?: string;\n renderDetail?: (item: T) => ReactNode;\n detailFields?: Array<{\n key: string;\n label: string;\n render?: (value: unknown, item: T) => ReactNode;\n }>;\n\n // Filters\n /**\n * Adds a status-chip filter. There is no dedicated status-change\n * callback: chip clicks update the same filter state that already\n * reports through `onFiltersChange`, whether or not the page is in\n * server-controlled mode. A caller combining `statusFilter` with server\n * pagination (`onPageChange` et al.) must supply `onFiltersChange` — see\n * that prop — or status changes will update the chip UI without ever\n * reaching the server. In server-controlled mode a status change also\n * resets to page 1 via `onPageChange(1)` — see {@link onPageChange}.\n */\n statusFilter?: string | { field: string; options?: string[] };\n searchFields?: string[];\n searchPlaceholder?: string;\n initialFilters?: FilterParam[];\n onFiltersChange?: (filters: FilterParam[]) => void;\n /**\n * Extra multi-select filter comboboxes, handed straight to `DataFilters`\n * and rendered beside the status chips. Each config owns its own\n * `selected` array and `onChange` — ResourcePage never reads or writes\n * them, because it cannot know what a caller's \"Grade\" or \"Subject\"\n * combobox means against the row shape. That is deliberate rather than a\n * gap: the built-in machinery (`searchFields`, `statusFilter`) covers the\n * two shapes it *can* interpret, and this prop covers everything else by\n * getting out of the way.\n *\n * Two consequences of that hands-off stance, stated rather than hidden:\n * - These selections are invisible to `page.hasActiveFilters`, so the\n * header's \"Clear filters\" affordance does not appear for them alone,\n * and `onClearFilters` does not reset them. DataFilters' own \"Clear all\"\n * does call each config's `onChange([])`, so wire real clearing there.\n * - In client-side mode the rows are NOT re-filtered by these selections.\n * A caller using them is expected to filter its own `data` (or ask the\n * server to), exactly as it already does in server-controlled mode.\n */\n filters?: DataFilterConfig[];\n\n // ─────────────────────────────────────────────────────────────────────────\n // Server-controlled list (opt-in, additive)\n //\n // Supplying ANY prop in this block puts the page in server-controlled\n // mode, in which ResourcePage renders `data` exactly as given: it does not\n // search it, sort it or paginate it a second time. That double-work is the\n // reason a server-paginated list could not previously adopt ResourcePage —\n // page 3 of 40 would be re-filtered and re-sorted against only its own 25\n // rows, and then re-paged on top of that.\n //\n // Consequences, stated rather than hidden:\n // - Table column headers stop being sort triggers (a header click could\n // only reorder the current page, which would be a lie about the sort).\n // The sort control in `DataFilters` drives `onSortChange` instead.\n // - `DataTable`'s own pagination is switched off; the pager below the list\n // is driven by `page` / `perPage` / `total` / `onPageChange`, and is only\n // rendered when `onPageChange` is supplied. BOTH `perPage` AND `total`\n // are required for that pager's math, and neither can be derived from\n // the rows: a short final page is smaller than the real page size, so\n // `data.length` must not be used as the divisor, and `data` holds only\n // the current page, so it cannot supply the total either.\n // - Changing search or sort calls `onPageChange(1)` as well, so the caller\n // is never left requesting page 7 of a one-page result.\n // - Grid and list views are NOT forced to table view, and they render\n // cards for the current server page only. That is accepted rather than\n // worked around, because it is not actually wrong here: the pager is\n // rendered OUTSIDE DataGrid precisely so it pages grid and list too, so\n // \"this view shows one page, and there is a pager under it\" is the same\n // contract the table view has. Forcing `viewMode=\"table\"` would instead\n // silently discard a `renderCard` the caller supplied, and silently\n // overriding a user's own view choice is the worse failure. The one real\n // caveat: DataGrid's infinite-scroll batching (48 at a time) tops out at\n // the page size, so a server page smaller than 48 never scroll-loads —\n // harmless, but it means infinite scroll and server paging do not\n // compose into an endless list.\n // ─────────────────────────────────────────────────────────────────────────\n\n /** Current page, 1-based. Server-controlled mode only. */\n page?: number;\n /**\n * Rows per page the server was asked for. Required whenever\n * `onPageChange` is supplied: pager math (total pages, range start, Next)\n * cannot be inferred from `data.length`, because a short final page is\n * smaller than the real page size. Wins over the per-user page size\n * persisted by `viewSettingsKey` — an explicit prop always beats a stored\n * preference.\n *\n * Required whenever `onPageChange` is supplied. A short final page (the\n * server's last page returning fewer rows than its page size) is\n * indistinguishable from a small page size — there is no correct way to\n * infer the divisor from the rows handed back. Rather than guess and\n * render a wrong range or a stuck Next button, the component refuses to\n * render the pager and shows an error instead when `onPageChange` is\n * present without `perPage`.\n *\n * `total` is required on the same terms — see {@link total}. The error\n * names every missing prop, not just the first.\n */\n perPage?: number;\n /**\n * Called with the next 1-based page number. The pager only renders when\n * this is supplied AND both `perPage` and `total` are supplied — see\n * {@link perPage} and {@link total}. Supplying this without either one\n * renders an error naming the missing props instead of a pager.\n *\n * Status changes reach the server through `onFiltersChange` — not a\n * dedicated callback here — because `statusFilter` state is tracked by\n * the same filter machinery that already calls `onFiltersChange`\n * regardless of controlled mode (see {@link statusFilter}). In\n * server-controlled mode a status change also calls `onPageChange(1)`\n * directly, since the previous page number is meaningless against a new\n * filtered result set.\n */\n onPageChange?: (page: number) => void;\n /** Called when the user picks a different page size in the header's view settings. */\n onPerPageChange?: (perPage: number) => void;\n /** Called when the user changes the sort, with `null` when the sort is cleared. */\n onSortChange?: (sort: SortParam | null) => void;\n /** Called when the user changes the search text (including clearing it). */\n onSearchChange?: (search: string) => void;\n\n // ── Fetch state for server-data mode ──\n //\n // In client-side mode ResourcePage owns the fetch, so it knows on its own\n // when the list is in flight or has failed and renders the shell's spinner\n // or error panel accordingly. In server-data mode the caller owns the\n // fetch, and ResourcePage sees only the `data` array that comes out the\n // far end — which means a request that is still in flight and a request\n // that failed both arrive as `data={[]}`, indistinguishable from a\n // genuinely empty result. Left alone that renders a failed fetch as an\n // ordinary \"no records\" table: the page shows nothing and says nothing is\n // wrong, which is the worst of the three outcomes. These props let the\n // caller say which of the three it is. They are read only outside\n // client-side mode, so a `resource`-driven page behaves exactly as before\n // whether or not they are supplied.\n\n /**\n * Server-data mode: the caller's fetch is in flight, so render the shell's\n * loading skeleton instead of the (as yet meaningless) `data`. Ignored in\n * client-side mode, where `useResource`'s own loading state is used.\n */\n loading?: boolean;\n /**\n * Server-data mode: the caller's fetch failed, so render the shell's error\n * panel instead of an empty table. Takes effect even when `data` is\n * non-empty — stale rows beside no indication of failure are exactly the\n * silent-failure this prop exists to prevent. Ignored in client-side mode,\n * where `useResource`'s own error state is used.\n */\n error?: boolean;\n /**\n * Message shown in the error panel, in place of the shell's generic\n * \"Failed to load …\". Forwarded in both modes — it is inert unless an\n * error state is actually showing — so a client-side page can also give\n * its failure a human sentence.\n */\n errorMessage?: string;\n /**\n * Server-data mode: invoked by the error panel's Retry button. The button\n * only appears when this is supplied, so a caller with no way to retry\n * simply omits it and gets an error panel without a dead control. In\n * client-side mode the button is already wired to `useResource`'s own\n * `refetch` and this prop is ignored.\n */\n onRetry?: () => void;\n\n // ── Saved views — passed straight through to DataFilters ──\n /** Saved filter views to offer. Pair with `useSavedViews` for per-user storage. */\n savedViews?: SavedViewItem[];\n onLoadView?: (filters: Record<string, unknown>) => void;\n onSaveView?: (name: string) => void;\n onDeleteView?: (id: string) => void;\n /** Show the \"save current view\" affordance. */\n canSaveViews?: boolean;\n\n /**\n * What the data source can do. A control it can't serve is hidden rather\n * than left to error (DATA-STUDIO.md decision 9): `search: false` hides the\n * search box, `sort: false` the sort select. Pass a provider's\n * `capabilities()` straight in. Omitted, both show, as before.\n */\n capabilities?: { search?: boolean; sort?: boolean };\n\n // ── Table chrome — passed straight through to DataTable ──\n /** Show the column-visibility dropdown. DataTable's default is `true`. */\n columnVisibility?: boolean;\n /** Persist key for the user's column-visibility picks. */\n columnVisibilityKey?: string;\n /** Allow drag-resizing columns. DataTable's default is `true`. */\n resizableColumns?: boolean;\n /** Persist key for the user's column widths. */\n resizeKey?: string;\n /** Keep the table header visible while scrolling. DataTable's default is `true`. */\n stickyHeader?: boolean;\n /** Keep the first column visible while scrolling horizontally. */\n stickyFirstColumn?: boolean;\n /**\n * Page-size choices offered by `DataTable`'s own pager. Client-side mode\n * only — server-controlled mode switches that pager off. (The header's\n * view-settings popover has its own fixed 10/25/50/100 list.)\n */\n pageSizeOptions?: number[];\n\n // CRUD — presence enables the action\n onCreate?: () => void;\n onEdit?: (item: T) => void;\n onDelete?: (item: T) => void;\n createLabel?: string;\n /**\n * Extra header actions beyond the create button, in one overflow menu.\n * See {@link PageHeaderAction} — the budget is one primary, the rest here.\n */\n secondaryActions?: PageHeaderAction[];\n\n // Built-in form support (Phase 2)\n /** Enable built-in create form (ignored if onCreate callback is provided). */\n allowCreate?: boolean;\n /** Enable built-in edit form (ignored if onEdit callback is provided). */\n allowEdit?: boolean;\n /** Field definitions for the built-in form. */\n formFields?: ResourceFormFieldDef[];\n /** Custom form renderer — receives form instance and resolved fields. */\n renderForm?: (\n form: UseFormReturn<Record<string, unknown>>,\n fields: ResourceFormFieldDef[],\n ) => ReactNode;\n\n /** Form presentation mode. Default \"standard\". */\n formMode?: \"standard\" | \"wizard\";\n /** Wizard step definitions. Required when formMode is \"wizard\". */\n formSteps?: WizardStep[];\n /** Layout mode for the built-in form container. If not set, defaults to sheet for edit, dialog for create. */\n formLayout?: \"dialog\" | \"sheet\" | \"page\";\n\n // Bulk actions\n bulkActions?: Array<{\n label: string;\n icon?: LucideIcon;\n variant?: \"default\" | \"destructive\";\n onAction: (ids: string[]) => void | Promise<void>;\n /**\n * Forwarded straight to the rendered bulk button (see `BulkAction`).\n * Exists so a consumer can kill every bulk action while one of them is\n * in flight — an early return inside `onAction` blocks the second call\n * but leaves the button looking live, which misstates what it will do.\n */\n disabled?: boolean;\n /** `data-testid` on the rendered bulk button, so e2e can drive it. */\n testId?: string;\n }>;\n\n // Grid/list rendering + keyboard nav\n /**\n * Override the default card renderer used for grid view (and, absent a\n * dedicated list layout, list view too — DataGrid falls back to the same\n * renderer there). ResourcePage still owns data-fetching, filtering,\n * sorting, and layout (grid columns, infinite-scroll batching, stagger\n * animation) — this only swaps what's rendered inside each item slot.\n *\n * Receives `ResourceCardActions`: the row's `update`/`remove`/`refetch`\n * plus `open()` to activate the row (opening the configured detail\n * panel/modal/route). Row activation is *not* applied automatically to a\n * custom card — wrapping it would double-fire against cards that bring\n * their own click handling and would hijack clicks on nested buttons — so\n * call `actions.open()` from wherever your card should activate.\n */\n renderCard?: (\n item: T,\n index: number,\n actions: ResourceCardActions<T>,\n ) => ReactNode;\n /**\n * Replace the built-in `DataTable` that table view renders, keeping every\n * other piece of the page — header, counts, view settings, filters,\n * bulk bar, detail panel, form, pager — exactly as it is. The counterpart\n * to `renderCard`, which does the same for grid and list view.\n *\n * Receives the rows for the current view, which in server-controlled mode\n * is precisely the page the server returned. Ownership is total: row\n * click-through, selection, density, column visibility and resizing are\n * all things the built-in table wires for you and a custom table must\n * wire for itself. That is the trade this prop makes, and it is why\n * `renderCard` remains the lighter option when only the *cells* need to\n * change — a `ResourceColumnDef.render` is lighter still.\n *\n * Omitted, the default `DataTable` render is used unchanged.\n */\n renderTable?: (items: T[]) => ReactNode;\n /**\n * Tailwind grid-column classes for the card grid, passed through to\n * `DataGrid`'s `gridCols` — e.g. `\"grid-cols-1 sm:grid-cols-2 lg:grid-cols-3\"`.\n * Defaults to DataGrid's own responsive 1/2/3/4-column ramp.\n */\n gridCols?: string;\n /**\n * Built-in list keyboard navigation via `useKeyboardNavigation`: j/k (or\n * Arrow Up/Down) move a focus cursor, Enter opens the focused item,\n * Backspace (⌫) closes an open detail view, and x toggles the focused\n * item's selection when `bulkActions` are configured. Set to `false` to\n * opt out.\n *\n * Default-on, and scoped so that being on by default stays safe:\n * - Only while the grid or list view is showing. Table view keeps its own\n * independent sort/pagination, so a flat focus index can't reliably map\n * onto its visible rows.\n * - Cursor keys suspend while a detail panel/modal or the built-in form\n * is open, so they can't drive the list behind the overlay; ⌫ stays\n * live there so it can close it.\n * - Backspace is only intercepted while there's an open detail to close.\n * - Modified chords (Ctrl/Cmd/Alt) are never captured, so an app's\n * Cmd+K-style shortcuts keep working.\n */\n keyboardNavigation?: boolean;\n\n // Slots\n toolbar?: ReactNode;\n emptyState?: ReactNode;\n\n /**\n * Imperative navigation used only when `detail=\"route\"` (navigates to\n * `/{resource}/{id}` on row click). Defaults to a full-page navigation.\n * Router consumers pass their navigate fn — e.g. RR `useNavigate()` or\n * Next `router.push`.\n */\n onNavigate?: NavigateFn;\n\n // Data options (client-side mode only)\n resourceOptions?: UseResourceOptions<T>;\n defaultView?: ViewMode;\n /**\n * Persist key for density / page size via `useViewSettings`.\n * Defaults to `resource` or a slug of `title`.\n */\n viewSettingsKey?: string;\n\n /**\n * The interior parts `ResourcePage` composes, by name. Replace one with your\n * own component, or pass `null` to eject it entirely — see\n * {@link ResourcePageSlots}.\n *\n * This is the reason a surface that needs one part to differ does not have\n * to drop to the primitives and re-derive the pagination, selection and\n * detail wiring that were already correct.\n */\n slots?: ResourcePageSlots<T>;\n /** Extra props merged into a part you are KEEPING. Wins over ours. */\n slotProps?: SlotPropsFor<ResourcePageSlotMap<T>>;\n /** Merged onto the page shell's root. */\n className?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function ResourcePage<\n T extends Record<string, unknown> = Record<string, unknown>,\n>(props: ResourcePageProps<T>) {\n const {\n resource: resourceName,\n data: dataProp,\n total: totalProp,\n title,\n subtitle,\n icon,\n columns: columnsProp,\n getKey: getKeyProp,\n detail = \"panel\",\n detailWidth = \"md\",\n titleField: titleFieldProp,\n subtitleField: subtitleFieldProp,\n renderDetail: renderDetailProp,\n detailFields,\n statusFilter,\n searchFields,\n searchPlaceholder,\n initialFilters,\n onFiltersChange,\n filters: filtersProp,\n page: pageProp,\n perPage: perPageProp,\n onPageChange,\n onPerPageChange,\n onSortChange,\n onSearchChange,\n loading: loadingProp,\n error: errorProp,\n errorMessage,\n onRetry: onRetryProp,\n savedViews,\n onLoadView,\n onSaveView,\n onDeleteView,\n canSaveViews,\n columnVisibility,\n columnVisibilityKey,\n resizableColumns,\n resizeKey,\n stickyHeader,\n stickyFirstColumn,\n pageSizeOptions,\n onCreate,\n onEdit,\n onDelete,\n createLabel = \"New\",\n secondaryActions,\n allowCreate,\n allowEdit,\n formFields,\n renderForm: renderFormProp,\n formMode,\n formSteps,\n formLayout: formLayoutProp,\n bulkActions,\n renderCard: renderCardProp,\n renderTable: renderTableProp,\n gridCols: gridColsProp,\n keyboardNavigation = true,\n capabilities,\n toolbar,\n emptyState,\n resourceOptions,\n defaultView = \"table\",\n onNavigate = defaultNavigate,\n viewSettingsKey: viewSettingsKeyProp,\n slots,\n slotProps,\n className,\n } = props;\n\n // ── Determine mode ──\n const isClientMode = !!resourceName;\n\n /**\n * Server-controlled mode is entered by supplying ANY of the controlled\n * props — presence is the switch, so a caller that only pages (no server\n * search) still gets its `data` left alone.\n */\n const isServerControlled =\n pageProp !== undefined ||\n perPageProp !== undefined ||\n onPageChange !== undefined ||\n onPerPageChange !== undefined ||\n onSortChange !== undefined ||\n onSearchChange !== undefined;\n\n const viewSettingsKey =\n viewSettingsKeyProp ??\n resourceName ??\n title.toLowerCase().replace(/\\s+/g, \"-\");\n const { settings, updateSetting } = useViewSettings(viewSettingsKey);\n\n /** Explicit prop beats the per-user stored preference. */\n const effectivePageSize = perPageProp ?? settings.pageSize;\n\n // ── Client-side mode: call useResource (hook is always called for rules-of-hooks) ──\n // Core's useResource constrains its row type to BaseRecord (rows carry an\n // `id`), which is stricter than ResourcePage's public `T extends\n // Record<string, unknown>`. Intersect at the call site so the public\n // ResourcePageProps<T> generic stays unchanged while satisfying the hook.\n const resourceHook = useResource<T & BaseRecord>(\n resourceName ?? \"__noop__\",\n isClientMode ? resourceOptions : { enabled: false },\n );\n\n // ── Resolve display data ──\n const displayData: T[] = isClientMode\n ? (resourceHook.list.data?.data ?? [])\n : (dataProp ?? []);\n const displayTotal: number = isClientMode\n ? (resourceHook.list.data?.total ?? 0)\n : (totalProp ?? 0);\n // Client-side mode reads the hook it owns; server-data mode reads the\n // caller's `loading` / `error` props, defaulting to false so a page that\n // supplies neither renders exactly as it did before they existed.\n const isLoading = isClientMode\n ? resourceHook.list.isLoading\n : (loadingProp ?? false);\n const hasError = isClientMode\n ? resourceHook.list.isError\n : (errorProp ?? false);\n\n // ── Call useResourcePage ──\n const page = useResourcePage<T>({\n resource: resourceName,\n data: displayData,\n total: displayTotal,\n columns: columnsProp,\n statusFilter,\n searchFields,\n initialFilters,\n onFiltersChange,\n defaultView,\n detail,\n titleField: titleFieldProp,\n subtitleField: subtitleFieldProp,\n controlled: isServerControlled,\n });\n\n // ── Build ResourceActions for column render functions ──\n const actions: ResourceActions<T> = useMemo(() => {\n if (isClientMode) {\n return {\n update: resourceHook.update as ResourceActions<T>[\"update\"],\n remove: resourceHook.remove,\n refetch: () => resourceHook.list.refetch(),\n };\n }\n return {\n update: async () => {\n throw new Error(\n \"ResourceActions.update not available in server-data mode\",\n );\n },\n remove: async () => {\n throw new Error(\n \"ResourceActions.remove not available in server-data mode\",\n );\n },\n refetch: () => {\n /* no-op in server-data mode */\n },\n };\n }, [\n isClientMode,\n resourceHook.update,\n resourceHook.remove,\n resourceHook.list,\n ]);\n\n // ── Row identity ──\n const keyOf = useCallback(\n (item: T): string =>\n getKeyProp ? getKeyProp(item) : String((item as Record<string, unknown>).id ?? \"\"),\n [getKeyProp],\n );\n\n // ── Bulk selection ──\n const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());\n\n const handleToggleSelect = useCallback((id: string) => {\n setSelectedIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n }, []);\n\n const handleToggleAll = useCallback(() => {\n setSelectedIds((prev) => {\n if (prev.size === page.data.length) return new Set();\n return new Set(page.data.map(keyOf));\n });\n }, [page.data, keyOf]);\n\n const handleClearSelection = useCallback(() => {\n setSelectedIds(new Set());\n }, []);\n\n // ── Built-in form state ──\n const [formOpen, setFormOpen] = useState(false);\n const [formAction, setFormAction] = useState<\"create\" | \"edit\">(\"create\");\n const [formItem, setFormItem] = useState<T | null>(null);\n\n // Determine if built-in form should handle create/edit\n const useBuiltInCreate = allowCreate && !onCreate && isClientMode;\n const useBuiltInEdit = allowEdit && !onEdit && isClientMode;\n\n const handleCreate = useCallback(() => {\n if (useBuiltInCreate) {\n setFormAction(\"create\");\n setFormItem(null);\n setFormOpen(true);\n } else if (onCreate) {\n onCreate();\n }\n }, [useBuiltInCreate, onCreate]);\n\n const handleEdit = useCallback(\n (item: T) => {\n if (useBuiltInEdit) {\n setFormAction(\"edit\");\n setFormItem(item);\n setFormOpen(true);\n } else if (onEdit) {\n onEdit(item);\n }\n },\n [useBuiltInEdit, onEdit],\n );\n\n // ── Patch tableColumns to use real actions (client-side mode) ──\n const tableColumns = useMemo(() => {\n const base = isClientMode\n ? page.columns.map((col) => ({\n key: col.key,\n header: col.header ?? col.key,\n sortable: col.sortable ?? true,\n hideBelow: col.hideBelow,\n editable: col.editable,\n accessor: col.accessor,\n render: col.render\n ? (item: T, value: unknown) => col.render!(item, value, actions)\n : undefined,\n }))\n : page.tableColumns;\n if (!isServerControlled) return base;\n // The server owns the ordering. DataTable's header sort is client-side\n // and would only reorder the rows of the current page — a visibly wrong\n // answer presented as a sort — so the affordance is withdrawn rather\n // than left to lie. The DataFilters sort control drives `onSortChange`.\n return base.map((col) => ({ ...col, sortable: false }));\n }, [\n isClientMode,\n isServerControlled,\n page.columns,\n page.tableColumns,\n actions,\n ]);\n\n // ── Server-driven pager state, needed above for handleSearchChange's\n // already-on-page-1 check. ──\n const currentPage = pageProp ?? 1;\n\n // ── Filter changes: keep the controlled UI state, and tell the server ──\n // In client-side mode these are exactly the hook's own setters; in\n // server-controlled mode they additionally notify the caller and reset to\n // page 1, since the previous page number is meaningless against a new\n // query. The reset is skipped when already on page 1 — nothing changed,\n // so there is nothing for the caller to do.\n const handleSearchChange = useCallback(\n (value: string) => {\n page.filterConfig.onSearchChange(value);\n if (!isServerControlled) return;\n onSearchChange?.(value);\n if (currentPage !== 1) onPageChange?.(1);\n },\n [\n page.filterConfig,\n isServerControlled,\n onSearchChange,\n onPageChange,\n currentPage,\n ],\n );\n\n const handleSortSelect = useCallback(\n (value: string) => {\n page.filterConfig.onSortChange(value);\n if (!isServerControlled) return;\n const [field, order] = value.split(\":\");\n onSortChange?.(\n field && (order === \"asc\" || order === \"desc\")\n ? { field, order }\n : null,\n );\n onPageChange?.(1);\n },\n [page.filterConfig, isServerControlled, onSortChange, onPageChange],\n );\n\n const handleClearFilters = useCallback(() => {\n page.clearFilters();\n if (!isServerControlled) return;\n // Clearing has to reach the server too — otherwise \"Clear all\" empties\n // the controls and leaves the same rows on screen.\n onSearchChange?.(\"\");\n onSortChange?.(null);\n onPageChange?.(1);\n }, [page, isServerControlled, onSearchChange, onSortChange, onPageChange]);\n\n // ── Status-chip changes: same page-1 reset as search/sort ──\n // In server-controlled mode `useResourcePage` skips client-side status\n // filtering, so a status change only reaches the caller through\n // `onFiltersChange`. Nothing else calls `onPageChange(1)` for it, so\n // selecting a more restrictive status while on page 3 could otherwise\n // fetch page 3 of the new result set and render an empty page while the\n // matching rows sit on page 1. Guarded the same way as\n // `handleSearchChange`, and not reachable from `handleClearFilters`\n // (which already does its own single reset).\n const handleStatusChange = useCallback(\n (values: string[]) => {\n page.filterConfig.statusChips?.onChange(values);\n if (!isServerControlled) return;\n if (currentPage !== 1) onPageChange?.(1);\n },\n [page.filterConfig, isServerControlled, onPageChange, currentPage],\n );\n\n const statusChipsConfig = useMemo(() => {\n const base = page.filterConfig.statusChips;\n if (!base) return undefined;\n return { ...base, onChange: handleStatusChange };\n }, [page.filterConfig.statusChips, handleStatusChange]);\n\n const handlePageSizeChange = useCallback(\n (size: number) => {\n updateSetting(\"pageSize\", size);\n onPerPageChange?.(size);\n if (isServerControlled) onPageChange?.(1);\n },\n [updateSetting, onPerPageChange, isServerControlled, onPageChange],\n );\n\n // ── Pagination-config error ──\n // `perPage` AND `total` are both required whenever `onPageChange` is\n // supplied. Neither can be derived from the other, and neither can be\n // derived from the rows:\n // - `perPage`: see the prop doc on `perPage`. A short final page has\n // fewer rows than the page size, so the row count of a page cannot\n // stand in for the page size.\n // - `total`: `displayTotal` falls back to `0` (Line 453). With `total`\n // omitted the range span reads \"No records\" and `Next` stays\n // disabled, while `page.data` renders rows directly below it. A\n // surface that says \"no records\" above visible records is a lie, not\n // a degraded view.\n // Rather than silently guess either one, the pager below refuses to\n // render and shows the error instead. Logged once per mount (not on\n // every render) so it's visible in a console without spamming it.\n const missingPerPage =\n isServerControlled && !!onPageChange && perPageProp === undefined;\n const missingTotal =\n isServerControlled && !!onPageChange && totalProp === undefined;\n const pagerMisconfigured = missingPerPage || missingTotal;\n const missingPagerProps = [\n ...(missingPerPage ? [\"perPage\"] : []),\n ...(missingTotal ? [\"total\"] : []),\n ];\n const loggedMissingPerPageRef = useRef(false);\n useEffect(() => {\n if (!pagerMisconfigured) return;\n if (loggedMissingPerPageRef.current) return;\n loggedMissingPerPageRef.current = true;\n console.error(\n `ResourcePage: ${missingPagerProps\n .map((name) => `\\`${name}\\``)\n .join(\" and \")} ${\n missingPagerProps.length > 1 ? \"are\" : \"is\"\n } required when \\`onPageChange\\` is supplied.`,\n );\n // `missingPagerProps` is derived from `pagerMisconfigured`'s own inputs\n // and the ref makes this run at most once, so it is not a dependency.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [pagerMisconfigured]);\n\n // ── Server-driven pager math ──\n // By the time the pager renders, `pagerMisconfigured` has already gated\n // it off, so `perPageProp` and `totalProp` are both present here.\n const pagerPageSize = perPageProp ?? effectivePageSize;\n const totalPages = Math.max(\n 1,\n Math.ceil(displayTotal / Math.max(1, pagerPageSize)),\n );\n const rangeFrom =\n page.data.length === 0 ? 0 : (currentPage - 1) * pagerPageSize + 1;\n const rangeTo = rangeFrom === 0 ? 0 : rangeFrom + page.data.length - 1;\n\n // ── Detail title/subtitle values ──\n const detailTitle = page.selectedItem\n ? String(\n (page.selectedItem as Record<string, unknown>)[page.titleField] ?? \"\",\n )\n : \"\";\n const detailSubtitle =\n page.selectedItem && page.subtitleField\n ? String(\n (page.selectedItem as Record<string, unknown>)[page.subtitleField] ??\n \"\",\n )\n : undefined;\n\n // ── Row click handler (route mode navigates) ──\n const handleRowClick = (item: T) => {\n if (detail === \"route\") {\n // Navigate to /{resource}/{id}\n const id = (item as Record<string, unknown>).id;\n if (resourceName && id) {\n onNavigate(`/${resourceName}/${id}`);\n }\n return;\n }\n page.handleRowClick(item);\n };\n\n // ── Keyboard navigation (j/k, Enter, Backspace, x) ──\n // Only engaged for grid/list views: table view runs its own independent\n // client-side sort + pagination (DataTable), so a flat index into\n // `page.data` can't reliably be mapped back onto its currently-visible,\n // possibly differently-ordered rows.\n const hasBulkSelect = !!bulkActions && bulkActions.length > 0;\n // A detail panel/modal or the built-in form is covering the list. Cursor\n // keys suspend (they'd otherwise drive the list behind the overlay, and\n // Enter would re-open the row instead of activating the focused control);\n // ⌫ stays live so it can dismiss the overlay.\n const overlayOpen = page.detailOpen || formOpen;\n const keyboardNav = useKeyboardNavigation({\n itemCount: page.data.length,\n enabled: keyboardNavigation && page.viewMode !== \"table\",\n overlayOpen,\n onOpen: (index) => {\n const item = page.data[index];\n if (item) handleRowClick(item);\n },\n onToggleSelect: hasBulkSelect\n ? (index) => {\n const item = page.data[index];\n if (item) {\n handleToggleSelect(keyOf(item));\n }\n }\n : undefined,\n // Supplied only while there is an open detail to close — the hook\n // suppresses Backspace's default whenever this is present, so leaving it\n // wired up permanently would swallow the browser/app's Backspace on\n // every grid/list page (including detail=\"none\" and detail=\"route\",\n // which never open one). `detailOpen` is only ever true for the panel\n // and modal modes, so it is the precise precondition here.\n onBack: page.detailOpen\n ? () => {\n page.setDetailOpen(false);\n page.setSelectedItem(null);\n }\n : undefined,\n });\n\n // ── Create button ──\n const showCreateButton = onCreate || useBuiltInCreate;\n const createButton = showCreateButton ? (\n <Button size=\"sm\" onClick={handleCreate}>\n <Plus className=\"h-4 w-4 mr-1\" />\n {createLabel}\n </Button>\n ) : null;\n\n const createAction =\n toolbar || createButton ? (\n <div className=\"flex items-center gap-2\">\n {toolbar}\n {createButton}\n </div>\n ) : undefined;\n\n // ── Empty state ──\n const isEmpty = !isLoading && !hasError && page.data.length === 0;\n\n /**\n * Row-bound actions for a custom `renderCard`. The shared `actions` object\n * is memoized once for the whole resource, so the per-row `open()` is bound\n * here instead. Without it a custom card has no way to open the detail\n * panel/modal/route by pointer — the built-in cards get that from their own\n * onClick, which a custom card replaces.\n */\n const cardActionsFor = (item: T): ResourceCardActions<T> => ({\n ...actions,\n open: () => handleRowClick(item),\n });\n\n /**\n * Props that turn a plain `div`/`Card` into a real activatable row: a tab\n * stop, a button role, and Enter/Space activation to match the pointer\n * click. Without these the default card is reachable by mouse and by the\n * j/k cursor but not by Tab, which is the one path a keyboard-only user\n * actually has.\n *\n * Enter does not double-fire against the list cursor: `useKeyboardNavigation`\n * bails out whenever the event target owns its own keys, and `role=\"button\"`\n * is one of the roles it checks (covered by a test in\n * `resource-page-render-card-keyboard-nav.test.tsx`).\n */\n const rowActivationProps = (item: T, label: string, testId: string) => ({\n role: \"button\",\n tabIndex: 0,\n \"aria-label\": label || undefined,\n \"data-testid\": testId,\n onClick: () => handleRowClick(item),\n onKeyDown: (e: ReactKeyboardEvent<HTMLElement>) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleRowClick(item);\n }\n },\n });\n\n /** Default card renderer (grid view) — used unless `renderCard` is given. */\n const renderDefaultCard = (item: T): ReactNode => {\n const cols = page.columns;\n const titleCol = cols[0];\n const titleVal = titleCol\n ? String((item as Record<string, unknown>)[titleCol.key] ?? \"\")\n : \"\";\n // Second column is typically the status badge\n const badgeCol = cols[1];\n const badgeVal = badgeCol\n ? (item as Record<string, unknown>)[badgeCol.key]\n : null;\n // Find a numeric-looking column for the price position\n const priceCol = cols.find(\n (c, i) => i > 1 && /price|cost|amount|total/i.test(c.key),\n );\n const priceVal = priceCol\n ? (item as Record<string, unknown>)[priceCol.key]\n : null;\n // Remaining metadata columns (skip title, badge, price)\n const metaCols = cols.filter(\n (c) => c !== titleCol && c !== badgeCol && c !== priceCol,\n );\n return (\n <Card\n {...rowActivationProps(item, titleVal, \"resource-card\")}\n className=\"h-full cursor-pointer hover:shadow-md motion-safe:transition-shadow focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n >\n <CardHeader className=\"pb-2\">\n <CardTitle className=\"text-base truncate\">{titleVal}</CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n {badgeCol && (\n <span>\n {badgeCol.render\n ? badgeCol.render(item, badgeVal, actions)\n : badgeVal != null\n ? String(badgeVal)\n : \"—\"}\n </span>\n )}\n {priceVal != null && (\n <span className=\"text-sm font-semibold\">\n {String(priceVal)}\n </span>\n )}\n </div>\n {metaCols.map((col) => {\n const val = (item as Record<string, unknown>)[col.key];\n return (\n <p\n key={col.key}\n className=\"text-xs text-muted-foreground truncate\"\n >\n {col.render\n ? col.render(item, val, actions)\n : val != null\n ? String(val)\n : \"—\"}\n </p>\n );\n })}\n </div>\n </CardContent>\n </Card>\n );\n };\n\n /** Default list-row renderer (list view) — used unless `renderCard` is given. */\n const renderDefaultListItem = (item: T): ReactNode => {\n const cols = page.columns;\n const titleCol = cols[0];\n const titleVal = titleCol\n ? String((item as Record<string, unknown>)[titleCol.key] ?? \"\")\n : \"\";\n return (\n <div\n {...rowActivationProps(item, titleVal, \"resource-list-row\")}\n className=\"flex items-center justify-between px-3 py-2 border-b cursor-pointer hover:bg-muted/50 motion-safe:transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring\"\n >\n <span className=\"font-medium text-sm truncate\">{titleVal}</span>\n <div className=\"flex items-center gap-3 text-xs text-muted-foreground\">\n {cols.slice(1, 4).map((col) => {\n const val = (item as Record<string, unknown>)[col.key];\n return (\n <span key={col.key}>\n {col.render\n ? col.render(item, val, actions)\n : val != null\n ? String(val)\n : \"—\"}\n </span>\n );\n })}\n </div>\n </div>\n );\n };\n\n // The root slot. Unlike the interior parts it cannot be ejected — a page\n // with no shell is not a page — so it resolves to a component, never null.\n // `slotProps.shell` merges last and wins, except `className`, which is\n // merged rather than replaced so a consumer adding a class does not\n // silently drop the shell's own layout.\n const Shell = slots?.shell ?? DataPageShell;\n const shellSlotProps = slotProps?.shell;\n\n return (\n <Shell\n title={title}\n subtitle={subtitle}\n icon={icon}\n count={page.data.length}\n totalCount={displayTotal}\n isLoading={isLoading}\n hasError={hasError}\n isEmpty={isEmpty}\n errorMessage={errorMessage}\n onRetry={isClientMode ? () => resourceHook.list.refetch() : onRetryProp}\n viewMode={page.viewMode}\n onViewModeChange={page.setViewMode}\n pageSize={effectivePageSize}\n onPageSizeChange={handlePageSizeChange}\n density={settings.density}\n onDensityChange={(d) => updateSetting(\"density\", d)}\n createAction={createAction}\n secondaryActions={secondaryActions}\n hasActiveFilters={page.hasActiveFilters}\n onClearFilters={handleClearFilters}\n emptyAction={emptyState}\n filters={renderSlot(\n DataFilters,\n slots?.filters,\n {\n search: page.filterConfig.search,\n onSearchChange: handleSearchChange,\n searchPlaceholder,\n sort: page.filterConfig.sort,\n onSortChange: handleSortSelect,\n sortOptions: page.filterConfig.sortOptions,\n filters: filtersProp,\n statusChips: statusChipsConfig,\n savedViews,\n onLoadView,\n onSaveView,\n onDeleteView,\n canSaveViews,\n onClearAll: page.hasActiveFilters ? handleClearFilters : undefined,\n showSearch: capabilities?.search !== false,\n showSort: capabilities?.sort !== false,\n },\n slotProps?.filters,\n )}\n {...shellSlotProps}\n className={cn(className, shellSlotProps?.className)}\n >\n {bulkActions &&\n bulkActions.length > 0 &&\n renderSlot(\n DataBulkBar,\n slots?.bulkBar,\n {\n selected: selectedIds,\n totalCount: page.data.length,\n onToggleAll: handleToggleAll,\n onClearSelection: handleClearSelection,\n actions: bulkActions.map((a) => ({\n label: a.label,\n icon: a.icon ?? Trash2,\n variant: a.variant,\n disabled: a.disabled,\n testId: a.testId,\n onClick: () => {\n void a.onAction(Array.from(selectedIds));\n },\n })),\n },\n slotProps?.bulkBar,\n )}\n\n {renderSlot(\n DataGrid<T>,\n slots?.grid,\n {\n items: page.data,\n viewMode: page.viewMode,\n gridCols: gridColsProp,\n getKey: keyOf,\n focusedIndex: keyboardNav.focusedIndex,\n keyboardContainerRef: keyboardNav.containerRef,\n renderTable: (items: T[]) =>\n renderTableProp ? (\n renderTableProp(items)\n ) : (\n renderSlot(\n DataTable<T>,\n slots?.table,\n {\n items,\n columns: tableColumns,\n getKey: keyOf,\n onRowClick: detail !== \"none\" ? handleRowClick : undefined,\n selectable: !!bulkActions && bulkActions.length > 0,\n selected: selectedIds,\n onToggleSelect: handleToggleSelect,\n onToggleAll: handleToggleAll,\n density: settings.density,\n pageSize: effectivePageSize,\n pageSizeOptions,\n columnVisibility,\n columnVisibilityKey,\n resizableColumns,\n resizeKey,\n stickyHeader,\n stickyFirstColumn,\n // The server already cut the page window; DataTable's own\n // pagination would slice the slice.\n pagination: isServerControlled ? false : undefined,\n },\n slotProps?.table,\n )\n )\n ,\n renderCard: (item: T, index: number) =>\n renderCardProp\n ? renderCardProp(item, index, cardActionsFor(item))\n : renderDefaultCard(item),\n renderListItem: (item: T, index: number) =>\n renderCardProp\n ? renderCardProp(item, index, cardActionsFor(item))\n : renderDefaultListItem(item),\n },\n slotProps?.grid,\n )}\n\n {/* Server-driven pager. Rendered only when `onPageChange` is supplied —\n without a handler the buttons would be decoration, and a control\n that does nothing is worse than no control. It sits outside\n DataGrid so it pages the grid and list views too, not just the\n table.\n\n When `onPageChange` is supplied without `perPage`, this renders an\n error instead of a pager computed from a guess — see the\n `pagerMisconfigured` comment above. A pager reporting the wrong range\n with a Next button that never disables is worse than one that\n says why it can't render. */}\n {isServerControlled && onPageChange && pagerMisconfigured && (\n <div\n className=\"flex items-center gap-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive\"\n data-testid=\"resource-page-pagination-error\"\n role=\"alert\"\n >\n <AlertTriangle className=\"h-4 w-4 shrink-0\" aria-hidden=\"true\" />\n <span>\n Pagination unavailable:{\" \"}\n {missingPagerProps.map((name, index) => (\n <Fragment key={name}>\n {index > 0 ? \" and \" : null}\n <code>{name}</code>\n </Fragment>\n ))}{\" \"}\n {missingPagerProps.length > 1 ? \"are\" : \"is\"} required when{\" \"}\n <code>onPageChange</code> is supplied.\n </span>\n </div>\n )}\n {isServerControlled && onPageChange && !pagerMisconfigured && (\n <nav\n aria-label=\"Pagination\"\n className=\"flex flex-col sm:flex-row items-center justify-between gap-2 px-3 py-2 text-sm\"\n data-testid=\"resource-page-pagination\"\n >\n <span\n className=\"text-muted-foreground\"\n data-testid=\"resource-page-range\"\n aria-live=\"polite\"\n >\n {displayTotal === 0\n ? \"No records\"\n : `Showing ${rangeFrom}-${rangeTo} of ${displayTotal}`}\n </span>\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={currentPage <= 1}\n onClick={() => onPageChange(currentPage - 1)}\n testID=\"resource-page-prev\"\n >\n <ChevronLeft className=\"h-4 w-4 mr-1\" aria-hidden=\"true\" />\n Previous\n </Button>\n <span\n className=\"text-muted-foreground\"\n data-testid=\"resource-page-indicator\"\n >\n Page {currentPage} of {totalPages}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={currentPage >= totalPages}\n onClick={() => onPageChange(currentPage + 1)}\n testID=\"resource-page-next\"\n >\n Next\n <ChevronRight className=\"h-4 w-4 ml-1\" aria-hidden=\"true\" />\n </Button>\n </div>\n </nav>\n )}\n\n {/* Detail panel / modal — DetailPanel's `layout` prop picks the shell;\n \"panel\" gets its default fixed slide-in sheet, \"modal\" gets a\n centered dialog. Both share one implementation (header, content,\n edit/delete affordances) instead of ResourcePage hand-rolling a\n second Dialog. */}\n {(detail === \"panel\" || detail === \"modal\") && (\n renderSlot(\n DetailPanel<T>,\n slots?.detail,\n {\n item: page.selectedItem,\n open: page.detailOpen,\n onClose: () => {\n page.setDetailOpen(false);\n page.setSelectedItem(null);\n },\n title: detailTitle,\n subtitle: detailSubtitle,\n onEdit: onEdit ?? (useBuiltInEdit ? handleEdit : undefined),\n onDelete,\n fields: detailFields,\n width: detailWidth,\n layout: detail === \"modal\" ? \"dialog\" : \"sheet\",\n children: renderDetailProp\n ? (item: T) => renderDetailProp(item)\n : undefined,\n },\n slotProps?.detail,\n )\n )}\n {/* Built-in create/edit form */}\n {(useBuiltInCreate || useBuiltInEdit) && resourceName && (\n renderSlot(\n ResourceForm,\n slots?.form,\n {\n resource: resourceName,\n action: formAction,\n layout:\n formLayoutProp ?? (formAction === \"edit\" ? \"sheet\" : \"dialog\"),\n mode: formMode,\n steps: formSteps,\n item:\n formAction === \"edit\"\n ? ((formItem as Record<string, unknown> | null) ?? undefined)\n : page.data.length > 0\n ? Object.fromEntries(\n Object.keys(page.data[0] as Record<string, unknown>)\n .filter((k) => k !== \"id\")\n .map((k) => [k, \"\"]),\n )\n : undefined,\n open: formOpen,\n onOpenChange: setFormOpen,\n fields: formFields,\n listData: page.data as Record<string, unknown>[],\n renderForm: renderFormProp,\n onSuccess: () => {\n // Data auto-refreshes via TanStack Query invalidation in useResourceForm\n page.setDetailOpen(false);\n page.setSelectedItem(null);\n },\n },\n slotProps?.form,\n )\n )}\n </Shell>\n );\n}\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { AlertTriangle } from \"lucide-react\";\nimport { useOne } from \"@marktiderman/genesis-core/hooks\";\nimport type { BaseRecord, Identifier } from \"@marktiderman/genesis-core/provider\";\nimport { DetailPage } from \"../layout/detail-page\";\nimport { EmptyState } from \"../patterns/empty-state\";\nimport { PageLoading } from \"../patterns/page-loading\";\n\nexport interface ResourceDetailPageProps<T extends BaseRecord = BaseRecord> {\n /** Resource name, resolved through the mounted `DataProvider`. */\n resource: string;\n /**\n * Record id. Nullish means \"not resolved yet\" — no request goes out and the\n * page shows its loading state, which is what a route param that hasn't\n * arrived should look like. It is deliberately NOT the not-found state:\n * nothing has been asked, so nothing is missing.\n */\n id: Identifier | undefined | null;\n /**\n * Field used as the page title. Defaults to `name`, then `title`, then the\n * id — the same fallback chain `ResourcePage` uses for a row's label.\n */\n titleField?: string;\n /** Field used as the line under the title. */\n subtitleField?: string;\n /** Provider select/join syntax, e.g. `\"*, owner:profiles(name)\"`. */\n select?: string;\n /** Slot above the title: a `Breadcrumb`, a back link, a `StatusBadge`. */\n breadcrumb?: ReactNode;\n /** Record-scoped controls, built from the loaded record. */\n actions?: (record: T) => ReactNode;\n /** Metadata column, built from the loaded record. */\n sidebar?: (record: T) => ReactNode;\n /** The primary content region. */\n children: (record: T) => ReactNode;\n className?: string;\n /** Stable test/automation selector (emitted as `data-testid`). */\n testID?: string;\n}\n\n/** `name` -> `title` -> id. Mirrors `ResourcePage`'s row-label fallback. */\nfunction pick(record: BaseRecord, field: string | undefined): string {\n const value = field ? record[field] : record.name ?? record.title ?? record.id;\n return value == null ? \"\" : String(value);\n}\n\n/**\n * Does this error mean \"no such row\" rather than \"the request failed\"?\n *\n * Every provider Genesis ships reports a missing record by THROWING, not by\n * resolving with empty data, so without this the not-found state would be\n * dead code and a deleted record would show a generic failure carrying a raw\n * database string. Verified against each provider's `getOne` rather than\n * assumed:\n *\n * - `packages/core/src/provider/supabase-provider.ts` — `.single()`, whose\n * PostgREST error for zero rows is code `PGRST116`; `throwIfError` copies\n * `code` onto the thrown Error.\n * - `packages/core/src/provider/mock-provider.ts` — throws\n * `[MockProvider] Record not found: <resource>#<id>`.\n * - `packages/data-switchboard/src/data-provider.ts` — throws\n * `switchboard-data-provider: no \"<resource>\" row with id \"<id>\".`\n *\n * Deliberately narrow: anything it does not recognise falls through to the\n * error state, which is the safe direction. A custom provider that instead\n * resolves with no data is also handled — see the `!data` branch below.\n */\n/** The absent-record state, reached from two directions — see below. */\nfunction NotFound() {\n return (\n <EmptyState\n title=\"Not found\"\n description=\"This record no longer exists, or you don't have access to it.\"\n />\n );\n}\n\nfunction isNotFoundError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n if ((error as { code?: unknown }).code === \"PGRST116\") return true;\n return (\n /\\[MockProvider\\] Record not found/i.test(error.message) ||\n /switchboard-data-provider: no \".*\" row with id/i.test(error.message)\n );\n}\n\n/**\n * ResourceDetailPage — `DetailPage` with a record bound to it: fetches one\n * record by id through the mounted `DataProvider` and hands it to the title,\n * the actions, the sidebar and the content.\n *\n * ```tsx\n * <ResourceDetailPage\n * resource=\"people\"\n * id={params.id}\n * subtitleField=\"role\"\n * actions={(person) => <Button testID=\"edit\">Edit {person.name}</Button>}\n * sidebar={(person) => <StatCard label=\"Sessions\" value={person.session_count} />}\n * >\n * {(person) => <Section title=\"Timeline\"><Timeline personId={person.id} /></Section>}\n * </ResourceDetailPage>\n * ```\n *\n * This is the detail-route counterpart to `ResourcePage`, which is the list\n * one. Both are **data-bound**, not layouts: they need a resource contract\n * to be useful, which is the layers table's admission test for this tier.\n * The structure they render is a layout and lives one layer down —\n * `DetailPage` in `@marktiderman/genesis-ui/layout` — so an app with its own\n * fetching keeps the page shape without inheriting the provider. That\n * layout/data-bound pairing is the same one `AppShell` and `ResourcePage`\n * already have.\n *\n * The three non-record states are rendered here rather than left to the\n * caller, because a per-app \"loading…\" is exactly the hand-written code a\n * template exists to remove:\n * - loading, or no id yet -> `PageLoading`\n * - absent -> `EmptyState` saying so, distinct from the error state, since a\n * deleted record and a broken query need different words. Every provider\n * Genesis ships signals \"no such row\" by throwing rather than by resolving\n * empty, so this state is reached by classifying the error (see\n * `isNotFoundError`) as well as by a falsy `data`\n * - any other failure -> `EmptyState` carrying the provider's message, which\n * is kept verbatim: an error state that hides what went wrong is the one\n * nobody can act on\n *\n * `titleField` is exact: name a field and you get that field, empty string\n * included. The `name` -> `title` -> id chain is the DEFAULT, not a fallback\n * layered under an explicit choice — a page silently titled by a different\n * column than the one asked for is worse than a blank one.\n *\n * @stability Beta\n */\nexport function ResourceDetailPage<T extends BaseRecord = BaseRecord>({\n resource,\n id,\n titleField,\n subtitleField,\n select,\n breadcrumb,\n actions,\n sidebar,\n children,\n className,\n testID,\n}: ResourceDetailPageProps<T>) {\n const { data, isLoading, isError, error } = useOne<T>(resource, id, {\n select,\n // `useOne` defaults to `enabled: !!id`, which is wrong for a numeric\n // primary key: id `0` is falsy, so the query would never run and the page\n // would report a record that exists as missing, without ever asking the\n // provider. `Identifier` is `string | number`, so this is reachable.\n // Presence is the question, not truthiness.\n enabled: id != null,\n });\n\n // A disabled query reports neither loading nor error nor data, so the\n // \"no id yet\" case has to be named explicitly or it falls through to\n // not-found — nothing was asked, so nothing is missing.\n if (id == null || isLoading) {\n return <PageLoading testID={testID ? `${testID}-loading` : undefined} />;\n }\n\n // Order matters: `isError` implies `data` is undefined, so testing `!data`\n // first would swallow every failure into the not-found state.\n if (isError) {\n if (isNotFoundError(error)) return <NotFound />;\n return (\n <EmptyState\n icon={AlertTriangle}\n title=\"Couldn't load this record\"\n description={error instanceof Error ? error.message : undefined}\n />\n );\n }\n\n // A provider that answers successfully with nothing. None of the three\n // Genesis ships does this, but the `DataProvider` contract permits it and\n // a custom adapter is free to.\n if (!data) return <NotFound />;\n\n return (\n <DetailPage\n className={className}\n testID={testID}\n breadcrumb={breadcrumb}\n title={pick(data, titleField)}\n subtitle={subtitleField ? pick(data, subtitleField) : undefined}\n actions={actions?.(data)}\n sidebar={sidebar?.(data)}\n >\n {children(data)}\n </DetailPage>\n );\n}\n","export { DataPageShell, type DataPageShellProps } from \"./DataPageShell\";\nexport {\n DataFilters,\n type DataFilterConfig,\n type SavedViewItem,\n type StatusChipOption,\n type StatusChipsVariant,\n} from \"./DataFilters\";\nexport { DataGrid } from \"./DataGrid\";\nexport {\n DataTable,\n ThumbnailCell,\n LinkCell,\n type DataTableColumn,\n type DataTableProps,\n} from \"./DataTable\";\nexport { DataBulkBar, type BulkAction } from \"./DataBulkBar\";\nexport { FilterCombobox, type FilterOption } from \"./FilterCombobox\";\nexport { DateCell, NumberCell, CurrencyCell, BadgeCell } from \"./cell-formatters\";\nexport { EmptyState } from \"./EmptyState\";\nexport { ViewToggle, type ViewMode } from \"../patterns/view-toggle\";\nexport { ViewSettings } from \"../patterns/view-settings\";\nexport { StatCard, type StatCardProps, type StatCardColor } from \"./StatCard\";\nexport { KanbanBoard, type KanbanColumn, type KanbanBoardProps, type ColumnStatus } from \"./KanbanBoard\";\nexport { DataList, type DataListProps } from \"./DataList\";\nexport { DetailPanel, type DetailPanelProps } from \"./DetailPanel\";\nexport {\n ResourcePage,\n type ResourcePageProps,\n type ResourceCardActions,\n} from \"./ResourcePage\";\nexport {\n ResourceDetailPage,\n type ResourceDetailPageProps,\n} from \"./ResourceDetailPage\";\nexport { ResourceForm, type ResourceFormProps } from \"./ResourceForm\";\nexport { type ResourceFormFieldDef, type FieldType, type SelectOption } from \"./ResourceFormField\";\nexport { RelationField } from \"./RelationField\";\nexport { FileUploadField } from \"./FileUploadField\";\nexport { FieldArrayRenderer } from \"./FieldArrayRenderer\";\nexport { WizardForm } from \"./WizardForm\";\nexport type { ResourceColumnDef, ResourceActions } from \"../../hooks/use-resource-page\";\n// `AppShell` and `PageHeader` are layouts, not data-bound components — neither\n// takes a `DataProvider`. They stay re-exported here for one deprecation window\n// per docs/FRAMEWORK.md rule 5, and leave `/data` in the next major.\n//\n// These are LOCAL RE-BINDINGS rather than `export { X } from \"../layout/X\"`,\n// and that is load-bearing, not style. TypeScript does not attach a JSDoc\n// `@deprecated` on an `export ... from` statement to the symbol a consumer\n// imports: hovering the import shows no tag and no migration note, so the\n// deprecation is invisible exactly where it needs to be read. Only a local\n// binding carries the tag through to the emitted `.d.ts` and to the consumer's\n// editor. Verified against the TypeScript language service — the regression\n// test in `src/components/data/__tests__/deprecated-aliases.test.ts` asserts it\n// on the real build output, so this cannot silently rot back.\nimport {\n AppShell as AppShellImpl,\n type AppShellProps,\n type AppShellOptions,\n type NavItem,\n} from \"../layout/AppShell\";\nimport {\n PageHeader as PageHeaderImpl,\n type PageHeaderProps,\n type PageHeaderOptions,\n} from \"../layout/PageHeader\";\n\n/**\n * @deprecated Import `AppShell` from `@marktiderman/genesis-ui/layout` instead.\n * `AppShell` is a layout, not a data-bound component. This `/data` alias is\n * removed in the next major — see docs/FRAMEWORK.md rule 5.\n * @stability Deprecated\n */\nexport const AppShell = AppShellImpl;\n/**\n * @deprecated Import `PageHeader` from `@marktiderman/genesis-ui/layout`\n * instead. `PageHeader` is a layout, not a data-bound component. This `/data`\n * alias is removed in the next major — see docs/FRAMEWORK.md rule 5.\n * @stability Deprecated\n */\nexport const PageHeader = PageHeaderImpl;\nexport type { AppShellProps, AppShellOptions, NavItem };\nexport type { PageHeaderProps, PageHeaderOptions };\n\n// Router-agnostic navigation primitives (re-exported for `/data` consumers)\nexport {\n DefaultLink,\n isPathActive,\n resolveNavigation,\n defaultNavigate,\n type GenesisLinkProps,\n type IsPathActiveOptions,\n type NavigationNode,\n type ResolvedNavigation,\n type LinkComponent,\n type NavigateFn,\n} from \"../../navigation\";\n\n// Re-export Density for DataTable consumers who import from `/data`\nexport type { Density } from \"../../hooks/use-view-settings\";\nexport {\n CommandPalette,\n useCommandPaletteHotkey,\n type CommandPaletteProps,\n type CommandPaletteItem,\n} from \"../ui/command-palette\";\nexport { useSavedViews, type UseSavedViewsReturn } from \"../../hooks/use-saved-views\";\n"]}