@alaarab/ogrid-react-material 2.1.3 → 2.1.5

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/esm/index.js CHANGED
@@ -1,11 +1,1621 @@
1
- // Components
2
- export { OGrid } from './OGrid';
3
- export { DataGridTable } from './DataGridTable/DataGridTable';
4
- export { ColumnChooser } from './ColumnChooser/ColumnChooser';
5
- export { ColumnHeaderFilter } from './ColumnHeaderFilter/ColumnHeaderFilter';
6
- export { PaginationControls } from './PaginationControls/PaginationControls';
7
- export { ColumnHeaderMenu } from './ColumnHeaderMenu/ColumnHeaderMenu';
8
- // Re-export all from base package for consumer convenience.
9
- // Note: This prevents tree-shaking of unused utilities.
10
- // Consider explicit named exports in a future major version.
11
- export * from '@alaarab/ogrid-react';
1
+ import * as React3 from 'react';
2
+ import { useMemo, useCallback, useState, useRef, useEffect } from 'react';
3
+ import { Box, Tooltip, Typography, IconButton, Popover, Button, Select, MenuItem, useTheme, Checkbox, Table, TableHead, TableRow, TableCell, FormControlLabel, Avatar, TextField, InputAdornment, CircularProgress, Menu, Divider } from '@mui/material';
4
+ import { useColumnHeaderFilterState, getColumnHeaderFilterStateParams, renderFilterContent, areGridRowPropsEqual, usePaginationControls, createOGrid, CHECKBOX_COLUMN_WIDTH, STOP_PROPAGATION, ROW_NUMBER_COLUMN_WIDTH, useDataGridTableOrchestration, useColumnMeta, getCellRenderDescriptor, buildInlineEditorProps, buildPopoverEditorProps, resolveCellDisplayContent, resolveCellStyle, getCellInteractionProps, CellErrorBoundary, PREVENT_DEFAULT, getHeaderFilterConfig, MarchingAntsOverlay, NOOP, useColumnChooserState, useListVirtualizer, BaseInlineCellEditor, getContextMenuHandlers, GRID_CONTEXT_MENU_ITEMS, formatShortcut, getColumnHeaderMenuItems, getStatusBarParts } from '@alaarab/ogrid-react';
5
+ export { BaseColumnHeaderMenu, BaseDropIndicator, BaseEmptyState, BaseInlineCellEditor, BaseLoadingOverlay, CELL_PADDING, CHECKBOX_COLUMN_WIDTH, COLUMN_HEADER_MENU_ITEMS, CURSOR_CELL_STYLE, CellErrorBoundary, DEFAULT_MIN_COLUMN_WIDTH, DateFilterContent, EmptyState, GRID_BORDER_RADIUS, GRID_CONTEXT_MENU_ITEMS, GRID_ROOT_STYLE, GridContextMenu, MAX_PAGE_BUTTONS, MarchingAntsOverlay, NOOP, OGridLayout, PAGE_SIZE_OPTIONS, POPOVER_ANCHOR_STYLE, PREVENT_DEFAULT, ROW_NUMBER_COLUMN_WIDTH, STOP_PROPAGATION, SideBar, StatusBar, UndoRedoStack, areGridRowPropsEqual, booleanParser, buildCsvHeader, buildCsvRows, buildHeaderRows, buildInlineEditorProps, buildPopoverEditorProps, clampSelectionToBounds, computeAggregations, computeAutoScrollSpeed, computeTabNavigation, createOGrid, currencyParser, dateParser, deriveFilterOptionsFromData, editorInputStyle, editorWrapperStyle, emailParser, escapeCsvValue, exportToCsv, findCtrlArrowTarget, flattenColumns, formatCellValueForTsv, formatSelectionAsTsv, formatShortcut, getCellInteractionProps, getCellRenderDescriptor, getCellValue, getColumnHeaderFilterStateParams, getColumnHeaderMenuItems, getContextMenuHandlers, getDataGridStatusBarConfig, getDateFilterContentProps, getFilterField, getHeaderFilterConfig, getMultiSelectFilterFields, getPaginationViewModel, getStatusBarParts, isInSelectionRange, isRowInRange, mergeFilter, normalizeSelectionRange, numberParser, parseTsvClipboard, parseValue, processClientSideData, rangesEqual, renderFilterContent, resolveCellDisplayContent, resolveCellStyle, richSelectDropdownStyle, richSelectNoMatchesStyle, richSelectOptionHighlightedStyle, richSelectOptionStyle, richSelectWrapperStyle, selectChevronStyle, selectDisplayStyle, selectEditorStyle, toUserLike, triggerCsvDownload, useActiveCell, useCellEditing, useCellSelection, useClipboard, useColumnChooserState, useColumnHeaderFilterState, useColumnMeta, useColumnReorder, useColumnResize, useContextMenu, useDataGridState, useDataGridTableOrchestration, useDateFilterState, useDebounce, useFillHandle, useFilterOptions, useInlineCellEditorState, useKeyboardNavigation, useLatestRef, useListVirtualizer, useMultiSelectFilterState, useOGrid, usePaginationControls, usePeopleFilterState, useRichSelectState, useRowSelection, useSelectState, useSideBarState, useTableLayout, useTextFilterState, useUndoRedo, useVirtualScroll } from '@alaarab/ogrid-react';
6
+ import { createPortal } from 'react-dom';
7
+ import { FilterList, FirstPage, ChevronLeft, ChevronRight, LastPage, ExpandLess, ExpandMore, ViewColumn, Clear, Search } from '@mui/icons-material';
8
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
9
+
10
+ // src/OGrid/OGrid.tsx
11
+
12
+ // src/DataGridTable/DataGridTable.styles.ts
13
+ var STYLES = `
14
+ .ogrid-mat-row:hover > td { background-color: var(--ogrid-hover-bg); }
15
+ .ogrid-mat-row--selected > td { background-color: var(--ogrid-selection-bg, rgba(25, 118, 210, 0.08)); }
16
+
17
+ .ogrid-mat-td { position: relative; padding: 0; height: 1px; border-bottom: 1px solid var(--ogrid-border, rgba(224,224,224,1)); }
18
+ .ogrid-mat-td--pinned-left { position: sticky; left: 0; z-index: 6; background-color: var(--ogrid-paper-bg, #fff); will-change: transform; border-right: 1px solid var(--ogrid-border, rgba(224,224,224,1)); box-shadow: 2px 0 4px -1px rgba(0,0,0,0.1); }
19
+ .ogrid-mat-td--pinned-right { position: sticky; right: 0; z-index: 6; background-color: var(--ogrid-paper-bg, #fff); will-change: transform; border-left: 1px solid var(--ogrid-border, rgba(224,224,224,1)); box-shadow: -2px 0 4px -1px rgba(0,0,0,0.1); }
20
+
21
+ .ogrid-mat-cell { width: 100%; height: 100%; display: flex; align-items: center; min-width: 0; box-sizing: border-box; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; user-select: none; outline: none; }
22
+ .ogrid-mat-cell:focus-visible { outline: 2px solid var(--ogrid-primary, #1976d2); outline-offset: -2px; z-index: 3; }
23
+
24
+ .ogrid-mat-cell--numeric { justify-content: flex-end; text-align: right; }
25
+ .ogrid-mat-cell--boolean { justify-content: center; text-align: center; }
26
+ .ogrid-mat-cell--editable { cursor: cell; }
27
+
28
+ .ogrid-mat-cell--active { outline: 2px solid var(--ogrid-selection, #217346); outline-offset: -1px; z-index: 2; position: relative; overflow: visible; background-color: var(--ogrid-hover-bg); }
29
+ .ogrid-mat-cell--active:focus-visible { outline: 2px solid var(--ogrid-selection, #217346); outline-offset: -1px; }
30
+ .ogrid-mat-cell--range { background-color: var(--ogrid-bg-range, rgba(33,115,70,0.12)); }
31
+ .ogrid-mat-cell--range:focus-visible { outline: none; }
32
+ .ogrid-mat-cell--cut { background-color: var(--ogrid-hover-bg); opacity: 0.7; }
33
+
34
+ .ogrid-mat-fill-handle { position: absolute; right: -3px; bottom: -3px; width: 7px; height: 7px; background-color: var(--ogrid-selection, #217346); border: 1px solid var(--ogrid-bg, #fff); border-radius: 1px; cursor: crosshair; pointer-events: auto; z-index: 3; }
35
+
36
+ .ogrid-mat-checkbox-wrapper { display: flex; align-items: center; justify-content: center; }
37
+
38
+ .ogrid-mat-row-number { text-align: center; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ogrid-fg-secondary); background-color: var(--ogrid-hover-bg); position: sticky; z-index: 3; }
39
+
40
+ .ogrid-mat-tbody tr:last-child > td { border-bottom: none; }
41
+
42
+ .ogrid-mat-wrapper [data-drag-range] { background-color: rgba(33,115,70,0.12) !important; }
43
+ .ogrid-mat-wrapper [data-drag-anchor] { background-color: var(--ogrid-paper-bg, #fff) !important; }
44
+ `;
45
+ var injected = false;
46
+ function injectDataGridStyles() {
47
+ if (injected || typeof document === "undefined") return;
48
+ injected = true;
49
+ const style = document.createElement("style");
50
+ style.setAttribute("data-ogrid-mat", "");
51
+ style.textContent = STYLES;
52
+ document.head.appendChild(style);
53
+ }
54
+ var TextFilterPopover = ({
55
+ value,
56
+ onValueChange,
57
+ onApply,
58
+ onClear
59
+ }) => /* @__PURE__ */ jsxs(Box, { sx: { width: 260 }, children: [
60
+ /* @__PURE__ */ jsx(Box, { sx: { p: 1.5 }, children: /* @__PURE__ */ jsx(
61
+ TextField,
62
+ {
63
+ placeholder: "Enter search term...",
64
+ value,
65
+ onChange: (e) => onValueChange(e.target.value),
66
+ onKeyDown: (e) => {
67
+ e.stopPropagation();
68
+ if (e.key === "Enter") {
69
+ e.preventDefault();
70
+ onApply();
71
+ }
72
+ },
73
+ autoComplete: "off",
74
+ size: "small",
75
+ fullWidth: true,
76
+ slotProps: {
77
+ input: {
78
+ startAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "start", children: /* @__PURE__ */ jsx(Search, { fontSize: "small" }) })
79
+ }
80
+ }
81
+ }
82
+ ) }),
83
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "flex-end", gap: 1, p: 1.5, pt: 0 }, children: [
84
+ /* @__PURE__ */ jsx(Button, { size: "small", disabled: !value, onClick: onClear, children: "Clear" }),
85
+ /* @__PURE__ */ jsx(Button, { size: "small", variant: "contained", onClick: onApply, children: "Apply" })
86
+ ] })
87
+ ] });
88
+ TextFilterPopover.displayName = "TextFilterPopover";
89
+ var ITEM_HEIGHT = 40;
90
+ var MultiSelectFilterPopover = ({
91
+ searchText,
92
+ onSearchChange,
93
+ options,
94
+ filteredOptions,
95
+ selected,
96
+ onOptionToggle,
97
+ onSelectAll,
98
+ onClearSelection,
99
+ onApply,
100
+ isLoading
101
+ }) => {
102
+ const virt = useListVirtualizer({ count: filteredOptions.length, itemHeight: ITEM_HEIGHT, containerHeight: 240 });
103
+ return /* @__PURE__ */ jsxs(Box, { sx: { width: 280 }, children: [
104
+ /* @__PURE__ */ jsxs(Box, { sx: { p: 1.5, pb: 0.5 }, children: [
105
+ /* @__PURE__ */ jsx(
106
+ TextField,
107
+ {
108
+ placeholder: "Search...",
109
+ value: searchText,
110
+ onChange: (e) => onSearchChange(e.target.value),
111
+ onKeyDown: (e) => e.stopPropagation(),
112
+ autoComplete: "off",
113
+ size: "small",
114
+ fullWidth: true,
115
+ slotProps: {
116
+ input: {
117
+ startAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "start", children: /* @__PURE__ */ jsx(Search, { fontSize: "small" }) })
118
+ }
119
+ }
120
+ }
121
+ ),
122
+ /* @__PURE__ */ jsxs(Typography, { variant: "caption", color: "text.secondary", sx: { mt: 0.5, display: "block" }, children: [
123
+ filteredOptions.length,
124
+ " of ",
125
+ options.length,
126
+ " options"
127
+ ] })
128
+ ] }),
129
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "space-between", px: 1.5, py: 0.5 }, children: [
130
+ /* @__PURE__ */ jsxs(Button, { size: "small", onClick: onSelectAll, children: [
131
+ "Select All (",
132
+ filteredOptions.length,
133
+ ")"
134
+ ] }),
135
+ /* @__PURE__ */ jsx(Button, { size: "small", onClick: onClearSelection, children: "Clear" })
136
+ ] }),
137
+ /* @__PURE__ */ jsx(Box, { ref: virt.containerRef, onScroll: virt.onScroll, sx: { maxHeight: 240, overflowY: "auto", px: 0.5 }, children: isLoading ? /* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "center", py: 2 }, children: /* @__PURE__ */ jsx(CircularProgress, { size: 24 }) }) : filteredOptions.length === 0 ? /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { py: 2, textAlign: "center" }, children: "No options found" }) : /* @__PURE__ */ jsx(Box, { sx: { height: virt.totalHeight, position: "relative" }, children: virt.visibleItems.map(({ index, offsetTop }) => {
138
+ const option = filteredOptions[index];
139
+ return /* @__PURE__ */ jsx(
140
+ FormControlLabel,
141
+ {
142
+ control: /* @__PURE__ */ jsx(
143
+ Checkbox,
144
+ {
145
+ size: "small",
146
+ checked: selected.has(option),
147
+ onChange: (e) => onOptionToggle(option, e.target.checked)
148
+ }
149
+ ),
150
+ label: /* @__PURE__ */ jsx(Typography, { variant: "body2", children: option }),
151
+ sx: { position: "absolute", top: offsetTop, width: "100%", height: ITEM_HEIGHT, boxSizing: "border-box", display: "flex", alignItems: "center", mx: 0, "& .MuiFormControlLabel-label": { flex: 1, minWidth: 0 } }
152
+ },
153
+ option
154
+ );
155
+ }) }) }),
156
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "flex-end", gap: 1, p: 1.5, pt: 1, borderTop: 1, borderColor: "divider" }, children: [
157
+ /* @__PURE__ */ jsx(Button, { size: "small", onClick: onClearSelection, children: "Clear" }),
158
+ /* @__PURE__ */ jsx(Button, { size: "small", variant: "contained", onClick: onApply, children: "Apply" })
159
+ ] })
160
+ ] });
161
+ };
162
+ MultiSelectFilterPopover.displayName = "MultiSelectFilterPopover";
163
+ var PeopleFilterPopover = ({
164
+ selectedUser,
165
+ searchText,
166
+ onSearchChange,
167
+ suggestions,
168
+ isLoading,
169
+ onUserSelect,
170
+ onClearUser,
171
+ inputRef
172
+ }) => /* @__PURE__ */ jsxs(Box, { sx: { width: 300 }, children: [
173
+ selectedUser && /* @__PURE__ */ jsxs(Box, { sx: { p: 1.5, pb: 1, borderBottom: 1, borderColor: "divider" }, children: [
174
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", children: "Currently filtered by:" }),
175
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1, mt: 0.5 }, children: [
176
+ /* @__PURE__ */ jsx(Avatar, { src: selectedUser.photo, alt: selectedUser.displayName, sx: { width: 32, height: 32 }, children: selectedUser.displayName?.[0] }),
177
+ /* @__PURE__ */ jsxs(Box, { sx: { flex: 1, minWidth: 0 }, children: [
178
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", noWrap: true, children: selectedUser.displayName }),
179
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", noWrap: true, children: selectedUser.email })
180
+ ] }),
181
+ /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: onClearUser, "aria-label": "Remove filter", children: /* @__PURE__ */ jsx(Clear, { fontSize: "small" }) })
182
+ ] })
183
+ ] }),
184
+ /* @__PURE__ */ jsx(Box, { sx: { p: 1.5, pb: 0.5 }, children: /* @__PURE__ */ jsx(
185
+ TextField,
186
+ {
187
+ inputRef,
188
+ placeholder: "Search for a person...",
189
+ value: searchText,
190
+ onChange: (e) => onSearchChange(e.target.value),
191
+ onKeyDown: (e) => e.stopPropagation(),
192
+ autoComplete: "off",
193
+ size: "small",
194
+ fullWidth: true,
195
+ slotProps: {
196
+ input: {
197
+ startAdornment: /* @__PURE__ */ jsx(InputAdornment, { position: "start", children: /* @__PURE__ */ jsx(Search, { fontSize: "small" }) })
198
+ }
199
+ }
200
+ }
201
+ ) }),
202
+ /* @__PURE__ */ jsx(Box, { sx: { maxHeight: 240, overflowY: "auto" }, children: isLoading && searchText.trim() ? /* @__PURE__ */ jsx(Box, { sx: { display: "flex", justifyContent: "center", py: 2 }, children: /* @__PURE__ */ jsx(CircularProgress, { size: 24 }) }) : suggestions.length === 0 && searchText.trim() ? /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { py: 2, textAlign: "center" }, children: "No results found" }) : searchText.trim() ? suggestions.map((user) => /* @__PURE__ */ jsxs(
203
+ Box,
204
+ {
205
+ onClick: () => onUserSelect(user),
206
+ sx: {
207
+ display: "flex",
208
+ alignItems: "center",
209
+ gap: 1,
210
+ px: 1.5,
211
+ py: 1,
212
+ cursor: "pointer",
213
+ "&:hover": { bgcolor: "action.hover" }
214
+ },
215
+ children: [
216
+ /* @__PURE__ */ jsx(Avatar, { src: user.photo, alt: user.displayName, sx: { width: 32, height: 32 }, children: user.displayName?.[0] }),
217
+ /* @__PURE__ */ jsxs(Box, { sx: { flex: 1, minWidth: 0 }, children: [
218
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", noWrap: true, children: user.displayName }),
219
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "text.secondary", noWrap: true, children: user.email })
220
+ ] })
221
+ ]
222
+ },
223
+ user.id || user.email || user.displayName
224
+ )) : /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { py: 2, textAlign: "center" }, children: "Type to search..." }) }),
225
+ selectedUser && /* @__PURE__ */ jsx(Box, { sx: { p: 1.5, pt: 1, borderTop: 1, borderColor: "divider" }, children: /* @__PURE__ */ jsx(Button, { size: "small", fullWidth: true, onClick: onClearUser, children: "Clear Filter" }) })
226
+ ] });
227
+ PeopleFilterPopover.displayName = "PeopleFilterPopover";
228
+ var materialRenderers = {
229
+ renderMultiSelect: (p) => /* @__PURE__ */ jsx(
230
+ MultiSelectFilterPopover,
231
+ {
232
+ searchText: p.searchText,
233
+ onSearchChange: p.onSearchChange,
234
+ options: p.options,
235
+ filteredOptions: p.filteredOptions,
236
+ selected: p.selected,
237
+ onOptionToggle: p.onOptionToggle,
238
+ onSelectAll: p.onSelectAll,
239
+ onClearSelection: p.onClearSelection,
240
+ onApply: p.onApply,
241
+ isLoading: p.isLoading
242
+ }
243
+ ),
244
+ renderText: (p) => /* @__PURE__ */ jsx(
245
+ TextFilterPopover,
246
+ {
247
+ value: p.value,
248
+ onValueChange: p.onValueChange,
249
+ onApply: p.onApply,
250
+ onClear: p.onClear
251
+ }
252
+ ),
253
+ renderPeople: (p) => /* @__PURE__ */ jsx(
254
+ PeopleFilterPopover,
255
+ {
256
+ selectedUser: p.selectedUser,
257
+ searchText: p.searchText,
258
+ onSearchChange: p.onSearchChange,
259
+ suggestions: p.suggestions,
260
+ isLoading: p.isLoading,
261
+ onUserSelect: p.onUserSelect,
262
+ onClearUser: p.onClearUser,
263
+ inputRef: p.inputRef
264
+ }
265
+ ),
266
+ renderDate: (p) => /* @__PURE__ */ jsxs(Box, { sx: { p: 1.5, display: "flex", flexDirection: "column", gap: 1 }, children: [
267
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
268
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", sx: { minWidth: 36 }, children: "From:" }),
269
+ /* @__PURE__ */ jsx("input", { type: "date", value: p.tempDateFrom, onChange: (e) => p.setTempDateFrom(e.target.value), style: { flex: 1, padding: "4px 6px" } })
270
+ ] }),
271
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
272
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", sx: { minWidth: 36 }, children: "To:" }),
273
+ /* @__PURE__ */ jsx("input", { type: "date", value: p.tempDateTo, onChange: (e) => p.setTempDateTo(e.target.value), style: { flex: 1, padding: "4px 6px" } })
274
+ ] }),
275
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", justifyContent: "flex-end", gap: 1, mt: 0.5 }, children: [
276
+ /* @__PURE__ */ jsx("button", { onClick: p.onClear, disabled: !p.tempDateFrom && !p.tempDateTo, style: { padding: "4px 12px", cursor: "pointer" }, children: "Clear" }),
277
+ /* @__PURE__ */ jsx("button", { onClick: p.onApply, style: { padding: "4px 12px", cursor: "pointer" }, children: "Apply" })
278
+ ] })
279
+ ] })
280
+ };
281
+ var ColumnHeaderFilter = React3.memo((props) => {
282
+ const {
283
+ columnName,
284
+ filterType,
285
+ options = [],
286
+ isLoadingOptions = false,
287
+ selectedUser
288
+ } = props;
289
+ const state = useColumnHeaderFilterState(getColumnHeaderFilterStateParams(props));
290
+ const {
291
+ headerRef,
292
+ isFilterOpen,
293
+ setFilterOpen,
294
+ hasActiveFilter,
295
+ popoverPosition,
296
+ handlers
297
+ } = state;
298
+ return /* @__PURE__ */ jsxs(Box, { ref: headerRef, sx: { display: "flex", alignItems: "center", width: "100%", minWidth: 0 }, children: [
299
+ /* @__PURE__ */ jsx(Box, { sx: { flex: 1, minWidth: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx(Tooltip, { title: columnName, arrow: true, children: /* @__PURE__ */ jsx(
300
+ Typography,
301
+ {
302
+ variant: "body2",
303
+ fontWeight: 600,
304
+ noWrap: true,
305
+ "data-header-label": true,
306
+ sx: { lineHeight: 1.4 },
307
+ children: columnName
308
+ }
309
+ ) }) }),
310
+ /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", ml: 0.5, flexShrink: 0 }, children: filterType !== "none" && /* @__PURE__ */ jsxs(
311
+ IconButton,
312
+ {
313
+ size: "small",
314
+ onClick: handlers.handleFilterIconClick,
315
+ "aria-label": `Filter ${columnName}`,
316
+ title: `Filter ${columnName}`,
317
+ color: hasActiveFilter || isFilterOpen ? "primary" : "default",
318
+ sx: { p: 0.25, position: "relative" },
319
+ children: [
320
+ /* @__PURE__ */ jsx(FilterList, { sx: { fontSize: 16 } }),
321
+ hasActiveFilter && /* @__PURE__ */ jsx(
322
+ Box,
323
+ {
324
+ sx: {
325
+ position: "absolute",
326
+ top: 2,
327
+ right: 2,
328
+ width: 6,
329
+ height: 6,
330
+ borderRadius: "50%",
331
+ bgcolor: "primary.main"
332
+ }
333
+ }
334
+ )
335
+ ]
336
+ }
337
+ ) }),
338
+ /* @__PURE__ */ jsxs(
339
+ Popover,
340
+ {
341
+ open: isFilterOpen && filterType !== "none",
342
+ onClose: () => setFilterOpen(false),
343
+ anchorReference: "anchorPosition",
344
+ anchorPosition: popoverPosition ?? { top: 0, left: 0 },
345
+ anchorOrigin: { vertical: "bottom", horizontal: "left" },
346
+ transformOrigin: { vertical: "top", horizontal: "left" },
347
+ slotProps: {
348
+ paper: {
349
+ sx: { mt: 0.5, overflow: "visible" },
350
+ onClick: (e) => e.stopPropagation()
351
+ }
352
+ },
353
+ children: [
354
+ /* @__PURE__ */ jsx(Box, { sx: { borderBottom: 1, borderColor: "divider", px: 1.5, py: 1 }, children: /* @__PURE__ */ jsxs(Typography, { variant: "subtitle2", children: [
355
+ "Filter: ",
356
+ columnName
357
+ ] }) }),
358
+ renderFilterContent(filterType, state, options ?? [], isLoadingOptions, selectedUser, materialRenderers)
359
+ ]
360
+ }
361
+ )
362
+ ] });
363
+ });
364
+ ColumnHeaderFilter.displayName = "ColumnHeaderFilter";
365
+ function ColumnHeaderMenu(props) {
366
+ const {
367
+ isOpen,
368
+ anchorElement,
369
+ onClose,
370
+ onPinLeft,
371
+ onPinRight,
372
+ onUnpin,
373
+ onSortAsc,
374
+ onSortDesc,
375
+ onClearSort,
376
+ onAutosizeThis,
377
+ onAutosizeAll,
378
+ canPinLeft,
379
+ canPinRight,
380
+ canUnpin,
381
+ currentSort,
382
+ isSortable,
383
+ isResizable
384
+ } = props;
385
+ const [anchorPosition, setAnchorPosition] = useState(void 0);
386
+ useEffect(() => {
387
+ if (isOpen && anchorElement) {
388
+ const rect = anchorElement.getBoundingClientRect();
389
+ setAnchorPosition({
390
+ top: rect.bottom + 4,
391
+ left: rect.left
392
+ });
393
+ } else {
394
+ setAnchorPosition(void 0);
395
+ }
396
+ }, [isOpen, anchorElement]);
397
+ const menuInput = useMemo(
398
+ () => ({
399
+ canPinLeft,
400
+ canPinRight,
401
+ canUnpin,
402
+ currentSort,
403
+ isSortable,
404
+ isResizable
405
+ }),
406
+ [canPinLeft, canPinRight, canUnpin, currentSort, isSortable, isResizable]
407
+ );
408
+ const items = useMemo(() => getColumnHeaderMenuItems(menuInput), [menuInput]);
409
+ const handlers = useMemo(
410
+ () => ({
411
+ pinLeft: onPinLeft,
412
+ pinRight: onPinRight,
413
+ unpin: onUnpin,
414
+ sortAsc: onSortAsc,
415
+ sortDesc: onSortDesc,
416
+ clearSort: onClearSort,
417
+ autosizeThis: onAutosizeThis,
418
+ autosizeAll: onAutosizeAll
419
+ }),
420
+ [onPinLeft, onPinRight, onUnpin, onSortAsc, onSortDesc, onClearSort, onAutosizeThis, onAutosizeAll]
421
+ );
422
+ return /* @__PURE__ */ jsx(
423
+ Menu,
424
+ {
425
+ open: isOpen && !!anchorPosition,
426
+ onClose,
427
+ anchorReference: "anchorPosition",
428
+ anchorPosition,
429
+ slotProps: {
430
+ paper: {
431
+ sx: {
432
+ minWidth: 140
433
+ }
434
+ }
435
+ },
436
+ children: items.flatMap((item, idx) => {
437
+ const elements = [
438
+ /* @__PURE__ */ jsx(
439
+ MenuItem,
440
+ {
441
+ disabled: item.disabled,
442
+ onClick: () => {
443
+ handlers[item.id]();
444
+ onClose();
445
+ },
446
+ children: item.label
447
+ },
448
+ item.id
449
+ )
450
+ ];
451
+ if (item.divider && idx < items.length - 1) {
452
+ elements.push(/* @__PURE__ */ jsx(Divider, {}, `${item.id}-divider`));
453
+ }
454
+ return elements;
455
+ })
456
+ }
457
+ );
458
+ }
459
+ function InlineCellEditor(props) {
460
+ return /* @__PURE__ */ jsx(
461
+ BaseInlineCellEditor,
462
+ {
463
+ ...props,
464
+ renderCheckbox: (checked, onCommit, onCancel) => /* @__PURE__ */ jsx(
465
+ Checkbox,
466
+ {
467
+ checked,
468
+ onChange: (_, c) => onCommit(c),
469
+ onKeyDown: (e) => e.key === "Escape" && (e.preventDefault(), onCancel()),
470
+ size: "small"
471
+ }
472
+ )
473
+ }
474
+ );
475
+ }
476
+ var partSx = (isLast) => ({
477
+ display: "inline-flex",
478
+ alignItems: "center",
479
+ gap: 0.5,
480
+ ...isLast ? {} : { mr: 2, "&::after": { content: '"|"', ml: 2, color: "divider" } }
481
+ });
482
+ function StatusBar(props) {
483
+ const parts = getStatusBarParts(props);
484
+ return /* @__PURE__ */ jsx(Box, { role: "status", "aria-live": "polite", sx: { mt: "auto", px: 1.5, py: 0.75, borderTop: 1, borderColor: "divider", bgcolor: "action.hover" }, children: parts.map((p, i) => /* @__PURE__ */ jsxs(Typography, { component: "span", variant: "body2", sx: partSx(i === parts.length - 1), children: [
485
+ /* @__PURE__ */ jsx(Typography, { component: "span", color: "text.secondary", children: p.label }),
486
+ /* @__PURE__ */ jsx(Typography, { component: "span", fontWeight: 600, children: p.value.toLocaleString() })
487
+ ] }, p.key)) });
488
+ }
489
+ function GridContextMenu(props) {
490
+ const { x, y, hasSelection, canUndo, canRedo, onClose } = props;
491
+ const handlers = React3.useMemo(() => getContextMenuHandlers(props), [props]);
492
+ const isDisabled = React3.useCallback(
493
+ (item) => {
494
+ if (item.disabledWhenNoSelection && !hasSelection) return true;
495
+ if (item.id === "undo" && !canUndo) return true;
496
+ if (item.id === "redo" && !canRedo) return true;
497
+ return false;
498
+ },
499
+ [hasSelection, canUndo, canRedo]
500
+ );
501
+ return /* @__PURE__ */ jsx(
502
+ Menu,
503
+ {
504
+ open: true,
505
+ onClose,
506
+ anchorReference: "anchorPosition",
507
+ anchorPosition: { top: y, left: x },
508
+ MenuListProps: { dense: true, "aria-label": "Grid context menu" },
509
+ children: GRID_CONTEXT_MENU_ITEMS.flatMap((item) => {
510
+ const elements = [];
511
+ if (item.dividerBefore) {
512
+ elements.push(/* @__PURE__ */ jsx(Divider, {}, `${item.id}-divider`));
513
+ }
514
+ elements.push(
515
+ /* @__PURE__ */ jsxs(
516
+ MenuItem,
517
+ {
518
+ onClick: handlers[item.id],
519
+ disabled: isDisabled(item),
520
+ children: [
521
+ /* @__PURE__ */ jsx("span", { style: { flex: 1 }, children: item.label }),
522
+ item.shortcut && /* @__PURE__ */ jsx("span", { style: { marginLeft: 24, color: "var(--ogrid-fg-muted, rgba(0,0,0,0.4))", fontSize: "0.8em" }, children: formatShortcut(item.shortcut) })
523
+ ]
524
+ },
525
+ item.id
526
+ )
527
+ );
528
+ return elements;
529
+ })
530
+ }
531
+ );
532
+ }
533
+ var EMPTY_STATE_SX = { py: 4, px: 2, textAlign: "center", borderTop: 1, borderColor: "divider", bgcolor: "action.hover" };
534
+ function EmptyState({ emptyState }) {
535
+ return /* @__PURE__ */ jsx(Box, { sx: EMPTY_STATE_SX, children: emptyState.render ? emptyState.render() : /* @__PURE__ */ jsxs(Fragment, { children: [
536
+ /* @__PURE__ */ jsx(Typography, { variant: "h6", gutterBottom: true, children: "No results found" }),
537
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: emptyState.message != null ? emptyState.message : emptyState.hasActiveFilters ? /* @__PURE__ */ jsxs(Fragment, { children: [
538
+ "No items match your current filters. Try adjusting your search or",
539
+ " ",
540
+ /* @__PURE__ */ jsx(Button, { variant: "text", size: "small", onClick: emptyState.onClearAll, children: "clear all filters" }),
541
+ " ",
542
+ "to see all items."
543
+ ] }) : "There are no items available at this time." })
544
+ ] }) });
545
+ }
546
+ var LOADING_OVERLAY_SX = {
547
+ position: "absolute",
548
+ inset: 0,
549
+ zIndex: 2,
550
+ display: "flex",
551
+ alignItems: "center",
552
+ justifyContent: "center",
553
+ background: "var(--ogrid-loading-bg, rgba(255,255,255,0.7))"
554
+ };
555
+ var LOADING_INNER_SX = {
556
+ display: "flex",
557
+ flexDirection: "column",
558
+ alignItems: "center",
559
+ gap: 1,
560
+ p: 2,
561
+ bgcolor: "background.paper",
562
+ border: 1,
563
+ borderColor: "divider",
564
+ borderRadius: 1
565
+ };
566
+ function LoadingOverlay({ message }) {
567
+ return /* @__PURE__ */ jsx(Box, { sx: LOADING_OVERLAY_SX, children: /* @__PURE__ */ jsxs(Box, { sx: LOADING_INNER_SX, children: [
568
+ /* @__PURE__ */ jsx(CircularProgress, { size: 24 }),
569
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: message })
570
+ ] }) });
571
+ }
572
+ function DropIndicator({ dropIndicatorX, wrapperLeft }) {
573
+ return /* @__PURE__ */ jsx(
574
+ Box,
575
+ {
576
+ sx: {
577
+ position: "absolute",
578
+ top: 0,
579
+ bottom: 0,
580
+ width: 3,
581
+ bgcolor: "var(--ogrid-primary, #217346)",
582
+ pointerEvents: "none",
583
+ zIndex: 100,
584
+ transition: "left 0.05s",
585
+ left: dropIndicatorX - wrapperLeft
586
+ }
587
+ }
588
+ );
589
+ }
590
+ var gridRootSx = { position: "relative", flex: 1, minHeight: 0, display: "flex", flexDirection: "column" };
591
+ var EDITING_CELL_STYLE = {
592
+ width: "100%",
593
+ height: "100%",
594
+ display: "flex",
595
+ alignItems: "center",
596
+ boxSizing: "border-box",
597
+ outline: "2px solid var(--ogrid-selection-color, #217346)",
598
+ outlineOffset: "-1px",
599
+ zIndex: 2,
600
+ position: "relative",
601
+ background: "var(--ogrid-bg, #fff)",
602
+ overflow: "visible",
603
+ padding: 0
604
+ };
605
+ var CHECKBOX_CELL_SX = { width: CHECKBOX_COLUMN_WIDTH, minWidth: CHECKBOX_COLUMN_WIDTH, maxWidth: CHECKBOX_COLUMN_WIDTH, textAlign: "center" };
606
+ var CHECKBOX_PLACEHOLDER_SX = { width: CHECKBOX_COLUMN_WIDTH, minWidth: CHECKBOX_COLUMN_WIDTH, p: 0 };
607
+ var CHECKBOX_TD_STYLE = {
608
+ width: CHECKBOX_COLUMN_WIDTH,
609
+ minWidth: CHECKBOX_COLUMN_WIDTH,
610
+ maxWidth: CHECKBOX_COLUMN_WIDTH,
611
+ textAlign: "center",
612
+ padding: 0,
613
+ position: "relative",
614
+ height: "1px",
615
+ borderBottom: "1px solid var(--ogrid-border, rgba(224,224,224,1))"
616
+ };
617
+ var HEADER_BG = "var(--ogrid-header-bg, #f5f5f5)";
618
+ var STICKY_HEADER_SX = {
619
+ /* Removed position: 'sticky', top: 0 - breaks horizontal sticky on pinned columns.
620
+ Instead, apply sticky to individual header cells (HEADER_BASE_SX). */
621
+ zIndex: 8,
622
+ bgcolor: HEADER_BG,
623
+ "& th": { bgcolor: HEADER_BG }
624
+ };
625
+ var HEADER_ROW_SX = { bgcolor: HEADER_BG };
626
+ var GROUP_HEADER_CELL_SX = { textAlign: "center", fontWeight: 600, borderBottom: 2, borderColor: "divider", py: 0.75 };
627
+ function getDensityPadding(density) {
628
+ switch (density) {
629
+ case "compact":
630
+ return { px: "8px", py: "4px" };
631
+ case "comfortable":
632
+ return { px: "16px", py: "12px" };
633
+ default:
634
+ return { px: "10px", py: "6px" };
635
+ }
636
+ }
637
+ var DENSITY_CELL_STYLES = {
638
+ compact: { padding: "4px 8px" },
639
+ normal: { padding: "6px 10px" },
640
+ comfortable: { padding: "12px 16px" }
641
+ };
642
+ var HEADER_BASE_SX = {
643
+ fontWeight: 600,
644
+ position: "sticky",
645
+ /* Enables vertical sticky for all headers */
646
+ top: 0,
647
+ /* Sticky vertically */
648
+ zIndex: 8,
649
+ /* Stack above body cells */
650
+ bgcolor: HEADER_BG
651
+ /* Opaque — required for sticky overlap */
652
+ };
653
+ var HEADER_PINNED_LEFT_SX = {
654
+ ...HEADER_BASE_SX,
655
+ position: "sticky",
656
+ left: 0,
657
+ top: 0,
658
+ zIndex: 10,
659
+ bgcolor: HEADER_BG,
660
+ willChange: "transform",
661
+ borderRight: "1px solid",
662
+ borderRightColor: "divider",
663
+ boxShadow: "2px 0 4px -1px rgba(0,0,0,0.1)"
664
+ };
665
+ var HEADER_PINNED_RIGHT_SX = {
666
+ ...HEADER_BASE_SX,
667
+ position: "sticky",
668
+ right: 0,
669
+ top: 0,
670
+ zIndex: 10,
671
+ bgcolor: HEADER_BG,
672
+ willChange: "transform",
673
+ borderLeft: "1px solid",
674
+ borderLeftColor: "divider",
675
+ boxShadow: "-2px 0 4px -1px rgba(0,0,0,0.1)"
676
+ };
677
+ var HEADER_BASE_NO_STICKY_SX = {
678
+ fontWeight: 600,
679
+ zIndex: 8,
680
+ bgcolor: HEADER_BG
681
+ };
682
+ var HEADER_PINNED_LEFT_NO_STICKY_SX = {
683
+ ...HEADER_BASE_NO_STICKY_SX,
684
+ position: "sticky",
685
+ left: 0,
686
+ zIndex: 10,
687
+ bgcolor: HEADER_BG,
688
+ willChange: "transform",
689
+ borderRight: "1px solid",
690
+ borderRightColor: "divider",
691
+ boxShadow: "2px 0 4px -1px rgba(0,0,0,0.1)"
692
+ };
693
+ var HEADER_PINNED_RIGHT_NO_STICKY_SX = {
694
+ ...HEADER_BASE_NO_STICKY_SX,
695
+ position: "sticky",
696
+ right: 0,
697
+ zIndex: 10,
698
+ bgcolor: HEADER_BG,
699
+ willChange: "transform",
700
+ borderLeft: "1px solid",
701
+ borderLeftColor: "divider",
702
+ boxShadow: "-2px 0 4px -1px rgba(0,0,0,0.1)"
703
+ };
704
+ var RESIZE_HANDLE_SX = {
705
+ position: "absolute",
706
+ top: 0,
707
+ right: "-3px",
708
+ bottom: 0,
709
+ width: "8px",
710
+ cursor: "col-resize",
711
+ userSelect: "none",
712
+ "&::after": { content: '""', position: "absolute", top: 0, right: "3px", bottom: 0, width: "2px" },
713
+ "&:hover::after": { bgcolor: "primary.main" },
714
+ "&:active::after": { bgcolor: "primary.dark" }
715
+ };
716
+ var POPOVER_ANCHOR_SX = { minHeight: "100%", minWidth: 40 };
717
+ var POPOVER_CONTENT_SX = { p: 1 };
718
+ var WRAPPER_SCROLL_SX = { display: "flex", flexDirection: "column", minHeight: "100%" };
719
+ var HEADER_CONTENT_FLEX_SX = { display: "flex", alignItems: "center", gap: 0.5 };
720
+ var COLUMN_OPTIONS_BUTTON_SX = {
721
+ background: "transparent",
722
+ border: "none",
723
+ cursor: "pointer",
724
+ padding: "2px 4px",
725
+ fontSize: "16px",
726
+ lineHeight: 1,
727
+ color: "text.secondary",
728
+ opacity: 1,
729
+ transition: "background-color 0.15s",
730
+ borderRadius: "3px",
731
+ display: "flex",
732
+ alignItems: "center",
733
+ justifyContent: "center",
734
+ minWidth: "20px",
735
+ height: "20px",
736
+ "&:hover": {
737
+ bgcolor: "action.hover"
738
+ }
739
+ };
740
+ var TABLE_WRAPPER_SX = { position: "relative", opacity: 1 };
741
+ var TABLE_WRAPPER_LOADING_SX = { position: "relative", opacity: 0.6 };
742
+ function GridRowInner(props) {
743
+ const {
744
+ item,
745
+ rowIndex,
746
+ rowId,
747
+ isSelected,
748
+ columnLayouts,
749
+ renderCellContent,
750
+ handleSingleRowClick,
751
+ handleRowCheckboxChange,
752
+ lastMouseShiftRef,
753
+ hasCheckboxCol,
754
+ hasRowNumbersCol,
755
+ rowNumberOffset,
756
+ rowHeight
757
+ } = props;
758
+ return /* @__PURE__ */ jsxs(
759
+ "tr",
760
+ {
761
+ "data-row-id": rowId,
762
+ onClick: handleSingleRowClick,
763
+ "aria-selected": isSelected || void 0,
764
+ className: `ogrid-mat-row${isSelected ? " ogrid-mat-row--selected" : ""}`,
765
+ style: rowHeight ? { height: rowHeight } : void 0,
766
+ children: [
767
+ hasCheckboxCol && /* @__PURE__ */ jsx("td", { style: CHECKBOX_TD_STYLE, children: /* @__PURE__ */ jsx(
768
+ "div",
769
+ {
770
+ "data-row-index": rowIndex,
771
+ "data-col-index": 0,
772
+ onClick: STOP_PROPAGATION,
773
+ className: "ogrid-mat-checkbox-wrapper",
774
+ children: /* @__PURE__ */ jsx(
775
+ Checkbox,
776
+ {
777
+ checked: isSelected,
778
+ onChange: (_, checked) => handleRowCheckboxChange(rowId, checked, rowIndex, lastMouseShiftRef.current),
779
+ size: "small",
780
+ "aria-label": `Select row ${rowIndex + 1}`
781
+ }
782
+ )
783
+ }
784
+ ) }),
785
+ hasRowNumbersCol && /* @__PURE__ */ jsx(
786
+ "td",
787
+ {
788
+ className: "ogrid-mat-td ogrid-mat-row-number",
789
+ style: {
790
+ width: ROW_NUMBER_COLUMN_WIDTH,
791
+ minWidth: ROW_NUMBER_COLUMN_WIDTH,
792
+ maxWidth: ROW_NUMBER_COLUMN_WIDTH,
793
+ left: hasCheckboxCol ? CHECKBOX_COLUMN_WIDTH : 0,
794
+ borderBottom: "1px solid var(--ogrid-border, rgba(224,224,224,1))"
795
+ },
796
+ children: rowNumberOffset + rowIndex + 1
797
+ }
798
+ ),
799
+ columnLayouts.map((cl, colIdx) => /* @__PURE__ */ jsx(
800
+ "td",
801
+ {
802
+ "data-column-id": cl.col.columnId,
803
+ className: cl.tdClassName,
804
+ style: { ...cl.tdStyle, minWidth: cl.minWidth, width: cl.width, maxWidth: cl.maxWidth },
805
+ children: renderCellContent(item, cl.col, rowIndex, colIdx)
806
+ },
807
+ cl.col.columnId
808
+ ))
809
+ ]
810
+ }
811
+ );
812
+ }
813
+ var GridRow = React3.memo(GridRowInner, areGridRowPropsEqual);
814
+ injectDataGridStyles();
815
+ function DataGridTableInner(props) {
816
+ const o = useDataGridTableOrchestration({ props });
817
+ const {
818
+ wrapperRef,
819
+ tableContainerRef,
820
+ lastMouseShiftRef,
821
+ interaction,
822
+ pinning,
823
+ handleResizeStart,
824
+ getColumnWidth,
825
+ isReorderDragging,
826
+ dropIndicatorX,
827
+ handleHeaderMouseDown,
828
+ virtualScrollEnabled,
829
+ visibleRange,
830
+ items,
831
+ getRowId,
832
+ emptyState,
833
+ suppressHorizontalScroll,
834
+ isLoading,
835
+ loadingMessage,
836
+ ariaLabel,
837
+ ariaLabelledBy,
838
+ columnReorder,
839
+ density,
840
+ rowHeight,
841
+ rowNumberOffset,
842
+ headerRows,
843
+ allowOverflowX,
844
+ fitToContent,
845
+ editCallbacks,
846
+ interactionHandlers,
847
+ cellDescriptorInputRef,
848
+ pendingEditorValueRef,
849
+ popoverAnchorElRef,
850
+ handleSingleRowClick,
851
+ handlePasteVoid,
852
+ visibleCols,
853
+ hasCheckboxCol,
854
+ hasRowNumbersCol,
855
+ colOffset,
856
+ minTableWidth,
857
+ columnSizingOverrides,
858
+ measuredColumnWidths,
859
+ selectedRowIds,
860
+ handleRowCheckboxChange,
861
+ handleSelectAll,
862
+ allSelected,
863
+ someSelected,
864
+ editingCell,
865
+ setPopoverAnchorEl,
866
+ cancelPopoverEdit,
867
+ setActiveCell,
868
+ selectionRange,
869
+ hasCellSelection,
870
+ handleGridKeyDown,
871
+ handleFillHandleMouseDown,
872
+ handleCopy,
873
+ handleCut,
874
+ cutRange,
875
+ copyRange,
876
+ canUndo,
877
+ canRedo,
878
+ onUndo,
879
+ onRedo,
880
+ isDragging,
881
+ menuPosition,
882
+ closeContextMenu,
883
+ headerFilterInput,
884
+ statusBarConfig,
885
+ showEmptyInGrid,
886
+ onCellError,
887
+ headerMenu
888
+ } = o;
889
+ const densityPadding = useMemo(() => getDensityPadding(density), [density]);
890
+ const headerCellSx = useMemo(() => ({ px: densityPadding.px, py: densityPadding.py }), [densityPadding]);
891
+ const columnMeta = useColumnMeta({
892
+ visibleCols,
893
+ getColumnWidth,
894
+ columnSizingOverrides,
895
+ measuredColumnWidths,
896
+ pinnedColumns: pinning.pinnedColumns,
897
+ leftOffsets: pinning.leftOffsets,
898
+ rightOffsets: pinning.rightOffsets,
899
+ pinnedColLeftClass: "",
900
+ pinnedColRightClass: ""
901
+ });
902
+ const columnLayouts = useMemo(
903
+ () => visibleCols.map((col) => {
904
+ const isPinnedLeft = pinning.pinnedColumns[col.columnId] === "left";
905
+ const isPinnedRight = pinning.pinnedColumns[col.columnId] === "right";
906
+ let tdClassName = "ogrid-mat-td";
907
+ const tdStyle = {};
908
+ if (isPinnedLeft) {
909
+ tdClassName += " ogrid-mat-td--pinned-left";
910
+ if (pinning.leftOffsets[col.columnId] != null) tdStyle.left = pinning.leftOffsets[col.columnId];
911
+ } else if (isPinnedRight) {
912
+ tdClassName += " ogrid-mat-td--pinned-right";
913
+ if (pinning.rightOffsets[col.columnId] != null) tdStyle.right = pinning.rightOffsets[col.columnId];
914
+ }
915
+ const cellMeta = columnMeta.cellStyles[col.columnId];
916
+ return {
917
+ col,
918
+ tdClassName,
919
+ tdStyle,
920
+ minWidth: cellMeta?.minWidth ?? 0,
921
+ width: cellMeta?.width ?? getColumnWidth(col),
922
+ maxWidth: cellMeta?.maxWidth ?? getColumnWidth(col)
923
+ };
924
+ }),
925
+ [visibleCols, columnMeta, pinning.pinnedColumns, pinning.leftOffsets, pinning.rightOffsets, getColumnWidth]
926
+ );
927
+ const wrapperSx = useMemo(() => ({
928
+ position: "relative",
929
+ flex: 1,
930
+ minHeight: isLoading && items.length === 0 ? 200 : 0,
931
+ width: fitToContent ? "fit-content" : "100%",
932
+ maxWidth: "100%",
933
+ overflowX: suppressHorizontalScroll ? "hidden" : allowOverflowX ? "auto" : "hidden",
934
+ overflowY: "auto",
935
+ bgcolor: "background.paper",
936
+ willChange: "scroll-position"
937
+ }), [fitToContent, suppressHorizontalScroll, allowOverflowX, isLoading, items.length]);
938
+ const cellDensityStyle = DENSITY_CELL_STYLES[density] ?? DENSITY_CELL_STYLES.normal;
939
+ const renderCellContent = useCallback(
940
+ (item, col, rowIndex, colIdx) => {
941
+ const descriptor = getCellRenderDescriptor(item, col, rowIndex, colIdx, cellDescriptorInputRef.current);
942
+ const rowId = getRowId(item);
943
+ let cellContent;
944
+ if (descriptor.mode === "editing-inline") {
945
+ cellContent = /* @__PURE__ */ jsx("div", { style: EDITING_CELL_STYLE, children: /* @__PURE__ */ jsx(InlineCellEditor, { ...buildInlineEditorProps(item, col, descriptor, editCallbacks) }) });
946
+ } else if (descriptor.mode === "editing-popover" && typeof col.cellEditor === "function") {
947
+ const editorProps = buildPopoverEditorProps(item, col, descriptor, pendingEditorValueRef.current, editCallbacks);
948
+ const CustomEditor = col.cellEditor;
949
+ cellContent = /* @__PURE__ */ jsxs(Fragment, { children: [
950
+ /* @__PURE__ */ jsx(Box, { ref: (el) => {
951
+ if (el) setPopoverAnchorEl(el);
952
+ }, sx: POPOVER_ANCHOR_SX, "aria-hidden": true }),
953
+ /* @__PURE__ */ jsx(
954
+ Popover,
955
+ {
956
+ open: !!popoverAnchorElRef.current,
957
+ anchorEl: popoverAnchorElRef.current,
958
+ onClose: cancelPopoverEdit,
959
+ anchorOrigin: { vertical: "bottom", horizontal: "left" },
960
+ transformOrigin: { vertical: "top", horizontal: "left" },
961
+ children: /* @__PURE__ */ jsx(Box, { sx: POPOVER_CONTENT_SX, children: /* @__PURE__ */ jsx(CustomEditor, { ...editorProps }) })
962
+ }
963
+ )
964
+ ] });
965
+ } else {
966
+ const content = resolveCellDisplayContent(col, item, descriptor.displayValue);
967
+ const cellStyle = resolveCellStyle(col, item);
968
+ const styledContent = cellStyle ? /* @__PURE__ */ jsx("span", { style: cellStyle, children: content }) : content;
969
+ let cls = "ogrid-mat-cell";
970
+ if (col.type === "numeric") cls += " ogrid-mat-cell--numeric";
971
+ else if (col.type === "boolean") cls += " ogrid-mat-cell--boolean";
972
+ if (descriptor.canEditAny) cls += " ogrid-mat-cell--editable";
973
+ if (descriptor.isActive && !descriptor.isInRange) cls += " ogrid-mat-cell--active";
974
+ if (descriptor.isInRange) cls += " ogrid-mat-cell--range";
975
+ if (descriptor.isInCutRange) cls += " ogrid-mat-cell--cut";
976
+ const interactionProps = getCellInteractionProps(descriptor, col.columnId, interactionHandlers);
977
+ cellContent = /* @__PURE__ */ jsxs(
978
+ "div",
979
+ {
980
+ className: cls,
981
+ ...interactionProps,
982
+ style: cellDensityStyle,
983
+ children: [
984
+ styledContent,
985
+ descriptor.canEditAny && descriptor.isSelectionEndCell && /* @__PURE__ */ jsx("div", { className: "ogrid-mat-fill-handle", onMouseDown: handleFillHandleMouseDown, "aria-label": "Fill handle" })
986
+ ]
987
+ }
988
+ );
989
+ }
990
+ return /* @__PURE__ */ jsx(CellErrorBoundary, { onError: onCellError, children: cellContent }, `${rowId}-${col.columnId}`);
991
+ },
992
+ [editCallbacks, interactionHandlers, handleFillHandleMouseDown, setPopoverAnchorEl, cancelPopoverEdit, getRowId, onCellError, cellDescriptorInputRef, cellDensityStyle, pendingEditorValueRef, popoverAnchorElRef]
993
+ );
994
+ return /* @__PURE__ */ jsxs(Box, { sx: gridRootSx, children: [
995
+ /* @__PURE__ */ jsxs(
996
+ Box,
997
+ {
998
+ ref: wrapperRef,
999
+ tabIndex: 0,
1000
+ role: "region",
1001
+ "aria-label": ariaLabel ?? (ariaLabelledBy ? void 0 : "Data grid"),
1002
+ "aria-labelledby": ariaLabelledBy,
1003
+ onMouseDown: (e) => {
1004
+ lastMouseShiftRef.current = e.shiftKey;
1005
+ },
1006
+ onKeyDown: handleGridKeyDown,
1007
+ onContextMenu: PREVENT_DEFAULT,
1008
+ "data-overflow-x": allowOverflowX ? "true" : "false",
1009
+ "data-density": density,
1010
+ className: "ogrid-mat-wrapper",
1011
+ sx: wrapperSx,
1012
+ children: [
1013
+ /* @__PURE__ */ jsx(Box, { sx: WRAPPER_SCROLL_SX, children: /* @__PURE__ */ jsx("div", { style: { minWidth: allowOverflowX ? minTableWidth : void 0 }, children: /* @__PURE__ */ jsxs(Box, { ref: tableContainerRef, sx: isLoading && items.length > 0 ? TABLE_WRAPPER_LOADING_SX : TABLE_WRAPPER_SX, children: [
1014
+ /* @__PURE__ */ jsxs(
1015
+ Table,
1016
+ {
1017
+ size: "small",
1018
+ sx: { minWidth: minTableWidth, borderCollapse: "separate", borderSpacing: 0 },
1019
+ children: [
1020
+ /* @__PURE__ */ jsx(TableHead, { sx: STICKY_HEADER_SX, children: headerRows.map((row, rowIdx) => /* @__PURE__ */ jsxs(TableRow, { sx: HEADER_ROW_SX, children: [
1021
+ rowIdx === headerRows.length - 1 && hasCheckboxCol && /* @__PURE__ */ jsx(
1022
+ TableCell,
1023
+ {
1024
+ ...{ padding: "checkbox", rowSpan: headerRows.length > 1 ? 1 : void 0, sx: CHECKBOX_CELL_SX },
1025
+ children: /* @__PURE__ */ jsx(
1026
+ Checkbox,
1027
+ {
1028
+ checked: allSelected,
1029
+ indeterminate: someSelected,
1030
+ onChange: (_, c) => handleSelectAll(!!c),
1031
+ size: "small",
1032
+ "aria-label": "Select all rows"
1033
+ }
1034
+ )
1035
+ }
1036
+ ),
1037
+ rowIdx === 0 && rowIdx < headerRows.length - 1 && hasCheckboxCol && /* @__PURE__ */ jsx(TableCell, { ...{ rowSpan: headerRows.length - 1, sx: CHECKBOX_PLACEHOLDER_SX } }),
1038
+ rowIdx === headerRows.length - 1 && hasRowNumbersCol && /* @__PURE__ */ jsx(
1039
+ TableCell,
1040
+ {
1041
+ ...{
1042
+ component: "th",
1043
+ scope: "col",
1044
+ rowSpan: headerRows.length > 1 ? 1 : void 0,
1045
+ sx: {
1046
+ width: ROW_NUMBER_COLUMN_WIDTH,
1047
+ minWidth: ROW_NUMBER_COLUMN_WIDTH,
1048
+ maxWidth: ROW_NUMBER_COLUMN_WIDTH,
1049
+ textAlign: "center",
1050
+ fontWeight: 600,
1051
+ backgroundColor: HEADER_BG,
1052
+ position: "sticky",
1053
+ left: hasCheckboxCol ? CHECKBOX_COLUMN_WIDTH : 0,
1054
+ zIndex: 4,
1055
+ ...headerCellSx
1056
+ }
1057
+ },
1058
+ children: "#"
1059
+ }
1060
+ ),
1061
+ rowIdx === 0 && rowIdx < headerRows.length - 1 && hasRowNumbersCol && /* @__PURE__ */ jsx(
1062
+ TableCell,
1063
+ {
1064
+ ...{
1065
+ rowSpan: headerRows.length - 1,
1066
+ sx: {
1067
+ width: ROW_NUMBER_COLUMN_WIDTH,
1068
+ minWidth: ROW_NUMBER_COLUMN_WIDTH,
1069
+ position: "sticky",
1070
+ left: hasCheckboxCol ? CHECKBOX_COLUMN_WIDTH : 0,
1071
+ zIndex: 4,
1072
+ backgroundColor: "background.paper"
1073
+ }
1074
+ }
1075
+ }
1076
+ ),
1077
+ row.map((cell, cellIdx) => {
1078
+ if (cell.isGroup) {
1079
+ return /* @__PURE__ */ jsx(
1080
+ TableCell,
1081
+ {
1082
+ ...{
1083
+ colSpan: cell.colSpan,
1084
+ component: "th",
1085
+ scope: "colgroup",
1086
+ sx: GROUP_HEADER_CELL_SX
1087
+ },
1088
+ children: cell.label
1089
+ },
1090
+ cellIdx
1091
+ );
1092
+ }
1093
+ if (!cell.columnDef) return null;
1094
+ const col = cell.columnDef;
1095
+ const isPinnedLeft = pinning.pinnedColumns[col.columnId] === "left";
1096
+ const isPinnedRight = pinning.pinnedColumns[col.columnId] === "right";
1097
+ const baseHeaderSx = o.stickyHeader ? isPinnedLeft ? HEADER_PINNED_LEFT_SX : isPinnedRight ? HEADER_PINNED_RIGHT_SX : HEADER_BASE_SX : isPinnedLeft ? HEADER_PINNED_LEFT_NO_STICKY_SX : isPinnedRight ? HEADER_PINNED_RIGHT_NO_STICKY_SX : HEADER_BASE_NO_STICKY_SX;
1098
+ const headerSx = isPinnedLeft && pinning.leftOffsets[col.columnId] != null ? { ...baseHeaderSx, left: pinning.leftOffsets[col.columnId] } : isPinnedRight && pinning.rightOffsets[col.columnId] != null ? { ...baseHeaderSx, right: pinning.rightOffsets[col.columnId] } : baseHeaderSx;
1099
+ const hdrStyle = columnMeta.hdrStyles[col.columnId];
1100
+ const isSorted = props.sortBy === col.columnId;
1101
+ const ariaSort = isSorted ? props.sortDirection === "asc" ? "ascending" : "descending" : void 0;
1102
+ return /* @__PURE__ */ jsxs(
1103
+ TableCell,
1104
+ {
1105
+ ...{
1106
+ component: "th",
1107
+ scope: "col",
1108
+ "data-column-id": col.columnId,
1109
+ rowSpan: headerRows.length > 1 ? headerRows.length - rowIdx : void 0,
1110
+ "aria-sort": ariaSort,
1111
+ sx: {
1112
+ ...headerSx,
1113
+ ...headerCellSx,
1114
+ minWidth: hdrStyle?.minWidth,
1115
+ width: hdrStyle?.width,
1116
+ maxWidth: hdrStyle?.maxWidth,
1117
+ ...columnReorder ? { cursor: isReorderDragging ? "grabbing" : "grab" } : {},
1118
+ "&:focus-visible": {
1119
+ outline: "2px solid",
1120
+ outlineColor: "primary.main",
1121
+ outlineOffset: "-2px",
1122
+ zIndex: 11
1123
+ }
1124
+ },
1125
+ onMouseDown: columnReorder ? (e) => handleHeaderMouseDown(col.columnId, e) : void 0
1126
+ },
1127
+ children: [
1128
+ /* @__PURE__ */ jsxs(Box, { sx: HEADER_CONTENT_FLEX_SX, children: [
1129
+ /* @__PURE__ */ jsx(ColumnHeaderFilter, { ...getHeaderFilterConfig(col, headerFilterInput) }),
1130
+ /* @__PURE__ */ jsx(
1131
+ Box,
1132
+ {
1133
+ component: "button",
1134
+ onClick: (e) => {
1135
+ e.stopPropagation();
1136
+ headerMenu.open(col.columnId, e.currentTarget);
1137
+ },
1138
+ "aria-label": "Column options",
1139
+ title: "Column options",
1140
+ sx: COLUMN_OPTIONS_BUTTON_SX,
1141
+ children: "\u22EE"
1142
+ }
1143
+ )
1144
+ ] }),
1145
+ /* @__PURE__ */ jsx(Box, { onMouseDown: (e) => {
1146
+ setActiveCell(null);
1147
+ interaction.setSelectionRange(null);
1148
+ wrapperRef.current?.focus({ preventScroll: true });
1149
+ handleResizeStart(e, col);
1150
+ }, sx: RESIZE_HANDLE_SX })
1151
+ ]
1152
+ },
1153
+ col.columnId
1154
+ );
1155
+ })
1156
+ ] }, rowIdx)) }),
1157
+ !showEmptyInGrid && /* @__PURE__ */ jsxs("tbody", { className: "ogrid-mat-tbody", children: [
1158
+ virtualScrollEnabled && visibleRange.offsetTop > 0 && /* @__PURE__ */ jsx("tr", { style: { height: visibleRange.offsetTop }, "aria-hidden": true }),
1159
+ virtualScrollEnabled ? items.slice(visibleRange.startIndex, visibleRange.endIndex + 1).map((item, i) => {
1160
+ const rowIndex = visibleRange.startIndex + i;
1161
+ const rowIdStr = getRowId(item);
1162
+ return /* @__PURE__ */ jsx(
1163
+ GridRow,
1164
+ {
1165
+ item,
1166
+ rowIndex,
1167
+ rowId: rowIdStr,
1168
+ isSelected: selectedRowIds.has(rowIdStr),
1169
+ columnLayouts,
1170
+ renderCellContent,
1171
+ handleSingleRowClick,
1172
+ handleRowCheckboxChange,
1173
+ lastMouseShiftRef,
1174
+ hasCheckboxCol,
1175
+ hasRowNumbersCol,
1176
+ rowNumberOffset,
1177
+ selectionRange,
1178
+ activeCell: interaction.activeCell,
1179
+ cutRange,
1180
+ copyRange,
1181
+ isDragging,
1182
+ rowHeight,
1183
+ editingRowId: editingCell?.rowId ?? null
1184
+ },
1185
+ rowIdStr
1186
+ );
1187
+ }) : items.map((item, rowIndex) => {
1188
+ const rowIdStr = getRowId(item);
1189
+ return /* @__PURE__ */ jsx(
1190
+ GridRow,
1191
+ {
1192
+ item,
1193
+ rowIndex,
1194
+ rowId: rowIdStr,
1195
+ isSelected: selectedRowIds.has(rowIdStr),
1196
+ columnLayouts,
1197
+ renderCellContent,
1198
+ handleSingleRowClick,
1199
+ handleRowCheckboxChange,
1200
+ lastMouseShiftRef,
1201
+ hasCheckboxCol,
1202
+ hasRowNumbersCol,
1203
+ rowNumberOffset,
1204
+ selectionRange,
1205
+ activeCell: interaction.activeCell,
1206
+ cutRange,
1207
+ copyRange,
1208
+ isDragging,
1209
+ rowHeight,
1210
+ editingRowId: editingCell?.rowId ?? null
1211
+ },
1212
+ rowIdStr
1213
+ );
1214
+ }),
1215
+ virtualScrollEnabled && visibleRange.offsetBottom > 0 && /* @__PURE__ */ jsx("tr", { style: { height: visibleRange.offsetBottom }, "aria-hidden": true })
1216
+ ] })
1217
+ ]
1218
+ }
1219
+ ),
1220
+ isReorderDragging && dropIndicatorX != null && /* @__PURE__ */ jsx(DropIndicator, { dropIndicatorX, wrapperLeft: wrapperRef.current?.getBoundingClientRect().left ?? 0 }),
1221
+ /* @__PURE__ */ jsx(
1222
+ MarchingAntsOverlay,
1223
+ {
1224
+ containerRef: tableContainerRef,
1225
+ selectionRange,
1226
+ copyRange,
1227
+ cutRange,
1228
+ colOffset,
1229
+ items,
1230
+ visibleColumns: props.visibleColumns,
1231
+ columnSizingOverrides,
1232
+ columnOrder: props.columnOrder
1233
+ }
1234
+ ),
1235
+ showEmptyInGrid && emptyState && /* @__PURE__ */ jsx(EmptyState, { emptyState })
1236
+ ] }) }) }),
1237
+ menuPosition && createPortal(
1238
+ /* @__PURE__ */ jsx(
1239
+ GridContextMenu,
1240
+ {
1241
+ x: menuPosition.x,
1242
+ y: menuPosition.y,
1243
+ hasSelection: hasCellSelection,
1244
+ canUndo,
1245
+ canRedo,
1246
+ onUndo: onUndo ?? NOOP,
1247
+ onRedo: onRedo ?? NOOP,
1248
+ onCopy: handleCopy,
1249
+ onCut: handleCut,
1250
+ onPaste: handlePasteVoid,
1251
+ onSelectAll: o.interaction.handleSelectAllCells,
1252
+ onClose: closeContextMenu
1253
+ }
1254
+ ),
1255
+ document.body
1256
+ ),
1257
+ /* @__PURE__ */ jsx(
1258
+ ColumnHeaderMenu,
1259
+ {
1260
+ isOpen: headerMenu.isOpen,
1261
+ anchorElement: headerMenu.anchorElement,
1262
+ onClose: headerMenu.close,
1263
+ onPinLeft: headerMenu.handlePinLeft,
1264
+ onPinRight: headerMenu.handlePinRight,
1265
+ onUnpin: headerMenu.handleUnpin,
1266
+ onSortAsc: headerMenu.handleSortAsc,
1267
+ onSortDesc: headerMenu.handleSortDesc,
1268
+ onClearSort: headerMenu.handleClearSort,
1269
+ onAutosizeThis: headerMenu.handleAutosizeThis,
1270
+ onAutosizeAll: headerMenu.handleAutosizeAll,
1271
+ canPinLeft: headerMenu.canPinLeft,
1272
+ canPinRight: headerMenu.canPinRight,
1273
+ canUnpin: headerMenu.canUnpin,
1274
+ currentSort: headerMenu.currentSort,
1275
+ isSortable: headerMenu.isSortable,
1276
+ isResizable: headerMenu.isResizable
1277
+ }
1278
+ )
1279
+ ]
1280
+ }
1281
+ ),
1282
+ statusBarConfig && /* @__PURE__ */ jsx(
1283
+ StatusBar,
1284
+ {
1285
+ totalCount: statusBarConfig.totalCount,
1286
+ filteredCount: statusBarConfig.filteredCount,
1287
+ selectedCount: statusBarConfig.selectedCount ?? selectedRowIds.size,
1288
+ selectedCellCount: selectionRange ? (Math.abs(selectionRange.endRow - selectionRange.startRow) + 1) * (Math.abs(selectionRange.endCol - selectionRange.startCol) + 1) : void 0,
1289
+ aggregation: statusBarConfig.aggregation,
1290
+ suppressRowCount: statusBarConfig.suppressRowCount
1291
+ }
1292
+ ),
1293
+ isLoading && /* @__PURE__ */ jsx(LoadingOverlay, { message: loadingMessage })
1294
+ ] });
1295
+ }
1296
+ var DataGridTable = React3.memo(DataGridTableInner);
1297
+ var ColumnChooser = (props) => {
1298
+ const { columns, visibleColumns, onVisibilityChange, onSetVisibleColumns, className } = props;
1299
+ const [anchorEl, setAnchorEl] = useState(null);
1300
+ const buttonRef = useRef(null);
1301
+ const {
1302
+ open: isOpen,
1303
+ setOpen,
1304
+ handleClose,
1305
+ handleCheckboxChange: setColumnVisible,
1306
+ handleSelectAll,
1307
+ handleClearAll,
1308
+ visibleCount,
1309
+ totalCount
1310
+ } = useColumnChooserState({ columns, visibleColumns, onVisibilityChange, onSetVisibleColumns });
1311
+ const handleToggle = (e) => {
1312
+ if (isOpen) {
1313
+ handleClose();
1314
+ setAnchorEl(null);
1315
+ } else {
1316
+ setAnchorEl(e.currentTarget);
1317
+ setOpen(true);
1318
+ }
1319
+ };
1320
+ const handlePopoverClose = () => {
1321
+ handleClose();
1322
+ setAnchorEl(null);
1323
+ };
1324
+ const handleCheckboxChange = (columnKey) => (ev) => {
1325
+ ev.stopPropagation();
1326
+ setColumnVisible(columnKey)(ev.target.checked);
1327
+ };
1328
+ return /* @__PURE__ */ jsxs(Box, { className, sx: { display: "inline-flex" }, children: [
1329
+ /* @__PURE__ */ jsxs(
1330
+ Button,
1331
+ {
1332
+ ref: buttonRef,
1333
+ variant: "outlined",
1334
+ size: "small",
1335
+ color: "inherit",
1336
+ startIcon: /* @__PURE__ */ jsx(ViewColumn, {}),
1337
+ endIcon: isOpen ? /* @__PURE__ */ jsx(ExpandLess, {}) : /* @__PURE__ */ jsx(ExpandMore, {}),
1338
+ onClick: handleToggle,
1339
+ "aria-expanded": isOpen,
1340
+ "aria-haspopup": "listbox",
1341
+ sx: {
1342
+ textTransform: "none",
1343
+ fontWeight: 600,
1344
+ borderColor: isOpen ? "primary.main" : "divider"
1345
+ },
1346
+ children: [
1347
+ "Column Visibility (",
1348
+ visibleCount,
1349
+ " of ",
1350
+ totalCount,
1351
+ ")"
1352
+ ]
1353
+ }
1354
+ ),
1355
+ /* @__PURE__ */ jsxs(
1356
+ Popover,
1357
+ {
1358
+ open: isOpen,
1359
+ anchorEl,
1360
+ onClose: handlePopoverClose,
1361
+ anchorOrigin: { vertical: "bottom", horizontal: "right" },
1362
+ transformOrigin: { vertical: "top", horizontal: "right" },
1363
+ slotProps: {
1364
+ paper: {
1365
+ sx: { mt: 0.5, minWidth: 220 }
1366
+ }
1367
+ },
1368
+ children: [
1369
+ /* @__PURE__ */ jsx(
1370
+ Box,
1371
+ {
1372
+ sx: {
1373
+ px: 1.5,
1374
+ py: 1,
1375
+ borderBottom: 1,
1376
+ borderColor: "divider",
1377
+ bgcolor: "action.hover"
1378
+ },
1379
+ children: /* @__PURE__ */ jsxs(Typography, { variant: "subtitle2", fontWeight: 600, children: [
1380
+ "Select Columns (",
1381
+ visibleCount,
1382
+ " of ",
1383
+ totalCount,
1384
+ ")"
1385
+ ] })
1386
+ }
1387
+ ),
1388
+ /* @__PURE__ */ jsx(Box, { sx: { maxHeight: 320, overflowY: "auto", py: 0.5 }, children: columns.map((column) => /* @__PURE__ */ jsx(Box, { sx: { px: 1.5, minHeight: 32, display: "flex", alignItems: "center" }, children: /* @__PURE__ */ jsx(
1389
+ FormControlLabel,
1390
+ {
1391
+ control: /* @__PURE__ */ jsx(
1392
+ Checkbox,
1393
+ {
1394
+ size: "small",
1395
+ checked: visibleColumns.has(column.columnId),
1396
+ onChange: handleCheckboxChange(column.columnId),
1397
+ disabled: column.required === true
1398
+ }
1399
+ ),
1400
+ label: /* @__PURE__ */ jsx(Typography, { variant: "body2", children: column.name }),
1401
+ sx: { m: 0 }
1402
+ }
1403
+ ) }, column.columnId)) }),
1404
+ /* @__PURE__ */ jsxs(
1405
+ Box,
1406
+ {
1407
+ sx: {
1408
+ display: "flex",
1409
+ justifyContent: "flex-end",
1410
+ gap: 1,
1411
+ px: 1.5,
1412
+ py: 1,
1413
+ borderTop: 1,
1414
+ borderColor: "divider",
1415
+ bgcolor: "action.hover"
1416
+ },
1417
+ children: [
1418
+ /* @__PURE__ */ jsx(Button, { size: "small", onClick: handleClearAll, sx: { textTransform: "none" }, children: "Clear All" }),
1419
+ /* @__PURE__ */ jsx(
1420
+ Button,
1421
+ {
1422
+ size: "small",
1423
+ variant: "contained",
1424
+ onClick: handleSelectAll,
1425
+ sx: { textTransform: "none" },
1426
+ children: "Select All"
1427
+ }
1428
+ )
1429
+ ]
1430
+ }
1431
+ )
1432
+ ]
1433
+ }
1434
+ )
1435
+ ] });
1436
+ };
1437
+ var PaginationControls = React3.memo((props) => {
1438
+ const {
1439
+ currentPage,
1440
+ pageSize,
1441
+ totalCount,
1442
+ onPageChange,
1443
+ onPageSizeChange,
1444
+ pageSizeOptions,
1445
+ entityLabelPlural,
1446
+ className
1447
+ } = props;
1448
+ const { labelPlural, vm, handlePageSizeChange } = usePaginationControls({
1449
+ currentPage,
1450
+ pageSize,
1451
+ totalCount,
1452
+ onPageChange,
1453
+ onPageSizeChange,
1454
+ pageSizeOptions,
1455
+ entityLabelPlural
1456
+ });
1457
+ const handlePageSizeChangeEvent = (event) => {
1458
+ handlePageSizeChange(Number(event.target.value));
1459
+ };
1460
+ if (!vm) {
1461
+ return null;
1462
+ }
1463
+ const { pageNumbers, showStartEllipsis, showEndEllipsis, totalPages, startItem, endItem } = vm;
1464
+ return /* @__PURE__ */ jsxs(
1465
+ Box,
1466
+ {
1467
+ className,
1468
+ role: "navigation",
1469
+ "aria-label": "Pagination",
1470
+ sx: {
1471
+ display: "flex",
1472
+ alignItems: "center",
1473
+ justifyContent: "space-between",
1474
+ flexWrap: "wrap",
1475
+ gap: 2,
1476
+ px: 1.5,
1477
+ width: "100%",
1478
+ minWidth: 0,
1479
+ boxSizing: "border-box"
1480
+ },
1481
+ children: [
1482
+ /* @__PURE__ */ jsxs(Typography, { variant: "body2", color: "text.secondary", children: [
1483
+ "Showing ",
1484
+ startItem,
1485
+ " to ",
1486
+ endItem,
1487
+ " of ",
1488
+ totalCount.toLocaleString(),
1489
+ " ",
1490
+ labelPlural
1491
+ ] }),
1492
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 0.5 }, children: [
1493
+ /* @__PURE__ */ jsx(
1494
+ IconButton,
1495
+ {
1496
+ size: "small",
1497
+ onClick: () => onPageChange(1),
1498
+ disabled: currentPage === 1,
1499
+ "aria-label": "First page",
1500
+ children: /* @__PURE__ */ jsx(FirstPage, { fontSize: "small" })
1501
+ }
1502
+ ),
1503
+ /* @__PURE__ */ jsx(
1504
+ IconButton,
1505
+ {
1506
+ size: "small",
1507
+ onClick: () => onPageChange(currentPage - 1),
1508
+ disabled: currentPage === 1,
1509
+ "aria-label": "Previous page",
1510
+ children: /* @__PURE__ */ jsx(ChevronLeft, { fontSize: "small" })
1511
+ }
1512
+ ),
1513
+ showStartEllipsis && /* @__PURE__ */ jsxs(Fragment, { children: [
1514
+ /* @__PURE__ */ jsx(
1515
+ Button,
1516
+ {
1517
+ variant: "outlined",
1518
+ size: "small",
1519
+ onClick: () => onPageChange(1),
1520
+ "aria-label": "Page 1",
1521
+ sx: { minWidth: 32, px: 0.5 },
1522
+ children: "1"
1523
+ }
1524
+ ),
1525
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mx: 0.5 }, "aria-hidden": true, children: "\u2026" })
1526
+ ] }),
1527
+ pageNumbers.map((pageNum) => /* @__PURE__ */ jsx(
1528
+ Button,
1529
+ {
1530
+ variant: currentPage === pageNum ? "contained" : "outlined",
1531
+ size: "small",
1532
+ onClick: () => onPageChange(pageNum),
1533
+ "aria-label": `Page ${pageNum}`,
1534
+ "aria-current": currentPage === pageNum ? "page" : void 0,
1535
+ sx: { minWidth: 32, px: 0.5 },
1536
+ children: pageNum
1537
+ },
1538
+ pageNum
1539
+ )),
1540
+ showEndEllipsis && /* @__PURE__ */ jsxs(Fragment, { children: [
1541
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mx: 0.5 }, "aria-hidden": true, children: "\u2026" }),
1542
+ /* @__PURE__ */ jsx(
1543
+ Button,
1544
+ {
1545
+ variant: "outlined",
1546
+ size: "small",
1547
+ onClick: () => onPageChange(totalPages),
1548
+ "aria-label": `Page ${totalPages}`,
1549
+ sx: { minWidth: 32, px: 0.5 },
1550
+ children: totalPages
1551
+ }
1552
+ )
1553
+ ] }),
1554
+ /* @__PURE__ */ jsx(
1555
+ IconButton,
1556
+ {
1557
+ size: "small",
1558
+ onClick: () => onPageChange(currentPage + 1),
1559
+ disabled: currentPage >= totalPages,
1560
+ "aria-label": "Next page",
1561
+ children: /* @__PURE__ */ jsx(ChevronRight, { fontSize: "small" })
1562
+ }
1563
+ ),
1564
+ /* @__PURE__ */ jsx(
1565
+ IconButton,
1566
+ {
1567
+ size: "small",
1568
+ onClick: () => onPageChange(totalPages),
1569
+ disabled: currentPage >= totalPages,
1570
+ "aria-label": "Last page",
1571
+ children: /* @__PURE__ */ jsx(LastPage, { fontSize: "small" })
1572
+ }
1573
+ )
1574
+ ] }),
1575
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
1576
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: "Rows" }),
1577
+ /* @__PURE__ */ jsx(
1578
+ Select,
1579
+ {
1580
+ value: pageSize,
1581
+ onChange: handlePageSizeChangeEvent,
1582
+ size: "small",
1583
+ "aria-label": "Rows per page",
1584
+ sx: { minWidth: 70 },
1585
+ children: vm.pageSizeOptions.map((n) => /* @__PURE__ */ jsx(MenuItem, { value: n, children: n }, n))
1586
+ }
1587
+ )
1588
+ ] })
1589
+ ]
1590
+ }
1591
+ );
1592
+ });
1593
+ var MuiThemeContainer = React3.forwardRef(
1594
+ function MuiThemeContainer2(props, ref) {
1595
+ const theme = useTheme();
1596
+ const sx = React3.useMemo(() => ({
1597
+ display: "flex",
1598
+ flexDirection: "column",
1599
+ gap: 1,
1600
+ "--ogrid-bg": theme.palette.background.default,
1601
+ "--ogrid-border": theme.palette.divider,
1602
+ "--ogrid-header-bg": theme.palette.mode === "dark" ? theme.palette.grey[800] : theme.palette.grey[100],
1603
+ "--ogrid-fg": theme.palette.text.primary,
1604
+ "--ogrid-fg-secondary": theme.palette.text.secondary,
1605
+ "--ogrid-fg-muted": theme.palette.text.disabled,
1606
+ "--ogrid-hover-bg": theme.palette.action.hover,
1607
+ "--ogrid-paper-bg": theme.palette.background.paper,
1608
+ "--ogrid-primary": theme.palette.primary.main,
1609
+ "--ogrid-selection-bg": theme.palette.action.selected
1610
+ }), [theme]);
1611
+ return /* @__PURE__ */ jsx(Box, { ref, sx, ...props });
1612
+ }
1613
+ );
1614
+ var OGrid = createOGrid({
1615
+ DataGridTable,
1616
+ ColumnChooser,
1617
+ PaginationControls,
1618
+ containerComponent: MuiThemeContainer
1619
+ });
1620
+
1621
+ export { ColumnChooser, ColumnHeaderFilter, ColumnHeaderMenu, DataGridTable, OGrid, PaginationControls };