@lovett/ui 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/README.md +28 -0
  2. package/package.json +53 -0
  3. package/src/accordion.tsx +153 -0
  4. package/src/atoms.tsx +197 -0
  5. package/src/badge.tsx +91 -0
  6. package/src/brand-logo-tile.tsx +200 -0
  7. package/src/bulk-action-bar.tsx +104 -0
  8. package/src/button-group.tsx +46 -0
  9. package/src/button.tsx +93 -0
  10. package/src/calculator-shell-v2.tsx +380 -0
  11. package/src/calculator-shell.tsx +310 -0
  12. package/src/card.tsx +369 -0
  13. package/src/checkbox.tsx +114 -0
  14. package/src/chip-nav.tsx +347 -0
  15. package/src/choropleth.tsx +62 -0
  16. package/src/code-block.tsx +235 -0
  17. package/src/completion-ring.tsx +119 -0
  18. package/src/copy-field.tsx +169 -0
  19. package/src/data-grid/column-options-menu.tsx +127 -0
  20. package/src/data-grid/data-grid.tsx +391 -0
  21. package/src/data-grid/drawer-panel.tsx +146 -0
  22. package/src/data-grid/index.ts +29 -0
  23. package/src/data-grid/sortable-parts.tsx +215 -0
  24. package/src/data-grid/table-body.tsx +238 -0
  25. package/src/data-grid/table-elements.tsx +135 -0
  26. package/src/data-grid/table-header.tsx +95 -0
  27. package/src/data-grid/table-overlays.tsx +78 -0
  28. package/src/data-grid/table-parts.tsx +15 -0
  29. package/src/data-grid/table-summary-footer.tsx +101 -0
  30. package/src/data-grid/table-view.tsx +176 -0
  31. package/src/data-grid/types.ts +141 -0
  32. package/src/data-grid/use-grid-columns.ts +311 -0
  33. package/src/data-grid/use-grid-editing.ts +154 -0
  34. package/src/device-frame.tsx +274 -0
  35. package/src/dropdown-button.tsx +221 -0
  36. package/src/dropdown-menu.tsx +450 -0
  37. package/src/empty-state.tsx +85 -0
  38. package/src/file-upload/file-drop-zone.tsx +156 -0
  39. package/src/file-upload/file-preview-grid.tsx +39 -0
  40. package/src/file-upload/file-preview-item.tsx +175 -0
  41. package/src/file-upload/file-thumbnail.tsx +98 -0
  42. package/src/file-upload/file-upload-button.tsx +95 -0
  43. package/src/file-upload/index.ts +13 -0
  44. package/src/file-upload/use-file-upload.ts +371 -0
  45. package/src/filter-bar.tsx +125 -0
  46. package/src/filter-dropdown.tsx +289 -0
  47. package/src/floating-drawer.tsx +420 -0
  48. package/src/folder-card.tsx +188 -0
  49. package/src/folder-tree-picker.tsx +511 -0
  50. package/src/format.ts +117 -0
  51. package/src/frame-stack.tsx +73 -0
  52. package/src/hero-form-card.tsx +471 -0
  53. package/src/index.ts +372 -0
  54. package/src/input.tsx +130 -0
  55. package/src/kbd.tsx +41 -0
  56. package/src/lib/layout.ts +22 -0
  57. package/src/lib/utils.ts +6 -0
  58. package/src/markdown.tsx +214 -0
  59. package/src/menu-button.tsx +142 -0
  60. package/src/meta-previews/CreativeMedia.tsx +119 -0
  61. package/src/meta-previews/InstagramExplorePreview.tsx +340 -0
  62. package/src/meta-previews/InstagramFeedCarousel.tsx +245 -0
  63. package/src/meta-previews/InstagramFeedPreview.tsx +259 -0
  64. package/src/meta-previews/MetaFeedCarousel.tsx +228 -0
  65. package/src/meta-previews/MetaFeedPreview.tsx +294 -0
  66. package/src/meta-previews/MetaInstreamPreview.tsx +135 -0
  67. package/src/meta-previews/MetaMessengerPreview.tsx +795 -0
  68. package/src/meta-previews/MetaReelPreview.tsx +750 -0
  69. package/src/meta-previews/MetaRightColumnPreview.tsx +245 -0
  70. package/src/meta-previews/MetaSearchPreview.tsx +113 -0
  71. package/src/meta-previews/MetaStoryPreview.tsx +1132 -0
  72. package/src/meta-previews/ProfileAvatar.tsx +79 -0
  73. package/src/meta-previews/defaults.ts +27 -0
  74. package/src/meta-previews/index.ts +37 -0
  75. package/src/meta-previews/types.ts +219 -0
  76. package/src/metric-card.tsx +117 -0
  77. package/src/modal.tsx +131 -0
  78. package/src/option-tile.tsx +252 -0
  79. package/src/page-hero.tsx +78 -0
  80. package/src/page-shell.tsx +440 -0
  81. package/src/pagination.tsx +86 -0
  82. package/src/pill-button.tsx +103 -0
  83. package/src/profile-section.tsx +389 -0
  84. package/src/progress-bar.tsx +84 -0
  85. package/src/radio.tsx +172 -0
  86. package/src/range-slider.tsx +161 -0
  87. package/src/resizable.tsx +282 -0
  88. package/src/search-bar.tsx +81 -0
  89. package/src/segmented-pill.tsx +143 -0
  90. package/src/shell.tsx +464 -0
  91. package/src/slider.tsx +107 -0
  92. package/src/sortable-table.tsx +198 -0
  93. package/src/sortable.tsx +137 -0
  94. package/src/stat-row.tsx +132 -0
  95. package/src/stats-grid.tsx +38 -0
  96. package/src/step-loader.tsx +141 -0
  97. package/src/styles.css +562 -0
  98. package/src/tabs.tsx +143 -0
  99. package/src/tag-chip-input.tsx +394 -0
  100. package/src/textarea.tsx +39 -0
  101. package/src/toast.tsx +59 -0
  102. package/src/tokens.css +579 -0
