eidos-ui 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Avatar.types-BY-C09Ke.d.cts +23 -0
- package/dist/Avatar.types-BY-C09Ke.d.ts +23 -0
- package/dist/{Header.types-BZi80bWz.d.cts → Header.types-B3QtuiL-.d.cts} +7 -3
- package/dist/{Header.types-DJt-q01P.d.ts → Header.types-C6w0FBY8.d.ts} +7 -3
- package/dist/{Table.types-Cl5gR8r9.d.cts → Table.types-CPj-udMc.d.cts} +95 -0
- package/dist/{Table.types-jhPb7JNU.d.ts → Table.types-CZZ7QWAI.d.ts} +95 -0
- package/dist/Toolbar.types-DSk8z2iy.d.cts +38 -0
- package/dist/Toolbar.types-RN0klQzu.d.ts +38 -0
- package/dist/alert/index.cjs +4 -4
- package/dist/alert/index.d.cts +2 -1
- package/dist/alert/index.d.ts +2 -1
- package/dist/alert/index.js +3 -3
- package/dist/avatar/index.d.cts +3 -21
- package/dist/avatar/index.d.ts +3 -21
- package/dist/button/index.cjs +3 -3
- package/dist/button/index.js +2 -2
- package/dist/chip/index.cjs +3 -3
- package/dist/chip/index.js +2 -2
- package/dist/{chunk-KIXFSXIN.cjs → chunk-3E7TKBQI.cjs} +5 -3
- package/dist/chunk-3E7TKBQI.cjs.map +1 -0
- package/dist/{chunk-ZBKJ3EMK.cjs → chunk-442U3W6R.cjs} +3 -3
- package/dist/{chunk-ZBKJ3EMK.cjs.map → chunk-442U3W6R.cjs.map} +1 -1
- package/dist/{chunk-YQLCPKGV.js → chunk-5HUZYY54.js} +6 -4
- package/dist/chunk-5HUZYY54.js.map +1 -0
- package/dist/{chunk-G5IGADJI.cjs → chunk-5VM2256W.cjs} +7 -11
- package/dist/chunk-5VM2256W.cjs.map +1 -0
- package/dist/{chunk-Z4ZY7L7W.js → chunk-5ZL6PYU3.js} +3 -3
- package/dist/{chunk-A3NE2C7C.js → chunk-67RFMV6K.js} +2 -2
- package/dist/{chunk-2U7UJOOB.cjs → chunk-6HUHH6Y4.cjs} +17 -15
- package/dist/chunk-6HUHH6Y4.cjs.map +1 -0
- package/dist/{chunk-5WROPW7Z.js → chunk-A7WQINIG.js} +3 -3
- package/dist/{chunk-DKZTDYH5.cjs → chunk-AAA6TR5I.cjs} +3 -3
- package/dist/{chunk-DKZTDYH5.cjs.map → chunk-AAA6TR5I.cjs.map} +1 -1
- package/dist/{chunk-A7Z2QAFZ.cjs → chunk-APK5OQRV.cjs} +5 -5
- package/dist/{chunk-A7Z2QAFZ.cjs.map → chunk-APK5OQRV.cjs.map} +1 -1
- package/dist/{chunk-ISABZ2VX.cjs → chunk-AXBYJ2OY.cjs} +9 -9
- package/dist/{chunk-ISABZ2VX.cjs.map → chunk-AXBYJ2OY.cjs.map} +1 -1
- package/dist/{chunk-6RGJAQCU.cjs → chunk-B5G5XVFJ.cjs} +5 -5
- package/dist/{chunk-6RGJAQCU.cjs.map → chunk-B5G5XVFJ.cjs.map} +1 -1
- package/dist/{chunk-MW2S7PZ7.cjs → chunk-D5IY2HUV.cjs} +5 -5
- package/dist/{chunk-MW2S7PZ7.cjs.map → chunk-D5IY2HUV.cjs.map} +1 -1
- package/dist/{chunk-FMPXSF3H.cjs → chunk-DAXZRNNO.cjs} +4 -4
- package/dist/{chunk-FMPXSF3H.cjs.map → chunk-DAXZRNNO.cjs.map} +1 -1
- package/dist/{chunk-AJZTVCST.js → chunk-EXITZVB2.js} +24 -9
- package/dist/chunk-EXITZVB2.js.map +1 -0
- package/dist/{chunk-AYMD4D4M.cjs → chunk-EZME5CLK.cjs} +3 -3
- package/dist/{chunk-AYMD4D4M.cjs.map → chunk-EZME5CLK.cjs.map} +1 -1
- package/dist/{chunk-IV4LM3MB.js → chunk-F26VIKNF.js} +9 -11
- package/dist/chunk-F26VIKNF.js.map +1 -0
- package/dist/{chunk-WPTMMOA6.cjs → chunk-G77YR73R.cjs} +10 -13
- package/dist/chunk-G77YR73R.cjs.map +1 -0
- package/dist/chunk-GEHL4LKK.cjs +32 -0
- package/dist/chunk-GEHL4LKK.cjs.map +1 -0
- package/dist/chunk-GGSII6Y2.cjs +921 -0
- package/dist/chunk-GGSII6Y2.cjs.map +1 -0
- package/dist/{chunk-3VRMTWUS.js → chunk-GHQ6SQPI.js} +7 -10
- package/dist/chunk-GHQ6SQPI.js.map +1 -0
- package/dist/{chunk-56B6RLOE.js → chunk-GI6VJYOS.js} +4 -4
- package/dist/{chunk-56B6RLOE.js.map → chunk-GI6VJYOS.js.map} +1 -1
- package/dist/{chunk-UGMONQGH.cjs → chunk-GR2PMCVN.cjs} +10 -12
- package/dist/chunk-GR2PMCVN.cjs.map +1 -0
- package/dist/{chunk-7AHZTHXR.cjs → chunk-GT22EGJP.cjs} +5 -5
- package/dist/{chunk-7AHZTHXR.cjs.map → chunk-GT22EGJP.cjs.map} +1 -1
- package/dist/{chunk-ALGX5X4N.js → chunk-IFVT5UCY.js} +3 -3
- package/dist/{chunk-5CLC3FJO.js → chunk-KBG77JHC.js} +13 -2
- package/dist/chunk-KBG77JHC.js.map +1 -0
- package/dist/{chunk-HLNKIAE5.cjs → chunk-KJZUYC4X.cjs} +5 -5
- package/dist/{chunk-HLNKIAE5.cjs.map → chunk-KJZUYC4X.cjs.map} +1 -1
- package/dist/{chunk-4BQM5F76.cjs → chunk-LFWPQYWX.cjs} +3 -3
- package/dist/{chunk-4BQM5F76.cjs.map → chunk-LFWPQYWX.cjs.map} +1 -1
- package/dist/{chunk-XVSODE4K.cjs → chunk-LIFUHQH5.cjs} +35 -20
- package/dist/chunk-LIFUHQH5.cjs.map +1 -0
- package/dist/{chunk-PJC7NZUV.cjs → chunk-LUL6RZ4M.cjs} +3 -3
- package/dist/{chunk-PJC7NZUV.cjs.map → chunk-LUL6RZ4M.cjs.map} +1 -1
- package/dist/{chunk-4UJ7LG4W.cjs → chunk-N2IGZIEX.cjs} +3 -3
- package/dist/{chunk-4UJ7LG4W.cjs.map → chunk-N2IGZIEX.cjs.map} +1 -1
- package/dist/{chunk-3LHQUOGP.js → chunk-NGVOXM7P.js} +3 -3
- package/dist/{chunk-WTXASLBB.js → chunk-O5WEKLNF.js} +2 -2
- package/dist/{chunk-BOB5JJ7F.js → chunk-P7IQY5YH.js} +2 -2
- package/dist/{chunk-VZYLJSV5.js → chunk-R4PU2TBM.js} +2 -2
- package/dist/{chunk-P2GCAVUZ.js → chunk-RAZRQ57B.js} +2 -2
- package/dist/{chunk-K7IFNKMN.js → chunk-REVK7IGN.js} +2 -2
- package/dist/{chunk-6U2H26A4.cjs → chunk-RHOT7AEI.cjs} +3 -3
- package/dist/{chunk-6U2H26A4.cjs.map → chunk-RHOT7AEI.cjs.map} +1 -1
- package/dist/{chunk-MH2CD2QT.js → chunk-RKA2OJRT.js} +207 -102
- package/dist/chunk-RKA2OJRT.js.map +1 -0
- package/dist/{chunk-JC4WLVBG.js → chunk-RWOX2NJN.js} +2 -2
- package/dist/{chunk-4LM33LDV.js → chunk-S3CT536K.js} +2 -2
- package/dist/{chunk-4M3LZLOH.js → chunk-SHYSLWQG.js} +2 -2
- package/dist/{chunk-EQEV7GPT.cjs → chunk-SKEWTQJ7.cjs} +5 -5
- package/dist/{chunk-EQEV7GPT.cjs.map → chunk-SKEWTQJ7.cjs.map} +1 -1
- package/dist/{chunk-2ZENLZEQ.cjs → chunk-SKTDGCWJ.cjs} +232 -127
- package/dist/chunk-SKTDGCWJ.cjs.map +1 -0
- package/dist/{chunk-2BXCIWL7.js → chunk-SN6EWQDJ.js} +3 -3
- package/dist/{chunk-DW2YDWGN.js → chunk-TEJIPPZR.js} +2 -2
- package/dist/{chunk-OGKD5PLS.cjs → chunk-TRLBYA5G.cjs} +4 -4
- package/dist/{chunk-OGKD5PLS.cjs.map → chunk-TRLBYA5G.cjs.map} +1 -1
- package/dist/{chunk-WE5FTQGD.js → chunk-VHMOKXUT.js} +3 -7
- package/dist/chunk-VHMOKXUT.js.map +1 -0
- package/dist/{chunk-S77GR5YQ.cjs → chunk-VHQTDITV.cjs} +3 -3
- package/dist/{chunk-S77GR5YQ.cjs.map → chunk-VHQTDITV.cjs.map} +1 -1
- package/dist/{chunk-3HMKE2GJ.js → chunk-VSTQEHVZ.js} +6 -4
- package/dist/chunk-VSTQEHVZ.js.map +1 -0
- package/dist/{chunk-HNUTV3HR.cjs → chunk-WUBQJVB7.cjs} +3 -3
- package/dist/{chunk-HNUTV3HR.cjs.map → chunk-WUBQJVB7.cjs.map} +1 -1
- package/dist/{chunk-S7TWEVC3.js → chunk-Y53HCLGW.js} +2 -2
- package/dist/{chunk-WIE7HDIM.js → chunk-YJXZR7RL.js} +2 -2
- package/dist/{chunk-IJYYHBZC.cjs → chunk-Z4SLV6WG.cjs} +3 -3
- package/dist/{chunk-IJYYHBZC.cjs.map → chunk-Z4SLV6WG.cjs.map} +1 -1
- package/dist/chunk-ZEZK664O.js +921 -0
- package/dist/chunk-ZEZK664O.js.map +1 -0
- package/dist/{chunk-JMD3P4CY.js → chunk-ZHFPV43D.js} +2 -2
- package/dist/combobox/index.cjs +4 -4
- package/dist/combobox/index.js +3 -3
- package/dist/context-menu/index.cjs +4 -4
- package/dist/context-menu/index.js +3 -3
- package/dist/data-grid/index.cjs +13 -13
- package/dist/data-grid/index.d.cts +49 -3
- package/dist/data-grid/index.d.ts +49 -3
- package/dist/data-grid/index.js +12 -12
- package/dist/date-picker/index.cjs +6 -6
- package/dist/date-picker/index.js +5 -5
- package/dist/drawer/index.cjs +4 -4
- package/dist/drawer/index.d.cts +2 -1
- package/dist/drawer/index.d.ts +2 -1
- package/dist/drawer/index.js +3 -3
- package/dist/empty-state/index.d.cts +2 -2
- package/dist/empty-state/index.d.ts +2 -2
- package/dist/header/index.cjs +4 -4
- package/dist/header/index.d.cts +2 -2
- package/dist/header/index.d.ts +2 -2
- package/dist/header/index.js +3 -3
- package/dist/index.cjs +29 -29
- package/dist/index.css +318 -73
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +28 -28
- package/dist/inline-edit/index.cjs +4 -4
- package/dist/inline-edit/index.js +3 -3
- package/dist/input/index.cjs +3 -3
- package/dist/input/index.js +2 -2
- package/dist/menu/index.cjs +3 -3
- package/dist/menu/index.js +2 -2
- package/dist/modal/index.cjs +4 -4
- package/dist/modal/index.d.cts +2 -1
- package/dist/modal/index.d.ts +2 -1
- package/dist/modal/index.js +3 -3
- package/dist/navigation/index.cjs +4 -4
- package/dist/navigation/index.js +3 -3
- package/dist/page-layout/index.cjs +8 -8
- package/dist/page-layout/index.d.cts +3 -2
- package/dist/page-layout/index.d.ts +3 -2
- package/dist/page-layout/index.js +7 -7
- package/dist/pagination/index.cjs +6 -6
- package/dist/pagination/index.js +5 -5
- package/dist/popover/index.cjs +2 -2
- package/dist/popover/index.d.cts +2 -2
- package/dist/popover/index.d.ts +2 -2
- package/dist/popover/index.js +1 -1
- package/dist/segmented-control/index.cjs +3 -3
- package/dist/segmented-control/index.js +2 -2
- package/dist/select/index.cjs +4 -4
- package/dist/select/index.js +3 -3
- package/dist/snackbar/index.cjs +4 -4
- package/dist/snackbar/index.js +3 -3
- package/dist/split-button/index.cjs +4 -4
- package/dist/split-button/index.js +3 -3
- package/dist/table/index.cjs +11 -11
- package/dist/table/index.d.cts +3 -3
- package/dist/table/index.d.ts +3 -3
- package/dist/table/index.js +10 -10
- package/dist/tabs/index.cjs +3 -3
- package/dist/tabs/index.js +2 -2
- package/dist/tag-input/index.cjs +4 -4
- package/dist/tag-input/index.js +3 -3
- package/dist/textarea/index.cjs +3 -3
- package/dist/textarea/index.js +2 -2
- package/dist/toolbar/index.cjs +5 -5
- package/dist/toolbar/index.d.cts +3 -2
- package/dist/toolbar/index.d.ts +3 -2
- package/dist/toolbar/index.js +4 -4
- package/package.json +6 -5
- package/dist/Toolbar.types-BGD57Uhm.d.ts +0 -22
- package/dist/Toolbar.types-tQkLmPIu.d.cts +0 -22
- package/dist/chunk-2U7UJOOB.cjs.map +0 -1
- package/dist/chunk-2ZENLZEQ.cjs.map +0 -1
- package/dist/chunk-3HMKE2GJ.js.map +0 -1
- package/dist/chunk-3VRMTWUS.js.map +0 -1
- package/dist/chunk-5CLC3FJO.js.map +0 -1
- package/dist/chunk-AJZTVCST.js.map +0 -1
- package/dist/chunk-G5IGADJI.cjs.map +0 -1
- package/dist/chunk-GOR642KK.cjs +0 -21
- package/dist/chunk-GOR642KK.cjs.map +0 -1
- package/dist/chunk-IV4LM3MB.js.map +0 -1
- package/dist/chunk-KIXFSXIN.cjs.map +0 -1
- package/dist/chunk-MH2CD2QT.js.map +0 -1
- package/dist/chunk-QONDJ5VM.cjs +0 -744
- package/dist/chunk-QONDJ5VM.cjs.map +0 -1
- package/dist/chunk-UGMONQGH.cjs.map +0 -1
- package/dist/chunk-VSFKM7FE.js +0 -744
- package/dist/chunk-VSFKM7FE.js.map +0 -1
- package/dist/chunk-WE5FTQGD.js.map +0 -1
- package/dist/chunk-WPTMMOA6.cjs.map +0 -1
- package/dist/chunk-XVSODE4K.cjs.map +0 -1
- package/dist/chunk-YQLCPKGV.js.map +0 -1
- /package/dist/{chunk-Z4ZY7L7W.js.map → chunk-5ZL6PYU3.js.map} +0 -0
- /package/dist/{chunk-A3NE2C7C.js.map → chunk-67RFMV6K.js.map} +0 -0
- /package/dist/{chunk-5WROPW7Z.js.map → chunk-A7WQINIG.js.map} +0 -0
- /package/dist/{chunk-ALGX5X4N.js.map → chunk-IFVT5UCY.js.map} +0 -0
- /package/dist/{chunk-3LHQUOGP.js.map → chunk-NGVOXM7P.js.map} +0 -0
- /package/dist/{chunk-WTXASLBB.js.map → chunk-O5WEKLNF.js.map} +0 -0
- /package/dist/{chunk-BOB5JJ7F.js.map → chunk-P7IQY5YH.js.map} +0 -0
- /package/dist/{chunk-VZYLJSV5.js.map → chunk-R4PU2TBM.js.map} +0 -0
- /package/dist/{chunk-P2GCAVUZ.js.map → chunk-RAZRQ57B.js.map} +0 -0
- /package/dist/{chunk-K7IFNKMN.js.map → chunk-REVK7IGN.js.map} +0 -0
- /package/dist/{chunk-JC4WLVBG.js.map → chunk-RWOX2NJN.js.map} +0 -0
- /package/dist/{chunk-4LM33LDV.js.map → chunk-S3CT536K.js.map} +0 -0
- /package/dist/{chunk-4M3LZLOH.js.map → chunk-SHYSLWQG.js.map} +0 -0
- /package/dist/{chunk-2BXCIWL7.js.map → chunk-SN6EWQDJ.js.map} +0 -0
- /package/dist/{chunk-DW2YDWGN.js.map → chunk-TEJIPPZR.js.map} +0 -0
- /package/dist/{chunk-S7TWEVC3.js.map → chunk-Y53HCLGW.js.map} +0 -0
- /package/dist/{chunk-WIE7HDIM.js.map → chunk-YJXZR7RL.js.map} +0 -0
- /package/dist/{chunk-JMD3P4CY.js.map → chunk-ZHFPV43D.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/DataGrid/DataGrid.component.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useMemo, useLayoutEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport {\n GripVertical,\n ArrowUp,\n ArrowDown,\n ChevronsUpDown,\n ChevronRight,\n Plus,\n AlignJustify,\n Check,\n FolderOpen,\n SearchX,\n MoreVertical,\n} from 'lucide-react';\nimport {\n DndContext,\n PointerSensor,\n KeyboardSensor,\n useSensor,\n useSensors,\n closestCenter,\n} from '@dnd-kit/core';\nimport type { DragEndEvent } from '@dnd-kit/core';\nimport {\n SortableContext,\n verticalListSortingStrategy,\n useSortable,\n arrayMove,\n} from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { Button } from '../Button';\nimport { SplitButton } from '../SplitButton';\nimport { Input } from '../Input/Input.component';\nimport { Select } from '../Select/Select.component';\nimport { Combobox } from '../Combobox';\nimport { SegmentedControl } from '../SegmentedControl';\nimport { Checkbox } from '../Checkbox/Checkbox.component';\nimport { Spinner } from '../Spinner/Spinner.component';\nimport { Pagination } from '../Pagination';\nimport { EmptyState } from '../EmptyState';\nimport { Dropdown } from '../Dropdown';\nimport { Menu } from '../Menu';\nimport type { MenuItemType } from '../Menu';\nimport { TableFiltersDropdown } from '../Table/TableFiltersDropdown.component';\nimport type { FilterValue, TableColumn, TableFilters } from '../Table/Table.types';\nimport type {\n DataGridProps,\n DataGridActionsColumn,\n DataGridCellType,\n DataGridFilterField,\n DataGridQuickFilter,\n DataGridSelectOption,\n EditingCell,\n} from './DataGrid.types';\nimport { renderIcon, devWarn } from '../../utils';\nimport type { RowKey } from '../../utils';\nimport './DataGrid.scss';\n\n// Minimum usable widths (px) per column, summed into the automatic card-view\n// threshold so a grid with many columns doesn't have to overflow horizontally\n// before `cardViewBreakpoint` (a single, hand-tuned number) is reached. See\n// `isCardView` below.\n//\n// The system columns and the actions column are counted at their real, fixed\n// width rather than as a full data column: they never grow, so charging them\n// 100px each overstated the grid's minimum and flipped grids into card view\n// while they still had room to spare. Keep in sync with DataGrid.scss (and\n// with Table's own copy of these, which must agree for the two siblings to\n// switch over at the same point).\nconst MIN_DATA_COLUMN_WIDTH_PX = 100;\nconst ACTIONS_COLUMN_WIDTH_PX = 48;\nconst CHECKBOX_COLUMN_WIDTH_PX = 40;\nconst ROW_NUMBER_COLUMN_WIDTH_PX = 40;\nconst DRAG_HANDLE_COLUMN_WIDTH_PX = 32;\nconst EXPAND_COLUMN_WIDTH_PX = 32;\n\n// Container width (px) below which the toolbar's own buttons drop their labels\n// and render icon-only (with tooltips), and quick filters stretch to one per\n// row. Measured off the container, not the viewport, so a grid in a narrow pane\n// compacts too.\n//\n// Compaction only ever applies to what this component renders itself. A\n// consumer's `bulkActions` are rendered exactly as given and rely on the\n// toolbar wrapping instead - which is the part that actually guarantees\n// nothing overlaps, since arbitrary content can always be wider than any\n// threshold. Same value in Table.\nconst COMPACT_TOOLBAR_WIDTH_PX = 560;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Internal column + row access\n//\n// The public `DataGridColumn<T>` is a discriminated union, which is what lets\n// a consumer's `key` be checked against `keyof T` and gives `renderCell` /\n// `renderEditor` / `validate` the field's own value type instead of `unknown`.\n//\n// Internally the grid walks `columns` generically: it probes members that\n// exist on only one variant (`validate` on value columns, `actions` on the\n// actions column) and looks row fields up by a runtime string key. Narrowing\n// the union at each of those ~30 sites would add a lot of noise for no added\n// safety - the union is enforced where it matters, at the consumer's call\n// site - so the grid widens it once, here, and the render code below is\n// unchanged from when `DataGridColumn` was a single flat interface.\n// ─────────────────────────────────────────────────────────────────────────────\ntype InternalColumn<T extends object> = Omit<DataGridActionsColumn<T>, 'type' | 'key'> & {\n /**\n * Widened to a required plain string. Only the actions variant may omit\n * `key`, and it never reaches a path that consumes one: it renders in its\n * own dedicated slot with a hard-coded `data-col-key=\"__actions__\"`, and is\n * filtered out of `dataColumns` / `sortedColumns`.\n */\n key: string;\n type?: DataGridCellType;\n editable?: boolean;\n required?: boolean;\n options?: DataGridSelectOption[];\n validate?: (value: unknown) => string | true;\n renderCell?: (value: unknown, row: T, rowIndex: number) => React.ReactNode;\n renderEditor?: (value: unknown, onChange: (v: unknown) => void, row: T) => React.ReactNode;\n};\n\n/** Reads a row field by a runtime string key - see `InternalColumn` above. */\nconst cellOf = <T extends object>(row: T, key: string): unknown =>\n (row as Record<string, unknown>)[key];\n\n// Value of the reset (\"All\") segment a quick filter's SegmentedControl always\n// prepends - a SegmentedControl has no empty state of its own, so it needs an\n// explicit segment standing for \"no filter\".\nconst QUICK_FILTER_RESET_VALUE = '';\n\n// Whether a filter value is meaningful enough to keep in the filter state.\n// Empty values are *deleted* from it rather than stored as '' / [], so the\n// key count stays an accurate \"are any filters active?\" signal - that's what\n// drives the \"No results found\" empty state and the dropdown's active\n// indicator.\nconst hasFilterValue = (value: FilterValue): boolean => {\n if (value === undefined || value === null || value === '') return false;\n if (Array.isArray(value)) return value.length > 0;\n if (typeof value === 'object' && 'start' in value) return !!(value.start || value.end);\n return true;\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// SortableTableRow - wraps a <tr> with dnd-kit sortable behaviour.\n//\n// Render-prop pattern: passes `dragHandleProps` down to whichever child element\n// should be the drag handle (typically the grip icon's <span>), so the <tr>\n// itself owns the DOM ref + layout-transform while the handle owns the listeners.\n// Pass `disabled={true}` when draggableRows is off - useSortable is always\n// called unconditionally to satisfy the Rules of Hooks.\n// ─────────────────────────────────────────────────────────────────────────────\nfunction SortableTableRow({\n id,\n disabled,\n className,\n children,\n}: {\n id: string;\n disabled?: boolean;\n className?: string;\n children: (dragHandleProps: object, isDragging: boolean) => React.ReactNode;\n}): React.ReactElement {\n const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({\n id,\n disabled,\n });\n\n return (\n <tr\n ref={setNodeRef}\n className={[className, isDragging ? 'eidos-datagrid-row--dragging' : '']\n .filter(Boolean)\n .join(' ')}\n style={{\n transform: CSS.Transform.toString(transform),\n transition: transition ?? undefined,\n opacity: isDragging ? 0.4 : 1,\n }}\n {...attributes}\n >\n {children(listeners ?? {}, isDragging)}\n </tr>\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// useExpandAnimation - drives a row's expanded-content open/close transition.\n// Mirrors the max-height technique AccordionItem uses, so row expansion\n// animates consistently with Accordion elsewhere in the library - but also\n// keeps tracking the content's height for as long as the panel stays open\n// (via ResizeObserver on the unclipped inner node), not just once at the\n// moment it opens. Content whose height changes after opening - e.g. an\n// async fetch resolving into more/less content than a loading placeholder -\n// would otherwise stay clipped at whatever height was measured on open.\n//\n// Content stays mounted through the close animation (so it can transition\n// shut instead of vanishing instantly), but is never mounted before the row\n// is actually opened for the first time - so `renderExpandedContent` (which\n// may kick off a data fetch) never runs for a row nobody has expanded.\n//\n// Must be called from its own per-row component (not inline in a .map()\n// callback) so the number of hook calls stays constant across renders\n// regardless of how many rows are currently displayed.\n// ─────────────────────────────────────────────────────────────────────────────\nfunction useExpandAnimation(isOpen: boolean): {\n mounted: boolean;\n maxHeight: number;\n outerRef: React.RefObject<HTMLDivElement | null>;\n innerRef: React.RefObject<HTMLDivElement | null>;\n handleTransitionEnd: () => void;\n} {\n // outerRef: the clipped, max-height/overflow-hidden wrapper actually\n // animated - its own rendered height is pinned by `maxHeight` below, so it\n // can't be the thing observed for size changes (see innerRef).\n const outerRef = useRef<HTMLDivElement>(null);\n // innerRef: the unconstrained content itself - always laid out at its\n // natural height regardless of the outer wrapper's clipping, so its size\n // genuinely changes when its content does. That's what ResizeObserver\n // needs to be watching.\n const innerRef = useRef<HTMLDivElement>(null);\n const [maxHeight, setMaxHeight] = useState(0);\n const [mounted, setMounted] = useState(isOpen);\n\n useEffect(() => {\n if (isOpen) setMounted(true);\n }, [isOpen]);\n\n useEffect(() => {\n if (!mounted) return;\n\n if (!isOpen) {\n setMaxHeight(0);\n return;\n }\n\n const node = innerRef.current;\n if (!node) return;\n\n const update = () => setMaxHeight(node.scrollHeight);\n update();\n\n const observer = new ResizeObserver(update);\n observer.observe(node);\n return () => observer.disconnect();\n }, [isOpen, mounted]);\n\n const handleTransitionEnd = useCallback(() => {\n if (!isOpen) setMounted(false);\n }, [isOpen]);\n\n return { mounted, maxHeight, outerRef, innerRef, handleTransitionEnd };\n}\n\n// Table mode: one extra full-width <tr> rendered directly after an expanded\n// row - see `expandable`/`renderExpandedContent` on DataGridProps.\nfunction ExpandedTableRow({\n isOpen,\n colSpan,\n render,\n}: {\n isOpen: boolean;\n colSpan: number;\n render: () => React.ReactNode;\n}): React.ReactElement | null {\n const { mounted, maxHeight, outerRef, innerRef, handleTransitionEnd } =\n useExpandAnimation(isOpen);\n if (!mounted) return null;\n\n return (\n <tr className=\"eidos-datagrid-expanded-row\">\n <td colSpan={colSpan} className=\"eidos-datagrid-expanded-cell\">\n <div\n ref={outerRef}\n className=\"eidos-datagrid-expand-panel\"\n style={{ maxHeight: `${maxHeight}px` }}\n onTransitionEnd={handleTransitionEnd}\n >\n <div ref={innerRef} className=\"eidos-datagrid-expand-panel-inner\">\n {render()}\n </div>\n </div>\n </td>\n </tr>\n );\n}\n\n// Card mode: the same animated panel, appended inside the card itself below\n// its fields.\nfunction ExpandedCardPanel({\n isOpen,\n render,\n}: {\n isOpen: boolean;\n render: () => React.ReactNode;\n}): React.ReactElement | null {\n const { mounted, maxHeight, outerRef, innerRef, handleTransitionEnd } =\n useExpandAnimation(isOpen);\n if (!mounted) return null;\n\n return (\n <div\n ref={outerRef}\n className=\"eidos-datagrid-expand-panel\"\n style={{ maxHeight: `${maxHeight}px` }}\n onTransitionEnd={handleTransitionEnd}\n >\n <div ref={innerRef} className=\"eidos-datagrid-expand-panel-inner\">\n {render()}\n </div>\n </div>\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Inner implementation (generic function so we can assign .displayName cleanly)\n// ─────────────────────────────────────────────────────────────────────────────\nfunction DataGridInner<T extends object>({\n // ── Existing props ─────────────────────────────────────────────────────────\n columns: columnsProp,\n data,\n rowKey,\n onChange,\n onRowAdd,\n editable = false,\n loading = false,\n emptyText = 'No data available',\n className,\n stickyHeader = false,\n maxHeight,\n showRowNumbers = false,\n draggableRows = false,\n onRowReorder,\n // ── Sorting ────────────────────────────────────────────────────────────────\n currentSort,\n onSortChange,\n // ── Filtering ──────────────────────────────────────────────────────────────\n showFilters = false,\n filterConfig = [],\n filters,\n onFiltersChange,\n // ── Quick filters ──────────────────────────────────────────────────────────\n quickFilters = [],\n // ── Pagination ─────────────────────────────────────────────────────────────\n showPagination = false,\n pageSize = 10,\n pageSizeOptions,\n totalRows: totalRowsProp,\n onPageChange,\n // ── Row selection + bulk actions ───────────────────────────────────────────\n selectable = false,\n selectedRows: controlledSelectedRows,\n defaultSelectedRows,\n onSelectionChange,\n selectAllScope = 'all',\n onSelectAllMatching,\n bulkActions,\n // ── Row expansion ────────────────────────────────────────────────────────────\n expandable = false,\n renderExpandedContent,\n isRowExpandable,\n expandMultiple = true,\n expandedRows: controlledExpandedRows,\n defaultExpandedRows,\n onExpandedRowsChange,\n // ── Display ────────────────────────────────────────────────────────────────\n density = 'comfortable',\n showDensity = false,\n // ── Card view ────────────────────────────────────────────────────────────────\n hasCardView = true,\n cardViewBreakpoint = 640,\n cardMinWidth = 280,\n}: DataGridProps<T>): React.ReactElement {\n // See `InternalColumn` above - a cast, not a copy, so the identity\n // comparisons below (`c !== actionsColumn`) still hold.\n const columns = columnsProp as InternalColumn<T>[];\n // `rowKey` is `RowKey<T>` publicly, so the `'id'` default can't live in the\n // destructuring: `'id'` isn't a field of every `T`.\n const rowKeyField: string = rowKey ?? 'id';\n // ── State + paired refs (editing - preserved exactly) ─────────────────────\n // We keep a ref alongside each piece of mutable state so that event\n // handlers registered in effects can always read the *latest* value without\n // stale-closure bugs, while the state variables drive re-renders normally.\n\n const [localData, _setLocalData] = useState<T[]>(data);\n const localDataRef = useRef<T[]>(data);\n\n const [editingCell, _setEditingCell] = useState<EditingCell>(null);\n const editingCellRef = useRef<EditingCell>(null);\n\n const [editValue, _setEditValue] = useState<unknown>(null);\n const editValueRef = useRef<unknown>(null);\n\n const [editError, setEditError] = useState<string | null>(null);\n\n // ── Validation error tooltip (portaled) ─────────────────────────────────────\n // Positioned via a portal into document.body rather than `position: absolute`\n // inside the cell - a cell on the last visible row would otherwise place the\n // tooltip past the scroll container's bottom edge, which still counts toward\n // that container's scrollable content size and forces an unwanted scrollbar\n // just to reveal a tooltip nobody asked to scroll to. Portaling escapes the\n // scroll container's box entirely, the same way Dropdown's own content does.\n // HTMLElement (not HTMLTableCellElement) so the same ref can anchor either\n // a <td> in table mode or a card field <div> in card view - only\n // `getBoundingClientRect()` is ever called on it.\n const errorTooltipAnchorRef = useRef<HTMLElement | null>(null);\n const [errorTooltipPosition, setErrorTooltipPosition] = useState<{\n top: number;\n left: number;\n } | null>(null);\n const activeCellError = editingCell && editError ? editError : null;\n\n useLayoutEffect(() => {\n if (!activeCellError) {\n setErrorTooltipPosition(null);\n return;\n }\n\n const updatePosition = () => {\n const node = errorTooltipAnchorRef.current;\n if (!node) return;\n const rect = node.getBoundingClientRect();\n setErrorTooltipPosition({ top: rect.bottom + 4, left: rect.left });\n };\n\n updatePosition();\n\n // Capture phase catches scroll events from any scrollable ancestor\n // (e.g. this grid's own scroll container), not just window/document -\n // `scroll` doesn't bubble, so a plain (bubble-phase) listener on window\n // would miss it entirely.\n window.addEventListener('resize', updatePosition);\n window.addEventListener('scroll', updatePosition, true);\n return () => {\n window.removeEventListener('resize', updatePosition);\n window.removeEventListener('scroll', updatePosition, true);\n };\n }, [activeCellError]);\n\n // ── New state ──────────────────────────────────────────────────────────────\n // Density (internal when showDensity=true, otherwise respects the prop)\n const [internalDensity, setInternalDensity] = useState<'compact' | 'comfortable' | 'spacious'>(\n density,\n );\n const effectiveDensity = showDensity ? internalDensity : density;\n\n // Sorting (client-side internal state)\n const [internalSort, setInternalSort] = useState<{\n key: string;\n direction: 'asc' | 'desc';\n } | null>(null);\n\n // Filtering (client-side internal state), seeded from any quick filter\n // `defaultValue`s. Lazy, so it only reads `quickFilters` on mount - later\n // edits to the array's default values don't yank a filter the user has\n // since changed. In server-side mode this state is unused entirely, which\n // is why `defaultValue` is documented as client-side only.\n const [internalFilters, setInternalFilters] = useState<TableFilters>(() => {\n const seeded: TableFilters = {};\n quickFilters.forEach(({ key, defaultValue }) => {\n if (hasFilterValue(defaultValue)) seeded[key] = defaultValue;\n });\n return seeded;\n });\n\n // Pagination\n const [currentPage, setCurrentPage] = useState(1);\n const [currentPageSize, setCurrentPageSize] = useState(pageSize);\n\n // Selection\n const isControlledSelection = controlledSelectedRows !== undefined;\n const [internalSelectedKeys, setInternalSelectedKeys] = useState<Set<string>>(\n () => new Set(defaultSelectedRows ?? []),\n );\n\n // Row expansion\n const isControlledExpansion = controlledExpandedRows !== undefined;\n const [internalExpandedKeys, setInternalExpandedKeys] = useState<Set<string>>(\n () => new Set(defaultExpandedRows ?? []),\n );\n\n // Card view: measured off the grid's own container width (not the\n // viewport) via ResizeObserver, so it responds correctly even when the\n // grid sits in a narrow sidebar/split-pane on an otherwise wide screen.\n // Starts `null` (unmeasured) rather than 0, so the table is what renders\n // for one frame on mount instead of briefly flashing cards.\n const [containerWidth, setContainerWidth] = useState<number | null>(null);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n // A callback ref (not `useRef` + a `useLayoutEffect` keyed on `hasCardView`)\n // so this fires whenever the container DOM node actually becomes\n // available, not just when `hasCardView` changes. A plain effect only\n // reruns on its own dependency changing - it does NOT rerun just because\n // a *different* conditional branch attaches the ref for the first time.\n // The `loading` early-return below renders its own container div; any\n // consumer whose `loading` prop starts `true` on mount (e.g. fetching\n // data asynchronously, so it can never resolve before the first render)\n // would mount that div first, find `containerRef.current` still null, and\n // then never re-run the effect once `loading` flips to `false` and the\n // real container mounts - `hasCardView` itself never changed, so nothing\n // triggered a re-run, leaving `containerWidth` (and therefore card view)\n // permanently stuck. A callback ref sidesteps that entirely: whichever\n // container div actually mounts, this runs for it.\n // Deliberately NOT gated on `hasCardView`: the same measurement also drives\n // `isCompactToolbar` below, which a grid with `hasCardView={false}` still\n // needs - it has a toolbar to fit into a narrow container either way.\n const setContainerRef = useCallback((el: HTMLDivElement | null) => {\n resizeObserverRef.current?.disconnect();\n resizeObserverRef.current = null;\n\n if (!el) return;\n\n const observer = new ResizeObserver((entries) => {\n const width = entries[0]?.contentRect.width;\n if (width != null) setContainerWidth(width);\n });\n observer.observe(el);\n resizeObserverRef.current = observer;\n }, []);\n // Narrowest width the grid can render at without overflowing: the sum of\n // every column's own minimum (see the constants above). Computed directly\n // from props, so it's available here without waiting on the `dataColumns`/\n // `actionsColumn` memos below - `columns` already includes the actions\n // column if any, matching how `totalCols` is derived further down.\n const minTableWidth = useMemo(\n () =>\n columns.reduce(\n (total, column) =>\n total + (column.type === 'actions' ? ACTIONS_COLUMN_WIDTH_PX : MIN_DATA_COLUMN_WIDTH_PX),\n (showRowNumbers ? ROW_NUMBER_COLUMN_WIDTH_PX : 0) +\n (draggableRows ? DRAG_HANDLE_COLUMN_WIDTH_PX : 0) +\n (selectable ? CHECKBOX_COLUMN_WIDTH_PX : 0) +\n (expandable ? EXPAND_COLUMN_WIDTH_PX : 0),\n ),\n [columns, showRowNumbers, draggableRows, selectable, expandable],\n );\n\n // Card view kicks in below the explicit `cardViewBreakpoint` OR once the\n // container is too narrow to fit the grid at that minimum - the latter\n // means a wide/many-column grid auto-switches without the consumer having\n // to hand-calculate a breakpoint for it.\n const isCardView =\n hasCardView &&\n containerWidth !== null &&\n (containerWidth < cardViewBreakpoint || containerWidth < minTableWidth);\n\n // Independent of card view on purpose: card view can also trigger on column\n // count in a container that's still plenty wide for labelled buttons, and a\n // `hasCardView={false}` grid still needs its toolbar to fit.\n const isCompactToolbar = containerWidth !== null && containerWidth < COMPACT_TOOLBAR_WIDTH_PX;\n\n // Card view header/subheader: only the first matching column is honored\n // (see DataGridColumn.cardHeader/cardSubheader).\n const cardHeaderColumn = useMemo(() => columns.find((c) => c.cardHeader), [columns]);\n const cardSubheaderColumn = useMemo(() => columns.find((c) => c.cardSubheader), [columns]);\n // The row-actions column, if any - only the first `type: 'actions'` column\n // is honored (see DataGridColumn.actions). Rendered in its own dedicated\n // slot (far right in table mode, top-right of the card in card view),\n // never as a normal data column.\n const actionsColumn = useMemo(() => columns.find((c) => c.type === 'actions'), [columns]);\n // Every column that actually renders as data - excludes the actions\n // column entirely (it's never a normal cell) from both table columns and\n // pinning/filtering/validation logic.\n const dataColumns = useMemo(\n () => columns.filter((c) => c !== actionsColumn),\n [columns, actionsColumn],\n );\n // A card with no system controls, no heading and no actions column has\n // nothing to put in its top bar - rendering it anyway leaves a dead strip\n // and a divider above the first field. Table applies the same guard.\n const hasCardToolbar =\n selectable ||\n showRowNumbers ||\n expandable ||\n !!cardHeaderColumn ||\n !!cardSubheaderColumn ||\n !!actionsColumn;\n\n // Remaining columns render as label:value field rows, in declaration order.\n const cardFieldColumns = useMemo(\n () => dataColumns.filter((c) => c !== cardHeaderColumn && c !== cardSubheaderColumn),\n [dataColumns, cardHeaderColumn, cardSubheaderColumn],\n );\n\n // Pinned columns offset map (computed in useLayoutEffect)\n const theadRef = useRef<HTMLTableSectionElement>(null);\n const [pinnedOffsets, setPinnedOffsets] = useState<\n Map<string, { side: 'left' | 'right'; offset: number }>\n >(new Map());\n\n // ── Synced setters (preserved exactly) ────────────────────────────────────\n const setLocalData = useCallback((v: T[]) => {\n localDataRef.current = v;\n _setLocalData(v);\n }, []);\n\n const setEditingCell = useCallback((v: EditingCell) => {\n editingCellRef.current = v;\n _setEditingCell(v);\n }, []);\n\n const setEditValue = useCallback((v: unknown) => {\n editValueRef.current = v;\n _setEditValue(v);\n }, []);\n\n // ── Sync when the data prop changes externally (preserved) ─────────────────\n useEffect(() => {\n setLocalData(data);\n }, [data, setLocalData]);\n\n // ── Active sort / filters (derived) ───────────────────────────────────────\n // Server-side sort: caller controls currentSort + onSortChange.\n // Client-side sort: we manage internalSort.\n const activeSort = currentSort ?? internalSort;\n\n // Server-side filter: caller controls filters + onFiltersChange.\n // Client-side filter: we manage internalFilters.\n const activeFilters: TableFilters = useMemo(\n () => (onFiltersChange ? (filters ?? {}) : internalFilters),\n [onFiltersChange, filters, internalFilters],\n );\n\n // ── Selection derived state ────────────────────────────────────────────────\n const selectedSet = useMemo(\n () =>\n new Set(isControlledSelection ? (controlledSelectedRows ?? []) : [...internalSelectedKeys]),\n [isControlledSelection, controlledSelectedRows, internalSelectedKeys],\n );\n\n const hasSelection = selectedSet.size > 0;\n\n // Row objects for selected keys, kept across changes to `data`. Filtering\n // the current rows alone silently handed `bulkActions` and\n // `onSelectionChange` fewer rows than the selection count claimed - and\n // under server-side pagination, none at all once the user paged away from\n // everything they had selected. Always prefers the row currently in `data`\n // over the cached copy, so an edited row is never stale.\n const selectedRowCacheRef = useRef(new Map<string, T>());\n\n const rowsForKeys = useCallback(\n (keys: string[]): T[] => {\n const current = new Map<string, T>();\n localDataRef.current.forEach((row, idx) =>\n current.set(String(cellOf(row, rowKeyField) ?? idx), row),\n );\n const cache = selectedRowCacheRef.current;\n return keys\n .map((key) => current.get(key) ?? cache.get(key))\n .filter((row): row is T => row !== undefined);\n },\n [rowKeyField],\n );\n\n // Prunes as well as fills: an entry only survives while its key is still\n // selected, so the cache can't grow without bound.\n useEffect(() => {\n const cache = selectedRowCacheRef.current;\n const current = new Map<string, T>();\n localData.forEach((row, idx) => current.set(String(cellOf(row, rowKeyField) ?? idx), row));\n const next = new Map<string, T>();\n selectedSet.forEach((key) => {\n const row = current.get(key) ?? cache.get(key);\n if (row) next.set(key, row);\n });\n selectedRowCacheRef.current = next;\n }, [localData, selectedSet, rowKeyField]);\n\n const selectedItems = useMemo(\n () => rowsForKeys([...selectedSet]),\n // `localData` isn't read directly here - `rowsForKeys` reads it through a\n // ref - but it must still retrigger this when the loaded rows change.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [rowsForKeys, selectedSet, localData],\n );\n\n // ── Row expansion derived state ─────────────────────────────────────────────\n const expandedSet = useMemo(\n () =>\n new Set(isControlledExpansion ? (controlledExpandedRows ?? []) : [...internalExpandedKeys]),\n [isControlledExpansion, controlledExpandedRows, internalExpandedKeys],\n );\n\n // ── Quick filters: key ownership ───────────────────────────────────────────\n // Quick filters and the filter dropdown share one TableFilters object, so\n // each side has to own a disjoint set of keys - see `dropdownFilters` below\n // for why the dropdown can't just be handed the whole thing.\n const quickFilterKeys = useMemo(() => new Set(quickFilters.map((f) => f.key)), [quickFilters]);\n\n // ── Filter dropdown adapter: DataGridFilterField → TableColumn ─────────────\n // TableFiltersDropdown expects TableColumn<T>[]; we project our (decoupled,\n // column-independent) filter schema onto that shape. A key already claimed\n // by a quick filter is dropped: the quick filter is the always-visible\n // control, and two controls writing one key would each clobber the other.\n const filterDropdownColumns = useMemo((): TableColumn<T>[] => {\n return filterConfig\n .filter((field) => !quickFilterKeys.has(field.key))\n .map(\n (field: DataGridFilterField<T>) =>\n ({\n key: field.key,\n label: field.label,\n filterable: true,\n filterType: field.filterType,\n filterOptions: field.filterOptions,\n dateFilterMode: field.dateFilterMode,\n }) as TableColumn<T>,\n );\n }, [filterConfig, quickFilterKeys]);\n\n const dropdownFilterKeys = useMemo(\n () => new Set(filterDropdownColumns.map((col) => String(col.key))),\n [filterDropdownColumns],\n );\n\n // The dropdown gets only the keys it owns, never the whole filter object.\n // It mirrors every key it's handed into a filter row, so a key it has no\n // matching column for (a quick filter's, or a server-side caller's filter\n // on an unlisted field) would render as a blank, un-removable \"Select\n // column\" row - and its Apply, which emits its complete set, would drop\n // that value on the floor.\n const dropdownFilters = useMemo(\n () =>\n Object.fromEntries(\n Object.entries(activeFilters).filter(([key]) => dropdownFilterKeys.has(key)),\n ),\n [activeFilters, dropdownFilterKeys],\n );\n\n // ── Client-side filtering ──────────────────────────────────────────────────\n const filteredData = useMemo(() => {\n // Server-side mode: parent is responsible for filtering; use data as-is.\n if (onFiltersChange) return localData;\n\n const filterEntries = Object.entries(activeFilters).filter(([, val]) => {\n if (val === undefined || val === null || val === '') return false;\n if (Array.isArray(val) && val.length === 0) return false;\n return true;\n });\n\n if (filterEntries.length === 0) return localData;\n\n return localData.filter((row) =>\n filterEntries.every(([key, filterValue]) => {\n const cellValue = cellOf(row, key);\n\n if (Array.isArray(filterValue)) {\n return filterValue.includes(String(cellValue ?? ''));\n }\n if (typeof filterValue === 'boolean') {\n return Boolean(cellValue) === filterValue;\n }\n if (typeof filterValue === 'object' && filterValue !== null && 'start' in filterValue) {\n const { start, end } = filterValue as { start: string | null; end: string | null };\n const dateStr = String(cellValue ?? '');\n if (start && dateStr < start) return false;\n if (end && dateStr > end) return false;\n return true;\n }\n // Default: case-insensitive text contains\n return String(cellValue ?? '')\n .toLowerCase()\n .includes(String(filterValue).toLowerCase());\n }),\n );\n }, [localData, activeFilters, onFiltersChange]);\n\n // ── Client-side sorting ────────────────────────────────────────────────────\n const sortedData = useMemo(() => {\n // Server-side mode or no active sort: use data as-is.\n if (onSortChange || !activeSort) return filteredData;\n\n return [...filteredData].sort((a, b) => {\n const aVal = cellOf(a, activeSort.key);\n const bVal = cellOf(b, activeSort.key);\n\n if (aVal == null && bVal == null) return 0;\n if (aVal == null) return 1;\n if (bVal == null) return -1;\n\n const compare =\n typeof aVal === 'number' && typeof bVal === 'number'\n ? aVal - bVal\n : String(aVal).localeCompare(String(bVal));\n\n return activeSort.direction === 'asc' ? compare : -compare;\n });\n }, [filteredData, activeSort, onSortChange]);\n\n // ── Client-side pagination ─────────────────────────────────────────────────\n const displayData = useMemo(() => {\n if (!showPagination) return sortedData;\n if (onPageChange) return sortedData; // Server-side: parent slices the data\n const start = (currentPage - 1) * currentPageSize;\n return sortedData.slice(start, start + currentPageSize);\n }, [sortedData, showPagination, currentPage, currentPageSize, onPageChange]);\n\n const totalItemCount = totalRowsProp ?? sortedData.length;\n const totalPages = Math.max(1, Math.ceil(totalItemCount / currentPageSize));\n\n // ── Select-all (scope-aware) ──────────────────────────────────────────────\n // Defined after `displayData` because `'page'` scope is exactly that set.\n const selectAllKeys = useMemo(\n () =>\n (selectAllScope === 'page' ? displayData : localData).map((row, idx) =>\n String(cellOf(row, rowKeyField) ?? idx),\n ),\n [selectAllScope, displayData, localData, rowKeyField],\n );\n\n const allSelected =\n selectAllKeys.length > 0 && selectAllKeys.every((key) => selectedSet.has(key));\n const someSelected = !allSelected && selectAllKeys.some((key) => selectedSet.has(key));\n\n // `'all'` can only ever select the rows the grid holds. With server-side\n // pagination that's one page, and the keys of rows it has never received\n // are unknowable here - warn rather than quietly selecting a page and\n // calling it \"all\".\n useEffect(() => {\n if (!selectable || selectAllScope !== 'all') return;\n if (totalItemCount <= localData.length) return;\n devWarn(\n `datagrid-select-all-scope:${localData.length}/${totalItemCount}`,\n `DataGrid: selectAllScope=\"all\" can only select the ${localData.length} row(s) currently ` +\n `loaded, but there are ${totalItemCount} in total. The keys of rows the grid has never ` +\n `received cannot be known here - use selectAllScope=\"page\" to make the scope explicit, ` +\n 'or resolve the full key set yourself and pass it as `selectedRows`.',\n );\n }, [selectable, selectAllScope, totalItemCount, localData.length]);\n\n // Reset to page 1 when filters change (client-side and server-side).\n // Depend on the serialized *value* of activeFilters, not the object\n // reference: in server-side mode activeFilters is derived straight from\n // the caller's `filters` prop, and callers commonly build that object\n // inline in render (a new reference every render) whether or not its\n // contents actually changed. Comparing by reference made this effect -\n // and the page reset it causes - fire on every unrelated parent\n // re-render (e.g. new page data arriving), not just on real filter\n // changes.\n const activeFiltersKey = useMemo(() => JSON.stringify(activeFilters), [activeFilters]);\n useEffect(() => {\n setCurrentPage(1);\n }, [activeFiltersKey]);\n\n // Reset to page 1 when client-side sort changes\n useEffect(() => {\n setCurrentPage(1);\n }, [internalSort]);\n\n // ── Pinned columns: measure th widths and compute sticky offsets ───────────\n // Mirrors the exact pattern used in Table.component.tsx.\n // System columns (sel, drag, rownum, actions) contribute to the offset\n // accumulator but are not themselves sticky-positioned.\n useLayoutEffect(() => {\n const hasPinned = columns.some((c) => c.pin);\n if (!hasPinned || !theadRef.current) {\n setPinnedOffsets((prev) => (prev.size > 0 ? new Map() : prev));\n return;\n }\n\n const headerRow = theadRef.current.querySelector('tr');\n if (!headerRow) return;\n\n const cells = Array.from(headerRow.querySelectorAll<HTMLTableCellElement>('th[data-col-key]'));\n const newOffsets = new Map<string, { side: 'left' | 'right'; offset: number }>();\n\n // Left-pinned: scan left-to-right\n // When any data column is pin:'left', auto-pin the system columns too so\n // the entire frozen-left group moves as a coherent unit.\n const hasLeftPin = columns.some((c) => c.pin === 'left');\n let leftAccum = 0;\n for (const cell of cells) {\n const key = cell.dataset.colKey!;\n if (key === '__expand__' || key === '__sel__' || key === '__drag__' || key === '__rownum__') {\n if (hasLeftPin) {\n newOffsets.set(key, { side: 'left', offset: leftAccum });\n }\n leftAccum += cell.offsetWidth;\n } else {\n const col = columns.find((c) => c.key === key);\n if (col?.pin === 'left') {\n newOffsets.set(key, { side: 'left', offset: leftAccum });\n leftAccum += cell.offsetWidth;\n }\n }\n }\n\n // Right-pinned: scan right-to-left\n let rightAccum = 0;\n for (let i = cells.length - 1; i >= 0; i--) {\n const cell = cells[i];\n const key = cell.dataset.colKey!;\n if (key === '__actions__') {\n rightAccum += cell.offsetWidth;\n } else {\n const col = columns.find((c) => c.key === key);\n if (col?.pin === 'right') {\n newOffsets.set(key, { side: 'right', offset: rightAccum });\n rightAccum += cell.offsetWidth;\n }\n }\n }\n\n setPinnedOffsets(newOffsets);\n }, [columns, selectable, draggableRows, showRowNumbers, expandable]);\n\n // ── Sticky-column helpers ──────────────────────────────────────────────────\n const getCellPinnedProps = useCallback(\n (colKey: string): { style: React.CSSProperties; className: string } => {\n const info = pinnedOffsets.get(colKey);\n if (!info) return { style: {}, className: '' };\n return {\n style: { position: 'sticky', [info.side]: info.offset, zIndex: 1 },\n className:\n info.side === 'left'\n ? 'eidos-datagrid-cell--pinned-left'\n : 'eidos-datagrid-cell--pinned-right',\n };\n },\n [pinnedOffsets],\n );\n\n const getHeaderPinnedProps = useCallback(\n (colKey: string): { style: React.CSSProperties; className: string } => {\n const info = pinnedOffsets.get(colKey);\n if (!info) return { style: {}, className: '' };\n return {\n // z-index 3: above both body sticky cells (1) and non-sticky header (1 from SCSS)\n style: { position: 'sticky', [info.side]: info.offset, zIndex: 3 },\n className:\n info.side === 'left'\n ? 'eidos-datagrid-header-cell--pinned-left'\n : 'eidos-datagrid-header-cell--pinned-right',\n };\n },\n [pinnedOffsets],\n );\n\n // ── Editing helpers (preserved exactly) ────────────────────────────────────\n const isCellEditable = useCallback(\n (col: InternalColumn<T>): boolean => {\n if (!editable) return false;\n if (col.type === 'readonly' || col.type === 'actions') return false;\n if (col.editable === false) return false;\n return true;\n },\n [editable],\n );\n\n const validateCell = useCallback((col: InternalColumn<T>, value: unknown): string | null => {\n if (col.required && (value === '' || value === null || value === undefined)) {\n return 'This field is required';\n }\n if (col.validate) {\n const result = col.validate(value);\n if (result !== true) return result as string;\n }\n return null;\n }, []);\n\n const cellErrorKey = (rowIndex: number, colKey: string) => `${rowIndex}:${colKey}`;\n\n // Cells with a validation error, keyed by `${rowIndex}:${colKey}` - derived\n // directly from the actual data rather than tracked as its own state, so a\n // cell that starts out invalid (e.g. seeded with an empty required field)\n // is flagged immediately on render instead of only after the user has\n // focused and committed it at least once. Recomputes whenever the data\n // actually changes, which already covers every case that needs it: typing\n // a fix and committing, an external `data` prop update, a row being added,\n // etc. Painted as a background tint on every render (see\n // `eidos-data-grid-cell--has-error` below); the more prominent border +\n // text (`eidos-data-grid-cell--error`) only shows while that specific cell\n // is the one being edited, via `editError` (see `startEdit`).\n const cellErrors = useMemo(() => {\n const errors: Record<string, string> = {};\n localData.forEach((row, rowIndex) => {\n for (const col of columns) {\n if (!isCellEditable(col)) continue;\n const error = validateCell(col, cellOf(row, col.key));\n if (error) errors[cellErrorKey(rowIndex, col.key)] = error;\n }\n });\n return errors;\n }, [localData, columns, isCellEditable, validateCell]);\n\n // ── Commit / discard ────────────────────────────────────────────────────────\n /**\n * Validates a cell's value and always persists it (even if invalid - see\n * `commitEdit` below for why). `cellErrors` above picks the result up\n * automatically once `localData` updates. Returns the validation error, if any.\n */\n const commitValue = useCallback(\n (rowIndex: number, colKey: string, value: unknown): string | null => {\n const col = columns.find((c) => c.key === colKey);\n if (!col) return null;\n\n const error = validateCell(col, value);\n\n const newData = localDataRef.current.map<T>((row, idx) =>\n idx === rowIndex ? ({ ...row, [colKey]: value } as T) : row,\n );\n setLocalData(newData);\n onChange?.(newData);\n\n return error;\n },\n [columns, onChange, setLocalData, validateCell],\n );\n\n /**\n * Commits the currently-editing cell and exits edit mode. Never blocks: an\n * invalid value is still saved and flagged via `cellErrors` (see above)\n * rather than trapping the user in the cell - a required field going empty\n * is exactly the case validation is there to catch and surface, not a\n * reason to freeze every other interaction with the grid until it's fixed.\n */\n const commitEdit = useCallback(() => {\n const cell = editingCellRef.current;\n if (!cell) return;\n\n const col = columns.find((c) => c.key === cell.colKey);\n if (!col) {\n setEditingCell(null);\n return;\n }\n\n commitValue(cell.rowIndex, cell.colKey, editValueRef.current);\n setEditingCell(null);\n setEditError(null);\n }, [columns, commitValue, setEditingCell]);\n\n const discardEdit = useCallback(() => {\n setEditingCell(null);\n setEditError(null);\n }, [setEditingCell]);\n\n // Keep a ref to the latest commit so the global handler never captures\n // a stale version, without having the effect re-run on every re-render.\n const commitEditRef = useRef(commitEdit);\n useEffect(() => {\n commitEditRef.current = commitEdit;\n }, [commitEdit]);\n\n // ── Global mousedown: commit on blur - i.e. any click that isn't on the\n // active editor itself ──────────────────────────────────────────────────\n // Using mousedown (fires before blur/click) lets us finalize the active\n // cell before a click elsewhere starts a new edit or does anything else.\n //\n // Deliberately NOT scoped to \"outside the grid container\" - a click on\n // another cell already commits via that cell's own `handleCellClick`\n // (which commits any in-flight edit before starting its own), but a grid\n // has plenty of space that isn't a cell at all: toolbar buttons, sort\n // headers, pagination, row actions, and - especially in card view - the\n // card's own padding, gaps, and labels. None of those have a handler that\n // commits the edit, so scoping this to \"outside the grid\" left the editor\n // stuck open for any click that landed inside the grid but outside an\n // actual cell. The only clicks that should NOT commit are ones still\n // interacting with the editor being edited (identified by its own\n // `--editing` class, shared by both the <td> and card versions) or its\n // portaled dropdown content (eidos-dropdown-content) - e.g. opening a\n // Select's own options list.\n useEffect(() => {\n if (!editingCell) return;\n\n const handleMouseDown = (e: MouseEvent) => {\n const target = e.target as Element;\n\n if (\n target.closest?.(\n '.eidos-data-grid-cell--editing, .eidos-datagrid-card-value--editing, .eidos-dropdown-content',\n )\n ) {\n return;\n }\n\n commitEditRef.current();\n };\n\n document.addEventListener('mousedown', handleMouseDown);\n return () => document.removeEventListener('mousedown', handleMouseDown);\n }, [editingCell]);\n\n // ── Start editing ────────────────────────────────────────────────────────\n const startEdit = useCallback(\n (rowIndex: number, colKey: string, currentValue: unknown) => {\n const col = columns.find((c) => c.key === colKey);\n if (!col || !isCellEditable(col)) return;\n setEditingCell({ rowIndex, colKey });\n setEditValue(currentValue);\n // Re-focusing a cell that's already flagged shows its error\n // immediately, without needing to retype/re-trigger validation first.\n setEditError(cellErrors[cellErrorKey(rowIndex, colKey)] ?? null);\n },\n [columns, isCellEditable, setEditingCell, setEditValue, cellErrors],\n );\n\n // ── Cell click handler (preserved) ─────────────────────────────────────────\n const handleCellClick = useCallback(\n (rowIndex: number, col: InternalColumn<T>) => {\n const row = localDataRef.current[rowIndex];\n const value = row === undefined ? undefined : cellOf(row, col.key);\n\n // Checkbox cells: toggle immediately - no \"edit mode\" UI needed\n if (col.type === 'checkbox') {\n if (!editable || col.editable === false) return;\n const newData = localDataRef.current.map<T>((row, idx) =>\n idx === rowIndex ? ({ ...row, [col.key]: !value } as T) : row,\n );\n setLocalData(newData);\n onChange?.(newData);\n return;\n }\n\n if (!isCellEditable(col)) return;\n\n // Already editing this exact cell - do nothing\n const cell = editingCellRef.current;\n if (cell?.rowIndex === rowIndex && cell?.colKey === col.key) return;\n\n // Commit any in-flight edit first - never blocks navigation, see commitEdit.\n if (cell) commitEdit();\n\n startEdit(rowIndex, col.key, value);\n },\n [editable, isCellEditable, commitEdit, startEdit, setLocalData, onChange],\n );\n\n // ── Keyboard navigation inside an editing cell (preserved) ─────────────────\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, rowIndex: number, colKey: string) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n discardEdit();\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n commitEdit();\n return;\n }\n\n if (e.key === 'Tab') {\n e.preventDefault();\n\n // Flat list of editable cells in DOM order (over the full dataset)\n const editableCells: Array<{ rowIndex: number; colKey: string }> = [];\n for (let ri = 0; ri < localDataRef.current.length; ri++) {\n for (const c of columns) {\n if (isCellEditable(c)) {\n editableCells.push({ rowIndex: ri, colKey: c.key });\n }\n }\n }\n\n const idx = editableCells.findIndex((c) => c.rowIndex === rowIndex && c.colKey === colKey);\n const next = e.shiftKey ? editableCells[idx - 1] : editableCells[idx + 1];\n\n // Commit the current cell - never blocks navigation, see commitEdit.\n commitValue(rowIndex, colKey, editValueRef.current);\n\n if (next) {\n setEditingCell(next);\n setEditValue(cellOf(localDataRef.current[next.rowIndex], next.colKey));\n setEditError(cellErrors[cellErrorKey(next.rowIndex, next.colKey)] ?? null);\n } else {\n setEditingCell(null);\n setEditError(null);\n }\n }\n },\n [\n columns,\n isCellEditable,\n commitEdit,\n commitValue,\n discardEdit,\n cellErrors,\n setEditingCell,\n setEditValue,\n ],\n );\n\n const handleRowAdd = useCallback(() => {\n if (!onRowAdd) return;\n const newRow = onRowAdd();\n const newData = [newRow, ...localDataRef.current];\n setLocalData(newData);\n onChange?.(newData);\n setCurrentPage(1);\n }, [onRowAdd, onChange, setLocalData]);\n\n // ── Selection handlers ──────────────────────────────────────────────────────\n const commitSelection = useCallback(\n (keys: string[]) => {\n if (!isControlledSelection) setInternalSelectedKeys(new Set(keys));\n onSelectionChange?.(keys, rowsForKeys(keys));\n },\n [isControlledSelection, onSelectionChange, rowsForKeys],\n );\n\n const toggleRow = useCallback(\n (key: string) => {\n const next = selectedSet.has(key)\n ? [...selectedSet].filter((k) => k !== key)\n : [...selectedSet, key];\n commitSelection(next);\n },\n [selectedSet, commitSelection],\n );\n\n // ── \"Select all N matching\" (see `onSelectAllMatching`) ───────────────────\n // The grid can only enumerate the keys it has been given, so selecting\n // everything behind a server-side query has to come from the caller.\n const [isSelectingAllMatching, setIsSelectingAllMatching] = useState(false);\n\n const holdsEveryRow = totalItemCount <= localData.length;\n const hasSelectedAllMatching = !holdsEveryRow && selectedSet.size >= totalItemCount;\n // Offered once everything the grid holds is selected, so the select-all\n // checkbox has nothing left to give - but not once every matching row is\n // already selected, where it would be a no-op sitting next to \"Clear\n // selection\".\n const canSelectAllMatching =\n !!onSelectAllMatching && selectable && !holdsEveryRow && allSelected && !hasSelectedAllMatching;\n\n const selectAllMatching = useCallback(async () => {\n if (!onSelectAllMatching) return;\n setIsSelectingAllMatching(true);\n try {\n // Replaces rather than merges: the caller is returning the full\n // matching set, so anything not in it is by definition not a match.\n commitSelection(await onSelectAllMatching());\n } catch (error) {\n devWarn(\n 'datagrid-select-all-matching-failed',\n `DataGrid: onSelectAllMatching() rejected, so the selection was left untouched. ${String(error)}`,\n );\n } finally {\n setIsSelectingAllMatching(false);\n }\n }, [onSelectAllMatching, commitSelection]);\n\n // Adds or removes only the keys in scope, so a selection made on another\n // page (or outside `'page'` scope) is never silently dropped by toggling\n // the select-all control.\n const toggleAll = useCallback(() => {\n const inScope = new Set(selectAllKeys);\n commitSelection(\n allSelected\n ? [...selectedSet].filter((key) => !inScope.has(key))\n : [...new Set([...selectedSet, ...selectAllKeys])],\n );\n }, [allSelected, selectAllKeys, selectedSet, commitSelection]);\n\n // Only reachable from the \"all N matching\" state below - the select-all\n // checkbox is what clears an ordinary selection.\n const clearSelection = useCallback(() => commitSelection([]), [commitSelection]);\n\n // ── Row expansion handlers ───────────────────────────────────────────────────\n const commitExpanded = useCallback(\n (keys: string[]) => {\n if (!isControlledExpansion) setInternalExpandedKeys(new Set(keys));\n onExpandedRowsChange?.(keys);\n },\n [isControlledExpansion, onExpandedRowsChange],\n );\n\n const toggleExpanded = useCallback(\n (key: string) => {\n const isOpen = expandedSet.has(key);\n const next = expandMultiple\n ? isOpen\n ? [...expandedSet].filter((k) => k !== key)\n : [...expandedSet, key]\n : isOpen\n ? []\n : [key];\n commitExpanded(next);\n },\n [expandedSet, expandMultiple, commitExpanded],\n );\n\n // ── Sort handler ────────────────────────────────────────────────────────────\n const handleSortClick = useCallback(\n (colKey: string) => {\n if (onSortChange) {\n // Server-side: delegate to parent\n const newDir =\n currentSort?.key === colKey && currentSort?.direction === 'asc' ? 'desc' : 'asc';\n // `colKey` came from a rendered column, so it is a field of `T` by\n // construction - the public callback is narrowed for the caller's\n // benefit, which this internal string can't prove on its own.\n onSortChange(colKey as RowKey<T>, newDir);\n } else {\n // Client-side: cycle asc → desc → unsorted (null)\n setInternalSort((prev) => {\n if (prev?.key === colKey) {\n return prev.direction === 'asc' ? { key: colKey, direction: 'desc' } : null;\n }\n return { key: colKey, direction: 'asc' };\n });\n }\n },\n [onSortChange, currentSort],\n );\n\n // ── Filter handlers ──────────────────────────────────────────────────────────\n const commitFilters = useCallback(\n (newFilters: TableFilters) => {\n setCurrentPage(1);\n if (onFiltersChange) {\n onFiltersChange(newFilters);\n } else {\n setInternalFilters(newFilters);\n }\n },\n [onFiltersChange],\n );\n\n // The dropdown's writer. It emits its complete cleaned set, covering only\n // the keys it owns, so everything else in the filter state - quick filters\n // included - has to be merged back in rather than replaced. This is also\n // what makes its \"Clear All\" clear only the dropdown's own filters.\n const handleFiltersChange = useCallback(\n (newFilters: TableFilters) => {\n const preserved = Object.entries(activeFilters).filter(\n ([key]) => !dropdownFilterKeys.has(key),\n );\n commitFilters({ ...Object.fromEntries(preserved), ...newFilters });\n },\n [activeFilters, dropdownFilterKeys, commitFilters],\n );\n\n // A quick filter's writer. Empty values delete the key instead of storing\n // '' / [] - see `hasFilterValue`.\n const handleQuickFilterChange = useCallback(\n (key: string, value: FilterValue) => {\n const next = { ...activeFilters };\n if (hasFilterValue(value)) {\n next[key] = value;\n } else {\n delete next[key];\n }\n commitFilters(next);\n },\n [activeFilters, commitFilters],\n );\n\n // Resets every filter, whichever control owns it - what the \"no results\"\n // empty state offers, unlike the dropdown's own scoped \"Clear All\".\n const clearAllFilters = useCallback(() => commitFilters({}), [commitFilters]);\n\n // ── Page handlers ────────────────────────────────────────────────────────────\n const handlePageChange = useCallback(\n (page: number) => {\n setCurrentPage(page);\n onPageChange?.(page, currentPageSize);\n },\n [currentPageSize, onPageChange],\n );\n\n const handlePageSizeChange = useCallback(\n (newPageSize: number) => {\n setCurrentPageSize(newPageSize);\n setCurrentPage(1);\n onPageChange?.(1, newPageSize);\n },\n [onPageChange],\n );\n\n // ── dnd-kit: sensors + drag-end handler (preserved) ───────────────────────\n // Sensors are always initialised (hook rules) - PointerSensor's distance\n // constraint prevents accidental drags on normal cell clicks.\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),\n useSensor(KeyboardSensor),\n );\n\n const handleRowDragEnd = useCallback(\n (event: DragEndEvent) => {\n if (!draggableRows) return; // belt-and-suspenders\n const { active, over } = event;\n if (!over || active.id === over.id) return;\n\n const oldIndex = localDataRef.current.findIndex(\n (row, i) => String(cellOf(row, rowKeyField) ?? i) === String(active.id),\n );\n const newIndex = localDataRef.current.findIndex(\n (row, i) => String(cellOf(row, rowKeyField) ?? i) === String(over.id),\n );\n\n if (oldIndex === -1 || newIndex === -1) return;\n\n const newData = arrayMove(localDataRef.current, oldIndex, newIndex);\n setLocalData(newData);\n onChange?.(newData);\n onRowReorder?.(newData);\n },\n [draggableRows, rowKeyField, setLocalData, onChange, onRowReorder],\n );\n\n // ── Cell content renderers (preserved exactly) ─────────────────────────────\n const renderViewCell = (\n col: InternalColumn<T>,\n value: unknown,\n row: T,\n rowIndex: number,\n ): React.ReactNode => {\n if (col.renderCell) return col.renderCell(value, row, rowIndex);\n\n switch (col.type) {\n case 'checkbox':\n // The <td> onClick handles toggling; onChange is a no-op here so that\n // the controlled Checkbox doesn't re-toggle via its own handler.\n return (\n <Checkbox\n checked={Boolean(value)}\n onChange={() => {\n /* handled by td onClick */\n }}\n size=\"sm\"\n />\n );\n\n case 'select': {\n const option = col.options?.find((o) => o.value === String(value ?? ''));\n return <span>{option ? option.label : String(value ?? '')}</span>;\n }\n\n case 'readonly':\n case 'text':\n case 'number':\n case 'date':\n default:\n return <span>{String(value ?? '')}</span>;\n }\n };\n\n // `variant`/`size` default to the table cell's look: 'bare' has no border/\n // background/radius of its own so the surrounding <td>'s own inset ring\n // (`.eidos-data-grid-cell--editing`) reads as the field's border, and\n // 'sm' keeps the editor from growing the row's height. A card field isn't\n // sitting inside that ring - it's a standalone field in a stack, so it\n // should just look like any other standalone Input/Select in the design\n // system (their own component defaults), not the table's cell-shaped\n // variant. Passing `undefined` here (rather than omitting the prop) is\n // equivalent to omitting it - falls back to each component's own default.\n const renderEditCell = (\n col: InternalColumn<T>,\n value: unknown,\n row: T,\n rowIndex: number,\n context: 'table' | 'card' = 'table',\n ): React.ReactNode => {\n if (col.renderEditor) {\n return col.renderEditor(value, (v) => setEditValue(v), row);\n }\n\n const variant = context === 'table' ? 'bare' : undefined;\n const size = context === 'table' ? 'sm' : undefined;\n\n switch (col.type) {\n case 'number':\n return (\n <Input\n type=\"number\"\n variant={variant}\n size={size}\n value={String(value ?? '')}\n onChange={(e) => setEditValue(e.target.value)}\n autoFocus\n fullWidth\n clearable={false}\n />\n );\n\n case 'date':\n return (\n <Input\n type=\"date\"\n variant={variant}\n size={size}\n value={String(value ?? '')}\n onChange={(e) => setEditValue(e.target.value)}\n autoFocus\n fullWidth\n clearable={false}\n />\n );\n\n case 'select': {\n // Auto-commit as soon as the user picks an option; the Dropdown's portal\n // means we can't rely on a simple onBlur for this cell type.\n // autoOpen=true so the dropdown opens on the same click that entered\n // edit mode - no second click needed.\n const selectOptions = (col.options ?? []).map((o) => ({\n id: o.value,\n value: o.value,\n label: o.label,\n }));\n\n return (\n <Select\n options={selectOptions}\n value={String(value ?? '')}\n autoOpen\n fullWidth\n inputProps={{ variant, size }}\n onChange={(v) => {\n const selected = Array.isArray(v) ? (v[0] ?? '') : v;\n const newData = localDataRef.current.map<T>((r, i) =>\n i === rowIndex ? ({ ...r, [col.key]: selected } as T) : r,\n );\n setLocalData(newData);\n onChange?.(newData);\n setEditingCell(null);\n }}\n clearable={false}\n />\n );\n }\n\n default:\n return (\n <Input\n type=\"text\"\n variant={variant}\n size={size}\n value={String(value ?? '')}\n onChange={(e) => setEditValue(e.target.value)}\n autoFocus\n fullWidth\n clearable={false}\n />\n );\n }\n };\n\n // ── Card view cell value ─────────────────────────────────────────────────\n // Mirrors the <td> cell's click/edit/error-state wiring in `renderViewCell`/\n // `renderEditCell` above, just wrapped in a plain <div> so it can sit\n // either in a card's label:value field row or its header/subheader - both\n // stay just as editable as any table cell.\n const renderCardValue = (\n col: InternalColumn<T>,\n row: T,\n localIndex: number,\n baseClassName: string,\n ): React.ReactNode => {\n const value = cellOf(row, col.key);\n const isEditing = editingCell?.rowIndex === localIndex && editingCell?.colKey === col.key;\n const canEdit = isCellEditable(col);\n const isFlagged = cellErrorKey(localIndex, col.key) in cellErrors;\n const hasError = isEditing && Boolean(editError);\n\n const valueCls = [\n baseClassName,\n // Deliberately NOT `eidos-data-grid-cell--editing` (unlike the <td>\n // version of this same state) - that class's whole job is forcing the\n // editor into `position: absolute; inset: 0` so it fills a <td>\n // without changing the table row's height. A card field has no row\n // to preserve the height of, so it just needs its own \"is editing\"\n // hook for spacing - the editor itself renders normally, with each\n // component's own default (non-`bare`) look (see `renderEditCell`).\n isEditing && 'eidos-datagrid-card-value--editing',\n hasError && 'eidos-data-grid-cell--error',\n isFlagged && !hasError && 'eidos-data-grid-cell--has-error',\n canEdit && !isEditing && 'eidos-data-grid-cell--editable',\n col.type === 'readonly' && 'eidos-data-grid-cell--readonly',\n // Checkbox glyph is intrinsically narrow - without this the value\n // wrapper stretches to the card's full width (block layout), making\n // the whole row clickable/toggleable instead of just the checkbox.\n col.type === 'checkbox' && 'eidos-datagrid-card-value--checkbox',\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div\n ref={\n hasError ? (errorTooltipAnchorRef as React.RefObject<HTMLDivElement | null>) : undefined\n }\n className={valueCls}\n onClick={() => handleCellClick(localIndex, col)}\n onKeyDown={isEditing ? (e) => handleKeyDown(e, localIndex, col.key) : undefined}\n tabIndex={isEditing ? -1 : undefined}\n >\n {isEditing\n ? renderEditCell(col, editValue, row, localIndex, 'card')\n : renderViewCell(col, value, row, localIndex)}\n </div>\n );\n };\n\n // Label-above-value field, stacked - used for every column that isn't the\n // card's header/subheader.\n const renderCardField = (col: InternalColumn<T>, row: T, localIndex: number): React.ReactNode => (\n <div key={col.key} className=\"eidos-datagrid-card-field\">\n <span className=\"eidos-datagrid-card-field-label\">{col.header}</span>\n {renderCardValue(col, row, localIndex, 'eidos-datagrid-card-field-value')}\n </div>\n );\n\n // ── Row-actions menu (type: 'actions' column) ──────────────────────────────\n // Shared between the table's dedicated actions <td> and the card's\n // top-right toolbar slot - see `actionsColumn`/`DataGridColumn.actions`.\n // Renders nothing if there's no actions column, or it has no actions.\n const renderActionsMenu = (row: T, localIndex: number): React.ReactNode => {\n if (!actionsColumn) return null;\n\n const items: MenuItemType[] = actionsColumn.renderActions\n ? actionsColumn.renderActions(row, localIndex)\n : (actionsColumn.actions ?? []).flatMap((action, index) => {\n const id = action.id ?? `${action.label}-${index}`;\n const isDisabled =\n typeof action.disabled === 'function' ? action.disabled(row) : Boolean(action.disabled);\n\n const item: MenuItemType = {\n id,\n type: 'item',\n label: action.label,\n icon: action.icon,\n disabled: isDisabled,\n color: action.danger ? 'danger' : undefined,\n onClick: () => action.onClick(row, localIndex),\n };\n\n return action.divider\n ? [{ id: `${id}-divider`, type: 'separator' as const }, item]\n : [item];\n });\n\n if (!items.length) return null;\n\n return (\n <Menu\n trigger={\n <button type=\"button\" className=\"eidos-datagrid-actions-trigger\" aria-label=\"Row actions\">\n {actionsColumn.actionsIcon ? (\n renderIcon(actionsColumn.actionsIcon, 'eidos-datagrid-actions-trigger-icon')\n ) : (\n <MoreVertical size={16} />\n )}\n </button>\n }\n items={items}\n />\n );\n };\n\n // Columns sorted for rendering: pin:left → unpinned → pin:right. Excludes\n // the actions column (see `dataColumns`) - it's never a normal, sortable/\n // pinnable data column, always rendered in its own dedicated slot instead.\n // This ensures a pinned column defined in the middle of the columns array\n // is always displayed at the correct edge regardless of its original position.\n // The original `columns` prop is still used for key-based lookups above.\n const sortedColumns = useMemo(\n () => [\n ...dataColumns.filter((c) => c.pin === 'left'),\n ...dataColumns.filter((c) => !c.pin),\n ...dataColumns.filter((c) => c.pin === 'right'),\n ],\n [dataColumns],\n );\n\n const totalCols =\n dataColumns.length +\n (showRowNumbers ? 1 : 0) +\n (actionsColumn ? 1 : 0) +\n (draggableRows ? 1 : 0) +\n (selectable ? 1 : 0) +\n (expandable ? 1 : 0);\n\n // Row IDs for SortableContext - must be the displayed rows (not full dataset)\n // so dnd-kit knows which items are currently rendered.\n const rowIds = displayData.map((row, i) => String(cellOf(row, rowKeyField) ?? i));\n\n const containerStyle: React.CSSProperties = {};\n if (stickyHeader && maxHeight) {\n containerStyle.maxHeight = typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight;\n }\n\n // Toolbar visibility: show whenever filters, quick filters, density picker,\n // selectable, or add-row are active.\n const showToolbar =\n !!showFilters || quickFilters.length > 0 || !!showDensity || !!selectable || !!onRowAdd;\n\n // Quick filters share the toolbar's left zone with the selection count and\n // bulk actions, which take it over entirely while rows are selected.\n const showQuickFilters = quickFilters.length > 0 && !(selectable && hasSelection);\n\n const renderQuickFilter = (quickFilter: DataGridQuickFilter): React.ReactElement => {\n const { key, label, disabled, width } = quickFilter;\n const value = activeFilters[key];\n // Only set inline when supplied - the default lives in the stylesheet, so\n // the common case emits no style attribute at all.\n const style =\n width === undefined\n ? undefined\n : ({\n '--eidos-datagrid-quick-filter-width': typeof width === 'number' ? `${width}px` : width,\n } as React.CSSProperties);\n\n const control = (() => {\n switch (quickFilter.type) {\n case 'segmented':\n return (\n <SegmentedControl\n size=\"sm\"\n color={quickFilter.color}\n disabled={disabled}\n // Select/Combobox are already `fullWidth` and just fill their\n // box; a SegmentedControl sizes itself to its segments, so it\n // needs telling to fill the row once quick filters stack.\n fullWidth={isCompactToolbar}\n // The reset segment is always prepended: a SegmentedControl\n // always has exactly one segment selected, so without it the\n // filter could never be cleared.\n options={[\n { value: QUICK_FILTER_RESET_VALUE, label: quickFilter.allLabel ?? 'All' },\n ...quickFilter.options,\n ]}\n value={typeof value === 'string' ? value : QUICK_FILTER_RESET_VALUE}\n onChange={(next) => handleQuickFilterChange(key, next)}\n />\n );\n case 'combobox':\n return (\n <Combobox\n size=\"sm\"\n fullWidth\n disabled={disabled}\n placeholder={quickFilter.placeholder ?? label}\n clearable={quickFilter.clearable ?? true}\n emptyText={quickFilter.emptyText}\n loading={quickFilter.loading}\n loadingText={quickFilter.loadingText}\n onSearch={quickFilter.onSearch}\n options={(quickFilter.options ?? []).map((option) => ({\n ...option,\n id: option.value,\n }))}\n value={typeof value === 'string' ? value : ''}\n onChange={(next) => handleQuickFilterChange(key, next)}\n />\n );\n case 'select':\n default:\n return (\n <Select\n fullWidth\n inputProps={{ size: 'sm' }}\n disabled={disabled}\n placeholder={quickFilter.placeholder ?? label}\n clearable={quickFilter.clearable ?? true}\n multiple={quickFilter.multiple}\n options={quickFilter.options.map((option) => ({ ...option, id: option.value }))}\n // Never `undefined` - Select and Combobox both treat that as\n // \"uncontrolled\" and would then keep showing a value the\n // filter state no longer holds after a clear.\n value={\n quickFilter.multiple\n ? Array.isArray(value)\n ? value\n : []\n : typeof value === 'string'\n ? value\n : ''\n }\n onChange={(next) => handleQuickFilterChange(key, next)}\n />\n );\n }\n })();\n\n return (\n <div\n key={key}\n className={`eidos-datagrid-quick-filter eidos-datagrid-quick-filter--${quickFilter.type}`}\n style={style}\n // No visible field label fits in the toolbar, so the group carries the\n // accessible name for whichever control it wraps.\n role=\"group\"\n aria-label={label}\n >\n {control}\n </div>\n );\n };\n\n // Density modifier class (comfortable = default = no extra class)\n const densityClass =\n effectiveDensity !== 'comfortable' ? `eidos-datagrid--${effectiveDensity}` : '';\n\n // Always include the current page size in the options so the Select is never blank.\n const effectivePageSizeOptions = useMemo(() => {\n const opts = pageSizeOptions ?? [10, 25, 50, 100];\n return opts.includes(pageSize) ? opts : [...opts, pageSize].sort((a, b) => a - b);\n }, [pageSizeOptions, pageSize]);\n\n // ── Loading state (preserved) ───────────────────────────────────────────────\n // `ref={setContainerRef}` here too (not just the main return below) - a\n // consumer whose `loading` prop starts `true` on mount renders this\n // branch first, and without it `hasCardView` would never get a container\n // to measure until some unrelated re-render happened to remount it - see\n // `setContainerRef`'s comment above for the full explanation.\n if (loading) {\n return (\n <div\n ref={setContainerRef}\n className={['eidos-data-grid-container', className].filter(Boolean).join(' ')}\n >\n <div className=\"eidos-data-grid-loading\">\n <Spinner size=\"md\" />\n <p>Loading…</p>\n </div>\n </div>\n );\n }\n\n // ── Render ─────────────────────────────────────────────────────────────────\n // Pre-compute sticky props for system columns so we can spread them on\n // header <th>s and body <td>s without calling the helpers multiple times.\n const expandHeaderPin = getHeaderPinnedProps('__expand__');\n const selHeaderPin = getHeaderPinnedProps('__sel__');\n const dragHeaderPin = getHeaderPinnedProps('__drag__');\n const rownumHeaderPin = getHeaderPinnedProps('__rownum__');\n const expandCellPin = getCellPinnedProps('__expand__');\n const selCellPin = getCellPinnedProps('__sel__');\n const dragCellPin = getCellPinnedProps('__drag__');\n const rownumCellPin = getCellPinnedProps('__rownum__');\n\n return (\n <div\n ref={setContainerRef}\n className={[\n 'eidos-data-grid-container',\n stickyHeader && 'eidos-data-grid-container--sticky-header',\n densityClass,\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={containerStyle}\n >\n {/* ── Toolbar ─────────────────────────────────────────────────────── */}\n {showToolbar && (\n <div className=\"eidos-datagrid-toolbar\">\n {/* Left zone: quick filters, or selection count + bulk actions */}\n <div className=\"eidos-datagrid-toolbar-left\">\n {/* Card view's stand-in for the header checkbox, which doesn't\n exist without a header row. Also the way out of selection mode\n there: clicking it while checked clears the selection, exactly\n as the header checkbox does in table mode. */}\n {selectable && isCardView && (\n <Checkbox\n size=\"sm\"\n checked={allSelected}\n indeterminate={someSelected}\n onChange={toggleAll}\n // Labelled even in the compact toolbar, unlike the buttons\n // beside it: those keep a recognisable icon, whereas a bare\n // checkbox floating in a toolbar says nothing about what it\n // selects - and a tooltip is no help on touch.\n label=\"Select all\"\n aria-label=\"Select all rows\"\n />\n )}\n\n {showQuickFilters && (\n <div\n className={[\n 'eidos-datagrid-quick-filters',\n isCompactToolbar && 'eidos-datagrid-quick-filters--compact',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {quickFilters.map(renderQuickFilter)}\n </div>\n )}\n\n {selectable && hasSelection && (\n <>\n <span className=\"eidos-datagrid-selection-count\">{selectedSet.size} selected</span>\n\n {/* The select-all checkbox can only reach the loaded rows, so\n reaching past them is an explicit action - and undoing it\n has to be explicit too: with more rows selected than the\n checkbox's own scope, toggling it would strip the page and\n leave the rest selected, which reads as a no-op. */}\n {canSelectAllMatching && (\n <Button\n variant=\"text\"\n size=\"sm\"\n loading={isSelectingAllMatching}\n onClick={() => void selectAllMatching()}\n >\n {`Select all ${totalItemCount}`}\n </Button>\n )}\n\n {hasSelectedAllMatching && (\n <Button variant=\"text\" size=\"sm\" color=\"secondary\" onClick={clearSelection}>\n Clear selection\n </Button>\n )}\n\n {bulkActions && bulkActions.length > 0 && (\n <div className=\"eidos-datagrid-bulk-actions\">\n {bulkActions.map((action) => {\n const isDisabled =\n typeof action.disabled === 'function'\n ? action.disabled(selectedItems)\n : (action.disabled ?? false);\n\n if (action.type === 'split-button') {\n return (\n <SplitButton\n key={action.id}\n size=\"sm\"\n variant={action.variant ?? 'outlined'}\n color={action.color ?? 'secondary'}\n preIcon={action.icon}\n disabled={isDisabled}\n label={action.label}\n onClick={() => action.onClick(selectedItems)}\n options={action.options.map((option) => ({\n id: option.id,\n label: option.label,\n icon: option.icon,\n disabled: option.disabled,\n onClick: () => option.onClick(selectedItems),\n }))}\n />\n );\n }\n\n return action.label ? (\n <Button\n key={action.id}\n size=\"sm\"\n variant={action.variant ?? 'outlined'}\n color={action.color ?? 'secondary'}\n preIcon={action.icon}\n posIcon={action.posIcon}\n disabled={isDisabled}\n onClick={() => action.onClick(selectedItems)}\n >\n {action.label}\n </Button>\n ) : action.icon ? (\n <Button\n key={action.id}\n size=\"sm\"\n variant={action.variant ?? 'outlined'}\n color={action.color ?? 'secondary'}\n icon={action.icon}\n disabled={isDisabled}\n onClick={() => action.onClick(selectedItems)}\n />\n ) : null;\n })}\n </div>\n )}\n </>\n )}\n </div>\n\n {/* Right zone: density picker + filter button + add-row button */}\n <div className=\"eidos-datagrid-toolbar-right\">\n {/* Icon-only below `COMPACT_TOOLBAR_WIDTH_PX`, with the label moved\n into a tooltip so the control stays identifiable. */}\n {showDensity && (\n <Dropdown\n placement=\"bottom\"\n align=\"end\"\n autoWidth={false}\n trigger={\n isCompactToolbar ? (\n <Button variant=\"text\" size=\"sm\" icon={AlignJustify} tooltip=\"Density\" />\n ) : (\n <Button variant=\"text\" size=\"sm\" preIcon={AlignJustify}>\n Density\n </Button>\n )\n }\n content={\n <div className=\"eidos-table-menu-panel\">\n {(\n [\n { value: 'compact', label: 'Compact' },\n { value: 'comfortable', label: 'Comfortable' },\n { value: 'spacious', label: 'Spacious' },\n ] as const\n ).map((option) => (\n <button\n key={option.value}\n className={[\n 'eidos-table-menu-item',\n effectiveDensity === option.value ? 'eidos-table-menu-item--active' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={() => setInternalDensity(option.value)}\n >\n <span className=\"eidos-table-menu-item-check\">\n {effectiveDensity === option.value && <Check size={14} />}\n </span>\n <span>{option.label}</span>\n </button>\n ))}\n </div>\n }\n />\n )}\n\n {showFilters && filterDropdownColumns.length > 0 && (\n <TableFiltersDropdown<T>\n columns={filterDropdownColumns}\n filters={dropdownFilters}\n onFiltersChange={handleFiltersChange}\n />\n )}\n\n {onRowAdd &&\n (isCompactToolbar ? (\n <Button\n variant=\"outlined\"\n size=\"sm\"\n icon={Plus}\n tooltip=\"Add row\"\n onClick={handleRowAdd}\n />\n ) : (\n <Button variant=\"outlined\" size=\"sm\" preIcon={Plus} onClick={handleRowAdd}>\n Add row\n </Button>\n ))}\n </div>\n </div>\n )}\n\n {isCardView ? (\n /* ── Card view ────────────────────────────────────────────────── */\n <div\n className=\"eidos-datagrid-cards\"\n style={{ '--eidos-datagrid-card-min-width': `${cardMinWidth}px` } as React.CSSProperties}\n >\n {displayData.length > 0 ? (\n displayData.map((row, displayIndex) => {\n const localIndex = localData.indexOf(row);\n const rowKeyValue = String(cellOf(row, rowKeyField) ?? displayIndex);\n const isRowSelected = selectable && selectedSet.has(rowKeyValue);\n const isRowExpanded = expandable && expandedSet.has(rowKeyValue);\n const canExpandRow = !isRowExpandable || isRowExpandable(row);\n\n return (\n <div\n key={rowKeyValue}\n className={[\n 'eidos-datagrid-card',\n isRowSelected && 'eidos-datagrid-card--selected',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {/* stopPropagation so the checkbox/actions menu never bubble\n into a consumer's own row-click handler (e.g. opening a\n details drawer) - mirrors the selection/drag-handle <td>s'\n own `onClick={(e) => e.stopPropagation()}` in table mode. */}\n {hasCardToolbar && (\n <div\n className=\"eidos-datagrid-card-toolbar\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"eidos-datagrid-card-toolbar-left\">\n {expandable && canExpandRow && (\n <button\n type=\"button\"\n className={[\n 'eidos-datagrid-expand-toggle',\n isRowExpanded && 'eidos-datagrid-expand-toggle--open',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={() => toggleExpanded(rowKeyValue)}\n aria-expanded={isRowExpanded}\n aria-label={isRowExpanded ? 'Collapse row' : 'Expand row'}\n >\n <ChevronRight size={14} />\n </button>\n )}\n {selectable && (\n <Checkbox\n checked={isRowSelected}\n onChange={() => toggleRow(rowKeyValue)}\n size=\"sm\"\n />\n )}\n {showRowNumbers && (\n <span className=\"eidos-datagrid-card-row-number\">#{localIndex + 1}</span>\n )}\n </div>\n\n {/* Always rendered (even empty) so it occupies the toolbar's\n middle grid column - conditionally omitting the element\n itself would shift `eidos-datagrid-card-toolbar-right`\n into this column instead of the third one. */}\n <div className=\"eidos-datagrid-card-heading\">\n {cardHeaderColumn &&\n renderCardValue(\n cardHeaderColumn,\n row,\n localIndex,\n 'eidos-datagrid-card-heading-title',\n )}\n {cardSubheaderColumn &&\n renderCardValue(\n cardSubheaderColumn,\n row,\n localIndex,\n 'eidos-datagrid-card-heading-subtitle',\n )}\n </div>\n\n <div className=\"eidos-datagrid-card-toolbar-right\">\n {renderActionsMenu(row, localIndex)}\n </div>\n </div>\n )}\n\n <div className=\"eidos-datagrid-card-fields\">\n {cardFieldColumns.map((col) => renderCardField(col, row, localIndex))}\n </div>\n\n {expandable && renderExpandedContent && (\n <ExpandedCardPanel\n isOpen={isRowExpanded}\n render={() => renderExpandedContent(row, localIndex)}\n />\n )}\n </div>\n );\n })\n ) : (\n <div className=\"eidos-datagrid-card-empty\">\n {Object.keys(activeFilters).length > 0 ? (\n <EmptyState\n icon={<SearchX />}\n title=\"No results found\"\n description=\"Try adjusting your filters or search terms.\"\n action={\n <Button size=\"sm\" variant=\"outlined\" color=\"primary\" onClick={clearAllFilters}>\n Clear filters\n </Button>\n }\n size=\"sm\"\n />\n ) : (\n <EmptyState\n icon={<FolderOpen />}\n title={emptyText}\n description={\n onRowAdd ? 'Add a row to get started.' : 'There are no records to display.'\n }\n size=\"sm\"\n />\n )}\n </div>\n )}\n </div>\n ) : (\n <>\n {/* ── Table (wrapped for horizontal scroll) ───────────────────────── */}\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleRowDragEnd}\n >\n <div className=\"eidos-data-grid-scroll\">\n <table className={['eidos-data-grid', densityClass].filter(Boolean).join(' ')}>\n <thead ref={theadRef}>\n <tr>\n {/* Drag-handle column - must come before every other system column */}\n {draggableRows && (\n <th\n className={[\n 'eidos-data-grid-header-cell',\n 'eidos-datagrid-drag-handle-cell',\n dragHeaderPin.className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={dragHeaderPin.style}\n data-col-key=\"__drag__\"\n />\n )}\n\n {/* Expand-toggle column */}\n {expandable && (\n <th\n className={[\n 'eidos-data-grid-header-cell',\n 'eidos-datagrid-expand-cell',\n expandHeaderPin.className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={expandHeaderPin.style}\n data-col-key=\"__expand__\"\n />\n )}\n\n {/* Selection checkbox column - must come before row numbers */}\n {selectable && (\n <th\n className={[\n 'eidos-data-grid-header-cell',\n 'eidos-datagrid-checkbox-cell',\n selHeaderPin.className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={selHeaderPin.style}\n data-col-key=\"__sel__\"\n >\n <Checkbox\n checked={allSelected}\n indeterminate={someSelected}\n onChange={toggleAll}\n size=\"sm\"\n />\n </th>\n )}\n\n {showRowNumbers && (\n <th\n className={[\n 'eidos-data-grid-header-cell',\n 'eidos-data-grid-row-number-col',\n rownumHeaderPin.className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={rownumHeaderPin.style}\n data-col-key=\"__rownum__\"\n >\n #\n </th>\n )}\n\n {sortedColumns.map((col) => {\n const colKey = col.key;\n const isSortable = !!col.sortable;\n const isCurrentlySorted = activeSort?.key === colKey;\n const sortDir = isCurrentlySorted ? activeSort!.direction : null;\n const alignClass = `eidos-datagrid-align-${col.align ?? 'left'}`;\n const { style: pinnedStyle, className: pinnedClass } =\n getHeaderPinnedProps(colKey);\n\n return (\n <th\n key={colKey}\n className={[\n 'eidos-data-grid-header-cell',\n isSortable && 'eidos-datagrid-header-cell--sortable',\n isCurrentlySorted && 'eidos-datagrid-header-cell--sorted',\n alignClass,\n pinnedClass,\n ]\n .filter(Boolean)\n .join(' ')}\n style={{\n width:\n col.width != null\n ? typeof col.width === 'number'\n ? `${col.width}px`\n : col.width\n : undefined,\n minWidth:\n col.minWidth != null\n ? typeof col.minWidth === 'number'\n ? `${col.minWidth}px`\n : col.minWidth\n : undefined,\n ...pinnedStyle,\n }}\n data-col-key={colKey}\n onClick={isSortable ? () => handleSortClick(colKey) : undefined}\n >\n <div className={`eidos-datagrid-header-content ${alignClass}`}>\n <span className=\"eidos-datagrid-header-label\">{col.header}</span>\n {isSortable && (\n <span className=\"eidos-datagrid-sort-icon\">\n {sortDir === 'asc' && <ArrowUp size={14} />}\n {sortDir === 'desc' && <ArrowDown size={14} />}\n {!sortDir && <ChevronsUpDown size={14} />}\n </span>\n )}\n </div>\n </th>\n );\n })}\n\n {actionsColumn && (\n <th\n className=\"eidos-data-grid-header-cell eidos-data-grid-actions-col\"\n data-col-key=\"__actions__\"\n />\n )}\n </tr>\n </thead>\n\n <tbody>\n <SortableContext items={rowIds} strategy={verticalListSortingStrategy}>\n {displayData.length > 0 ? (\n displayData.map((row, displayIndex) => {\n // Find this row's position in the full localData array.\n // displayData rows are the same object references as in localData\n // (filter/sort/slice never clone row objects), so indexOf is O(n)\n // but always accurate - even after edits that produce new row objects.\n const localIndex = localData.indexOf(row);\n const rowKeyValue = String(cellOf(row, rowKeyField) ?? displayIndex);\n const isRowSelected = selectable && selectedSet.has(rowKeyValue);\n const isRowExpanded = expandable && expandedSet.has(rowKeyValue);\n const canExpandRow = !isRowExpandable || isRowExpandable(row);\n\n return (\n // React.Fragment (rather than SortableTableRow taking the\n // `key` directly) so an expanded row's detail <tr> - see\n // ExpandedTableRow below - can sit right underneath it as\n // a sibling, keyed together as one reconciliation unit.\n <React.Fragment key={rowKeyValue}>\n {/* SortableTableRow is always rendered (hooks unconditional);\n disabled={true} when draggableRows is off so dnd-kit is a no-op. */}\n <SortableTableRow\n id={rowKeyValue}\n disabled={!draggableRows}\n className={[\n 'eidos-data-grid-row',\n isRowSelected && 'eidos-datagrid-row--selected',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {(dragHandleProps, isDragging) => (\n <>\n {draggableRows && (\n <td\n className={[\n 'eidos-datagrid-drag-handle-cell',\n dragCellPin.className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={dragCellPin.style}\n // Prevent a click on the handle from triggering cell editing\n onClick={(e) => e.stopPropagation()}\n >\n <span\n {...(dragHandleProps as React.HTMLAttributes<HTMLSpanElement>)}\n className={[\n 'eidos-datagrid-drag-handle',\n isDragging && 'eidos-datagrid-drag-handle--dragging',\n ]\n .filter(Boolean)\n .join(' ')}\n title=\"Drag to reorder\"\n >\n <GripVertical size={14} />\n </span>\n </td>\n )}\n\n {expandable && (\n <td\n className={[\n 'eidos-data-grid-cell',\n 'eidos-datagrid-expand-cell',\n expandCellPin.className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={expandCellPin.style}\n // Prevent a click on the toggle from triggering cell editing\n onClick={(e) => e.stopPropagation()}\n >\n {canExpandRow && (\n <button\n type=\"button\"\n className={[\n 'eidos-datagrid-expand-toggle',\n isRowExpanded && 'eidos-datagrid-expand-toggle--open',\n ]\n .filter(Boolean)\n .join(' ')}\n onClick={() => toggleExpanded(rowKeyValue)}\n aria-expanded={isRowExpanded}\n aria-label={isRowExpanded ? 'Collapse row' : 'Expand row'}\n >\n <ChevronRight size={14} />\n </button>\n )}\n </td>\n )}\n\n {selectable && (\n <td\n className={[\n 'eidos-data-grid-cell',\n 'eidos-datagrid-checkbox-cell',\n selCellPin.className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={selCellPin.style}\n onClick={(e) => e.stopPropagation()}\n >\n <Checkbox\n checked={isRowSelected}\n onChange={() => toggleRow(rowKeyValue)}\n size=\"sm\"\n />\n </td>\n )}\n\n {showRowNumbers && (\n <td\n className={[\n 'eidos-data-grid-cell',\n 'eidos-data-grid-row-number',\n rownumCellPin.className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={rownumCellPin.style}\n >\n {localIndex + 1}\n </td>\n )}\n\n {sortedColumns.map((col) => {\n const value = cellOf(row, col.key);\n const isEditing =\n editingCell?.rowIndex === localIndex &&\n editingCell?.colKey === col.key;\n const canEdit = isCellEditable(col);\n // Persists for a cell regardless of focus (background tint only);\n // the border + message only show once this exact cell is\n // focused again, via `hasError` below.\n const isFlagged =\n cellErrorKey(localIndex, col.key) in cellErrors;\n const hasError = isEditing && Boolean(editError);\n const { style: pinnedStyle, className: pinnedClass } =\n getCellPinnedProps(col.key);\n\n const cellCls = [\n 'eidos-data-grid-cell',\n isEditing && 'eidos-data-grid-cell--editing',\n hasError && 'eidos-data-grid-cell--error',\n isFlagged && !hasError && 'eidos-data-grid-cell--has-error',\n canEdit && !isEditing && 'eidos-data-grid-cell--editable',\n col.type === 'readonly' && 'eidos-data-grid-cell--readonly',\n `eidos-datagrid-align-${col.align ?? 'left'}`,\n pinnedClass,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <td\n key={col.key}\n ref={\n hasError\n ? (errorTooltipAnchorRef as React.RefObject<HTMLTableDataCellElement | null>)\n : undefined\n }\n className={cellCls}\n style={pinnedStyle}\n onClick={() => handleCellClick(localIndex, col)}\n onKeyDown={\n isEditing\n ? (e) => handleKeyDown(e, localIndex, col.key)\n : undefined\n }\n // Make editing cells focusable so keydown events register\n tabIndex={isEditing ? -1 : undefined}\n >\n {isEditing\n ? renderEditCell(col, editValue, row, localIndex)\n : renderViewCell(col, value, row, localIndex)}\n </td>\n );\n })}\n\n {actionsColumn && (\n <td\n className=\"eidos-data-grid-cell eidos-data-grid-actions-col\"\n // Prevent a click on the actions menu from bubbling into a\n // consumer's own row-click handler (e.g. opening a details\n // drawer) - mirrors the selection/drag-handle <td>s above.\n onClick={(e) => e.stopPropagation()}\n >\n {renderActionsMenu(row, localIndex)}\n </td>\n )}\n </>\n )}\n </SortableTableRow>\n\n {expandable && renderExpandedContent && (\n <ExpandedTableRow\n isOpen={isRowExpanded}\n colSpan={totalCols}\n render={() => renderExpandedContent(row, localIndex)}\n />\n )}\n </React.Fragment>\n );\n })\n ) : (\n <tr className=\"eidos-data-grid-empty-row\">\n <td\n colSpan={totalCols}\n className=\"eidos-data-grid-cell eidos-data-grid-empty-cell\"\n >\n {Object.keys(activeFilters).length > 0 ? (\n <EmptyState\n icon={<SearchX />}\n title=\"No results found\"\n description=\"Try adjusting your filters or search terms.\"\n action={\n <Button\n size=\"sm\"\n variant=\"outlined\"\n color=\"primary\"\n onClick={clearAllFilters}\n >\n Clear filters\n </Button>\n }\n size=\"sm\"\n />\n ) : (\n <EmptyState\n icon={<FolderOpen />}\n title={emptyText}\n description={\n onRowAdd\n ? 'Add a row to get started.'\n : 'There are no records to display.'\n }\n size=\"sm\"\n />\n )}\n </td>\n </tr>\n )}\n </SortableContext>\n </tbody>\n </table>\n </div>\n </DndContext>\n </>\n )}\n\n {/* ── Pagination footer ────────────────────────────────────────────── */}\n {showPagination && (\n <div className=\"eidos-datagrid-footer\">\n <Pagination\n page={currentPage}\n totalPages={totalPages}\n onChange={handlePageChange}\n totalItems={totalItemCount}\n pageSize={currentPageSize}\n onPageSizeChange={handlePageSizeChange}\n pageSizeOptions={effectivePageSizeOptions}\n />\n </div>\n )}\n\n {/* Portaled rather than a child of the erroring cell - see errorTooltipPosition above */}\n {activeCellError &&\n errorTooltipPosition &&\n createPortal(\n <div\n className=\"eidos-data-grid-cell-error\"\n style={{ top: errorTooltipPosition.top, left: errorTooltipPosition.left }}\n >\n {activeCellError}\n </div>,\n document.body,\n )}\n </div>\n );\n}\n\n// Assign displayName cleanly without losing the generic signature\nexport const DataGrid = Object.assign(DataGridInner, { displayName: 'DataGrid' });\n"],"mappings":"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","names":["row"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Button
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-YJXZR7RL.js";
|
|
4
4
|
|
|
5
5
|
// src/components/Snackbar/Snackbar.context.tsx
|
|
6
6
|
import { createContext, useContext, useState, useCallback, useRef } from "react";
|
|
@@ -235,4 +235,4 @@ export {
|
|
|
235
235
|
SnackbarContainer,
|
|
236
236
|
useSnackbar
|
|
237
237
|
};
|
|
238
|
-
//# sourceMappingURL=chunk-
|
|
238
|
+
//# sourceMappingURL=chunk-RWOX2NJN.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Input
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VHMOKXUT.js";
|
|
4
4
|
|
|
5
5
|
// src/components/InlineEdit/InlineEdit.component.tsx
|
|
6
6
|
import { useState, useRef, useCallback } from "react";
|
|
@@ -122,4 +122,4 @@ var InlineEdit = ({
|
|
|
122
122
|
export {
|
|
123
123
|
InlineEdit
|
|
124
124
|
};
|
|
125
|
-
//# sourceMappingURL=chunk-
|
|
125
|
+
//# sourceMappingURL=chunk-S3CT536K.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
renderIcon
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KBG77JHC.js";
|
|
4
4
|
import {
|
|
5
5
|
Tooltip
|
|
6
6
|
} from "./chunk-YV57RSPD.js";
|
|
@@ -85,4 +85,4 @@ var Chip = ({
|
|
|
85
85
|
export {
|
|
86
86
|
Chip
|
|
87
87
|
};
|
|
88
|
-
//# sourceMappingURL=chunk-
|
|
88
|
+
//# sourceMappingURL=chunk-SHYSLWQG.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkDAXZRNNOcjs = require('./chunk-DAXZRNNO.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var _chunkFRUOA2QUcjs = require('./chunk-FRUOA2QU.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunkGEHL4LKKcjs = require('./chunk-GEHL4LKK.cjs');
|
|
10
10
|
|
|
11
11
|
// src/components/SplitButton/SplitButton.component.tsx
|
|
12
12
|
var _react = require('react');
|
|
@@ -71,7 +71,7 @@ var SplitButton = ({
|
|
|
71
71
|
disabled: disabledOrLoading,
|
|
72
72
|
onClick,
|
|
73
73
|
children: [
|
|
74
|
-
loading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.LoaderCircle, { className: "eidos-split-button__spinner", "aria-hidden": "true" }) : preIcon &&
|
|
74
|
+
loading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.LoaderCircle, { className: "eidos-split-button__spinner", "aria-hidden": "true" }) : preIcon && _chunkGEHL4LKKcjs.renderIcon.call(void 0, preIcon, "eidos-split-button__pre-icon"),
|
|
75
75
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-split-button__label", children: label })
|
|
76
76
|
]
|
|
77
77
|
}
|
|
@@ -80,7 +80,7 @@ var SplitButton = ({
|
|
|
80
80
|
_chunkFRUOA2QUcjs.Dropdown,
|
|
81
81
|
{
|
|
82
82
|
trigger: chevronTrigger,
|
|
83
|
-
content: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
83
|
+
content: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkDAXZRNNOcjs.MenuPanel, { items: menuItems, onItemClick: handleItemClick }),
|
|
84
84
|
placement: "bottom",
|
|
85
85
|
align: "end",
|
|
86
86
|
disabled: disabledOrLoading
|
|
@@ -94,4 +94,4 @@ var SplitButton = ({
|
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
exports.SplitButton = SplitButton;
|
|
97
|
-
//# sourceMappingURL=chunk-
|
|
97
|
+
//# sourceMappingURL=chunk-SKEWTQJ7.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-SKEWTQJ7.cjs","../src/components/SplitButton/SplitButton.component.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACVA,8BAAmC;AACnC,2CAA0C;AAmEpC,+CAAA;AAzCC,IAAM,YAAA,EAA0C,CAAC;AAAA,EACtD,KAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,SAAA;AAAA,EACR,KAAA,EAAO,IAAA;AAAA,EACP,SAAA,EAAW,KAAA;AAAA,EACX,QAAA,EAAU,KAAA;AAAA,EACV,OAAA;AAAA,EACA,UAAA,EAAY;AACd,CAAA,EAAA,GAAM;AAEJ,EAAA,MAAM,UAAA,EAAwB,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAA,EAAA,GAAA,CAAS;AAAA,IAClD,IAAA,EAAM,MAAA;AAAA,IACN,EAAA,EAAI,GAAA,CAAI,EAAA;AAAA,IACR,KAAA,EAAO,GAAA,CAAI,KAAA;AAAA,IACX,IAAA,EAAM,GAAA,CAAI,IAAA;AAAA,IACV,QAAA,EAAU,GAAA,CAAI,QAAA;AAAA,IACd,OAAA,EAAS,GAAA,CAAI;AAAA,EACf,CAAA,CAAE,CAAA;AAEF,EAAA,MAAM,gBAAA,EAAkB,gCAAA,CAAY,EAAA,GAAM;AAExC,IAAA,UAAA,CAAW,CAAA,EAAA,GAAM;AACf,MAAA,QAAA,CAAS,aAAA;AAAA,QACP,IAAI,UAAA,CAAW,WAAA,EAAa,EAAE,OAAA,EAAS,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,IAAA,EAAM,OAAO,CAAC;AAAA,MAC/E,CAAA;AAAA,IACF,CAAA,EAAG,EAAE,CAAA;AAAA,EACP,CAAA,EAAG,CAAC,CAAC,CAAA;AAEL,EAAA,MAAM,UAAA,EAAY,CAAA,2BAAA,EAA8B,OAAO,CAAA,eAAA,EAAkB,KAAK,CAAA,eAAA,EAAkB,IAAI,CAAA,CAAA;AAC9D,EAAA;AAGpC,EAAA;AAAC,IAAA;AAAA,IAAA;AACM,MAAA;AACkB,MAAA;AACb,MAAA;AACC,MAAA;AAE+C,MAAA;AAAmB,IAAA;AAC/E,EAAA;AAIA,EAAA;AAAC,IAAA;AAAA,IAAA;AACY,MAAA;AACT,QAAA;AAC8B,QAAA;AACF,QAAA;AACD,QAAA;AACN,QAAA;AACrB,QAAA;AAGS,MAAA;AAGX,MAAA;AAAA,wBAAA;AAAC,UAAA;AAAA,UAAA;AACM,YAAA;AACkB,YAAA;AACb,YAAA;AACV,YAAA;AAEC,YAAA;AACuD,cAAA;AAIL,8BAAA;AAAA,YAAA;AAAA,UAAA;AACrD,QAAA;AAGA,wBAAA;AAAC,UAAA;AAAA,UAAA;AACU,YAAA;AAC2D,YAAA;AAC1D,YAAA;AACJ,YAAA;AACI,YAAA;AAAA,UAAA;AACZ,QAAA;AAAA,MAAA;AAAA,IAAA;AACF,EAAA;AAEJ;ADlBuG;AACA;AACA;AACA","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-SKEWTQJ7.cjs","sourcesContent":[null,"import React, { useCallback } from 'react';\nimport { ChevronDown, LoaderCircle } from 'lucide-react';\nimport { Dropdown } from '../Dropdown/Dropdown.component';\nimport { MenuPanel } from '../Menu';\nimport type { MenuItem } from '../Menu';\nimport { renderIcon } from '../../utils';\nimport type { SplitButtonProps } from './SplitButton.types';\n\n/**\n * SplitButton - a two-part control with a primary action button on the left\n * and a chevron that opens a dropdown of secondary actions on the right.\n *\n * The primary button fires `onClick` directly; clicking the chevron opens the\n * dropdown. Visually the two parts share a single bordered unit.\n *\n * @example\n * ```tsx\n * <SplitButton\n * label=\"Save\"\n * onClick={() => save()}\n * options={[\n * { id: 'draft', label: 'Save as draft', onClick: saveDraft },\n * { id: 'template', label: 'Save as template', onClick: saveTemplate },\n * ]}\n * />\n * ```\n */\nexport const SplitButton: React.FC<SplitButtonProps> = ({\n label,\n onClick,\n options,\n variant = 'filled',\n color = 'primary',\n size = 'md',\n disabled = false,\n loading = false,\n preIcon,\n className = '',\n}) => {\n // Convert SplitButtonOption → MenuItemType so MenuPanel can render them.\n const menuItems: MenuItem[] = options.map((opt) => ({\n type: 'item' as const,\n id: opt.id,\n label: opt.label,\n icon: opt.icon,\n disabled: opt.disabled,\n onClick: opt.onClick,\n }));\n\n const handleItemClick = useCallback(() => {\n // Close the dropdown by dispatching a mousedown outside it.\n setTimeout(() => {\n document.dispatchEvent(\n new MouseEvent('mousedown', { bubbles: true, cancelable: true, view: window }),\n );\n }, 10);\n }, []);\n\n const baseClass = `eidos-button eidos-button--${variant} eidos-button--${color} eidos-button--${size}`;\n const disabledOrLoading = disabled || loading;\n\n const chevronTrigger = (\n <button\n type=\"button\"\n className={`${baseClass} eidos-split-button__chevron`}\n disabled={disabledOrLoading}\n aria-label=\"More options\"\n >\n <ChevronDown className=\"eidos-split-button__chevron-icon\" aria-hidden=\"true\" />\n </button>\n );\n\n return (\n <div\n className={[\n 'eidos-split-button',\n `eidos-split-button--${variant}`,\n `eidos-split-button--${color}`,\n `eidos-split-button--${size}`,\n disabledOrLoading && 'eidos-split-button--disabled',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {/* Primary action */}\n <button\n type=\"button\"\n className={`${baseClass} eidos-split-button__primary`}\n disabled={disabledOrLoading}\n onClick={onClick}\n >\n {loading ? (\n <LoaderCircle className=\"eidos-split-button__spinner\" aria-hidden=\"true\" />\n ) : (\n preIcon && renderIcon(preIcon, 'eidos-split-button__pre-icon')\n )}\n <span className=\"eidos-split-button__label\">{label}</span>\n </button>\n\n {/* Secondary actions dropdown */}\n <Dropdown\n trigger={chevronTrigger}\n content={<MenuPanel items={menuItems} onItemClick={handleItemClick} />}\n placement=\"bottom\"\n align=\"end\"\n disabled={disabledOrLoading}\n />\n </div>\n );\n};\n"]}
|