@exxatdesignux/ui 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +701 -6
- package/README.md +138 -0
- package/bin/init.mjs +134 -31
- package/consumer-extras/cursor-rules/exxat-board-cards.mdc +1 -1
- package/consumer-extras/cursor-rules/exxat-centralized-list-dataset.mdc +2 -2
- package/consumer-extras/cursor-rules/exxat-collaboration-access.mdc +1 -1
- package/consumer-extras/cursor-rules/exxat-data-tables.mdc +2 -0
- package/consumer-extras/cursor-rules/exxat-dedicated-search-surfaces.mdc +1 -1
- package/consumer-extras/cursor-rules/exxat-ds-agents.mdc +3 -3
- package/consumer-extras/cursor-rules/exxat-library-hub-header.mdc +28 -0
- package/consumer-extras/cursor-rules/exxat-mono-ids.mdc +1 -1
- package/consumer-extras/cursor-rules/exxat-person-identity-display.mdc +1 -1
- package/consumer-extras/cursor-rules/exxat-primary-nav-secondary-panel.mdc +6 -6
- package/consumer-extras/cursor-rules/exxat-reuse-before-custom.mdc +1 -1
- package/consumer-extras/cursor-skills/exxat-board-cards/SKILL.md +2 -2
- package/consumer-extras/cursor-skills/exxat-centralized-list-dataset/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-collaboration-access/SKILL.md +3 -3
- package/consumer-extras/cursor-skills/exxat-dedicated-search-surfaces/SKILL.md +2 -2
- package/consumer-extras/cursor-skills/exxat-ds-skill/SKILL.md +7 -7
- package/consumer-extras/cursor-skills/exxat-kpi-flat-band/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-list-page-view-shells/SKILL.md +1 -1
- package/consumer-extras/cursor-skills/exxat-mono-ids/SKILL.md +4 -4
- package/consumer-extras/cursor-skills/exxat-primary-nav-secondary-panel/SKILL.md +8 -8
- package/consumer-extras/cursor-skills/exxat-token-economy/SKILL.md +277 -0
- package/consumer-extras/handbook/HANDBOOK.md +2 -0
- package/consumer-extras/handbook/glossary.md +2 -1
- package/consumer-extras/handbook/reference-implementations.md +31 -4
- package/consumer-extras/patterns/collaboration-access-pattern.md +7 -7
- package/consumer-extras/patterns/data-views-pattern.md +18 -16
- package/consumer-extras/patterns/kpi-flat-band-pattern.md +2 -2
- package/dist/components/data-table/index.js +2 -2
- package/dist/components/data-table/index.js.map +1 -1
- package/dist/components/data-table/pagination.js +3 -3
- package/dist/components/data-table/pagination.js.map +1 -1
- package/dist/components/data-table/use-table-state.d.ts +1 -1
- package/dist/components/data-table/use-table-state.js.map +1 -1
- package/dist/components/data-views/data-row-list.js.map +1 -1
- package/dist/components/data-views/finder-panel-view.d.ts +1 -1
- package/dist/components/data-views/finder-panel-view.js.map +1 -1
- package/dist/components/data-views/hub-table.d.ts +9 -3
- package/dist/components/data-views/hub-table.js +262 -40
- package/dist/components/data-views/hub-table.js.map +1 -1
- package/dist/components/data-views/index.js +262 -40
- package/dist/components/data-views/index.js.map +1 -1
- package/dist/components/data-views/list-page-split-hub-tokens.d.ts +2 -2
- package/dist/components/data-views/list-page-split-hub-tokens.js.map +1 -1
- package/dist/components/data-views/list-page-tree-column-header.d.ts +1 -1
- package/dist/components/data-views/list-page-tree-column-header.js.map +1 -1
- package/dist/components/data-views/list-page-tree-panel-shell.js.map +1 -1
- package/dist/components/data-views/os-folder-glyph.d.ts +1 -1
- package/dist/components/data-views/os-folder-glyph.js.map +1 -1
- package/dist/components/ui/avatar.d.ts +1 -1
- package/dist/components/ui/key-metrics.js.map +1 -1
- package/dist/index.js +136 -39
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/src/components/data-table/index.tsx +2 -2
- package/src/components/data-table/pagination.tsx +5 -1
- package/src/components/data-table/use-table-state.ts +1 -1
- package/src/components/data-views/data-row-list.tsx +1 -1
- package/src/components/data-views/finder-panel-view.tsx +2 -2
- package/src/components/data-views/hub-table.tsx +149 -41
- package/src/components/data-views/list-page-split-hub-tokens.ts +2 -2
- package/src/components/data-views/list-page-tree-column-header.tsx +1 -1
- package/src/components/data-views/os-folder-glyph.tsx +1 -1
- package/src/components/ui/key-metrics.tsx +1 -1
- package/template/.claude/skills/exxat-ds-skill/SKILL.md +8 -7
- package/template/.cursor/rules/exxat-accessibility.mdc +1 -1
- package/template/.cursor/rules/exxat-command-menu.mdc +1 -1
- package/template/.cursor/rules/exxat-dashboard-view-charts.mdc +6 -6
- package/template/.cursor/rules/exxat-data-tables.mdc +3 -3
- package/template/.cursor/rules/exxat-kbd-shortcuts.mdc +5 -5
- package/template/.cursor/rules/exxat-mono-ids.mdc +1 -1
- package/template/.cursor/rules/exxat-page-vs-drawer.mdc +1 -1
- package/template/.cursor/rules/exxat-table-properties-drawer.mdc +1 -1
- package/template/AGENTS.md +43 -37
- package/template/app/(app)/columns/page.tsx +11 -0
- package/template/app/(app)/library/all/page.tsx +11 -0
- package/template/app/(app)/library/find/page.tsx +12 -0
- package/template/app/(app)/{question-bank → library}/layout.tsx +16 -16
- package/template/app/(app)/library/list/page.tsx +12 -0
- package/template/app/(app)/{question-bank → library}/new/page.tsx +10 -10
- package/template/app/(app)/library/page.tsx +11 -0
- package/template/app/(app)/tokens-themes/page.tsx +11 -0
- package/template/components/ask-leo-composer.tsx +2 -2
- package/template/components/columns-client.tsx +158 -0
- package/template/components/columns-showcase.tsx +541 -0
- package/template/components/data-views/index.ts +32 -6
- package/template/components/data-views/{question-bank-folder-tree-branch.tsx → library-folder-tree-branch.tsx} +19 -19
- package/template/components/data-views/table-cells.tsx +673 -0
- package/template/components/folder-details-shell.tsx +11 -11
- package/template/components/hub-tree-panel-view.tsx +24 -24
- package/template/components/{question-bank-board-view.tsx → library-board-view.tsx} +44 -44
- package/template/components/{question-bank-client.tsx → library-client.tsx} +82 -82
- package/template/components/{question-bank-dashboard-charts.tsx → library-dashboard-charts.tsx} +14 -14
- package/template/components/{question-bank-favorite-button.tsx → library-favorite-button.tsx} +7 -7
- package/template/components/{question-bank-hub-client.tsx → library-hub-client.tsx} +43 -43
- package/template/components/{question-bank-new-folder-sheet.tsx → library-new-folder-sheet.tsx} +14 -14
- package/template/components/{question-bank-os-folder-view.tsx → library-os-folder-view.tsx} +31 -31
- package/template/components/{question-bank-page-header.tsx → library-page-header.tsx} +6 -6
- package/template/components/library-panel-activator.tsx +8 -0
- package/template/components/{question-bank-secondary-nav.tsx → library-secondary-nav.tsx} +60 -60
- package/template/components/{question-bank-table.tsx → library-table.tsx} +97 -97
- package/template/components/list-hub-status-badge.tsx +2 -2
- package/template/components/{new-question-composer.tsx → new-library-item-form.tsx} +37 -37
- package/template/components/sidebar/app-sidebar.tsx +61 -5
- package/template/components/sidebar/secondary-panel.tsx +109 -56
- package/template/components/sidebar/sidebar-auto-collapse.tsx +2 -2
- package/template/components/sidebar/sidebar-auto-open.tsx +2 -1
- package/template/components/table-properties/types.ts +1 -1
- package/template/components/templates/discovery-hub-template.tsx +1 -1
- package/template/components/templates/new-focus-template.tsx +2 -2
- package/template/components/templates/secondary-panel-hub-template.tsx +1 -1
- package/template/components/tokens-secondary-nav.tsx +192 -0
- package/template/components/tokens-themes-client.tsx +476 -0
- package/template/components/tokens-themes-section.tsx +386 -0
- package/template/docs/HANDBOOK.md +187 -0
- package/template/docs/blueprints/README.md +1 -1
- package/template/docs/blueprints/board-card.md +1 -1
- package/template/docs/blueprints/data-table.md +2 -2
- package/template/docs/blueprints/list-page-template.md +3 -3
- package/template/docs/blueprints/page-header.md +4 -4
- package/template/docs/collaboration-access-pattern.md +7 -7
- package/template/docs/component-selection-guide.md +1 -1
- package/template/docs/data-views-pattern.md +18 -16
- package/template/docs/glossary.md +58 -0
- package/template/docs/kpi-flat-band-pattern.md +3 -3
- package/template/docs/kpi-trend-pattern.md +18 -3
- package/template/docs/large-dataset-strategy.md +155 -0
- package/template/docs/library-hub-header-pattern.md +25 -0
- package/template/docs/migrations/_template.md +1 -1
- package/template/docs/reference-implementations.md +151 -0
- package/template/docs/token-taxonomy.md +1 -1
- package/template/docs/voice-and-tone.md +262 -0
- package/template/eslint.config.mjs +9 -39
- package/template/hooks/use-secondary-panel-hub-nav.ts +10 -10
- package/template/lib/ask-leo-route-context.ts +6 -18
- package/template/lib/coach-mark-registry.ts +0 -16
- package/template/lib/command-menu-config.ts +5 -12
- package/template/lib/command-menu-search-data.ts +8 -39
- package/template/lib/{question-bank-authoring.ts → library-authoring.ts} +89 -88
- package/template/lib/library-dedicated-search.ts +19 -0
- package/template/lib/library-hub-search.ts +90 -0
- package/template/lib/library-nav.ts +477 -0
- package/template/lib/library-recent-searches.ts +22 -0
- package/template/lib/{placements-supported-views.ts → library-supported-views.ts} +2 -2
- package/template/lib/list-status-badges.ts +16 -104
- package/template/lib/mock/dashboard.ts +1 -1
- package/template/lib/mock/{question-bank-folders.ts → library-folders.ts} +30 -30
- package/template/lib/mock/library-header-collaborators.ts +54 -0
- package/template/lib/mock/{question-bank-inspector.ts → library-inspector.ts} +29 -29
- package/template/lib/mock/{question-bank-kpi.ts → library-kpi.ts} +20 -20
- package/template/lib/mock/library.ts +249 -0
- package/template/lib/mock/navigation.tsx +32 -26
- package/template/lib/table-state-lifecycle.ts +1 -1
- package/template/next.config.mjs +7 -4
- package/template/package.json +0 -1
- package/tokens/hooks-index.json +2874 -0
- package/consumer-extras/cursor-rules/exxat-question-bank-hub-header.mdc +0 -28
- package/template/app/(app)/examples/page.tsx +0 -41
- package/template/app/(app)/question-bank/find/page.tsx +0 -12
- package/template/app/(app)/question-bank/library/page.tsx +0 -11
- package/template/app/(app)/question-bank/list/page.tsx +0 -12
- package/template/app/(app)/question-bank/page.tsx +0 -11
- package/template/components/compliance-board-view.tsx +0 -142
- package/template/components/compliance-client.tsx +0 -92
- package/template/components/compliance-page-header.tsx +0 -89
- package/template/components/compliance-table.tsx +0 -468
- package/template/components/data-view-dashboard-charts-compliance.tsx +0 -963
- package/template/components/data-view-dashboard-charts-team.tsx +0 -971
- package/template/components/data-view-dashboard-charts.tsx +0 -1503
- package/template/components/new-placement-back-btn.tsx +0 -28
- package/template/components/new-placement-form.tsx +0 -942
- package/template/components/placement-board-card.tsx +0 -250
- package/template/components/placement-detail.tsx +0 -438
- package/template/components/placements-board-view.tsx +0 -397
- package/template/components/placements-client.tsx +0 -220
- package/template/components/placements-list-view.tsx +0 -124
- package/template/components/placements-page-header.tsx +0 -166
- package/template/components/placements-table-cells.test.tsx +0 -22
- package/template/components/placements-table-cells.tsx +0 -173
- package/template/components/placements-table-columns.tsx +0 -210
- package/template/components/placements-table.tsx +0 -934
- package/template/components/question-bank-panel-activator.tsx +0 -8
- package/template/components/rotations-empty-state.tsx +0 -50
- package/template/components/rotations-panel-activator.tsx +0 -8
- package/template/components/sites-board-view.tsx +0 -67
- package/template/components/sites-client.tsx +0 -154
- package/template/components/sites-table.tsx +0 -249
- package/template/components/team-board-view.tsx +0 -122
- package/template/components/team-client.tsx +0 -100
- package/template/components/team-page-header.tsx +0 -92
- package/template/components/team-table.tsx +0 -553
- package/template/docs/question-bank-hub-header-pattern.md +0 -25
- package/template/lib/compliance-supported-views.ts +0 -10
- package/template/lib/data-view-dashboard-placements-layout.ts +0 -215
- package/template/lib/mock/compliance-kpi.ts +0 -61
- package/template/lib/mock/compliance.ts +0 -146
- package/template/lib/mock/placements-kpi.ts +0 -134
- package/template/lib/mock/placements.ts +0 -176
- package/template/lib/mock/question-bank-header-collaborators.ts +0 -54
- package/template/lib/mock/question-bank.ts +0 -249
- package/template/lib/mock/sites-directory.ts +0 -16
- package/template/lib/mock/sites-kpi.ts +0 -25
- package/template/lib/mock/team-kpi.ts +0 -60
- package/template/lib/mock/team.ts +0 -118
- package/template/lib/placement-board-card-layout.ts +0 -79
- package/template/lib/question-bank-dedicated-search.ts +0 -19
- package/template/lib/question-bank-hub-search.ts +0 -90
- package/template/lib/question-bank-nav.ts +0 -477
- package/template/lib/question-bank-recent-searches.ts +0 -22
- package/template/lib/question-bank-supported-views.ts +0 -12
- package/template/lib/sites-supported-views.ts +0 -10
- package/template/lib/team-supported-views.ts +0 -10
|
@@ -12,7 +12,7 @@ declare function useTableState<TData extends Record<string, unknown>>(data: TDat
|
|
|
12
12
|
},
|
|
13
13
|
/**
|
|
14
14
|
* When defined (including `""`), toolbar search is synced from the URL (`?q=`).
|
|
15
|
-
* Use `searchParams.get("q") ?? ""` on
|
|
15
|
+
* Use `searchParams.get("q") ?? ""` on library list routes; omit for other hubs.
|
|
16
16
|
*/
|
|
17
17
|
syncedSearchFromUrl?: string): {
|
|
18
18
|
sortRules: SortRule[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/date-filter.ts","../../../src/components/data-table/use-table-state.ts"],"names":["hay"],"mappings":"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","file":"use-table-state.js","sourcesContent":["/**\n * Format any date string (ISO, MM/DD/YYYY, \"Mar 15 2026\", etc.) into the\n * app-wide display format: MM/DD/YYYY.\n * Returns \"—\" for empty / unparseable values.\n */\nexport function formatDateUS(raw: string | null | undefined): string {\n if (!raw || raw.trim() === \"—\" || raw.trim() === \"-\") return \"—\"\n // Already MM/DD/YYYY — return as-is\n if (/^\\d{2}\\/\\d{2}\\/\\d{4}$/.test(raw.trim())) return raw.trim()\n const d = new Date(raw)\n if (Number.isNaN(d.getTime())) return raw\n const m = String(d.getMonth() + 1).padStart(2, \"0\")\n const day = String(d.getDate()).padStart(2, \"0\")\n const y = d.getFullYear()\n return `${m}/${day}/${y}`\n}\n\n/** Format a `Date` with local calendar fields as MM/DD/YYYY (avoids UTC drift from `toISOString()`). */\nexport function formatDateFromDate(raw: Date | null | undefined): string {\n if (!raw || Number.isNaN(raw.getTime())) return \"—\"\n const m = String(raw.getMonth() + 1).padStart(2, \"0\")\n const day = String(raw.getDate()).padStart(2, \"0\")\n const y = raw.getFullYear()\n return `${m}/${day}/${y}`\n}\n\n/**\n * Format a Date (or ISO string) into \"MM/DD/YYYY hh:mm AM/PM EST\".\n * Time zone label is always appended as the literal string \"EST\" (display only).\n */\nexport function formatDateTimeUS(raw: Date | string | null | undefined): string {\n if (!raw) return \"—\"\n const d = raw instanceof Date ? raw : new Date(raw)\n if (Number.isNaN(d.getTime())) return String(raw)\n const m = String(d.getMonth() + 1).padStart(2, \"0\")\n const day = String(d.getDate()).padStart(2, \"0\")\n const y = d.getFullYear()\n let h = d.getHours()\n const min = String(d.getMinutes()).padStart(2, \"0\")\n const ampm = h >= 12 ? \"PM\" : \"AM\"\n h = h % 12 || 12\n return `${m}/${day}/${y} ${String(h).padStart(2, \"0\")}:${min} ${ampm} EST`\n}\n\n/** Parse a human-readable date string into YYYY-MM-DD for comparison (local timezone). */\nexport function parseRowDateToYmd(raw: string): string | null {\n const t = raw.trim()\n if (!t || t === \"—\" || t === \"-\") return null\n const d = new Date(t)\n if (Number.isNaN(d.getTime())) return null\n const y = d.getFullYear()\n const m = String(d.getMonth() + 1).padStart(2, \"0\")\n const day = String(d.getDate()).padStart(2, \"0\")\n return `${y}-${m}-${day}`\n}\n\n/** Format YYYY-MM-DD for filter chip labels (MM/DD/YYYY). */\nexport function formatYmdForDisplay(ymd: string): string {\n const d = ymdToLocalDate(ymd)\n if (!d) return ymd\n return formatDateFromDate(d)\n}\n\n/** Local noon to avoid timezone shifting the calendar day. */\nexport function ymdToLocalDate(ymd: string | undefined): Date | undefined {\n if (!ymd || !/^\\d{4}-\\d{2}-\\d{2}$/.test(ymd)) return undefined\n const [y, m, d] = ymd.split(\"-\").map(Number)\n return new Date(y, m - 1, d, 12, 0, 0, 0)\n}\n\nexport function localDateToYmd(d: Date): string {\n const y = d.getFullYear()\n const m = String(d.getMonth() + 1).padStart(2, \"0\")\n const day = String(d.getDate()).padStart(2, \"0\")\n return `${y}-${m}-${day}`\n}\n","\"use client\"\n\n// ─────────────────────────────────────────────────────────────────────────────\n// useTableState — all non-display state shared by DataTable and DataTablePaginated\n// ─────────────────────────────────────────────────────────────────────────────\n\nimport * as React from \"react\"\nimport type { RowHeight } from \"../../lib/row-height\"\nimport type { ColumnDef, SortDir } from \"./types\"\nimport type { ActiveFilter, FilterOperator, SortRule } from \"../../lib/table-properties-types\"\nimport { parseRowDateToYmd } from \"../../lib/date-filter\"\n\nlet _filterId = 0\nfunction nextFilterId() { return `f-${++_filterId}` }\n\n/**\n * “Reflow” / high-zoom short viewport. At 200% zoom a 1080p monitor’s CSS\n * height is ≈ 540px — `500px` was too low and never disabled pins. 640px\n * catches typical 200% cases and small laptop tops without breaking `500px` flows.\n * Column stickies + edge shadows harm reflow (WCAG 1.4.10).\n */\nconst REFLOW_VIEWPORT_MQ = \"(max-height: 640px)\"\n\nfunction subscribeReflowViewport(callback: () => void) {\n if (typeof window === \"undefined\") return () => {}\n const mql = window.matchMedia(REFLOW_VIEWPORT_MQ)\n mql.addEventListener(\"change\", callback)\n return () => mql.removeEventListener(\"change\", callback)\n}\nfunction getReflowViewportSnapshot() {\n if (typeof window === \"undefined\") return false\n return window.matchMedia(REFLOW_VIEWPORT_MQ).matches\n}\nfunction getServerReflowViewportSnapshot() {\n return false\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction digitsOnly(s: string): string {\n return s.replace(/\\D/g, \"\")\n}\n\n/** Build the default widths map from column defs */\nfunction buildDefaultWidths<TData>(columns: ColumnDef<TData>[]): Record<string, number> {\n const map: Record<string, number> = {}\n for (const col of columns) {\n if (col.width !== undefined) map[col.key] = col.width\n }\n return map\n}\n\n/** Build the initial pin state from column defs */\nfunction buildDefaultPins<TData>(columns: ColumnDef<TData>[]): Record<string, \"left\" | \"right\"> {\n const map: Record<string, \"left\" | \"right\"> = {}\n for (const col of columns) {\n if (col.defaultPin) map[col.key] = col.defaultPin\n }\n return map\n}\n\nfunction compareUnknownSort(a: unknown, b: unknown): number {\n if (a === b) return 0\n if (a == null && b == null) return 0\n if (a == null) return 1\n if (b == null) return -1\n if (typeof a === \"number\" && typeof b === \"number\") return a < b ? -1 : a > b ? 1 : 0\n if (typeof a === \"string\" && typeof b === \"string\") return a < b ? -1 : a > b ? 1 : 0\n const as = String(a)\n const bs = String(b)\n return as < bs ? -1 : as > bs ? 1 : 0\n}\n\n/** Build the locked-pin set (columns that can never be unpinned) */\nfunction buildLockedPins<TData>(columns: ColumnDef<TData>[]): Record<string, \"left\" | \"right\"> {\n const map: Record<string, \"left\" | \"right\"> = {}\n for (const col of columns) {\n if (col.lockPin && col.defaultPin) map[col.key] = col.defaultPin\n }\n return map\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Hook\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport function useTableState<TData extends Record<string, unknown>>(\n data: TData[],\n columns: ColumnDef<TData>[],\n defaultSort?: { key: string; dir: SortDir },\n paginationOverride?: { page: number; pageSize: number },\n /**\n * When defined (including `\"\"`), toolbar search is synced from the URL (`?q=`).\n * Use `searchParams.get(\"q\") ?? \"\"` on question bank list routes; omit for other hubs.\n */\n syncedSearchFromUrl?: string,\n) {\n // ── Sort ──────────────────────────────────────────────────────────────────\n const [sortRules, setSortRules] = React.useState<SortRule[]>(() => {\n if (defaultSort) {\n return [{ id: \"sort-default\", fieldKey: defaultSort.key, direction: defaultSort.dir }]\n }\n return []\n })\n\n const primarySort = sortRules[0] ?? null\n const sortKey: string = primarySort?.fieldKey ?? \"\"\n const sortDir: SortDir = primarySort?.direction ?? \"asc\"\n\n const addSortRule = React.useCallback((fieldKey: string) => {\n setSortRules(prev => {\n if (prev.some(r => r.fieldKey === fieldKey)) return prev\n // New drawer sorts are primary (same as column-header sort), not trailing.\n return [{ id: `sort-${Date.now()}`, fieldKey, direction: \"asc\" }, ...prev]\n })\n }, [setSortRules])\n\n const removeSortRule = React.useCallback((id: string) => {\n setSortRules(prev => prev.filter(r => r.id !== id))\n }, [setSortRules])\n\n const toggleSortDir = React.useCallback((id: string) => {\n setSortRules(prev => prev.map(r =>\n r.id === id ? { ...r, direction: r.direction === \"asc\" ? \"desc\" : \"asc\" } : r\n ))\n }, [setSortRules])\n\n const handleSortByKey = React.useCallback((colKey: string) => {\n setSortRules(prev => {\n const idx = prev.findIndex(r => r.fieldKey === colKey)\n if (idx === 0) {\n return prev.map((r, i) => i === 0 ? { ...r, direction: r.direction === \"asc\" ? \"desc\" : \"asc\" } : r)\n }\n const filtered = prev.filter(r => r.fieldKey !== colKey)\n return [{ id: `sort-${Date.now()}`, fieldKey: colKey, direction: \"asc\" }, ...filtered]\n })\n }, [setSortRules])\n\n // ── Filters ───────────────────────────────────────────────────────────────\n const [search, setSearch] = React.useState(() =>\n syncedSearchFromUrl !== undefined ? syncedSearchFromUrl.trim() : \"\",\n )\n const [searchOpen, setSearchOpen] = React.useState(() =>\n syncedSearchFromUrl !== undefined && Boolean(syncedSearchFromUrl.trim()),\n )\n const searchRef = React.useRef<HTMLInputElement>(null)\n const [activeFilters, setActiveFilters] = React.useState<ActiveFilter[]>([])\n const [filterConnectors, setFilterConnectors] = React.useState<Record<string, \"and\" | \"or\">>({})\n const [openFilterId, setOpenFilterId] = React.useState<string | null>(null)\n const [filterBarVisible, setFilterBarVisible] = React.useState(true)\n const [drawerExpandedFilters, setDrawerExpandedFilters] = React.useState<Set<string>>(new Set())\n\n React.useEffect(() => {\n if (syncedSearchFromUrl === undefined) return\n const next = syncedSearchFromUrl.trim()\n setSearch(next)\n setSearchOpen(next.length > 0)\n }, [syncedSearchFromUrl])\n\n const toggleConnector = React.useCallback((leftId: string) => {\n setFilterConnectors(prev => ({ ...prev, [leftId]: prev[leftId] === \"or\" ? \"and\" : \"or\" }))\n }, [setFilterConnectors])\n\n function getConnector(leftId: string): \"and\" | \"or\" {\n return filterConnectors[leftId] ?? \"and\"\n }\n\n const addFilter = React.useCallback((fieldKey: string, fromDrawer = false) => {\n const col = columns.find(c => c.key === fieldKey)\n if (!col?.filter) return\n const id = nextFilterId()\n const f = col.filter\n const firstOperator: FilterOperator = (() => {\n if (f.type === \"select\" || f.type === \"date\") {\n const pick = f.operators?.find(o => o === \"is\" || o === \"is_not\")\n return pick ?? \"is\"\n }\n return f.operators?.[0] ?? \"contains\"\n })()\n const newFilter: ActiveFilter = { id, fieldKey, operator: firstOperator, values: [] }\n setActiveFilters(prev => [...prev, newFilter])\n if (fromDrawer) {\n setDrawerExpandedFilters(() => new Set([id]))\n // Keep toolbar pills hidden until a value is chosen — avoids mounting every\n // FilterPill (heavy) on each drawer \"Add filter\" click.\n } else {\n setOpenFilterId(id)\n setFilterBarVisible(true)\n }\n }, [columns, setActiveFilters, setDrawerExpandedFilters, setOpenFilterId, setFilterBarVisible])\n\n const updateFilter = React.useCallback((id: string, patch: Partial<ActiveFilter>) => {\n let shouldShowFilterBar = false\n setActiveFilters(prev => {\n const next = prev.map(f => {\n if (f.id !== id) return f\n const merged = { ...f, ...patch }\n const col = columns.find(c => c.key === merged.fieldKey)\n if (merged.values.length > 0) {\n shouldShowFilterBar =\n col?.filter?.type === \"text\"\n ? (merged.values[0] ?? \"\").trim().length > 0\n : true\n }\n return merged\n })\n return next\n })\n if (shouldShowFilterBar) setFilterBarVisible(true)\n }, [columns, setActiveFilters, setFilterBarVisible])\n\n const removeFilter = React.useCallback((id: string) => {\n // Use functional updates only — no stale-closure risk on activeFilters.\n setActiveFilters(prev => {\n const idx = prev.findIndex(f => f.id === id)\n const next = prev.filter(f => f.id !== id)\n setFilterConnectors(prevC => {\n const c = { ...prevC }\n if (idx > 0 && next.length > 0) {\n const leftId = prev[idx - 1].id\n c[leftId] = prevC[id] ?? prevC[leftId] ?? \"and\"\n }\n delete c[id]\n return c\n })\n return next\n })\n setOpenFilterId(prev => prev === id ? null : prev)\n }, [setActiveFilters, setFilterConnectors, setOpenFilterId])\n\n // ── Group by ──────────────────────────────────────────────────────────────\n const [groupBy, setGroupBy] = React.useState<string | null>(null)\n\n // ── Per-column quick-search ───────────────────────────────────────────────\n const [colMenuSearch, setColMenuSearch] = React.useState<Record<string, string>>({})\n\n // ── Selection ─────────────────────────────────────────────────────────────\n const [selected, setSelected] = React.useState<Set<string | number>>(new Set())\n\n // ── Column widths ─────────────────────────────────────────────────────────\n const [colWidths, setColWidths] = React.useState<Record<string, number>>(() => buildDefaultWidths(columns))\n const resizeRef = React.useRef<{ key: string; startX: number; startW: number } | null>(null)\n\n // ── Column order ──────────────────────────────────────────────────────────\n const [colOrder, setColOrder] = React.useState<string[]>(() => columns.map(c => c.key))\n\n // ── Column pins ───────────────────────────────────────────────────────────\n const [colPins, setColPins] = React.useState<Record<string, \"left\" | \"right\">>(() => buildDefaultPins(columns))\n const lockedPins = React.useMemo(() => buildLockedPins(columns), [columns])\n\n // ── Column wrap ───────────────────────────────────────────────────────────\n const [colWrap, setColWrap] = React.useState<Record<string, boolean>>({})\n\n // ── Drawer / display settings ─────────────────────────────────────────────\n const [sheetOpen, setSheetOpen] = React.useState(false)\n /**\n * Deep-link target for the Properties drawer. When a callsite wants to open\n * the drawer focused on a specific panel (e.g. \"conditional-rules\" from the\n * column header menu), it sets this before calling `setSheetOpen(true)`. The\n * drawer's `initialPanel` prop reads it and syncs its internal `sheetPanel`\n * accordingly. The toolbar Properties button clears it so it opens to \"main\".\n */\n const [sheetInitialPanel, setSheetInitialPanel] = React.useState<string | null>(null)\n const [showGridlines, setShowGridlines] = React.useState(true)\n const [rowHeight, setRowHeight] = React.useState<RowHeight>(\"default\")\n const [hiddenCols, setHiddenCols] = React.useState<Set<string>>(new Set())\n\n const toggleColVisibility = React.useCallback((key: string) => {\n setHiddenCols(prev => {\n const next = new Set(prev)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [setHiddenCols])\n\n const moveCol = React.useCallback((key: string, dir: \"up\" | \"down\") => {\n setColOrder(prev => {\n const lockedLeft = columns.filter(c => c.lockPin && c.defaultPin === \"left\").map(c => c.key)\n const lockedRight = columns.filter(c => c.lockPin && c.defaultPin === \"right\").map(c => c.key)\n const orderable = prev.filter(k => !lockedLeft.includes(k) && !lockedRight.includes(k))\n const idx = orderable.indexOf(key)\n if (dir === \"up\" && idx <= 0) return prev\n if (dir === \"down\" && idx >= orderable.length - 1) return prev\n const next = [...orderable]\n const swap = dir === \"up\" ? idx - 1 : idx + 1\n ;[next[idx], next[swap]] = [next[swap], next[idx]]\n return [...lockedLeft, ...next, ...lockedRight]\n })\n }, [columns, setColOrder])\n\n // ── Drag-to-reorder ───────────────────────────────────────────────────────\n const draggedKey = React.useRef<string | null>(null)\n const [dragOverKey, setDragOverKey] = React.useState<string | null>(null)\n\n // ── Scroll / overflow ─────────────────────────────────────────────────────\n const scrollRef = React.useRef<HTMLDivElement>(null)\n const [scrolled, setScrolled] = React.useState(false)\n const [scrollEnd, setScrollEnd] = React.useState(false)\n const [isOverflowing, setIsOverflowing] = React.useState(false)\n\n const isReflowViewport = React.useSyncExternalStore(\n subscribeReflowViewport,\n getReflowViewportSnapshot,\n getServerReflowViewportSnapshot,\n )\n\n // ── Hovered row ───────────────────────────────────────────────────────────\n const [hoveredRow, setHoveredRow] = React.useState<string | number | null>(null)\n\n // ── Column lookup index (stable per `columns` reference) ─────────────────\n // The previous implementation called `columns.find(c => c.key === ...)` inside\n // every filter/sort comparator and every sticky-offset getter — for large\n // datasets that's O(rows × cols) per render. Map lookups make those O(1).\n const columnsByKey = React.useMemo(() => {\n const map = new Map<string, ColumnDef<TData>>()\n for (const col of columns) map.set(col.key, col)\n return map\n }, [columns])\n\n // Searchable text cache. Per row, concatenate every value into one\n // lower-cased blob ONCE and reuse it across keystrokes. Keyed by row\n // identity via WeakMap so it never holds onto rows the consumer dropped.\n const searchableTextCache = React.useRef<WeakMap<object, string>>(new WeakMap())\n const getSearchableText = React.useCallback((row: TData): string => {\n const cache = searchableTextCache.current\n const cached = cache.get(row)\n if (cached !== undefined) return cached\n let blob = \"\"\n for (const v of Object.values(row)) {\n if (v == null) continue\n blob += String(v).toLowerCase() + \"\\n\"\n }\n cache.set(row, blob)\n return blob\n }, [])\n\n // Per-row per-column lower-cased value cache (column quick-search +\n // text-mask filters). One `Map` per row, lazily filled on first lookup.\n const lowerValueCache = React.useRef<WeakMap<object, Map<string, string>>>(new WeakMap())\n const getLowerValue = React.useCallback((row: TData, key: string): string => {\n const wm = lowerValueCache.current\n let perRow = wm.get(row)\n if (!perRow) {\n perRow = new Map()\n wm.set(row, perRow)\n }\n const cached = perRow.get(key)\n if (cached !== undefined) return cached\n const computed = String(row[key] ?? \"\").toLowerCase()\n perRow.set(key, computed)\n return computed\n }, [])\n\n // Reset the row-keyed caches whenever the dataset reference changes so we\n // don't pin stale strings for rows the consumer just replaced.\n React.useEffect(() => {\n searchableTextCache.current = new WeakMap()\n lowerValueCache.current = new WeakMap()\n }, [data])\n\n // ── Derived: filtered + sorted rows ──────────────────────────────────────\n const rows = React.useMemo(() => {\n let result = data.slice()\n\n const q = search.trim().toLowerCase()\n if (q) {\n result = result.filter(r => getSearchableText(r).includes(q))\n }\n\n const activeWithValues = activeFilters.filter(f => {\n if (f.values.length === 0) return false\n const col = columnsByKey.get(f.fieldKey)\n if (col?.filter?.type === \"text\") {\n return (f.values[0] ?? \"\").trim().length > 0\n }\n return true\n })\n if (activeWithValues.length > 0) {\n // Pre-resolve column, operator, normalised needle, and select-value Set\n // for each active filter ONCE (instead of per row).\n type CompiledFilter = {\n col: ColumnDef<TData>\n id: string\n type: \"select\" | \"date\" | \"text\"\n operator: ActiveFilter[\"operator\"]\n selectValues?: Set<string>\n dateTarget?: string\n textNeedle?: string\n digitsNeedle?: string\n isDigitsMask?: boolean\n }\n const compiled: CompiledFilter[] = []\n for (const f of activeWithValues) {\n const col = columnsByKey.get(f.fieldKey)\n if (!col?.filter) continue\n if (col.filter.type === \"select\") {\n compiled.push({\n col,\n id: f.id,\n type: \"select\",\n operator: f.operator,\n selectValues: new Set(f.values),\n })\n } else if (col.filter.type === \"date\") {\n compiled.push({\n col,\n id: f.id,\n type: \"date\",\n operator: f.operator,\n dateTarget: f.values[0],\n })\n } else {\n const raw = f.values[0] ?? \"\"\n const isDigitsMask = col.filter.textMask === \"phone\" || col.filter.textMask === \"zip\"\n compiled.push({\n col,\n id: f.id,\n type: \"text\",\n operator: f.operator,\n isDigitsMask,\n digitsNeedle: isDigitsMask ? digitsOnly(raw) : undefined,\n textNeedle: !isDigitsMask ? raw.toLowerCase() : undefined,\n })\n }\n }\n\n const matchesCompiled = (r: TData, f: CompiledFilter): boolean => {\n const rowVal = String(r[f.col.key] ?? \"\")\n if (f.type === \"select\") {\n const hit = f.selectValues!.has(rowVal)\n return f.operator === \"is\" ? hit : !hit\n }\n if (f.type === \"date\") {\n if (!f.dateTarget) return true\n const rowYmd = parseRowDateToYmd(rowVal)\n const op = f.operator === \"is_not\" ? \"is_not\" : \"is\"\n if (rowYmd === null) return op === \"is_not\"\n return op === \"is\" ? rowYmd === f.dateTarget : rowYmd !== f.dateTarget\n }\n if (f.isDigitsMask) {\n if (!f.digitsNeedle) return true\n const hay = digitsOnly(rowVal)\n return f.operator === \"contains\" ? hay.includes(f.digitsNeedle) : !hay.includes(f.digitsNeedle)\n }\n if (!f.textNeedle) return true\n const hay = getLowerValue(r, f.col.key)\n return f.operator === \"contains\" ? hay.includes(f.textNeedle) : !hay.includes(f.textNeedle)\n }\n\n if (compiled.length > 0) {\n result = result.filter(r => {\n let res = matchesCompiled(r, compiled[0])\n for (let i = 1; i < compiled.length; i++) {\n const connector = filterConnectors[compiled[i - 1].id] ?? \"and\"\n const match = matchesCompiled(r, compiled[i])\n res = connector === \"and\" ? res && match : res || match\n }\n return res\n })\n }\n }\n\n // Column menu quick-search — pre-normalise needles outside the row loop.\n const colMenuEntries: { key: string; lower: string }[] = []\n for (const [key, raw] of Object.entries(colMenuSearch)) {\n const trimmed = raw.trim()\n if (trimmed) colMenuEntries.push({ key, lower: trimmed.toLowerCase() })\n }\n if (colMenuEntries.length > 0) {\n result = result.filter(r => {\n for (const { key, lower } of colMenuEntries) {\n if (!getLowerValue(r, key).includes(lower)) return false\n }\n return true\n })\n }\n\n // Sort — resolve each rule's sort key ONCE, then run the comparator over\n // an indexed list so the inner loop is a tight array walk, not a chain of\n // `columns.find` lookups per comparison.\n if (sortRules.length > 0) {\n const resolved: { sk: string; dir: SortDir }[] = []\n for (const rule of sortRules) {\n const col = columnsByKey.get(rule.fieldKey)\n const sk = col?.sortKey ?? col?.key\n if (sk) resolved.push({ sk: sk as string, dir: rule.direction })\n }\n if (resolved.length > 0) {\n result.sort((a, b) => {\n for (let i = 0; i < resolved.length; i++) {\n const { sk, dir } = resolved[i]\n const cmp = compareUnknownSort(a[sk], b[sk])\n if (cmp !== 0) return dir === \"asc\" ? cmp : -cmp\n }\n return 0\n })\n }\n }\n\n return result\n }, [\n data,\n search,\n activeFilters,\n filterConnectors,\n colMenuSearch,\n sortRules,\n columnsByKey,\n getSearchableText,\n getLowerValue,\n ])\n\n // ── Paged rows (slice of rows when pagination is active) ─────────────────\n const pagedRows = React.useMemo(() => {\n if (!paginationOverride || paginationOverride.pageSize <= 0) return rows\n const { page, pageSize } = paginationOverride\n const safePage = Math.max(1, page)\n return rows.slice((safePage - 1) * pageSize, safePage * pageSize)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [rows, paginationOverride?.page, paginationOverride?.pageSize])\n\n // ── Grouped rows ──────────────────────────────────────────────────────────\n const groupedRows = React.useMemo(() => {\n if (!groupBy) return [{ groupKey: null as string | null, groupLabel: null as string | null, rows }]\n const groups = new Map<string, TData[]>()\n rows.forEach(row => {\n const val = String(row[groupBy] ?? \"—\")\n if (!groups.has(val)) groups.set(val, [])\n groups.get(val)!.push(row)\n })\n return [...groups.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, groupRows]) => ({ groupKey: key, groupLabel: key, rows: groupRows }))\n }, [rows, groupBy])\n\n // ── Effective pins (respect overflow) ─────────────────────────────────────\n const LOCKED_KEYS = React.useMemo(() => new Set(Object.keys(lockedPins)), [lockedPins])\n\n // When the table fits within its container (not overflowing) there is no need\n // to sticky-pin any column — even locked ones. Pins only activate once the\n // user has to scroll horizontally so the selection / action edges stay visible.\n // In reflow viewports (high zoom), disable all column stickies — shadow + sticky\n // fight the short viewport and overlap content.\n const effectivePins = React.useMemo(() => {\n if (isReflowViewport || !isOverflowing) return {}\n const result: Record<string, \"left\" | \"right\"> = {}\n for (const [key, pin] of Object.entries(colPins)) {\n result[key] = pin\n }\n return result\n }, [colPins, isOverflowing, isReflowViewport])\n\n // ── Display columns ───────────────────────────────────────────────────────\n const displayCols = React.useMemo(() => {\n const leftPinned: string[] = []\n const free: string[] = []\n const rightPinned: string[] = []\n for (const k of colOrder) {\n const pin = colPins[k]\n if (pin === \"left\") leftPinned.push(k)\n else if (pin === \"right\") rightPinned.push(k)\n else free.push(k)\n }\n const ordered = [...leftPinned, ...free, ...rightPinned]\n const out: ColumnDef<TData>[] = []\n for (const k of ordered) {\n if (hiddenCols.has(k)) continue\n const col = columnsByKey.get(k)\n if (col) out.push(col)\n }\n return out\n }, [colOrder, colPins, hiddenCols, columnsByKey])\n\n // ── Column actions ────────────────────────────────────────────────────────\n function startResize(key: string, e: React.MouseEvent) {\n e.preventDefault()\n e.stopPropagation()\n const minW = columns.find(c => c.key === key)?.minWidth ?? 60\n const startW = colWidths[key] ?? (columns.find(c => c.key === key)?.width ?? 100)\n resizeRef.current = { key, startX: e.clientX, startW }\n const onMove = (ev: MouseEvent) => {\n if (!resizeRef.current) return\n const { key: k, startX, startW: sw } = resizeRef.current\n setColWidths(p => ({ ...p, [k]: Math.max(minW, sw + ev.clientX - startX) }))\n }\n const onUp = () => {\n resizeRef.current = null\n document.removeEventListener(\"mousemove\", onMove)\n document.removeEventListener(\"mouseup\", onUp)\n }\n document.addEventListener(\"mousemove\", onMove)\n document.addEventListener(\"mouseup\", onUp)\n }\n\n function handleDragStart(key: string, e: React.DragEvent<HTMLTableCellElement>) {\n draggedKey.current = key\n e.dataTransfer.effectAllowed = \"move\"\n }\n function handleDragOver(key: string, e: React.DragEvent<HTMLTableCellElement>) {\n e.preventDefault()\n e.dataTransfer.dropEffect = \"move\"\n if (draggedKey.current && draggedKey.current !== key) setDragOverKey(key)\n }\n function handleDrop(key: string) {\n if (!draggedKey.current || draggedKey.current === key) { setDragOverKey(null); return }\n const order = [...colOrder]\n const from = order.indexOf(draggedKey.current)\n const to = order.indexOf(key)\n order.splice(from, 1)\n order.splice(to, 0, draggedKey.current!)\n setColOrder(order)\n draggedKey.current = null\n setDragOverKey(null)\n }\n function handleDragEnd() { draggedKey.current = null; setDragOverKey(null) }\n\n function pinColumn(key: string, pin: \"left\" | \"right\") {\n setColPins(p => ({ ...p, [key]: pin }))\n }\n function unpinColumn(key: string) {\n if (lockedPins[key]) return\n setColPins(p => { const n = { ...p }; delete n[key]; return n })\n }\n function toggleWrap(key: string) {\n setColWrap(p => ({ ...p, [key]: !p[key] }))\n }\n\n // ── Scroll handlers ───────────────────────────────────────────────────────\n function checkOverflow() {\n const el = scrollRef.current\n if (!el) return\n setIsOverflowing(el.scrollWidth > el.clientWidth + 1)\n }\n function handleScroll() {\n const el = scrollRef.current\n if (!el) return\n setScrolled(el.scrollLeft > 1)\n setScrollEnd(el.scrollLeft >= el.scrollWidth - el.clientWidth - 1)\n setIsOverflowing(el.scrollWidth > el.clientWidth + 1)\n }\n\n // ── Selection helpers ─────────────────────────────────────────────────────\n function getRowId(row: TData, index: number, getIdFn?: (r: TData, i: number) => string | number): string | number {\n return getIdFn ? getIdFn(row, index) : (row.id as string | number ?? index)\n }\n\n const toggleRow = React.useCallback((id: string | number) => {\n setSelected(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 }, [setSelected])\n\n const toggleAll = React.useCallback((allRowIds: (string | number)[]) => {\n setSelected(prev => prev.size === allRowIds.length ? new Set() : new Set(allRowIds))\n }, [setSelected])\n\n // ── Sticky offset calculations ────────────────────────────────────────────\n // Precompute every pinned column's offset ONCE per render so the per-cell\n // `stickyStyle()` call is an O(1) map lookup instead of an O(cols) walk.\n // With `cells = rows × cols`, the previous O(rows × cols²) became the\n // dominant cost on wide tables.\n const stickyOffsets = React.useMemo(() => {\n const left = new Map<string, number>()\n const right = new Map<string, number>()\n let leftOffset = 0\n for (const col of displayCols) {\n if (effectivePins[col.key] !== \"left\") break\n left.set(col.key, leftOffset)\n leftOffset += colWidths[col.key] ?? col.width ?? 100\n }\n let rightOffset = 0\n for (let i = displayCols.length - 1; i >= 0; i--) {\n const col = displayCols[i]\n if (effectivePins[col.key] !== \"right\") break\n right.set(col.key, rightOffset)\n rightOffset += colWidths[col.key] ?? col.width ?? 100\n }\n return { left, right }\n }, [displayCols, effectivePins, colWidths])\n\n const getStickyLeft = React.useCallback((key: string): number => {\n return stickyOffsets.left.get(key) ?? 0\n }, [stickyOffsets])\n\n const getStickyRight = React.useCallback((key: string): number => {\n return stickyOffsets.right.get(key) ?? 0\n }, [stickyOffsets])\n\n const stickyStyle = React.useCallback(\n (key: string, isHeader = false): React.CSSProperties => {\n if (isReflowViewport) return {}\n const pin = effectivePins[key]\n if (pin === \"left\") {\n return isHeader\n ? { position: \"sticky\", left: stickyOffsets.left.get(key) ?? 0, top: 0 }\n : { position: \"sticky\", left: stickyOffsets.left.get(key) ?? 0 }\n }\n if (pin === \"right\") {\n return isHeader\n ? { position: \"sticky\", right: stickyOffsets.right.get(key) ?? 0, top: 0 }\n : { position: \"sticky\", right: stickyOffsets.right.get(key) ?? 0 }\n }\n return isHeader ? { position: \"sticky\", top: 0 } : {}\n },\n [effectivePins, isReflowViewport, stickyOffsets],\n )\n\n const totalWidth = React.useMemo(\n () => displayCols.reduce((s, c) => s + (colWidths[c.key] ?? c.width ?? 100), 0),\n [displayCols, colWidths],\n )\n\n return {\n // Sort\n sortRules, setSortRules,\n sortKey, sortDir,\n addSortRule, removeSortRule, toggleSortDir, handleSortByKey,\n // Filters\n search, setSearch,\n searchOpen, setSearchOpen,\n searchRef,\n activeFilters, setActiveFilters,\n filterConnectors, setFilterConnectors, toggleConnector, getConnector,\n openFilterId, setOpenFilterId,\n filterBarVisible, setFilterBarVisible,\n drawerExpandedFilters, setDrawerExpandedFilters,\n addFilter, updateFilter, removeFilter,\n // Group\n groupBy, setGroupBy,\n // Column quick-search\n colMenuSearch, setColMenuSearch,\n // Selection\n selected, setSelected, toggleRow, toggleAll, getRowId,\n // Column widths / order / pins / wrap\n colWidths, setColWidths, resizeRef, startResize,\n colOrder, setColOrder, moveCol,\n colPins, setColPins, lockedPins, LOCKED_KEYS,\n pinColumn, unpinColumn,\n colWrap, setColWrap, toggleWrap,\n // Drag-to-reorder\n draggedKey, dragOverKey,\n handleDragStart, handleDragOver, handleDrop, handleDragEnd,\n // Scroll\n scrollRef, scrolled, scrollEnd, isOverflowing,\n checkOverflow, handleScroll,\n // Hover\n hoveredRow, setHoveredRow,\n // Derived\n rows, pagedRows, groupedRows,\n effectivePins, displayCols,\n isReflowViewport,\n getStickyLeft, getStickyRight, stickyStyle,\n totalWidth,\n // Display settings\n sheetOpen, setSheetOpen,\n sheetInitialPanel, setSheetInitialPanel,\n showGridlines, setShowGridlines,\n rowHeight, setRowHeight,\n hiddenCols, setHiddenCols, toggleColVisibility,\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/date-filter.ts","../../../src/components/data-table/use-table-state.ts"],"names":["hay"],"mappings":"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","file":"use-table-state.js","sourcesContent":["/**\n * Format any date string (ISO, MM/DD/YYYY, \"Mar 15 2026\", etc.) into the\n * app-wide display format: MM/DD/YYYY.\n * Returns \"—\" for empty / unparseable values.\n */\nexport function formatDateUS(raw: string | null | undefined): string {\n if (!raw || raw.trim() === \"—\" || raw.trim() === \"-\") return \"—\"\n // Already MM/DD/YYYY — return as-is\n if (/^\\d{2}\\/\\d{2}\\/\\d{4}$/.test(raw.trim())) return raw.trim()\n const d = new Date(raw)\n if (Number.isNaN(d.getTime())) return raw\n const m = String(d.getMonth() + 1).padStart(2, \"0\")\n const day = String(d.getDate()).padStart(2, \"0\")\n const y = d.getFullYear()\n return `${m}/${day}/${y}`\n}\n\n/** Format a `Date` with local calendar fields as MM/DD/YYYY (avoids UTC drift from `toISOString()`). */\nexport function formatDateFromDate(raw: Date | null | undefined): string {\n if (!raw || Number.isNaN(raw.getTime())) return \"—\"\n const m = String(raw.getMonth() + 1).padStart(2, \"0\")\n const day = String(raw.getDate()).padStart(2, \"0\")\n const y = raw.getFullYear()\n return `${m}/${day}/${y}`\n}\n\n/**\n * Format a Date (or ISO string) into \"MM/DD/YYYY hh:mm AM/PM EST\".\n * Time zone label is always appended as the literal string \"EST\" (display only).\n */\nexport function formatDateTimeUS(raw: Date | string | null | undefined): string {\n if (!raw) return \"—\"\n const d = raw instanceof Date ? raw : new Date(raw)\n if (Number.isNaN(d.getTime())) return String(raw)\n const m = String(d.getMonth() + 1).padStart(2, \"0\")\n const day = String(d.getDate()).padStart(2, \"0\")\n const y = d.getFullYear()\n let h = d.getHours()\n const min = String(d.getMinutes()).padStart(2, \"0\")\n const ampm = h >= 12 ? \"PM\" : \"AM\"\n h = h % 12 || 12\n return `${m}/${day}/${y} ${String(h).padStart(2, \"0\")}:${min} ${ampm} EST`\n}\n\n/** Parse a human-readable date string into YYYY-MM-DD for comparison (local timezone). */\nexport function parseRowDateToYmd(raw: string): string | null {\n const t = raw.trim()\n if (!t || t === \"—\" || t === \"-\") return null\n const d = new Date(t)\n if (Number.isNaN(d.getTime())) return null\n const y = d.getFullYear()\n const m = String(d.getMonth() + 1).padStart(2, \"0\")\n const day = String(d.getDate()).padStart(2, \"0\")\n return `${y}-${m}-${day}`\n}\n\n/** Format YYYY-MM-DD for filter chip labels (MM/DD/YYYY). */\nexport function formatYmdForDisplay(ymd: string): string {\n const d = ymdToLocalDate(ymd)\n if (!d) return ymd\n return formatDateFromDate(d)\n}\n\n/** Local noon to avoid timezone shifting the calendar day. */\nexport function ymdToLocalDate(ymd: string | undefined): Date | undefined {\n if (!ymd || !/^\\d{4}-\\d{2}-\\d{2}$/.test(ymd)) return undefined\n const [y, m, d] = ymd.split(\"-\").map(Number)\n return new Date(y, m - 1, d, 12, 0, 0, 0)\n}\n\nexport function localDateToYmd(d: Date): string {\n const y = d.getFullYear()\n const m = String(d.getMonth() + 1).padStart(2, \"0\")\n const day = String(d.getDate()).padStart(2, \"0\")\n return `${y}-${m}-${day}`\n}\n","\"use client\"\n\n// ─────────────────────────────────────────────────────────────────────────────\n// useTableState — all non-display state shared by DataTable and DataTablePaginated\n// ─────────────────────────────────────────────────────────────────────────────\n\nimport * as React from \"react\"\nimport type { RowHeight } from \"../../lib/row-height\"\nimport type { ColumnDef, SortDir } from \"./types\"\nimport type { ActiveFilter, FilterOperator, SortRule } from \"../../lib/table-properties-types\"\nimport { parseRowDateToYmd } from \"../../lib/date-filter\"\n\nlet _filterId = 0\nfunction nextFilterId() { return `f-${++_filterId}` }\n\n/**\n * “Reflow” / high-zoom short viewport. At 200% zoom a 1080p monitor’s CSS\n * height is ≈ 540px — `500px` was too low and never disabled pins. 640px\n * catches typical 200% cases and small laptop tops without breaking `500px` flows.\n * Column stickies + edge shadows harm reflow (WCAG 1.4.10).\n */\nconst REFLOW_VIEWPORT_MQ = \"(max-height: 640px)\"\n\nfunction subscribeReflowViewport(callback: () => void) {\n if (typeof window === \"undefined\") return () => {}\n const mql = window.matchMedia(REFLOW_VIEWPORT_MQ)\n mql.addEventListener(\"change\", callback)\n return () => mql.removeEventListener(\"change\", callback)\n}\nfunction getReflowViewportSnapshot() {\n if (typeof window === \"undefined\") return false\n return window.matchMedia(REFLOW_VIEWPORT_MQ).matches\n}\nfunction getServerReflowViewportSnapshot() {\n return false\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction digitsOnly(s: string): string {\n return s.replace(/\\D/g, \"\")\n}\n\n/** Build the default widths map from column defs */\nfunction buildDefaultWidths<TData>(columns: ColumnDef<TData>[]): Record<string, number> {\n const map: Record<string, number> = {}\n for (const col of columns) {\n if (col.width !== undefined) map[col.key] = col.width\n }\n return map\n}\n\n/** Build the initial pin state from column defs */\nfunction buildDefaultPins<TData>(columns: ColumnDef<TData>[]): Record<string, \"left\" | \"right\"> {\n const map: Record<string, \"left\" | \"right\"> = {}\n for (const col of columns) {\n if (col.defaultPin) map[col.key] = col.defaultPin\n }\n return map\n}\n\nfunction compareUnknownSort(a: unknown, b: unknown): number {\n if (a === b) return 0\n if (a == null && b == null) return 0\n if (a == null) return 1\n if (b == null) return -1\n if (typeof a === \"number\" && typeof b === \"number\") return a < b ? -1 : a > b ? 1 : 0\n if (typeof a === \"string\" && typeof b === \"string\") return a < b ? -1 : a > b ? 1 : 0\n const as = String(a)\n const bs = String(b)\n return as < bs ? -1 : as > bs ? 1 : 0\n}\n\n/** Build the locked-pin set (columns that can never be unpinned) */\nfunction buildLockedPins<TData>(columns: ColumnDef<TData>[]): Record<string, \"left\" | \"right\"> {\n const map: Record<string, \"left\" | \"right\"> = {}\n for (const col of columns) {\n if (col.lockPin && col.defaultPin) map[col.key] = col.defaultPin\n }\n return map\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Hook\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport function useTableState<TData extends Record<string, unknown>>(\n data: TData[],\n columns: ColumnDef<TData>[],\n defaultSort?: { key: string; dir: SortDir },\n paginationOverride?: { page: number; pageSize: number },\n /**\n * When defined (including `\"\"`), toolbar search is synced from the URL (`?q=`).\n * Use `searchParams.get(\"q\") ?? \"\"` on library list routes; omit for other hubs.\n */\n syncedSearchFromUrl?: string,\n) {\n // ── Sort ──────────────────────────────────────────────────────────────────\n const [sortRules, setSortRules] = React.useState<SortRule[]>(() => {\n if (defaultSort) {\n return [{ id: \"sort-default\", fieldKey: defaultSort.key, direction: defaultSort.dir }]\n }\n return []\n })\n\n const primarySort = sortRules[0] ?? null\n const sortKey: string = primarySort?.fieldKey ?? \"\"\n const sortDir: SortDir = primarySort?.direction ?? \"asc\"\n\n const addSortRule = React.useCallback((fieldKey: string) => {\n setSortRules(prev => {\n if (prev.some(r => r.fieldKey === fieldKey)) return prev\n // New drawer sorts are primary (same as column-header sort), not trailing.\n return [{ id: `sort-${Date.now()}`, fieldKey, direction: \"asc\" }, ...prev]\n })\n }, [setSortRules])\n\n const removeSortRule = React.useCallback((id: string) => {\n setSortRules(prev => prev.filter(r => r.id !== id))\n }, [setSortRules])\n\n const toggleSortDir = React.useCallback((id: string) => {\n setSortRules(prev => prev.map(r =>\n r.id === id ? { ...r, direction: r.direction === \"asc\" ? \"desc\" : \"asc\" } : r\n ))\n }, [setSortRules])\n\n const handleSortByKey = React.useCallback((colKey: string) => {\n setSortRules(prev => {\n const idx = prev.findIndex(r => r.fieldKey === colKey)\n if (idx === 0) {\n return prev.map((r, i) => i === 0 ? { ...r, direction: r.direction === \"asc\" ? \"desc\" : \"asc\" } : r)\n }\n const filtered = prev.filter(r => r.fieldKey !== colKey)\n return [{ id: `sort-${Date.now()}`, fieldKey: colKey, direction: \"asc\" }, ...filtered]\n })\n }, [setSortRules])\n\n // ── Filters ───────────────────────────────────────────────────────────────\n const [search, setSearch] = React.useState(() =>\n syncedSearchFromUrl !== undefined ? syncedSearchFromUrl.trim() : \"\",\n )\n const [searchOpen, setSearchOpen] = React.useState(() =>\n syncedSearchFromUrl !== undefined && Boolean(syncedSearchFromUrl.trim()),\n )\n const searchRef = React.useRef<HTMLInputElement>(null)\n const [activeFilters, setActiveFilters] = React.useState<ActiveFilter[]>([])\n const [filterConnectors, setFilterConnectors] = React.useState<Record<string, \"and\" | \"or\">>({})\n const [openFilterId, setOpenFilterId] = React.useState<string | null>(null)\n const [filterBarVisible, setFilterBarVisible] = React.useState(true)\n const [drawerExpandedFilters, setDrawerExpandedFilters] = React.useState<Set<string>>(new Set())\n\n React.useEffect(() => {\n if (syncedSearchFromUrl === undefined) return\n const next = syncedSearchFromUrl.trim()\n setSearch(next)\n setSearchOpen(next.length > 0)\n }, [syncedSearchFromUrl])\n\n const toggleConnector = React.useCallback((leftId: string) => {\n setFilterConnectors(prev => ({ ...prev, [leftId]: prev[leftId] === \"or\" ? \"and\" : \"or\" }))\n }, [setFilterConnectors])\n\n function getConnector(leftId: string): \"and\" | \"or\" {\n return filterConnectors[leftId] ?? \"and\"\n }\n\n const addFilter = React.useCallback((fieldKey: string, fromDrawer = false) => {\n const col = columns.find(c => c.key === fieldKey)\n if (!col?.filter) return\n const id = nextFilterId()\n const f = col.filter\n const firstOperator: FilterOperator = (() => {\n if (f.type === \"select\" || f.type === \"date\") {\n const pick = f.operators?.find(o => o === \"is\" || o === \"is_not\")\n return pick ?? \"is\"\n }\n return f.operators?.[0] ?? \"contains\"\n })()\n const newFilter: ActiveFilter = { id, fieldKey, operator: firstOperator, values: [] }\n setActiveFilters(prev => [...prev, newFilter])\n if (fromDrawer) {\n setDrawerExpandedFilters(() => new Set([id]))\n // Keep toolbar pills hidden until a value is chosen — avoids mounting every\n // FilterPill (heavy) on each drawer \"Add filter\" click.\n } else {\n setOpenFilterId(id)\n setFilterBarVisible(true)\n }\n }, [columns, setActiveFilters, setDrawerExpandedFilters, setOpenFilterId, setFilterBarVisible])\n\n const updateFilter = React.useCallback((id: string, patch: Partial<ActiveFilter>) => {\n let shouldShowFilterBar = false\n setActiveFilters(prev => {\n const next = prev.map(f => {\n if (f.id !== id) return f\n const merged = { ...f, ...patch }\n const col = columns.find(c => c.key === merged.fieldKey)\n if (merged.values.length > 0) {\n shouldShowFilterBar =\n col?.filter?.type === \"text\"\n ? (merged.values[0] ?? \"\").trim().length > 0\n : true\n }\n return merged\n })\n return next\n })\n if (shouldShowFilterBar) setFilterBarVisible(true)\n }, [columns, setActiveFilters, setFilterBarVisible])\n\n const removeFilter = React.useCallback((id: string) => {\n // Use functional updates only — no stale-closure risk on activeFilters.\n setActiveFilters(prev => {\n const idx = prev.findIndex(f => f.id === id)\n const next = prev.filter(f => f.id !== id)\n setFilterConnectors(prevC => {\n const c = { ...prevC }\n if (idx > 0 && next.length > 0) {\n const leftId = prev[idx - 1].id\n c[leftId] = prevC[id] ?? prevC[leftId] ?? \"and\"\n }\n delete c[id]\n return c\n })\n return next\n })\n setOpenFilterId(prev => prev === id ? null : prev)\n }, [setActiveFilters, setFilterConnectors, setOpenFilterId])\n\n // ── Group by ──────────────────────────────────────────────────────────────\n const [groupBy, setGroupBy] = React.useState<string | null>(null)\n\n // ── Per-column quick-search ───────────────────────────────────────────────\n const [colMenuSearch, setColMenuSearch] = React.useState<Record<string, string>>({})\n\n // ── Selection ─────────────────────────────────────────────────────────────\n const [selected, setSelected] = React.useState<Set<string | number>>(new Set())\n\n // ── Column widths ─────────────────────────────────────────────────────────\n const [colWidths, setColWidths] = React.useState<Record<string, number>>(() => buildDefaultWidths(columns))\n const resizeRef = React.useRef<{ key: string; startX: number; startW: number } | null>(null)\n\n // ── Column order ──────────────────────────────────────────────────────────\n const [colOrder, setColOrder] = React.useState<string[]>(() => columns.map(c => c.key))\n\n // ── Column pins ───────────────────────────────────────────────────────────\n const [colPins, setColPins] = React.useState<Record<string, \"left\" | \"right\">>(() => buildDefaultPins(columns))\n const lockedPins = React.useMemo(() => buildLockedPins(columns), [columns])\n\n // ── Column wrap ───────────────────────────────────────────────────────────\n const [colWrap, setColWrap] = React.useState<Record<string, boolean>>({})\n\n // ── Drawer / display settings ─────────────────────────────────────────────\n const [sheetOpen, setSheetOpen] = React.useState(false)\n /**\n * Deep-link target for the Properties drawer. When a callsite wants to open\n * the drawer focused on a specific panel (e.g. \"conditional-rules\" from the\n * column header menu), it sets this before calling `setSheetOpen(true)`. The\n * drawer's `initialPanel` prop reads it and syncs its internal `sheetPanel`\n * accordingly. The toolbar Properties button clears it so it opens to \"main\".\n */\n const [sheetInitialPanel, setSheetInitialPanel] = React.useState<string | null>(null)\n const [showGridlines, setShowGridlines] = React.useState(true)\n const [rowHeight, setRowHeight] = React.useState<RowHeight>(\"default\")\n const [hiddenCols, setHiddenCols] = React.useState<Set<string>>(new Set())\n\n const toggleColVisibility = React.useCallback((key: string) => {\n setHiddenCols(prev => {\n const next = new Set(prev)\n if (next.has(key)) next.delete(key)\n else next.add(key)\n return next\n })\n }, [setHiddenCols])\n\n const moveCol = React.useCallback((key: string, dir: \"up\" | \"down\") => {\n setColOrder(prev => {\n const lockedLeft = columns.filter(c => c.lockPin && c.defaultPin === \"left\").map(c => c.key)\n const lockedRight = columns.filter(c => c.lockPin && c.defaultPin === \"right\").map(c => c.key)\n const orderable = prev.filter(k => !lockedLeft.includes(k) && !lockedRight.includes(k))\n const idx = orderable.indexOf(key)\n if (dir === \"up\" && idx <= 0) return prev\n if (dir === \"down\" && idx >= orderable.length - 1) return prev\n const next = [...orderable]\n const swap = dir === \"up\" ? idx - 1 : idx + 1\n ;[next[idx], next[swap]] = [next[swap], next[idx]]\n return [...lockedLeft, ...next, ...lockedRight]\n })\n }, [columns, setColOrder])\n\n // ── Drag-to-reorder ───────────────────────────────────────────────────────\n const draggedKey = React.useRef<string | null>(null)\n const [dragOverKey, setDragOverKey] = React.useState<string | null>(null)\n\n // ── Scroll / overflow ─────────────────────────────────────────────────────\n const scrollRef = React.useRef<HTMLDivElement>(null)\n const [scrolled, setScrolled] = React.useState(false)\n const [scrollEnd, setScrollEnd] = React.useState(false)\n const [isOverflowing, setIsOverflowing] = React.useState(false)\n\n const isReflowViewport = React.useSyncExternalStore(\n subscribeReflowViewport,\n getReflowViewportSnapshot,\n getServerReflowViewportSnapshot,\n )\n\n // ── Hovered row ───────────────────────────────────────────────────────────\n const [hoveredRow, setHoveredRow] = React.useState<string | number | null>(null)\n\n // ── Column lookup index (stable per `columns` reference) ─────────────────\n // The previous implementation called `columns.find(c => c.key === ...)` inside\n // every filter/sort comparator and every sticky-offset getter — for large\n // datasets that's O(rows × cols) per render. Map lookups make those O(1).\n const columnsByKey = React.useMemo(() => {\n const map = new Map<string, ColumnDef<TData>>()\n for (const col of columns) map.set(col.key, col)\n return map\n }, [columns])\n\n // Searchable text cache. Per row, concatenate every value into one\n // lower-cased blob ONCE and reuse it across keystrokes. Keyed by row\n // identity via WeakMap so it never holds onto rows the consumer dropped.\n const searchableTextCache = React.useRef<WeakMap<object, string>>(new WeakMap())\n const getSearchableText = React.useCallback((row: TData): string => {\n const cache = searchableTextCache.current\n const cached = cache.get(row)\n if (cached !== undefined) return cached\n let blob = \"\"\n for (const v of Object.values(row)) {\n if (v == null) continue\n blob += String(v).toLowerCase() + \"\\n\"\n }\n cache.set(row, blob)\n return blob\n }, [])\n\n // Per-row per-column lower-cased value cache (column quick-search +\n // text-mask filters). One `Map` per row, lazily filled on first lookup.\n const lowerValueCache = React.useRef<WeakMap<object, Map<string, string>>>(new WeakMap())\n const getLowerValue = React.useCallback((row: TData, key: string): string => {\n const wm = lowerValueCache.current\n let perRow = wm.get(row)\n if (!perRow) {\n perRow = new Map()\n wm.set(row, perRow)\n }\n const cached = perRow.get(key)\n if (cached !== undefined) return cached\n const computed = String(row[key] ?? \"\").toLowerCase()\n perRow.set(key, computed)\n return computed\n }, [])\n\n // Reset the row-keyed caches whenever the dataset reference changes so we\n // don't pin stale strings for rows the consumer just replaced.\n React.useEffect(() => {\n searchableTextCache.current = new WeakMap()\n lowerValueCache.current = new WeakMap()\n }, [data])\n\n // ── Derived: filtered + sorted rows ──────────────────────────────────────\n const rows = React.useMemo(() => {\n let result = data.slice()\n\n const q = search.trim().toLowerCase()\n if (q) {\n result = result.filter(r => getSearchableText(r).includes(q))\n }\n\n const activeWithValues = activeFilters.filter(f => {\n if (f.values.length === 0) return false\n const col = columnsByKey.get(f.fieldKey)\n if (col?.filter?.type === \"text\") {\n return (f.values[0] ?? \"\").trim().length > 0\n }\n return true\n })\n if (activeWithValues.length > 0) {\n // Pre-resolve column, operator, normalised needle, and select-value Set\n // for each active filter ONCE (instead of per row).\n type CompiledFilter = {\n col: ColumnDef<TData>\n id: string\n type: \"select\" | \"date\" | \"text\"\n operator: ActiveFilter[\"operator\"]\n selectValues?: Set<string>\n dateTarget?: string\n textNeedle?: string\n digitsNeedle?: string\n isDigitsMask?: boolean\n }\n const compiled: CompiledFilter[] = []\n for (const f of activeWithValues) {\n const col = columnsByKey.get(f.fieldKey)\n if (!col?.filter) continue\n if (col.filter.type === \"select\") {\n compiled.push({\n col,\n id: f.id,\n type: \"select\",\n operator: f.operator,\n selectValues: new Set(f.values),\n })\n } else if (col.filter.type === \"date\") {\n compiled.push({\n col,\n id: f.id,\n type: \"date\",\n operator: f.operator,\n dateTarget: f.values[0],\n })\n } else {\n const raw = f.values[0] ?? \"\"\n const isDigitsMask = col.filter.textMask === \"phone\" || col.filter.textMask === \"zip\"\n compiled.push({\n col,\n id: f.id,\n type: \"text\",\n operator: f.operator,\n isDigitsMask,\n digitsNeedle: isDigitsMask ? digitsOnly(raw) : undefined,\n textNeedle: !isDigitsMask ? raw.toLowerCase() : undefined,\n })\n }\n }\n\n const matchesCompiled = (r: TData, f: CompiledFilter): boolean => {\n const rowVal = String(r[f.col.key] ?? \"\")\n if (f.type === \"select\") {\n const hit = f.selectValues!.has(rowVal)\n return f.operator === \"is\" ? hit : !hit\n }\n if (f.type === \"date\") {\n if (!f.dateTarget) return true\n const rowYmd = parseRowDateToYmd(rowVal)\n const op = f.operator === \"is_not\" ? \"is_not\" : \"is\"\n if (rowYmd === null) return op === \"is_not\"\n return op === \"is\" ? rowYmd === f.dateTarget : rowYmd !== f.dateTarget\n }\n if (f.isDigitsMask) {\n if (!f.digitsNeedle) return true\n const hay = digitsOnly(rowVal)\n return f.operator === \"contains\" ? hay.includes(f.digitsNeedle) : !hay.includes(f.digitsNeedle)\n }\n if (!f.textNeedle) return true\n const hay = getLowerValue(r, f.col.key)\n return f.operator === \"contains\" ? hay.includes(f.textNeedle) : !hay.includes(f.textNeedle)\n }\n\n if (compiled.length > 0) {\n result = result.filter(r => {\n let res = matchesCompiled(r, compiled[0])\n for (let i = 1; i < compiled.length; i++) {\n const connector = filterConnectors[compiled[i - 1].id] ?? \"and\"\n const match = matchesCompiled(r, compiled[i])\n res = connector === \"and\" ? res && match : res || match\n }\n return res\n })\n }\n }\n\n // Column menu quick-search — pre-normalise needles outside the row loop.\n const colMenuEntries: { key: string; lower: string }[] = []\n for (const [key, raw] of Object.entries(colMenuSearch)) {\n const trimmed = raw.trim()\n if (trimmed) colMenuEntries.push({ key, lower: trimmed.toLowerCase() })\n }\n if (colMenuEntries.length > 0) {\n result = result.filter(r => {\n for (const { key, lower } of colMenuEntries) {\n if (!getLowerValue(r, key).includes(lower)) return false\n }\n return true\n })\n }\n\n // Sort — resolve each rule's sort key ONCE, then run the comparator over\n // an indexed list so the inner loop is a tight array walk, not a chain of\n // `columns.find` lookups per comparison.\n if (sortRules.length > 0) {\n const resolved: { sk: string; dir: SortDir }[] = []\n for (const rule of sortRules) {\n const col = columnsByKey.get(rule.fieldKey)\n const sk = col?.sortKey ?? col?.key\n if (sk) resolved.push({ sk: sk as string, dir: rule.direction })\n }\n if (resolved.length > 0) {\n result.sort((a, b) => {\n for (let i = 0; i < resolved.length; i++) {\n const { sk, dir } = resolved[i]\n const cmp = compareUnknownSort(a[sk], b[sk])\n if (cmp !== 0) return dir === \"asc\" ? cmp : -cmp\n }\n return 0\n })\n }\n }\n\n return result\n }, [\n data,\n search,\n activeFilters,\n filterConnectors,\n colMenuSearch,\n sortRules,\n columnsByKey,\n getSearchableText,\n getLowerValue,\n ])\n\n // ── Paged rows (slice of rows when pagination is active) ─────────────────\n const pagedRows = React.useMemo(() => {\n if (!paginationOverride || paginationOverride.pageSize <= 0) return rows\n const { page, pageSize } = paginationOverride\n const safePage = Math.max(1, page)\n return rows.slice((safePage - 1) * pageSize, safePage * pageSize)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [rows, paginationOverride?.page, paginationOverride?.pageSize])\n\n // ── Grouped rows ──────────────────────────────────────────────────────────\n const groupedRows = React.useMemo(() => {\n if (!groupBy) return [{ groupKey: null as string | null, groupLabel: null as string | null, rows }]\n const groups = new Map<string, TData[]>()\n rows.forEach(row => {\n const val = String(row[groupBy] ?? \"—\")\n if (!groups.has(val)) groups.set(val, [])\n groups.get(val)!.push(row)\n })\n return [...groups.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, groupRows]) => ({ groupKey: key, groupLabel: key, rows: groupRows }))\n }, [rows, groupBy])\n\n // ── Effective pins (respect overflow) ─────────────────────────────────────\n const LOCKED_KEYS = React.useMemo(() => new Set(Object.keys(lockedPins)), [lockedPins])\n\n // When the table fits within its container (not overflowing) there is no need\n // to sticky-pin any column — even locked ones. Pins only activate once the\n // user has to scroll horizontally so the selection / action edges stay visible.\n // In reflow viewports (high zoom), disable all column stickies — shadow + sticky\n // fight the short viewport and overlap content.\n const effectivePins = React.useMemo(() => {\n if (isReflowViewport || !isOverflowing) return {}\n const result: Record<string, \"left\" | \"right\"> = {}\n for (const [key, pin] of Object.entries(colPins)) {\n result[key] = pin\n }\n return result\n }, [colPins, isOverflowing, isReflowViewport])\n\n // ── Display columns ───────────────────────────────────────────────────────\n const displayCols = React.useMemo(() => {\n const leftPinned: string[] = []\n const free: string[] = []\n const rightPinned: string[] = []\n for (const k of colOrder) {\n const pin = colPins[k]\n if (pin === \"left\") leftPinned.push(k)\n else if (pin === \"right\") rightPinned.push(k)\n else free.push(k)\n }\n const ordered = [...leftPinned, ...free, ...rightPinned]\n const out: ColumnDef<TData>[] = []\n for (const k of ordered) {\n if (hiddenCols.has(k)) continue\n const col = columnsByKey.get(k)\n if (col) out.push(col)\n }\n return out\n }, [colOrder, colPins, hiddenCols, columnsByKey])\n\n // ── Column actions ────────────────────────────────────────────────────────\n function startResize(key: string, e: React.MouseEvent) {\n e.preventDefault()\n e.stopPropagation()\n const minW = columns.find(c => c.key === key)?.minWidth ?? 60\n const startW = colWidths[key] ?? (columns.find(c => c.key === key)?.width ?? 100)\n resizeRef.current = { key, startX: e.clientX, startW }\n const onMove = (ev: MouseEvent) => {\n if (!resizeRef.current) return\n const { key: k, startX, startW: sw } = resizeRef.current\n setColWidths(p => ({ ...p, [k]: Math.max(minW, sw + ev.clientX - startX) }))\n }\n const onUp = () => {\n resizeRef.current = null\n document.removeEventListener(\"mousemove\", onMove)\n document.removeEventListener(\"mouseup\", onUp)\n }\n document.addEventListener(\"mousemove\", onMove)\n document.addEventListener(\"mouseup\", onUp)\n }\n\n function handleDragStart(key: string, e: React.DragEvent<HTMLTableCellElement>) {\n draggedKey.current = key\n e.dataTransfer.effectAllowed = \"move\"\n }\n function handleDragOver(key: string, e: React.DragEvent<HTMLTableCellElement>) {\n e.preventDefault()\n e.dataTransfer.dropEffect = \"move\"\n if (draggedKey.current && draggedKey.current !== key) setDragOverKey(key)\n }\n function handleDrop(key: string) {\n if (!draggedKey.current || draggedKey.current === key) { setDragOverKey(null); return }\n const order = [...colOrder]\n const from = order.indexOf(draggedKey.current)\n const to = order.indexOf(key)\n order.splice(from, 1)\n order.splice(to, 0, draggedKey.current!)\n setColOrder(order)\n draggedKey.current = null\n setDragOverKey(null)\n }\n function handleDragEnd() { draggedKey.current = null; setDragOverKey(null) }\n\n function pinColumn(key: string, pin: \"left\" | \"right\") {\n setColPins(p => ({ ...p, [key]: pin }))\n }\n function unpinColumn(key: string) {\n if (lockedPins[key]) return\n setColPins(p => { const n = { ...p }; delete n[key]; return n })\n }\n function toggleWrap(key: string) {\n setColWrap(p => ({ ...p, [key]: !p[key] }))\n }\n\n // ── Scroll handlers ───────────────────────────────────────────────────────\n function checkOverflow() {\n const el = scrollRef.current\n if (!el) return\n setIsOverflowing(el.scrollWidth > el.clientWidth + 1)\n }\n function handleScroll() {\n const el = scrollRef.current\n if (!el) return\n setScrolled(el.scrollLeft > 1)\n setScrollEnd(el.scrollLeft >= el.scrollWidth - el.clientWidth - 1)\n setIsOverflowing(el.scrollWidth > el.clientWidth + 1)\n }\n\n // ── Selection helpers ─────────────────────────────────────────────────────\n function getRowId(row: TData, index: number, getIdFn?: (r: TData, i: number) => string | number): string | number {\n return getIdFn ? getIdFn(row, index) : (row.id as string | number ?? index)\n }\n\n const toggleRow = React.useCallback((id: string | number) => {\n setSelected(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 }, [setSelected])\n\n const toggleAll = React.useCallback((allRowIds: (string | number)[]) => {\n setSelected(prev => prev.size === allRowIds.length ? new Set() : new Set(allRowIds))\n }, [setSelected])\n\n // ── Sticky offset calculations ────────────────────────────────────────────\n // Precompute every pinned column's offset ONCE per render so the per-cell\n // `stickyStyle()` call is an O(1) map lookup instead of an O(cols) walk.\n // With `cells = rows × cols`, the previous O(rows × cols²) became the\n // dominant cost on wide tables.\n const stickyOffsets = React.useMemo(() => {\n const left = new Map<string, number>()\n const right = new Map<string, number>()\n let leftOffset = 0\n for (const col of displayCols) {\n if (effectivePins[col.key] !== \"left\") break\n left.set(col.key, leftOffset)\n leftOffset += colWidths[col.key] ?? col.width ?? 100\n }\n let rightOffset = 0\n for (let i = displayCols.length - 1; i >= 0; i--) {\n const col = displayCols[i]\n if (effectivePins[col.key] !== \"right\") break\n right.set(col.key, rightOffset)\n rightOffset += colWidths[col.key] ?? col.width ?? 100\n }\n return { left, right }\n }, [displayCols, effectivePins, colWidths])\n\n const getStickyLeft = React.useCallback((key: string): number => {\n return stickyOffsets.left.get(key) ?? 0\n }, [stickyOffsets])\n\n const getStickyRight = React.useCallback((key: string): number => {\n return stickyOffsets.right.get(key) ?? 0\n }, [stickyOffsets])\n\n const stickyStyle = React.useCallback(\n (key: string, isHeader = false): React.CSSProperties => {\n if (isReflowViewport) return {}\n const pin = effectivePins[key]\n if (pin === \"left\") {\n return isHeader\n ? { position: \"sticky\", left: stickyOffsets.left.get(key) ?? 0, top: 0 }\n : { position: \"sticky\", left: stickyOffsets.left.get(key) ?? 0 }\n }\n if (pin === \"right\") {\n return isHeader\n ? { position: \"sticky\", right: stickyOffsets.right.get(key) ?? 0, top: 0 }\n : { position: \"sticky\", right: stickyOffsets.right.get(key) ?? 0 }\n }\n return isHeader ? { position: \"sticky\", top: 0 } : {}\n },\n [effectivePins, isReflowViewport, stickyOffsets],\n )\n\n const totalWidth = React.useMemo(\n () => displayCols.reduce((s, c) => s + (colWidths[c.key] ?? c.width ?? 100), 0),\n [displayCols, colWidths],\n )\n\n return {\n // Sort\n sortRules, setSortRules,\n sortKey, sortDir,\n addSortRule, removeSortRule, toggleSortDir, handleSortByKey,\n // Filters\n search, setSearch,\n searchOpen, setSearchOpen,\n searchRef,\n activeFilters, setActiveFilters,\n filterConnectors, setFilterConnectors, toggleConnector, getConnector,\n openFilterId, setOpenFilterId,\n filterBarVisible, setFilterBarVisible,\n drawerExpandedFilters, setDrawerExpandedFilters,\n addFilter, updateFilter, removeFilter,\n // Group\n groupBy, setGroupBy,\n // Column quick-search\n colMenuSearch, setColMenuSearch,\n // Selection\n selected, setSelected, toggleRow, toggleAll, getRowId,\n // Column widths / order / pins / wrap\n colWidths, setColWidths, resizeRef, startResize,\n colOrder, setColOrder, moveCol,\n colPins, setColPins, lockedPins, LOCKED_KEYS,\n pinColumn, unpinColumn,\n colWrap, setColWrap, toggleWrap,\n // Drag-to-reorder\n draggedKey, dragOverKey,\n handleDragStart, handleDragOver, handleDrop, handleDragEnd,\n // Scroll\n scrollRef, scrolled, scrollEnd, isOverflowing,\n checkOverflow, handleScroll,\n // Hover\n hoveredRow, setHoveredRow,\n // Derived\n rows, pagedRows, groupedRows,\n effectivePins, displayCols,\n isReflowViewport,\n getStickyLeft, getStickyRight, stickyStyle,\n totalWidth,\n // Display settings\n sheetOpen, setSheetOpen,\n sheetInitialPanel, setSheetInitialPanel,\n showGridlines, setShowGridlines,\n rowHeight, setRowHeight,\n hiddenCols, setHiddenCols, toggleColVisibility,\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/data-views/data-row-list.tsx"],"names":[],"mappings":"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","file":"data-row-list.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\n/**\n * DataRowList — generic vertical-stack list view used by every hub's \"list\"\n * tab (placements, team, compliance, sites,
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/data-views/data-row-list.tsx"],"names":[],"mappings":"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","file":"data-row-list.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\n/**\n * DataRowList — generic vertical-stack list view used by every hub's \"list\"\n * tab (placements, team, compliance, sites, library, …). Replaces the\n * hand-rolled `<ul …flex-col gap-2 px-4 pb-8 pt-2 lg:px-6> {rows.map(<li>…)}`\n * shell that was duplicated across `*-list-view.tsx` files.\n *\n * Composition over inheritance: callers provide a `renderRow(row)` that\n * returns whatever ListPageBoardCard / link / chip-stack they need — this\n * component owns the chrome (spacing, empty state, virtualization), not the\n * row body.\n *\n * Auto-virtualises with `@tanstack/react-virtual` when the row count meets\n * `virtualizeThreshold` (default 100). Disable by passing `0`.\n */\n\nimport * as React from \"react\"\nimport { useWindowVirtualizer } from \"@tanstack/react-virtual\"\nimport { cn } from \"../../lib/utils\"\n\nconst DEFAULT_VIRTUALIZE_THRESHOLD = 100\nconst DEFAULT_ESTIMATED_ROW_HEIGHT = 96\nconst DEFAULT_OVERSCAN = 8\n\nexport interface DataRowListProps<TRow> {\n /** The filtered/sorted rows from `tableState.rows` (or wherever). */\n rows: readonly TRow[]\n /** Stable id used as the React `key` and (for virtualizer) the v-key. */\n getRowId: (row: TRow, index: number) => string | number\n /** Render the body of one row. Wrap with `<ListPageBoardCard layout=\"row\">` etc. */\n renderRow: (row: TRow, index: number) => React.ReactNode\n /**\n * Shown when `rows.length === 0`. Strings render as muted body copy; pass\n * a `ReactNode` for richer empty states (illustration, CTA, etc.).\n */\n emptyState?: React.ReactNode\n /**\n * Auto-virtualise when `rows.length >= virtualizeThreshold`. Default 100.\n * Pass `0` to never virtualise (preserves predictable layout for short\n * lists like dashboards / pinned tabs).\n */\n virtualizeThreshold?: number\n /** Hint for the virtualizer; clamps to measured size after first paint. */\n estimatedRowHeight?: number\n /** Override the default container padding / gap if needed. */\n className?: string\n /** Override the per-row `<li>` className (e.g. tighter spacing). */\n rowClassName?: string\n /** `aria-label` for the `<ul>` (screen-reader name for the list). */\n ariaLabel?: string\n}\n\nconst DEFAULT_OUTER_CLASS = \"flex list-none flex-col gap-2 px-4 pb-8 pt-2 lg:px-6\"\n\nexport function DataRowList<TRow>(props: DataRowListProps<TRow>) {\n const {\n rows,\n getRowId,\n renderRow,\n emptyState,\n virtualizeThreshold = DEFAULT_VIRTUALIZE_THRESHOLD,\n estimatedRowHeight = DEFAULT_ESTIMATED_ROW_HEIGHT,\n className,\n rowClassName,\n ariaLabel,\n } = props\n\n if (rows.length === 0) {\n if (emptyState == null) return null\n if (typeof emptyState === \"string\") {\n return (\n <div className=\"px-4 py-16 text-center lg:px-6\">\n <p className=\"text-sm text-muted-foreground\">{emptyState}</p>\n </div>\n )\n }\n return <div className=\"px-4 py-16 text-center lg:px-6\">{emptyState}</div>\n }\n\n if (virtualizeThreshold > 0 && rows.length >= virtualizeThreshold) {\n return (\n <DataRowListVirtualized\n rows={rows}\n getRowId={getRowId}\n renderRow={renderRow}\n estimatedRowHeight={estimatedRowHeight}\n className={className}\n rowClassName={rowClassName}\n ariaLabel={ariaLabel}\n />\n )\n }\n\n return (\n <ul aria-label={ariaLabel} className={cn(DEFAULT_OUTER_CLASS, className)}>\n {rows.map((row, i) => (\n <li key={getRowId(row, i)} className={rowClassName}>\n {renderRow(row, i)}\n </li>\n ))}\n </ul>\n )\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Virtualised variant — keeps the DOM short on long lists (e.g. 1000+ rows).\n// Uses `useWindowVirtualizer` so the page scroll drives row recycling; this\n// is the right tool for hub-level lists (not nested-scroll containers).\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction DataRowListVirtualized<TRow>({\n rows,\n getRowId,\n renderRow,\n estimatedRowHeight,\n className,\n rowClassName,\n ariaLabel,\n}: {\n rows: readonly TRow[]\n getRowId: (row: TRow, index: number) => string | number\n renderRow: (row: TRow, index: number) => React.ReactNode\n estimatedRowHeight: number\n className?: string\n rowClassName?: string\n ariaLabel?: string\n}) {\n const anchorRef = React.useRef<HTMLDivElement | null>(null)\n // `scrollMargin` is read by the virtualizer during render, so it has to\n // be state (not a ref). We measure with `useLayoutEffect` after the first\n // paint and on resize so window-scroll math stays accurate when the page\n // layout shifts (sidebar collapse, banner, etc.).\n const [scrollMargin, setScrollMargin] = React.useState(0)\n\n const updateScrollMargin = React.useCallback(() => {\n const el = anchorRef.current\n if (!el) return\n setScrollMargin(el.getBoundingClientRect().top + window.scrollY)\n }, [])\n\n React.useLayoutEffect(() => {\n updateScrollMargin()\n window.addEventListener(\"resize\", updateScrollMargin)\n return () => window.removeEventListener(\"resize\", updateScrollMargin)\n }, [updateScrollMargin, rows.length])\n\n const virtualizer = useWindowVirtualizer({\n count: rows.length,\n estimateSize: () => estimatedRowHeight,\n overscan: DEFAULT_OVERSCAN,\n scrollMargin,\n getItemKey: i => String(getRowId(rows[i], i)),\n })\n\n const totalSize = virtualizer.getTotalSize()\n\n return (\n <div ref={anchorRef} className={cn(\"px-4 pb-8 pt-2 lg:px-6\", className)}>\n <ul\n aria-label={ariaLabel}\n className=\"relative m-0 w-full list-none p-0\"\n style={{ height: `${totalSize}px` }}\n >\n {virtualizer.getVirtualItems().map(vr => {\n const row = rows[vr.index]\n if (!row) return null\n return (\n <li\n key={vr.key}\n data-index={vr.index}\n ref={virtualizer.measureElement}\n className={cn(\"absolute left-0 top-0 w-full pb-2\", rowClassName)}\n style={{ transform: `translateY(${vr.start}px)` }}\n >\n {renderRow(row, vr.index)}\n </li>\n )\n })}\n </ul>\n </div>\n )\n}\n"]}
|
|
@@ -28,7 +28,7 @@ interface FinderPanelViewProps<T> {
|
|
|
28
28
|
* `ListPageSplitHubChrome` (shared split surface across hubs).
|
|
29
29
|
*/
|
|
30
30
|
embedded?: boolean;
|
|
31
|
-
/** Left column title (
|
|
31
|
+
/** Left column title (Library: “Categories”). */
|
|
32
32
|
groupsColumnTitle?: string;
|
|
33
33
|
/** Middle column title; defaults from the active group label. */
|
|
34
34
|
getListColumnTitle?: (activeGroup: FinderGroup | undefined) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/resizable.tsx","../../../src/components/data-views/list-page-tree-column-header.tsx","../../../src/components/data-views/list-page-split-details-placeholder.tsx","../../../src/components/data-views/list-page-split-hub-tokens.ts","../../../src/components/data-views/finder-panel-view.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"finder-panel-view.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { GripVertical } from \"lucide-react\"\nimport { Group, Panel, Separator } from \"react-resizable-panels\"\nimport type { GroupProps, PanelProps, SeparatorProps } from \"react-resizable-panels\"\n\nimport { cn } from \"../../lib/utils\"\n\n// ─── ResizablePanelGroup ──────────────────────────────────────────────────────\n\nexport type ResizablePanelGroupProps = Omit<GroupProps, \"orientation\"> & {\n direction?: \"horizontal\" | \"vertical\"\n}\n\nexport function ResizablePanelGroup({\n direction = \"horizontal\",\n className,\n ...props\n}: ResizablePanelGroupProps) {\n return (\n <Group\n orientation={direction}\n className={cn(\n \"flex h-full w-full\",\n direction === \"vertical\" && \"flex-col\",\n className,\n )}\n {...props}\n />\n )\n}\n\n// ─── ResizablePanel ───────────────────────────────────────────────────────────\n\nexport type ResizablePanelProps = PanelProps\n\nexport const ResizablePanel = Panel\n\n// ─── ResizableHandle ──────────────────────────────────────────────────────────\n\nexport type ResizableHandleProps = Omit<SeparatorProps, \"children\"> & {\n /** Render a visible grip icon on the handle. */\n withHandle?: boolean\n}\n\nexport function ResizableHandle({ withHandle, className, ...props }: ResizableHandleProps) {\n return (\n <Separator\n className={cn(\n // Base — horizontal handle (between side-by-side panels)\n \"relative flex w-1 shrink-0 cursor-col-resize items-center justify-center bg-border/60\",\n \"transition-colors hover:bg-border active:bg-primary/30\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1\",\n // Vertical handle (between stacked panels)\n \"data-[orientation=vertical]:h-1 data-[orientation=vertical]:w-full data-[orientation=vertical]:cursor-row-resize data-[orientation=vertical]:flex-row\",\n className,\n )}\n {...props}\n >\n {withHandle && (\n <div className=\"z-10 flex h-5 w-3.5 items-center justify-center rounded-sm border border-border bg-background shadow-sm\">\n <GripVertical className=\"h-3 w-3 text-muted-foreground\" />\n </div>\n )}\n </Separator>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\n\nexport interface ListPageTreeColumnHeaderProps {\n title: string\n /** Right side (e.g. icon buttons) — keep touch targets ≥ 24px */\n trailing?: React.ReactNode\n className?: string\n}\n\n/**\n * Shared left-column header for tree / outline surfaces — matches Question bank “Questions” bar.\n */\nexport function ListPageTreeColumnHeader({\n title,\n trailing,\n className,\n}: ListPageTreeColumnHeaderProps) {\n return (\n <div className={cn(\"shrink-0 border-b border-border/50 bg-card px-3 py-2\", className)}>\n <div className=\"flex h-9 items-center justify-between gap-2\">\n <h3 className=\"min-w-0 flex-1 truncate text-sm font-medium text-foreground\">{title}</h3>\n {trailing ? (\n <div className=\"flex shrink-0 items-center gap-0.5\">{trailing}</div>\n ) : null}\n </div>\n </div>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\n\nexport interface ListPageSplitDetailsPlaceholderProps {\n title?: string\n description?: React.ReactNode\n className?: string\n}\n\n/**\n * Empty right pane for split hubs — flat `bg-card` to match Miller / tree columns.\n */\nexport function ListPageSplitDetailsPlaceholder({\n title = \"Nothing selected\",\n description,\n className,\n}: ListPageSplitDetailsPlaceholderProps) {\n return (\n <div\n className={cn(\n \"flex h-full min-h-0 flex-col items-center justify-center bg-card px-6 py-10 text-center\",\n className,\n )}\n >\n <div className=\"mb-4 flex size-14 items-center justify-center rounded-2xl border border-dashed border-border/70 bg-card\">\n <i\n className=\"fa-light fa-sidebar text-[1.65rem] leading-none text-muted-foreground/70\"\n aria-hidden=\"true\"\n />\n </div>\n <p className=\"text-sm font-medium text-foreground\">{title}</p>\n {description ? (\n <div className=\"mt-1.5 max-w-[16rem] text-xs leading-relaxed text-muted-foreground\">{description}</div>\n ) : null}\n </div>\n )\n}\n","/**\n * Shared layout tokens for list-hub split surfaces (Miller columns, tree + details).\n * Keeps Question bank panel / tree and generic `FinderPanelView` visually aligned.\n */\n\n/** `ResizableHandle` between miller / tree columns — matches Question bank panel. */\nexport const LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS =\n \"w-1 bg-border/40 hover:bg-brand/20 transition-colors\"\n\n/** Primary column stack (scope list, folder list, record list, …). */\nexport const LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS =\n \"flex min-h-0 min-w-0 flex-col bg-card\"\n\n/** Right-hand inspector / detail column shell. */\nexport const LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS =\n \"flex min-h-0 min-w-0 flex-col bg-card\"\n","\"use client\"\n\n/**\n * FinderPanelView — Miller-style 3-column split for list-page hubs.\n *\n * Visual shell matches Question bank panel (`ListPageTreeColumnHeader`, `LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS`,\n * shared resizable handles) — see `list-page-split-hub-tokens.ts`.\n */\n\nimport * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\nimport {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from \"../ui/resizable\"\nimport { ListPageTreeColumnHeader } from \"./list-page-tree-column-header\"\nimport { ListPageSplitDetailsPlaceholder } from \"./list-page-split-details-placeholder\"\nimport {\n LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS,\n LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS,\n LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS,\n} from \"./list-page-split-hub-tokens\"\n\nexport interface FinderGroup {\n id: string\n label: string\n icon?: string\n accent?: string\n count: number\n}\n\nexport interface FinderPanelViewProps<T> {\n groups: FinderGroup[]\n rows: T[]\n getRowId: (row: T) => string | number\n getRowGroupId: (row: T) => string\n renderListRow: (row: T, isSelected: boolean) => React.ReactNode\n renderDetail: (row: T) => React.ReactNode\n emptyDetail?: React.ReactNode\n emptyList?: React.ReactNode\n defaultGroupId?: string\n ariaLabel?: string\n autoSaveId?: string\n className?: string\n style?: React.CSSProperties\n onAddItem?: () => void\n /**\n * When true, omit outer margin, border, and card fill so the grid fits inside\n * `ListPageSplitHubChrome` (shared split surface across hubs).\n */\n embedded?: boolean\n /** Left column title (Question bank: “Categories”). */\n groupsColumnTitle?: string\n /** Middle column title; defaults from the active group label. */\n getListColumnTitle?: (activeGroup: FinderGroup | undefined) => string\n}\n\nexport function GroupsColumn({\n groups,\n selectedGroupId,\n onSelect,\n columnTitle,\n}: {\n groups: FinderGroup[]\n selectedGroupId: string\n onSelect: (id: string) => void\n columnTitle: string\n}) {\n return (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden\">\n <ListPageTreeColumnHeader title={columnTitle} />\n <div\n className=\"min-h-0 flex-1 overflow-y-auto py-1\"\n role=\"listbox\"\n aria-label=\"Group navigation\"\n aria-multiselectable=\"false\"\n >\n {groups.map(group => {\n const isSelected = group.id === selectedGroupId\n return (\n <div key={group.id} className=\"group flex items-center hover:bg-muted/50\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => onSelect(group.id)}\n className={cn(\n \"flex w-full flex-1 items-center gap-2 px-3 py-2 text-start text-sm transition-colors duration-75\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\",\n isSelected\n ? \"bg-accent font-medium text-accent-foreground\"\n : \"text-foreground\",\n )}\n >\n {group.accent ? (\n <span className={cn(\"size-2 shrink-0 rounded-full\", group.accent)} aria-hidden=\"true\" />\n ) : group.icon ? (\n <i\n className={cn(\n \"fa-light shrink-0 text-xs\",\n group.icon,\n isSelected ? \"text-accent-foreground\" : \"text-muted-foreground\",\n )}\n aria-hidden=\"true\"\n />\n ) : null}\n <span className=\"min-w-0 flex-1 truncate leading-tight\">{group.label}</span>\n <span\n className={cn(\n \"shrink-0 tabular-nums text-xs\",\n isSelected ? \"text-accent-foreground/80\" : \"text-muted-foreground\",\n )}\n >\n {group.count}\n </span>\n </button>\n </div>\n )\n })}\n </div>\n </div>\n )\n}\n\n/**\n * Horizontal scope strip (toolbar toggles). Optional: place above a hub body when you need\n * status scope without consuming a Finder column.\n */\nexport function FinderGroupStrip({\n groups,\n selectedGroupId,\n onSelect,\n ariaLabel = \"Scope\",\n}: {\n groups: FinderGroup[]\n selectedGroupId: string\n onSelect: (id: string) => void\n ariaLabel?: string\n}) {\n return (\n <div\n role=\"toolbar\"\n aria-label={ariaLabel}\n className=\"flex min-h-10 flex-wrap items-center gap-1.5 border-b border-border bg-card px-2 py-2\"\n >\n {groups.map(group => {\n const isSelected = group.id === selectedGroupId\n return (\n <button\n key={group.id}\n type=\"button\"\n aria-pressed={isSelected}\n onClick={() => onSelect(group.id)}\n className={cn(\n \"inline-flex h-8 max-w-full min-w-0 shrink-0 items-center gap-1.5 rounded-lg border px-2.5 text-xs font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n isSelected\n ? \"border-brand/40 bg-accent text-accent-foreground\"\n : \"border-transparent bg-background/80 text-foreground hover:bg-muted\",\n )}\n >\n {group.accent ? (\n <span className={cn(\"size-2 shrink-0 rounded-full\", group.accent)} aria-hidden=\"true\" />\n ) : group.icon ? (\n <i\n className={cn(\n \"fa-light shrink-0 text-[11px]\",\n group.icon,\n isSelected ? \"text-accent-foreground\" : \"text-muted-foreground\",\n )}\n aria-hidden=\"true\"\n />\n ) : null}\n <span className=\"min-w-0 truncate\">{group.label}</span>\n <span\n className={cn(\n \"shrink-0 tabular-nums text-[11px]\",\n isSelected ? \"text-accent-foreground/85\" : \"text-muted-foreground\",\n )}\n >\n {group.count}\n </span>\n </button>\n )\n })}\n </div>\n )\n}\n\nfunction ListColumn<T>({\n rows,\n getRowId,\n selectedId,\n renderListRow,\n onSelect,\n emptyList,\n groupLabel,\n columnTitle,\n onAddItem,\n}: {\n rows: T[]\n getRowId: (row: T) => string | number\n selectedId: string | number | null\n renderListRow: (row: T, isSelected: boolean) => React.ReactNode\n onSelect: (id: string | number) => void\n emptyList?: React.ReactNode\n groupLabel: string\n columnTitle: string\n onAddItem?: () => void\n}) {\n return (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden\">\n <ListPageTreeColumnHeader title={columnTitle} />\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div\n className=\"min-h-0 flex-1 overflow-y-auto py-1\"\n role=\"listbox\"\n aria-label={`${groupLabel} items`}\n aria-multiselectable=\"false\"\n >\n {rows.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center px-4 py-12 text-center text-sm text-muted-foreground\">\n {emptyList ?? <p>No items in this group.</p>}\n </div>\n ) : (\n rows.map(row => {\n const id = getRowId(row)\n const isSelected = id === selectedId\n return (\n <div key={id} className=\"group flex items-center hover:bg-muted/50\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => onSelect(id)}\n className={cn(\n \"flex w-full flex-1 items-center gap-3 px-3 py-2 text-start text-sm transition-colors duration-75\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\",\n isSelected\n ? \"bg-accent font-medium text-accent-foreground\"\n : \"text-foreground\",\n )}\n >\n {renderListRow(row, isSelected)}\n </button>\n </div>\n )\n })\n )}\n </div>\n {onAddItem ? (\n <div className=\"flex shrink-0 items-center justify-center border-t border-border/50 px-2 py-1.5\">\n <button\n type=\"button\"\n onClick={onAddItem}\n className=\"flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={`Add item to ${groupLabel}`}\n >\n <i className=\"fa-light fa-plus text-xs\" aria-hidden=\"true\" />\n </button>\n </div>\n ) : null}\n </div>\n </div>\n )\n}\n\nfunction DetailColumn({ children }: { children: React.ReactNode }) {\n return (\n <div className={cn(LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS, \"overflow-hidden\")}>\n <ListPageTreeColumnHeader title=\"Details\" />\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">{children}</div>\n </div>\n )\n}\n\nfunction DefaultEmptyDetail() {\n return (\n <ListPageSplitDetailsPlaceholder title=\"Nothing selected\" />\n )\n}\n\nexport function FinderPanelView<T>({\n groups,\n rows,\n getRowId,\n getRowGroupId,\n renderListRow,\n renderDetail,\n emptyDetail,\n emptyList,\n defaultGroupId,\n ariaLabel = \"List and details\",\n autoSaveId = \"finder-panel-view\",\n className,\n style,\n onAddItem,\n embedded = false,\n groupsColumnTitle = \"Categories\",\n getListColumnTitle = g => g?.label ?? \"Items\",\n}: FinderPanelViewProps<T>) {\n const mergedStyle = React.useMemo<React.CSSProperties>(() => {\n if (embedded) {\n return { height: \"100%\", minHeight: 0, ...style }\n }\n return {\n height: \"calc(100vh - 280px)\",\n minHeight: 420,\n ...style,\n }\n }, [embedded, style])\n const firstGroupId = defaultGroupId ?? groups[0]?.id ?? \"all\"\n const [selectedGroupId, setSelectedGroupId] = React.useState(firstGroupId)\n const [selectedRowId, setSelectedRowId] = React.useState<string | number | null>(null)\n\n const visibleRows = React.useMemo(() => {\n if (selectedGroupId === \"all\") return rows\n return rows.filter(r => getRowGroupId(r) === selectedGroupId)\n }, [rows, selectedGroupId, getRowGroupId])\n\n React.useEffect(() => {\n setSelectedRowId(visibleRows[0] ? getRowId(visibleRows[0]) : null)\n }, [selectedGroupId, visibleRows, getRowId])\n\n React.useEffect(() => {\n if (selectedRowId !== null && !visibleRows.find(r => getRowId(r) === selectedRowId)) {\n setSelectedRowId(visibleRows[0] ? getRowId(visibleRows[0]) : null)\n }\n }, [visibleRows, selectedRowId, getRowId])\n\n const selectedRow =\n selectedRowId !== null\n ? (visibleRows.find(r => getRowId(r) === selectedRowId) ?? null)\n : null\n\n const selectedGroup = groups.find(g => g.id === selectedGroupId)\n const listColumnTitle = getListColumnTitle(selectedGroup)\n\n return (\n <div\n className={cn(\n embedded\n ? \"flex h-full min-h-0 flex-col overflow-hidden\"\n : \"mx-4 mb-6 overflow-hidden rounded-xl border border-border bg-card lg:mx-6\",\n className,\n )}\n style={mergedStyle}\n aria-label={ariaLabel}\n >\n <ResizablePanelGroup\n id={String(autoSaveId)}\n direction=\"horizontal\"\n className=\"h-full min-h-0 w-full flex-1\"\n >\n <ResizablePanel\n id=\"groups\"\n defaultSize=\"22%\"\n minSize=\"16%\"\n maxSize=\"32%\"\n className={LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS}\n >\n <GroupsColumn\n columnTitle={groupsColumnTitle}\n groups={groups}\n selectedGroupId={selectedGroupId}\n onSelect={id => setSelectedGroupId(id)}\n />\n </ResizablePanel>\n\n <ResizableHandle withHandle className={LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS} />\n\n <ResizablePanel\n id=\"list\"\n defaultSize=\"34%\"\n minSize=\"22%\"\n maxSize=\"48%\"\n className={LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS}\n >\n <ListColumn\n columnTitle={listColumnTitle}\n rows={visibleRows}\n getRowId={getRowId}\n selectedId={selectedRowId}\n renderListRow={renderListRow}\n onSelect={id => setSelectedRowId(id)}\n emptyList={emptyList}\n groupLabel={selectedGroup?.label ?? \"All\"}\n onAddItem={onAddItem}\n />\n </ResizablePanel>\n\n <ResizableHandle withHandle className={LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS} />\n\n <ResizablePanel id=\"detail\" defaultSize=\"44%\" minSize=\"30%\" className={LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS}>\n <DetailColumn>\n {selectedRow\n ? renderDetail(selectedRow)\n : (emptyDetail ?? <DefaultEmptyDetail />)}\n </DetailColumn>\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/resizable.tsx","../../../src/components/data-views/list-page-tree-column-header.tsx","../../../src/components/data-views/list-page-split-details-placeholder.tsx","../../../src/components/data-views/list-page-split-hub-tokens.ts","../../../src/components/data-views/finder-panel-view.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"finder-panel-view.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { GripVertical } from \"lucide-react\"\nimport { Group, Panel, Separator } from \"react-resizable-panels\"\nimport type { GroupProps, PanelProps, SeparatorProps } from \"react-resizable-panels\"\n\nimport { cn } from \"../../lib/utils\"\n\n// ─── ResizablePanelGroup ──────────────────────────────────────────────────────\n\nexport type ResizablePanelGroupProps = Omit<GroupProps, \"orientation\"> & {\n direction?: \"horizontal\" | \"vertical\"\n}\n\nexport function ResizablePanelGroup({\n direction = \"horizontal\",\n className,\n ...props\n}: ResizablePanelGroupProps) {\n return (\n <Group\n orientation={direction}\n className={cn(\n \"flex h-full w-full\",\n direction === \"vertical\" && \"flex-col\",\n className,\n )}\n {...props}\n />\n )\n}\n\n// ─── ResizablePanel ───────────────────────────────────────────────────────────\n\nexport type ResizablePanelProps = PanelProps\n\nexport const ResizablePanel = Panel\n\n// ─── ResizableHandle ──────────────────────────────────────────────────────────\n\nexport type ResizableHandleProps = Omit<SeparatorProps, \"children\"> & {\n /** Render a visible grip icon on the handle. */\n withHandle?: boolean\n}\n\nexport function ResizableHandle({ withHandle, className, ...props }: ResizableHandleProps) {\n return (\n <Separator\n className={cn(\n // Base — horizontal handle (between side-by-side panels)\n \"relative flex w-1 shrink-0 cursor-col-resize items-center justify-center bg-border/60\",\n \"transition-colors hover:bg-border active:bg-primary/30\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1\",\n // Vertical handle (between stacked panels)\n \"data-[orientation=vertical]:h-1 data-[orientation=vertical]:w-full data-[orientation=vertical]:cursor-row-resize data-[orientation=vertical]:flex-row\",\n className,\n )}\n {...props}\n >\n {withHandle && (\n <div className=\"z-10 flex h-5 w-3.5 items-center justify-center rounded-sm border border-border bg-background shadow-sm\">\n <GripVertical className=\"h-3 w-3 text-muted-foreground\" />\n </div>\n )}\n </Separator>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\n\nexport interface ListPageTreeColumnHeaderProps {\n title: string\n /** Right side (e.g. icon buttons) — keep touch targets ≥ 24px */\n trailing?: React.ReactNode\n className?: string\n}\n\n/**\n * Shared left-column header for tree / outline surfaces — matches Library “Questions” bar.\n */\nexport function ListPageTreeColumnHeader({\n title,\n trailing,\n className,\n}: ListPageTreeColumnHeaderProps) {\n return (\n <div className={cn(\"shrink-0 border-b border-border/50 bg-card px-3 py-2\", className)}>\n <div className=\"flex h-9 items-center justify-between gap-2\">\n <h3 className=\"min-w-0 flex-1 truncate text-sm font-medium text-foreground\">{title}</h3>\n {trailing ? (\n <div className=\"flex shrink-0 items-center gap-0.5\">{trailing}</div>\n ) : null}\n </div>\n </div>\n )\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\n\nexport interface ListPageSplitDetailsPlaceholderProps {\n title?: string\n description?: React.ReactNode\n className?: string\n}\n\n/**\n * Empty right pane for split hubs — flat `bg-card` to match Miller / tree columns.\n */\nexport function ListPageSplitDetailsPlaceholder({\n title = \"Nothing selected\",\n description,\n className,\n}: ListPageSplitDetailsPlaceholderProps) {\n return (\n <div\n className={cn(\n \"flex h-full min-h-0 flex-col items-center justify-center bg-card px-6 py-10 text-center\",\n className,\n )}\n >\n <div className=\"mb-4 flex size-14 items-center justify-center rounded-2xl border border-dashed border-border/70 bg-card\">\n <i\n className=\"fa-light fa-sidebar text-[1.65rem] leading-none text-muted-foreground/70\"\n aria-hidden=\"true\"\n />\n </div>\n <p className=\"text-sm font-medium text-foreground\">{title}</p>\n {description ? (\n <div className=\"mt-1.5 max-w-[16rem] text-xs leading-relaxed text-muted-foreground\">{description}</div>\n ) : null}\n </div>\n )\n}\n","/**\n * Shared layout tokens for list-hub split surfaces (Miller columns, tree + details).\n * Keeps Library panel / tree and generic `FinderPanelView` visually aligned.\n */\n\n/** `ResizableHandle` between miller / tree columns — matches Library panel. */\nexport const LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS =\n \"w-1 bg-border/40 hover:bg-brand/20 transition-colors\"\n\n/** Primary column stack (scope list, folder list, record list, …). */\nexport const LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS =\n \"flex min-h-0 min-w-0 flex-col bg-card\"\n\n/** Right-hand inspector / detail column shell. */\nexport const LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS =\n \"flex min-h-0 min-w-0 flex-col bg-card\"\n","\"use client\"\n\n/**\n * FinderPanelView — Miller-style 3-column split for list-page hubs.\n *\n * Visual shell matches Library panel (`ListPageTreeColumnHeader`, `LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS`,\n * shared resizable handles) — see `list-page-split-hub-tokens.ts`.\n */\n\nimport * as React from \"react\"\nimport { cn } from \"../../lib/utils\"\nimport {\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from \"../ui/resizable\"\nimport { ListPageTreeColumnHeader } from \"./list-page-tree-column-header\"\nimport { ListPageSplitDetailsPlaceholder } from \"./list-page-split-details-placeholder\"\nimport {\n LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS,\n LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS,\n LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS,\n} from \"./list-page-split-hub-tokens\"\n\nexport interface FinderGroup {\n id: string\n label: string\n icon?: string\n accent?: string\n count: number\n}\n\nexport interface FinderPanelViewProps<T> {\n groups: FinderGroup[]\n rows: T[]\n getRowId: (row: T) => string | number\n getRowGroupId: (row: T) => string\n renderListRow: (row: T, isSelected: boolean) => React.ReactNode\n renderDetail: (row: T) => React.ReactNode\n emptyDetail?: React.ReactNode\n emptyList?: React.ReactNode\n defaultGroupId?: string\n ariaLabel?: string\n autoSaveId?: string\n className?: string\n style?: React.CSSProperties\n onAddItem?: () => void\n /**\n * When true, omit outer margin, border, and card fill so the grid fits inside\n * `ListPageSplitHubChrome` (shared split surface across hubs).\n */\n embedded?: boolean\n /** Left column title (Library: “Categories”). */\n groupsColumnTitle?: string\n /** Middle column title; defaults from the active group label. */\n getListColumnTitle?: (activeGroup: FinderGroup | undefined) => string\n}\n\nexport function GroupsColumn({\n groups,\n selectedGroupId,\n onSelect,\n columnTitle,\n}: {\n groups: FinderGroup[]\n selectedGroupId: string\n onSelect: (id: string) => void\n columnTitle: string\n}) {\n return (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden\">\n <ListPageTreeColumnHeader title={columnTitle} />\n <div\n className=\"min-h-0 flex-1 overflow-y-auto py-1\"\n role=\"listbox\"\n aria-label=\"Group navigation\"\n aria-multiselectable=\"false\"\n >\n {groups.map(group => {\n const isSelected = group.id === selectedGroupId\n return (\n <div key={group.id} className=\"group flex items-center hover:bg-muted/50\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => onSelect(group.id)}\n className={cn(\n \"flex w-full flex-1 items-center gap-2 px-3 py-2 text-start text-sm transition-colors duration-75\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\",\n isSelected\n ? \"bg-accent font-medium text-accent-foreground\"\n : \"text-foreground\",\n )}\n >\n {group.accent ? (\n <span className={cn(\"size-2 shrink-0 rounded-full\", group.accent)} aria-hidden=\"true\" />\n ) : group.icon ? (\n <i\n className={cn(\n \"fa-light shrink-0 text-xs\",\n group.icon,\n isSelected ? \"text-accent-foreground\" : \"text-muted-foreground\",\n )}\n aria-hidden=\"true\"\n />\n ) : null}\n <span className=\"min-w-0 flex-1 truncate leading-tight\">{group.label}</span>\n <span\n className={cn(\n \"shrink-0 tabular-nums text-xs\",\n isSelected ? \"text-accent-foreground/80\" : \"text-muted-foreground\",\n )}\n >\n {group.count}\n </span>\n </button>\n </div>\n )\n })}\n </div>\n </div>\n )\n}\n\n/**\n * Horizontal scope strip (toolbar toggles). Optional: place above a hub body when you need\n * status scope without consuming a Finder column.\n */\nexport function FinderGroupStrip({\n groups,\n selectedGroupId,\n onSelect,\n ariaLabel = \"Scope\",\n}: {\n groups: FinderGroup[]\n selectedGroupId: string\n onSelect: (id: string) => void\n ariaLabel?: string\n}) {\n return (\n <div\n role=\"toolbar\"\n aria-label={ariaLabel}\n className=\"flex min-h-10 flex-wrap items-center gap-1.5 border-b border-border bg-card px-2 py-2\"\n >\n {groups.map(group => {\n const isSelected = group.id === selectedGroupId\n return (\n <button\n key={group.id}\n type=\"button\"\n aria-pressed={isSelected}\n onClick={() => onSelect(group.id)}\n className={cn(\n \"inline-flex h-8 max-w-full min-w-0 shrink-0 items-center gap-1.5 rounded-lg border px-2.5 text-xs font-medium transition-colors\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n isSelected\n ? \"border-brand/40 bg-accent text-accent-foreground\"\n : \"border-transparent bg-background/80 text-foreground hover:bg-muted\",\n )}\n >\n {group.accent ? (\n <span className={cn(\"size-2 shrink-0 rounded-full\", group.accent)} aria-hidden=\"true\" />\n ) : group.icon ? (\n <i\n className={cn(\n \"fa-light shrink-0 text-[11px]\",\n group.icon,\n isSelected ? \"text-accent-foreground\" : \"text-muted-foreground\",\n )}\n aria-hidden=\"true\"\n />\n ) : null}\n <span className=\"min-w-0 truncate\">{group.label}</span>\n <span\n className={cn(\n \"shrink-0 tabular-nums text-[11px]\",\n isSelected ? \"text-accent-foreground/85\" : \"text-muted-foreground\",\n )}\n >\n {group.count}\n </span>\n </button>\n )\n })}\n </div>\n )\n}\n\nfunction ListColumn<T>({\n rows,\n getRowId,\n selectedId,\n renderListRow,\n onSelect,\n emptyList,\n groupLabel,\n columnTitle,\n onAddItem,\n}: {\n rows: T[]\n getRowId: (row: T) => string | number\n selectedId: string | number | null\n renderListRow: (row: T, isSelected: boolean) => React.ReactNode\n onSelect: (id: string | number) => void\n emptyList?: React.ReactNode\n groupLabel: string\n columnTitle: string\n onAddItem?: () => void\n}) {\n return (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden\">\n <ListPageTreeColumnHeader title={columnTitle} />\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div\n className=\"min-h-0 flex-1 overflow-y-auto py-1\"\n role=\"listbox\"\n aria-label={`${groupLabel} items`}\n aria-multiselectable=\"false\"\n >\n {rows.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center px-4 py-12 text-center text-sm text-muted-foreground\">\n {emptyList ?? <p>No items in this group.</p>}\n </div>\n ) : (\n rows.map(row => {\n const id = getRowId(row)\n const isSelected = id === selectedId\n return (\n <div key={id} className=\"group flex items-center hover:bg-muted/50\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => onSelect(id)}\n className={cn(\n \"flex w-full flex-1 items-center gap-3 px-3 py-2 text-start text-sm transition-colors duration-75\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset\",\n isSelected\n ? \"bg-accent font-medium text-accent-foreground\"\n : \"text-foreground\",\n )}\n >\n {renderListRow(row, isSelected)}\n </button>\n </div>\n )\n })\n )}\n </div>\n {onAddItem ? (\n <div className=\"flex shrink-0 items-center justify-center border-t border-border/50 px-2 py-1.5\">\n <button\n type=\"button\"\n onClick={onAddItem}\n className=\"flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n aria-label={`Add item to ${groupLabel}`}\n >\n <i className=\"fa-light fa-plus text-xs\" aria-hidden=\"true\" />\n </button>\n </div>\n ) : null}\n </div>\n </div>\n )\n}\n\nfunction DetailColumn({ children }: { children: React.ReactNode }) {\n return (\n <div className={cn(LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS, \"overflow-hidden\")}>\n <ListPageTreeColumnHeader title=\"Details\" />\n <div className=\"flex min-h-0 flex-1 flex-col overflow-hidden\">{children}</div>\n </div>\n )\n}\n\nfunction DefaultEmptyDetail() {\n return (\n <ListPageSplitDetailsPlaceholder title=\"Nothing selected\" />\n )\n}\n\nexport function FinderPanelView<T>({\n groups,\n rows,\n getRowId,\n getRowGroupId,\n renderListRow,\n renderDetail,\n emptyDetail,\n emptyList,\n defaultGroupId,\n ariaLabel = \"List and details\",\n autoSaveId = \"finder-panel-view\",\n className,\n style,\n onAddItem,\n embedded = false,\n groupsColumnTitle = \"Categories\",\n getListColumnTitle = g => g?.label ?? \"Items\",\n}: FinderPanelViewProps<T>) {\n const mergedStyle = React.useMemo<React.CSSProperties>(() => {\n if (embedded) {\n return { height: \"100%\", minHeight: 0, ...style }\n }\n return {\n height: \"calc(100vh - 280px)\",\n minHeight: 420,\n ...style,\n }\n }, [embedded, style])\n const firstGroupId = defaultGroupId ?? groups[0]?.id ?? \"all\"\n const [selectedGroupId, setSelectedGroupId] = React.useState(firstGroupId)\n const [selectedRowId, setSelectedRowId] = React.useState<string | number | null>(null)\n\n const visibleRows = React.useMemo(() => {\n if (selectedGroupId === \"all\") return rows\n return rows.filter(r => getRowGroupId(r) === selectedGroupId)\n }, [rows, selectedGroupId, getRowGroupId])\n\n React.useEffect(() => {\n setSelectedRowId(visibleRows[0] ? getRowId(visibleRows[0]) : null)\n }, [selectedGroupId, visibleRows, getRowId])\n\n React.useEffect(() => {\n if (selectedRowId !== null && !visibleRows.find(r => getRowId(r) === selectedRowId)) {\n setSelectedRowId(visibleRows[0] ? getRowId(visibleRows[0]) : null)\n }\n }, [visibleRows, selectedRowId, getRowId])\n\n const selectedRow =\n selectedRowId !== null\n ? (visibleRows.find(r => getRowId(r) === selectedRowId) ?? null)\n : null\n\n const selectedGroup = groups.find(g => g.id === selectedGroupId)\n const listColumnTitle = getListColumnTitle(selectedGroup)\n\n return (\n <div\n className={cn(\n embedded\n ? \"flex h-full min-h-0 flex-col overflow-hidden\"\n : \"mx-4 mb-6 overflow-hidden rounded-xl border border-border bg-card lg:mx-6\",\n className,\n )}\n style={mergedStyle}\n aria-label={ariaLabel}\n >\n <ResizablePanelGroup\n id={String(autoSaveId)}\n direction=\"horizontal\"\n className=\"h-full min-h-0 w-full flex-1\"\n >\n <ResizablePanel\n id=\"groups\"\n defaultSize=\"22%\"\n minSize=\"16%\"\n maxSize=\"32%\"\n className={LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS}\n >\n <GroupsColumn\n columnTitle={groupsColumnTitle}\n groups={groups}\n selectedGroupId={selectedGroupId}\n onSelect={id => setSelectedGroupId(id)}\n />\n </ResizablePanel>\n\n <ResizableHandle withHandle className={LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS} />\n\n <ResizablePanel\n id=\"list\"\n defaultSize=\"34%\"\n minSize=\"22%\"\n maxSize=\"48%\"\n className={LIST_PAGE_SPLIT_MILLER_COLUMN_PANEL_CLASS}\n >\n <ListColumn\n columnTitle={listColumnTitle}\n rows={visibleRows}\n getRowId={getRowId}\n selectedId={selectedRowId}\n renderListRow={renderListRow}\n onSelect={id => setSelectedRowId(id)}\n emptyList={emptyList}\n groupLabel={selectedGroup?.label ?? \"All\"}\n onAddItem={onAddItem}\n />\n </ResizablePanel>\n\n <ResizableHandle withHandle className={LIST_PAGE_SPLIT_RESIZABLE_HANDLE_CLASS} />\n\n <ResizablePanel id=\"detail\" defaultSize=\"44%\" minSize=\"30%\" className={LIST_PAGE_SPLIT_MILLER_DETAIL_PANEL_CLASS}>\n <DetailColumn>\n {selectedRow\n ? renderDetail(selectedRow)\n : (emptyDetail ?? <DefaultEmptyDetail />)}\n </DetailColumn>\n </ResizablePanel>\n </ResizablePanelGroup>\n </div>\n )\n}\n"]}
|
|
@@ -129,14 +129,20 @@ interface HubTableProps<TRow extends Record<string, unknown>> {
|
|
|
129
129
|
tableRenderer?: (args: HubTableRendererArgs<TRow>) => React.ReactNode;
|
|
130
130
|
/**
|
|
131
131
|
* Forwarded to `useTableState` so the hub can switch on server-style pagination
|
|
132
|
-
*
|
|
132
|
+
* with externally-controlled page/pageSize (advanced; most hubs should leave
|
|
133
|
+
* this undefined and let `HubTable` own the internal page state — see
|
|
134
|
+
* `pagination` + `paginationPageSizeOptions`).
|
|
133
135
|
*/
|
|
134
136
|
paginationOverride?: {
|
|
135
137
|
page: number;
|
|
136
138
|
pageSize: number;
|
|
137
139
|
};
|
|
140
|
+
/** Page size options shown in the toolbar `<PaginationBar>`. Default `[10, 25, 50, 100]`. */
|
|
141
|
+
paginationPageSizeOptions?: number[];
|
|
142
|
+
/** Initial page size when `HubTable` owns pagination internally. Default `10`. */
|
|
143
|
+
paginationInitialPageSize?: number;
|
|
138
144
|
/**
|
|
139
|
-
* Forwarded to `useTableState` to sync toolbar search from `?q=` (
|
|
145
|
+
* Forwarded to `useTableState` to sync toolbar search from `?q=` (Library search routes).
|
|
140
146
|
* Defining as `""` enables sync without an initial query.
|
|
141
147
|
*/
|
|
142
148
|
syncedSearchFromUrl?: string;
|
|
@@ -159,7 +165,7 @@ interface HubTableProps<TRow extends Record<string, unknown>> {
|
|
|
159
165
|
/** Empty column copy for the default board renderer. Defaults to "No items". */
|
|
160
166
|
boardEmptyColumnLabel?: string;
|
|
161
167
|
}
|
|
162
|
-
declare function HubTable<TRow extends Record<string, unknown>>({ rows, columns, view, onViewChange, supportedViewTypes, hubLabel, lifecycleTabLabel, searchAriaLabel, getRowId, getRowSelectionLabel, defaultSort, emptyState, renderers, bulkActionsSlot, boardGroupByColumnOptions, displayOptionsInit, renderFilterOptionValue, groupable, selectable, onRowClick, displayOptions: displayOptionsControlled, onDisplayOptionsChange: onDisplayOptionsChangeControlled, pagination, onPaginationChange, handleRef, tableRenderer, paginationOverride, syncedSearchFromUrl, renderListRow, listAriaLabel, listEmptyState, listVirtualizeThreshold, listEstimatedRowHeight, renderBoardCard, boardGroups, boardColumnCountBadgeClassName, boardEmptyColumnLabel, }: HubTableProps<TRow>): react_jsx_runtime.JSX.Element;
|
|
168
|
+
declare function HubTable<TRow extends Record<string, unknown>>({ rows, columns, view, onViewChange, supportedViewTypes, hubLabel, lifecycleTabLabel, searchAriaLabel, getRowId, getRowSelectionLabel, defaultSort, emptyState, renderers, bulkActionsSlot, boardGroupByColumnOptions, displayOptionsInit, renderFilterOptionValue, groupable, selectable, onRowClick, displayOptions: displayOptionsControlled, onDisplayOptionsChange: onDisplayOptionsChangeControlled, pagination, onPaginationChange, handleRef, tableRenderer, paginationOverride, paginationPageSizeOptions, paginationInitialPageSize, syncedSearchFromUrl, renderListRow, listAriaLabel, listEmptyState, listVirtualizeThreshold, listEstimatedRowHeight, renderBoardCard, boardGroups, boardColumnCountBadgeClassName, boardEmptyColumnLabel, }: HubTableProps<TRow>): react_jsx_runtime.JSX.Element;
|
|
163
169
|
declare namespace HubTable {
|
|
164
170
|
var displayName: string;
|
|
165
171
|
}
|