@@ -0,0 +1,78 @@
1
+ /**
2
+ * DataGridDragOverlay + DataGridDropIndicator — visual chrome that
3
+ * renders during column drag-reorder.
4
+ *
5
+ * Ported 2026-05-18 from gray-ui-csm
6
+ * https://github.com/Jason-uxui/gray-ui-csm/blob/baf8346ac0c1160282e0b173de1bffc594d9c9c3/components/data-grid/table-overlays.tsx
7
+ * License: MIT (see packages/ui/licenses/gray-ui-csm-LICENSE.txt)
8
+ * Workspace ADR: ADR-025
9
+ *
10
+ * BRING_WITH_REFACTOR: token reskin to workspace vocabulary per
11
+ * ADR-025 D7.
12
+ */
13
+
14
+ import type { DataGridColumn } from './types'
15
+
16
+ type DataGridDragOverlayProps<ColumnId extends string> = {
17
+ dragOverlayColumn: DataGridColumn<ColumnId> | null
18
+ columnWidths: Record<ColumnId, number>
19
+ dragOverlayHeight: number
20
+ }
21
+
22
+ export function DataGridDragOverlay<ColumnId extends string>({
23
+ dragOverlayColumn,
24
+ columnWidths,
25
+ dragOverlayHeight,
26
+ }: DataGridDragOverlayProps<ColumnId>) {
27
+ if (!dragOverlayColumn) return null
28
+
29
+ const Icon = dragOverlayColumn.icon
30
+
31
+ return (
32
+ <div
33
+ className="pointer-events-none rounded-[var(--radius-md)]"
34
+ style={{
35
+ width: columnWidths[dragOverlayColumn.id],
36
+ height: dragOverlayHeight,
37
+ border: '1px solid rgb(var(--border))',
38
+ background: 'rgb(var(--bg-card))',
39
+ boxShadow: 'var(--shadow-lg, 0 10px 32px rgba(0,0,0,0.18))',
40
+ }}
41
+ >
42
+ <div
43
+ className="flex h-8 items-center gap-1.5 px-2 text-xs font-medium"
44
+ style={{
45
+ borderBottom: '1px solid rgb(var(--border))',
46
+ color: 'rgb(var(--foreground))',
47
+ }}
48
+ >
49
+ <Icon className="h-3.5 w-3.5 shrink-0" />
50
+ <span className="truncate">{dragOverlayColumn.label}</span>
51
+ </div>
52
+ </div>
53
+ )
54
+ }
55
+
56
+ type DataGridDropIndicatorProps = {
57
+ dropIndicatorLeft: number | null
58
+ dragTableRect: { top: number; height: number } | null
59
+ }
60
+
61
+ export function DataGridDropIndicator({
62
+ dropIndicatorLeft,
63
+ dragTableRect,
64
+ }: DataGridDropIndicatorProps) {
65
+ if (dropIndicatorLeft === null || !dragTableRect) return null
66
+
67
+ return (
68
+ <div
69
+ className="pointer-events-none fixed z-50 w-0.5"
70
+ style={{
71
+ left: dropIndicatorLeft - 1,
72
+ top: dragTableRect.top,
73
+ height: dragTableRect.height,
74
+ background: 'rgb(var(--accent))',
75
+ }}
76
+ />
77
+ )
78
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Re-export aggregator for the DataGrid's table sub-components.
3
+ *
4
+ * Ported 2026-05-18 from gray-ui-csm
5
+ * https://github.com/Jason-uxui/gray-ui-csm/blob/baf8346ac0c1160282e0b173de1bffc594d9c9c3/components/data-grid/table-parts.tsx
6
+ * License: MIT (see packages/ui/licenses/gray-ui-csm-LICENSE.txt)
7
+ * Workspace ADR: ADR-025
8
+ *
9
+ * BRING_AS_IS: re-exports only — relative-path adjustments only.
10
+ */
11
+
12
+ export { DataGridTableHeader } from './table-header'
13
+ export { DataGridTableBody } from './table-body'
14
+ export { DataGridSummaryFooter } from './table-summary-footer'
15
+ export { DataGridDragOverlay, DataGridDropIndicator } from './table-overlays'
@@ -0,0 +1,101 @@
1
+ /**
2
+ * DataGridSummaryFooter — optional sum-style row beneath the body.
3
+ *
4
+ * Ported 2026-05-18 from gray-ui-csm
5
+ * https://github.com/Jason-uxui/gray-ui-csm/blob/baf8346ac0c1160282e0b173de1bffc594d9c9c3/components/data-grid/table-summary-footer.tsx
6
+ * License: MIT (see packages/ui/licenses/gray-ui-csm-LICENSE.txt)
7
+ * Workspace ADR: ADR-025
8
+ *
9
+ * BRING_WITH_REFACTOR: token reskin per ADR-025 D7.
10
+ */
11
+
12
+ import type { CSSProperties, ReactNode } from 'react'
13
+
14
+ import { cn } from '../lib/utils'
15
+ import { TableCell, TableFooter, TableRow } from './table-elements'
16
+
17
+ import type { DataGridColumn, DataGridRowBase } from './types'
18
+
19
+ type DataGridSummaryFooterProps<
20
+ Row extends DataGridRowBase,
21
+ ColumnId extends string,
22
+ > = {
23
+ showSummaries: boolean
24
+ stickySummaryFooter: boolean
25
+ renderSummary:
26
+ | ((
27
+ column: DataGridColumn<ColumnId>,
28
+ visibleRows: Row[],
29
+ ) => ReactNode)
30
+ | undefined
31
+ visibleColumns: DataGridColumn<ColumnId>[]
32
+ visibleRows: Row[]
33
+ columnWidths: Record<ColumnId, number>
34
+ draggingColumnId: ColumnId | null
35
+ isEmptyValue: (value: ReactNode) => boolean
36
+ }
37
+
38
+ export function DataGridSummaryFooter<
39
+ Row extends DataGridRowBase,
40
+ ColumnId extends string,
41
+ >({
42
+ showSummaries,
43
+ stickySummaryFooter,
44
+ renderSummary,
45
+ visibleColumns,
46
+ visibleRows,
47
+ columnWidths,
48
+ draggingColumnId,
49
+ isEmptyValue,
50
+ }: DataGridSummaryFooterProps<Row, ColumnId>) {
51
+ if (!showSummaries || !renderSummary) return null
52
+
53
+ const stickyCellStyle: CSSProperties | undefined = stickySummaryFooter
54
+ ? {
55
+ position: 'sticky',
56
+ bottom: 0,
57
+ zIndex: 10,
58
+ background: 'rgb(var(--bg-card))',
59
+ borderTop: '1px solid rgb(var(--border))',
60
+ }
61
+ : undefined
62
+
63
+ return (
64
+ <TableFooter>
65
+ <TableRow className="hover:bg-transparent">
66
+ <TableCell
67
+ className={cn('h-10 px-2 py-1')}
68
+ style={{
69
+ borderRight: '1px solid rgb(var(--border))',
70
+ ...stickyCellStyle,
71
+ }}
72
+ />
73
+ {visibleColumns.map((column) => {
74
+ const summaryContent = renderSummary(column, visibleRows)
75
+ const isDraggingThisColumn = draggingColumnId === column.id
76
+
77
+ return (
78
+ <TableCell
79
+ key={`summary-${column.id}`}
80
+ className={cn('h-10 px-2 py-1 text-left text-xs whitespace-nowrap')}
81
+ style={{
82
+ width: columnWidths[column.id],
83
+ minWidth: columnWidths[column.id],
84
+ color: 'rgb(var(--text-muted))',
85
+ borderRight: '1px solid rgb(var(--border))',
86
+ background: isDraggingThisColumn
87
+ ? 'rgb(var(--surface-overlay-soft))'
88
+ : stickyCellStyle?.background,
89
+ ...stickyCellStyle,
90
+ }}
91
+ >
92
+ {!isEmptyValue(summaryContent) ? (
93
+ <span className="inline-block">{summaryContent}</span>
94
+ ) : null}
95
+ </TableCell>
96
+ )
97
+ })}
98
+ </TableRow>
99
+ </TableFooter>
100
+ )
101
+ }
@@ -0,0 +1,176 @@
1
+ /**
2
+ * DataGridTableView — composes Header + Body + SummaryFooter inside
3
+ * a single <Table>.
4
+ *
5
+ * Ported 2026-05-18 from gray-ui-csm
6
+ * https://github.com/Jason-uxui/gray-ui-csm/blob/baf8346ac0c1160282e0b173de1bffc594d9c9c3/components/data-grid/table-view.tsx
7
+ * License: MIT (see packages/ui/licenses/gray-ui-csm-LICENSE.txt)
8
+ * Workspace ADR: ADR-025
9
+ *
10
+ * BRING_WITH_REFACTOR:
11
+ * • Table sub-component imported from local table-elements (DEV-1)
12
+ * • No additional styling beyond what the sub-components carry
13
+ */
14
+
15
+ import type {
16
+ KeyboardEvent as ReactKeyboardEvent,
17
+ PointerEvent as ReactPointerEvent,
18
+ ReactNode,
19
+ RefObject,
20
+ } from 'react'
21
+
22
+ import { Table } from './table-elements'
23
+ import {
24
+ DataGridSummaryFooter,
25
+ DataGridTableBody,
26
+ DataGridTableHeader,
27
+ } from './table-parts'
28
+ import type {
29
+ DataGridColumn,
30
+ DataGridRowBase,
31
+ DataGridSortState,
32
+ EditingCell,
33
+ } from './types'
34
+
35
+ type DataGridTableViewProps<
36
+ Row extends DataGridRowBase,
37
+ ColumnId extends string,
38
+ > = {
39
+ tableRef: RefObject<HTMLTableElement | null>
40
+ gridMinWidth: number
41
+ visibleColumns: DataGridColumn<ColumnId>[]
42
+ columnWidths: Record<ColumnId, number>
43
+ visibleRows: Row[]
44
+ getRowLabel: (row: Row) => string
45
+ editingCell: EditingCell<ColumnId> | null
46
+ isEditableColumn: (columnId: ColumnId) => boolean
47
+ startEditing: (row: Row, columnId: ColumnId) => void
48
+ onCellKeyDown: (
49
+ event: ReactKeyboardEvent<HTMLTableCellElement>,
50
+ row: Row,
51
+ rowIndex: number,
52
+ column: DataGridColumn<ColumnId>,
53
+ colIndex: number,
54
+ ) => void
55
+ inputRef: RefObject<HTMLInputElement | null>
56
+ draftValue: string
57
+ setDraftValue: (value: string) => void
58
+ commitEdit: () => void
59
+ cancelEdit: () => void
60
+ canOpenDrawer: (columnId: ColumnId) => boolean
61
+ renderCell: (row: Row, column: DataGridColumn<ColumnId>) => ReactNode
62
+ onOpenDrawer: (cell: EditingCell<ColumnId>) => void
63
+ selectedRowIds: string[]
64
+ allVisibleRowsSelected: boolean
65
+ someVisibleRowsSelected: boolean
66
+ onToggleRowSelection: (rowId: string, checked: boolean) => void
67
+ onToggleAllRows: (checked: boolean) => void
68
+ showSummaries: boolean
69
+ renderSummary:
70
+ | ((
71
+ column: DataGridColumn<ColumnId>,
72
+ visibleRows: Row[],
73
+ ) => ReactNode)
74
+ | undefined
75
+ stickySummaryFooter: boolean
76
+ tableContainerClassName: string | undefined
77
+ isEmptyValue: (value: ReactNode) => boolean
78
+ onResizeStart: (
79
+ event: ReactPointerEvent<HTMLButtonElement>,
80
+ columnId: ColumnId,
81
+ ) => void
82
+ draggingColumnId: ColumnId | null
83
+ sort: DataGridSortState<ColumnId> | null
84
+ onSortChange: ((columnId: ColumnId) => void) | undefined
85
+ }
86
+
87
+ export function DataGridTableView<
88
+ Row extends DataGridRowBase,
89
+ ColumnId extends string,
90
+ >({
91
+ tableRef,
92
+ gridMinWidth,
93
+ visibleColumns,
94
+ columnWidths,
95
+ visibleRows,
96
+ getRowLabel,
97
+ editingCell,
98
+ isEditableColumn,
99
+ startEditing,
100
+ onCellKeyDown,
101
+ inputRef,
102
+ draftValue,
103
+ setDraftValue,
104
+ commitEdit,
105
+ cancelEdit,
106
+ canOpenDrawer,
107
+ renderCell,
108
+ onOpenDrawer,
109
+ selectedRowIds,
110
+ allVisibleRowsSelected,
111
+ someVisibleRowsSelected,
112
+ onToggleRowSelection,
113
+ onToggleAllRows,
114
+ showSummaries,
115
+ renderSummary,
116
+ stickySummaryFooter,
117
+ tableContainerClassName,
118
+ isEmptyValue,
119
+ onResizeStart,
120
+ draggingColumnId,
121
+ sort,
122
+ onSortChange,
123
+ }: DataGridTableViewProps<Row, ColumnId>) {
124
+ return (
125
+ <Table
126
+ ref={tableRef}
127
+ className="table-fixed"
128
+ containerClassName={tableContainerClassName}
129
+ style={{ width: `max(100%, ${gridMinWidth}px)` }}
130
+ >
131
+ <DataGridTableHeader
132
+ visibleColumns={visibleColumns}
133
+ columnWidths={columnWidths}
134
+ allVisibleRowsSelected={allVisibleRowsSelected}
135
+ someVisibleRowsSelected={someVisibleRowsSelected}
136
+ onToggleAllRows={onToggleAllRows}
137
+ onResizeStart={onResizeStart}
138
+ sort={sort}
139
+ onSortChange={onSortChange}
140
+ />
141
+
142
+ <DataGridTableBody
143
+ visibleRows={visibleRows}
144
+ getRowLabel={getRowLabel}
145
+ visibleColumns={visibleColumns}
146
+ editingCell={editingCell}
147
+ isEditableColumn={isEditableColumn}
148
+ startEditing={startEditing}
149
+ onCellKeyDown={onCellKeyDown}
150
+ inputRef={inputRef}
151
+ draftValue={draftValue}
152
+ setDraftValue={setDraftValue}
153
+ commitEdit={commitEdit}
154
+ cancelEdit={cancelEdit}
155
+ canOpenDrawer={canOpenDrawer}
156
+ renderCell={renderCell}
157
+ onOpenDrawer={onOpenDrawer}
158
+ selectedRowIds={selectedRowIds}
159
+ onToggleRowSelection={onToggleRowSelection}
160
+ columnWidths={columnWidths}
161
+ draggingColumnId={draggingColumnId}
162
+ />
163
+
164
+ <DataGridSummaryFooter
165
+ showSummaries={showSummaries}
166
+ renderSummary={renderSummary}
167
+ stickySummaryFooter={stickySummaryFooter}
168
+ visibleColumns={visibleColumns}
169
+ visibleRows={visibleRows}
170
+ columnWidths={columnWidths}
171
+ draggingColumnId={draggingColumnId}
172
+ isEmptyValue={isEmptyValue}
173
+ />
174
+ </Table>
175
+ )
176
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * DataGrid public types.
3
+ *
4
+ * Ported 2026-05-18 from gray-ui-csm
5
+ * https://github.com/Jason-uxui/gray-ui-csm/blob/baf8346ac0c1160282e0b173de1bffc594d9c9c3/components/data-grid/types.ts
6
+ * License: MIT (see packages/ui/licenses/gray-ui-csm-LICENSE.txt)
7
+ * Workspace ADR: ADR-025
8
+ *
9
+ * BRING_AS_IS per ADR-025 bucket table — surface API unchanged from
10
+ * source so the source repo's docs still apply.
11
+ */
12
+
13
+ import type { ComponentProps, ComponentType, ReactNode } from 'react'
14
+ import type { DndContext, DragEndEvent } from '@dnd-kit/core'
15
+
16
+ export type DataGridIcon = ComponentType<{
17
+ className?: string
18
+ }>
19
+
20
+ export type DataGridRowBase = {
21
+ id: string
22
+ }
23
+
24
+ export type DataGridColumn<ColumnId extends string> = {
25
+ id: ColumnId
26
+ label: string
27
+ icon: DataGridIcon
28
+ defaultWidth: number
29
+ minWidth?: number
30
+ /** Per-column sort opt-out (ADR-027). Defaults to true when DataGrid's
31
+ * `onSortChange` is provided; false when not. Set explicitly to disable
32
+ * sorting for columns that don't have a meaningful comparator. */
33
+ sortable?: boolean
34
+ }
35
+
36
+ /** Row-sort state (ADR-027). DataGrid renders the chevron + ARIA per
37
+ * this state but does NOT sort rows itself — parent passes pre-sorted
38
+ * `rows`. */
39
+ export type DataGridSortState<ColumnId extends string> = {
40
+ columnId: ColumnId
41
+ dir: 'asc' | 'desc'
42
+ }
43
+
44
+ export type DataGridDrawerPanelProps<Row, ColumnId extends string> = {
45
+ drawerRow: Row | null
46
+ drawerRowIndex: number
47
+ drawerRowCount: number
48
+ drawerColumn: DataGridColumn<ColumnId> | null
49
+ drawerCellValue: ReactNode
50
+ getRowLabel: (row: Row) => string
51
+ isEditableColumn: (columnId: ColumnId) => boolean
52
+ isEmptyValue: (value: ReactNode) => boolean
53
+ updateRow: (rowId: string, updater: (row: Row) => Row) => void
54
+ openPreviousRow: () => void
55
+ openNextRow: () => void
56
+ closeDrawer: () => void
57
+ /** Whether the drawer should be visible. The default <DrawerPanel>
58
+ * reads this to drive its <FloatingDrawer isOpen> binding; consumer
59
+ * render-overrides may use it the same way. Added in the workspace
60
+ * port (DEVIATION-5) to remove the `@base-ui/react` context coupling
61
+ * the source relied on. */
62
+ isOpen: boolean
63
+ }
64
+
65
+ export type DataGridToolbarRenderProps<ColumnId extends string> = {
66
+ visibleRowCount: number
67
+ selectedRowIds: string[]
68
+ selectedRowCount: number
69
+ allVisibleRowsSelected: boolean
70
+ someVisibleRowsSelected: boolean
71
+ onToggleAllRows: (checked: boolean) => void
72
+ clearSelection: () => void
73
+ showSummaries: boolean
74
+ onShowSummariesChange: (next: boolean) => void
75
+ visibleColumns: DataGridColumn<ColumnId>[]
76
+ visibleColumnIds: ColumnId[]
77
+ hiddenColumns: DataGridColumn<ColumnId>[]
78
+ toggleColumnVisibility: (columnId: ColumnId, visible: boolean) => void
79
+ optionsSensors: NonNullable<
80
+ ComponentProps<typeof DndContext>['sensors']
81
+ >
82
+ onOptionColumnDragEnd: (event: DragEndEvent) => void
83
+ optionsDndContextId: string
84
+ }
85
+
86
+ export type DataGridProps<
87
+ Row extends DataGridRowBase,
88
+ ColumnId extends string,
89
+ > = {
90
+ rows: Row[]
91
+ columns: DataGridColumn<ColumnId>[]
92
+ getRowLabel: (row: Row) => string
93
+ renderCell: (row: Row, column: DataGridColumn<ColumnId>) => ReactNode
94
+ isEditableColumn: (columnId: ColumnId) => boolean
95
+ getCellEditValue: (row: Row, columnId: ColumnId) => string
96
+ applyCellEdit: (row: Row, columnId: ColumnId, nextValue: string) => Row
97
+ getDrawerCellValue: (row: Row, columnId: ColumnId) => ReactNode
98
+ canOpenDrawer?: (columnId: ColumnId) => boolean
99
+ renderSummary?: (
100
+ column: DataGridColumn<ColumnId>,
101
+ visibleRows: Row[],
102
+ ) => ReactNode
103
+ renderDrawerPanel?: (
104
+ props: DataGridDrawerPanelProps<Row, ColumnId>,
105
+ ) => ReactNode
106
+ renderToolbar?: (
107
+ props: DataGridToolbarRenderProps<ColumnId>,
108
+ ) => ReactNode
109
+ onToolbarPropsChange?: (props: DataGridToolbarRenderProps<ColumnId>) => void
110
+ onOpenDrawerCell?: (cell: EditingCell<ColumnId>) => void
111
+ /** Drawer renders in modal mode (backdrop + Esc + scroll lock).
112
+ * Defaults to `false` per the source's contextless API. */
113
+ drawerModal?: boolean
114
+ /** Pixel width of the drawer panel; passed through to FloatingDrawer.
115
+ * Defaults to 520 (the FloatingDrawer side="right" default). */
116
+ drawerSize?: number
117
+ stickySummaryFooter?: boolean
118
+ fillAvailableHeight?: boolean
119
+ tableContainerClassName?: string
120
+ onRowsChange?: (rows: Row[]) => void
121
+ /** Currently-sorted column + direction (ADR-027). Parent owns the
122
+ * state and passes pre-sorted `rows`. When `null` or omitted, no
123
+ * chevron renders (all columns show the unsorted indicator). */
124
+ sort?: DataGridSortState<ColumnId> | null
125
+ /** Header click handler (ADR-027). Receives the clicked column id;
126
+ * parent decides next direction (typical: toggle if same column,
127
+ * else default to 'asc'). When omitted, headers are non-interactive
128
+ * for sort purposes. Drag-to-reorder still works. */
129
+ onSortChange?: (columnId: ColumnId) => void
130
+ }
131
+
132
+ export type EditingCell<ColumnId extends string> = {
133
+ rowId: string
134
+ columnId: ColumnId
135
+ originRect?: {
136
+ x: number
137
+ y: number
138
+ width: number
139
+ height: number
140
+ }
141
+ }