mgh-components 1.1.2 → 1.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":["../src/hooks/useResponsive.ts","../src/components/CustomNoRowsOverlay/CustomNoRowsOverlay.tsx","../src/components/MGHDataGrid/MGHDataGrid.tsx","../src/components/CustomGridToolbarExport/CustomGridToolbarExport.tsx","../src/components/Confirm-Dialog/confirm-dialog.tsx","../src/components/Exporting/Exporting-Dialog.tsx","../src/components/iconify/iconify.tsx","../src/components/Label/styles.ts","../src/components/Label/Label.tsx","../src/components/MGHGrid/utils.ts","../src/components/MGHGrid/MGHGrid.styles.ts","../src/components/MGHGrid/context.tsx","../src/components/MGHGrid/hooks.ts","../src/components/MGHGrid/export.ts","../src/components/MGHGrid/grouping.ts","../src/components/MGHGrid/icons.tsx","../src/components/MGHGrid/components/primitives.tsx","../src/components/MGHGrid/components/Toolbar.tsx","../src/components/MGHGrid/components/Footer.tsx","../src/components/MGHGrid/components/ColumnsPanel.tsx","../src/components/MGHGrid/components/FilterPanel.tsx","../src/components/MGHGrid/components/ColumnMenu.tsx","../src/components/MGHGrid/components/Overlays.tsx","../src/components/MGHGrid/components/ActionsCell.tsx","../src/components/MGHGrid/MGHGrid.tsx"],"sourcesContent":["import useMediaQuery from '@mui/material/useMediaQuery';\nimport { useTheme, Breakpoint } from '@mui/material/styles';\n\n// ----------------------------------------------------------------------\n\ntype ReturnType = boolean;\n\nexport type Query = 'up' | 'down' | 'between' | 'only';\n\nexport type Value = Breakpoint | number;\n\nexport function useResponsive(query: Query, start?: Value, end?: Value): ReturnType {\n const theme = useTheme();\n\n const mediaUp = useMediaQuery(theme.breakpoints.up(start as Value));\n\n const mediaDown = useMediaQuery(theme.breakpoints.down(start as Value));\n\n const mediaBetween = useMediaQuery(theme.breakpoints.between(start as Value, end as Value));\n\n const mediaOnly = useMediaQuery(theme.breakpoints.only(start as Breakpoint));\n\n if (query === 'up') {\n return mediaUp;\n }\n\n if (query === 'down') {\n return mediaDown;\n }\n\n if (query === 'between') {\n return mediaBetween;\n }\n\n return mediaOnly;\n}\n\n// ----------------------------------------------------------------------\n\ntype BreakpointOrNull = Breakpoint | null;\n\nexport function useWidth() {\n const theme = useTheme();\n\n const keys = [...theme.breakpoints.keys].reverse();\n\n return (\n keys.reduce((output: BreakpointOrNull, key: Breakpoint) => {\n const matches = useMediaQuery(theme.breakpoints.up(key));\n\n return !output && matches ? key : output;\n }, null) || 'xs'\n );\n}\n","import styled from '@emotion/styled';\n\nimport { Box } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n// import { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n\nimport React from 'react';\n// import { NoRowsOverlayPropsOverrides } from './CustomNoRowsOverlay.types';\n\n/// ---------------------------------------------------------------------------------------\n\ndeclare module '@mui/x-data-grid-premium' {\n export interface NoRowsOverlayPropsOverrides {\n text: string;\n useSettingsContext?: () => { themeMode?: string };\n }\n}\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomNoRowsOverlay({ text, useSettingsContext }: NoRowsOverlayPropsOverrides) {\n const theme = useTheme();\n const themeMode = useSettingsContext?.()?.themeMode ?? theme.palette.mode ?? 'light';\n\n const StyledGridOverlay = styled('div')(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: '100%',\n '& .ant-empty-img-1': {\n fill: themeMode === 'light' ? '#aeb8c2' : '#262626',\n },\n '& .ant-empty-img-2': {\n fill: themeMode === 'light' ? '#f5f5f7' : '#595959',\n },\n '& .ant-empty-img-3': {\n fill: themeMode === 'light' ? '#dce0e6' : '#434343',\n },\n '& .ant-empty-img-4': {\n fill: themeMode === 'light' ? '#fff' : '#1c1c1c',\n },\n '& .ant-empty-img-5': {\n fillOpacity: themeMode === 'light' ? '0.8' : '0.08',\n fill: themeMode === 'light' ? '#f5f5f5' : '#fff',\n },\n }));\n return (\n <StyledGridOverlay>\n <Box\n component=\"img\"\n alt=\"empty content\"\n src=\"/assets/icons/empty/ic_content.svg\"\n sx={{ width: 50, maxWidth: 160 }}\n />\n <Box sx={{ mb: 0 }}>{text}</Box>\n </StyledGridOverlay>\n );\n}\n","import React, { JSX } from 'react';\nimport dayjs from 'dayjs';\n\nimport { DateRange } from '@mui/x-date-pickers-pro';\n// `GridInitialStatePremium` itself only lives under an internal (non-exported) subpath; the\n// package re-exports it under this name from its public entry point instead.\nimport { GridInitialState as GridInitialStatePremium } from '@mui/x-data-grid-premium';\nimport { Box, Card, Theme, Badge, styled, SxProps, Tooltip, TextField, CardHeader, InputAdornment } from '@mui/material';\nimport {\n Toolbar,\n GridColDef,\n QuickFilter,\n GridRowParams,\n ToolbarButton,\n GridCloseIcon,\n GridSearchIcon,\n DataGridPremium,\n GridToolbarProps,\n QuickFilterClear,\n GridEventListener,\n GridSlotsComponent,\n FilterPanelTrigger,\n GridViewColumnIcon,\n GridFilterListIcon,\n QuickFilterControl,\n QuickFilterTrigger,\n GridCallbackDetails,\n ColumnsPanelTrigger,\n GridRowHeightParams,\n GridCsvExportOptions,\n GridRowSelectionModel,\n GridCsvExportMenuItem,\n ToolbarPropsOverrides,\n GridRowClassNameParams,\n GridExcelExportOptions,\n GridPrintExportOptions,\n GridExcelExportMenuItem,\n GridPrintExportMenuItem,\n GridSlotsComponentsProps,\n GridExportDisplayOptions,\n GridRowHeightReturnValue,\n GridColumnVisibilityModel,\n GridToolbarExportContainer,\n GridPinnedRowsProp,\n} from '@mui/x-data-grid-premium';\nimport { useResponsive } from '../../hooks/useResponsive';\nimport CustomNoRowsOverlay from '../CustomNoRowsOverlay/CustomNoRowsOverlay';\n\ninterface CustomToolbarProps {\n dateValues: React.SetStateAction<DateRange<dayjs.Dayjs>>;\n setDateValues: React.Dispatch<React.SetStateAction<DateRange<dayjs.Dayjs>>>;\n renderDateRange?: React.ReactNode;\n customMenuItem?: JSX.Element[];\n currentParentFolderKey?: number | null;\n types?: any;\n typeKey?: number;\n setTypeKey?: React.Dispatch<React.SetStateAction<number>>;\n userData?: unknown;\n exporting?: boolean;\n setExporting?: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\ninterface MGHDataGridProps {\n rows: any[];\n columns: GridColDef[];\n onRowClick?: GridEventListener<'rowClick'>;\n onRowDoubleClick?: GridEventListener<'rowDoubleClick'>;\n header: string;\n pagination?: boolean;\n pageSize?: number;\n pageSizeOptions?: number[];\n slots?: Partial<GridSlotsComponent>;\n slotProps?: GridSlotsComponentsProps & {\n toolbar?: Partial<GridToolbarProps & ToolbarPropsOverrides & CustomToolbarProps>;\n };\n toolbarProps?: any;\n initialState?: GridInitialStatePremium;\n sx?: SxProps<Theme>;\n cardSx?: SxProps<Theme>;\n boxSx?: SxProps<Theme>;\n columnVisibilityModel?: GridColumnVisibilityModel;\n onColumnVisibilityModelChange?: (model: GridColumnVisibilityModel, details: GridCallbackDetails) => void;\n columnVisibilityStorageKey?: string;\n columnOrderStorageKey?: string;\n disableDensitySelector?: boolean;\n disableRowSelectionOnClick?: boolean;\n disableColumnFilter?: boolean;\n disableColumnMenu?: boolean;\n disableColumnSelector?: boolean;\n renderHeaderEndContent?: JSX.Element;\n renderHeaderCenterContent?: JSX.Element;\n noRowsText?: string;\n checkboxSelection?: boolean;\n checkboxSelectionVisibleOnly?: boolean;\n onRowSelectionModelChange?:\n | ((rowSelectionModel: GridRowSelectionModel, details: GridCallbackDetails<any>) => void)\n | undefined;\n rowSelectionModel?: GridRowSelectionModel | undefined;\n getRowClassName?: ((params: GridRowClassNameParams<any>) => string) | undefined;\n getDetailPanelContent?: (params: GridRowParams<any>) => React.ReactNode;\n getDetailPanelHeight?: () => number;\n loading?: boolean;\n isRowSelectable?: (params: GridRowParams<any>) => boolean;\n getRowHeight?: ((params: GridRowHeightParams) => GridRowHeightReturnValue) | undefined;\n showToolbar?: boolean;\n hideFooterRowCount?: boolean;\n onColumnOrderChange?: GridEventListener<'columnOrderChange'> | undefined;\n defaultGroupingExpansionDepth?: number;\n pinnedRows?: GridPinnedRowsProp;\n keepNonExistentRowsSelected?: boolean;\n}\n\nconst canUseLocalStorage = () => typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';\n\nconst readLocalStorage = <T,>(key: string): T | null => {\n if (!canUseLocalStorage()) {\n return null;\n }\n try {\n const value = window.localStorage.getItem(key);\n return value ? (JSON.parse(value) as T) : null;\n } catch {\n return null;\n }\n};\n\nconst writeLocalStorage = (key: string, value: unknown) => {\n if (!canUseLocalStorage()) {\n return;\n }\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n return;\n }\n};\n\nconst normalizeOrderedFields = (orderedFields: string[] | null, columns: GridColDef[]) => {\n if (!orderedFields || orderedFields.length === 0) {\n return undefined;\n }\n const columnFields = new Set(columns.map((column) => column.field));\n return orderedFields.filter((field) => columnFields.has(field));\n};\n\nexport default function MGHDataGrid({\n header,\n rows,\n columns,\n onRowClick,\n onRowDoubleClick,\n pagination = true,\n pageSize = 25,\n slots = {},\n slotProps = {},\n toolbarProps = {},\n initialState = {},\n pageSizeOptions = [10, 25, 50, 100],\n sx = {},\n cardSx = { flexGrow: 1 },\n boxSx = { flexGrow: 1 },\n columnVisibilityModel,\n onColumnVisibilityModelChange,\n columnVisibilityStorageKey,\n columnOrderStorageKey,\n disableDensitySelector = false,\n disableRowSelectionOnClick = true,\n disableColumnFilter = false,\n disableColumnMenu = false,\n disableColumnSelector = false,\n checkboxSelectionVisibleOnly = false,\n renderHeaderEndContent,\n renderHeaderCenterContent,\n noRowsText = 'No data found within selected parameters.',\n checkboxSelection = false,\n onRowSelectionModelChange = undefined,\n rowSelectionModel = undefined,\n getRowClassName = undefined,\n getDetailPanelContent,\n getDetailPanelHeight,\n loading = false,\n isRowSelectable = undefined,\n getRowHeight,\n showToolbar = true,\n hideFooterRowCount = false,\n onColumnOrderChange = undefined,\n defaultGroupingExpansionDepth = undefined,\n pinnedRows = undefined,\n keepNonExistentRowsSelected = true,\n}: MGHDataGridProps) {\n const smDown = useResponsive('down', 'sm');\n const persistedColumnVisibilityModel = React.useMemo(() => {\n if (!columnVisibilityStorageKey) {\n return undefined;\n }\n return readLocalStorage<GridColumnVisibilityModel>(columnVisibilityStorageKey) ?? undefined;\n }, [columnVisibilityStorageKey]);\n\n const persistedOrderedFields = React.useMemo(() => {\n if (!columnOrderStorageKey) {\n return undefined;\n }\n const storedOrder = readLocalStorage<string[]>(columnOrderStorageKey);\n return normalizeOrderedFields(storedOrder, columns);\n }, [columnOrderStorageKey, columns]);\n\n const resolvedColumnVisibilityModel =\n columnVisibilityModel !== undefined ? columnVisibilityModel : persistedColumnVisibilityModel;\n\n const handleColumnVisibilityModelChange = React.useCallback(\n (model: GridColumnVisibilityModel, details: GridCallbackDetails) => {\n if (columnVisibilityStorageKey) {\n writeLocalStorage(columnVisibilityStorageKey, model);\n }\n onColumnVisibilityModelChange?.(model, details);\n },\n [columnVisibilityStorageKey, onColumnVisibilityModelChange]\n );\n\n const handleColumnOrderChange = React.useCallback<GridEventListener<'columnOrderChange'>>(\n (params, event, details) => {\n if (columnOrderStorageKey) {\n const orderedFields = details.api.getAllColumns().map((column) => column.field);\n writeLocalStorage(columnOrderStorageKey, orderedFields);\n }\n onColumnOrderChange?.(params, event, details);\n },\n [columnOrderStorageKey, onColumnOrderChange]\n );\n\n const mergedInitialState: GridInitialStatePremium = {\n density: 'compact',\n pagination: { paginationModel: { pageSize } },\n filter: {\n filterModel: {\n items: [],\n quickFilterExcludeHiddenColumns: false,\n },\n },\n ...initialState,\n columns: {\n ...initialState?.columns,\n columnVisibilityModel: resolvedColumnVisibilityModel ?? initialState?.columns?.columnVisibilityModel,\n orderedFields: persistedOrderedFields ?? initialState?.columns?.orderedFields,\n },\n };\n\n return (\n <Card sx={{ height: 'auto', ...cardSx }}>\n <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', pr: 1 }}>\n <CardHeader title={header} sx={{ mb: 2 }} />\n {renderHeaderCenterContent}\n <Box\n sx={{\n display: 'flex',\n gap: smDown ? 1 : 2,\n alignItems: 'center',\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n }}\n >\n {renderHeaderEndContent}\n </Box>\n </Box>\n <Box component=\"div\" sx={{ display: 'flex', flexDirection: 'column', flexGrow: 1, ...boxSx }}>\n <DataGridPremium\n loading={loading}\n onRowClick={onRowClick}\n onRowDoubleClick={onRowDoubleClick}\n rows={rows}\n columns={columns}\n pagination={pagination}\n disableDensitySelector={disableDensitySelector}\n disableRowSelectionOnClick={disableRowSelectionOnClick}\n disableColumnFilter={disableColumnFilter}\n disableColumnMenu={disableColumnMenu}\n disableColumnSelector={disableColumnSelector}\n slots={{ noRowsOverlay: CustomNoRowsOverlay, toolbar: MGHGridToolbar, ...slots }}\n slotProps={{ noRowsOverlay: { text: noRowsText }, toolbar: toolbarProps, ...slotProps }}\n initialState={mergedInitialState}\n pageSizeOptions={pageSizeOptions}\n sx={{\n '& .MuiDataGrid-row:hover': {\n cursor: onRowClick || onRowDoubleClick ? 'pointer' : 'default',\n },\n ...sx,\n }}\n \n onColumnVisibilityModelChange={handleColumnVisibilityModelChange}\n checkboxSelection={checkboxSelection}\n onRowSelectionModelChange={onRowSelectionModelChange}\n rowSelectionModel={rowSelectionModel}\n isRowSelectable={isRowSelectable}\n getRowClassName={getRowClassName}\n getDetailPanelContent={getDetailPanelContent}\n getDetailPanelHeight={getDetailPanelHeight}\n checkboxSelectionVisibleOnly={checkboxSelectionVisibleOnly}\n disableRowSelectionExcludeModel\n showToolbar={showToolbar}\n hideFooterRowCount={hideFooterRowCount}\n getRowHeight={getRowHeight}\n onColumnOrderChange={handleColumnOrderChange}\n defaultGroupingExpansionDepth={defaultGroupingExpansionDepth}\n pinnedRows={pinnedRows}\n keepNonExistentRowsSelected={keepNonExistentRowsSelected}\n />\n </Box>\n </Card>\n );\n}\n\ninterface MGHGridToolbarProps {\n showColumnsButton?: boolean;\n showFilterButton?: boolean;\n showExportButton?: boolean;\n showQuickFilter?: boolean;\n renderOtherButtons?: JSX.Element;\n renderDateRange?: JSX.Element;\n customMenuItem?: JSX.Element[];\n showCsvOption?: boolean;\n}\nexport function MGHGridToolbar({\n showColumnsButton = true,\n showFilterButton = true,\n showExportButton = true,\n showQuickFilter = true,\n renderOtherButtons,\n renderDateRange,\n customMenuItem,\n showCsvOption = true,\n}: MGHGridToolbarProps) {\n return (\n <Toolbar style={{ display: 'flex', justifyContent: 'space-between' }}>\n <div>\n {showColumnsButton && (\n <Tooltip title=\"Columns\">\n <ColumnsPanelTrigger render={<ToolbarButton />}>\n <GridViewColumnIcon fontSize=\"small\" />\n </ColumnsPanelTrigger>\n </Tooltip>\n )}\n {showFilterButton && (\n <Tooltip title=\"Filters\">\n <FilterPanelTrigger\n render={(props, state) => (\n <ToolbarButton {...props} color=\"default\">\n <Badge badgeContent={state.filterCount} color=\"primary\" variant=\"dot\">\n <GridFilterListIcon fontSize=\"small\" />\n </Badge>\n </ToolbarButton>\n )}\n />\n </Tooltip>\n )}\n {showExportButton && (\n <CustomGridToolbarExport customMenuItem={customMenuItem} showCsvOption={showCsvOption} />\n )}\n </div>\n\n {renderDateRange}\n\n <div>\n {renderOtherButtons}\n {showQuickFilter && <DataGridQuickFilter />}\n </div>\n </Toolbar>\n );\n}\n\ninterface ExportContainerProps {\n csvOptions?: GridCsvExportOptions & GridExportDisplayOptions;\n excelOptions?: GridExcelExportOptions & GridExportDisplayOptions;\n printOptions?: GridPrintExportOptions & GridExportDisplayOptions;\n customMenuItem?: JSX.Element[] | undefined;\n showCsvOption?: boolean;\n}\nexport const CustomGridToolbarExport = ({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n customMenuItem,\n showCsvOption = true,\n ...other\n}: ExportContainerProps) => (\n <GridToolbarExportContainer {...other}>\n {customMenuItem?.map((el) => el)}\n {showCsvOption && <GridCsvExportMenuItem options={csvOptions} />}\n <GridExcelExportMenuItem options={excelOptions} />\n <GridPrintExportMenuItem options={printOptions} />\n </GridToolbarExportContainer>\n);\n\nexport function DataGridQuickFilter() {\n type OwnerState = {\n expanded: boolean;\n };\n\n const StyledQuickFilter = styled(QuickFilter)({\n display: 'grid',\n alignItems: 'center',\n });\n\n const StyledToolbarButton = styled(ToolbarButton)<{ ownerState: OwnerState }>(({ theme, ownerState }) => ({\n gridArea: '1 / 1',\n width: 'min-content',\n height: 'min-content',\n zIndex: 1,\n opacity: ownerState.expanded ? 0 : 1,\n pointerEvents: ownerState.expanded ? 'none' : 'auto',\n transition: theme.transitions.create(['opacity']),\n }));\n\n const StyledTextField = styled(TextField)<{\n ownerState: OwnerState;\n }>(({ theme, ownerState }) => ({\n gridArea: '1 / 1',\n overflowX: 'clip',\n width: ownerState.expanded ? 260 : 'var(--trigger-width)',\n opacity: ownerState.expanded ? 1 : 0,\n transition: theme.transitions.create(['width', 'opacity']),\n }));\n\n return (\n <StyledQuickFilter>\n <QuickFilterTrigger\n render={(triggerProps, state) => (\n <Tooltip title=\"Search\" enterDelay={0}>\n <StyledToolbarButton\n {...triggerProps}\n ownerState={{ expanded: state.expanded }}\n color=\"default\"\n aria-disabled={state.expanded}\n >\n <GridSearchIcon fontSize=\"small\" />\n </StyledToolbarButton>\n </Tooltip>\n )}\n />\n <QuickFilterControl\n render={({ ref, ...controlProps }, state) => (\n <StyledTextField\n {...controlProps}\n ownerState={{ expanded: state.expanded }}\n inputRef={ref}\n aria-label=\"Search\"\n placeholder=\"Search...\"\n size=\"small\"\n slotProps={{\n input: {\n startAdornment: (\n <InputAdornment position=\"start\">\n <GridSearchIcon fontSize=\"small\" />\n </InputAdornment>\n ),\n endAdornment: state.value ? (\n <InputAdornment position=\"end\">\n <QuickFilterClear\n edge=\"end\"\n size=\"small\"\n aria-label=\"Clear search\"\n material={{ sx: { marginRight: -0.75 } }}\n >\n <GridCloseIcon fontSize=\"small\" />\n </QuickFilterClear>\n </InputAdornment>\n ) : null,\n ...controlProps.slotProps?.input,\n },\n ...controlProps.slotProps,\n }}\n />\n )}\n />\n </StyledQuickFilter>\n );\n}\n","import {\n GridToolbarExportContainer,\n GridCsvExportMenuItem,\n GridExcelExportMenuItem,\n GridPrintExportMenuItem,\n} from '@mui/x-data-grid-premium';\nimport React from 'react';\nimport { ExportContainerProps } from './CustomGridToolbarExport.types';\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomGridToolbarExport({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n // color,\n customMenuItem,\n ...other\n}: ExportContainerProps) {\n return (\n <GridToolbarExportContainer\n {...other}\n // color={color}\n >\n {customMenuItem}\n <GridCsvExportMenuItem options={csvOptions} />\n <GridExcelExportMenuItem options={excelOptions} />\n <GridPrintExportMenuItem options={printOptions} />\n </GridToolbarExportContainer>\n );\n}\n","import Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\n\nimport { ConfirmDialogProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nexport default function ConfirmDialog({ title, content, action, open, onClose, ...other }: ConfirmDialogProps) {\n return (\n <Dialog fullWidth maxWidth=\"xs\" open={open} onClose={onClose} {...other}>\n <DialogTitle sx={{ pb: 2 }}>{title}</DialogTitle>\n\n {content && <DialogContent sx={{ typography: 'body2' }}> {content} </DialogContent>}\n\n <DialogActions>\n <Button onClick={onClose}>Cancel</Button>\n {action}\n </DialogActions>\n </Dialog>\n );\n}\n","import { JSX } from 'react';\n\nimport { Dialog, Typography, DialogContent, CircularProgress } from '@mui/material';\nimport React from 'react';\n\n/// ---------------------------------------------------------------------------------------\n\ninterface ExportingProps {\n open: boolean;\n text?: JSX.Element | string;\n}\nexport default function ExportingDialog({\n open,\n text = (\n <>\n Your export is currently being built. Some larger exports can take a couple of minutes to complete. <br />\n <br />\n Please do not close your browser or refresh the page.\n </>\n ),\n}: ExportingProps) {\n return (\n <Dialog open={open} fullWidth sx={{ p: 4 }}>\n <DialogContent sx={{ p: 4, textAlign: 'center' }}>\n <Typography variant=\"subtitle1\" sx={{ mb: 3 }}>\n {text}\n </Typography>\n <CircularProgress />\n </DialogContent>\n </Dialog>\n );\n}\n","import { forwardRef } from 'react';\nimport { Icon } from '@iconify/react';\n\nimport { IconifyProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\ninterface Props {\n icon: IconifyProps;\n width?: number;\n height?: number;\n sx?: any;\n}\n\nconst Iconify = forwardRef<SVGElement, Props>(({ icon, width = 20, sx, ...other }, ref) => (\n <Icon icon={icon} style={{ width: 20, height: width ?? 20, ...sx }} />\n));\n\nexport default Iconify;\n","import type { ComponentProps, ComponentType } from 'react';\nimport Box from '@mui/material/Box';\nimport { alpha, styled, useTheme } from '@mui/material/styles';\nimport { LabelColor, LabelVariant } from './types';\n\n// ----------------------------------------------------------------------\n\ninterface StyledLabelOwnerState {\n color: LabelColor;\n variant: LabelVariant;\n}\n\n// Explicitly annotated so TS doesn't need to synthesize (and re-print) an anonymous type that\n// references @mui/system's install path — under pnpm that path is store-relative and triggers\n// TS2742 (\"inferred type cannot be named without a reference to ...\") during declaration emit.\nexport const StyledLabel = styled(Box)(({\n // theme,\n ownerState,\n}: {\n // theme: Theme;\n ownerState: StyledLabelOwnerState;\n}) => {\n const theme = useTheme();\n\n const lightMode = theme.palette.mode === 'light';\n\n const filledVariant = ownerState.variant === 'filled';\n\n const outlinedVariant = ownerState.variant === 'outlined';\n\n const softVariant = ownerState.variant === 'soft';\n\n const defaultStyle = {\n ...(ownerState.color === 'default' && {\n // FILLED\n ...(filledVariant && {\n color: lightMode ? theme.palette.common.white : theme.palette.grey[800],\n backgroundColor: theme.palette.text.primary,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette.text.primary,\n border: `2px solid ${theme.palette.text.primary}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette.text.secondary,\n backgroundColor: alpha(theme.palette.grey[500], 0.16),\n }),\n }),\n };\n\n const colorStyle = {\n ...(ownerState.color !== 'default' && {\n // FILLED\n ...(filledVariant && {\n color: theme.palette[ownerState.color].contrastText,\n backgroundColor: theme.palette[ownerState.color].main,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette[ownerState.color].main,\n border: `2px solid ${theme.palette[ownerState.color].main}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette[ownerState.color][lightMode ? 'dark' : 'light'],\n backgroundColor: alpha(theme.palette[ownerState.color].main, 0.16),\n }),\n }),\n };\n\n return {\n height: 24,\n minWidth: 24,\n lineHeight: 0,\n borderRadius: 6,\n cursor: 'default',\n alignItems: 'center',\n whiteSpace: 'nowrap',\n display: 'inline-flex',\n justifyContent: 'center',\n textTransform: 'capitalize',\n padding: theme.spacing(0, 0.75),\n fontSize: theme.typography.pxToRem(12),\n fontWeight: theme.typography.fontWeightBold,\n transition: theme.transitions.create('all', {\n duration: theme.transitions.duration.shorter,\n }),\n ...defaultStyle,\n ...colorStyle,\n };\n}) as ComponentType<ComponentProps<typeof Box> & { ownerState: StyledLabelOwnerState }>;\n","import { forwardRef } from 'react';\n\nimport Box from '@mui/material/Box';\nimport { LabelProps } from './types';\nimport { StyledLabel } from './styles';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nconst Label = forwardRef<HTMLSpanElement, LabelProps>(\n ({ children, color = 'default', variant = 'soft', startIcon, endIcon, sx, ...other }, ref) => {\n // const theme = useTheme();\n\n const iconStyles = {\n width: 16,\n height: 16,\n '& svg, img': { width: 1, height: 1, objectFit: 'cover' },\n };\n\n return (\n <StyledLabel\n ref={ref}\n // component=\"span\"\n ownerState={{ color, variant }}\n sx={{\n ...(startIcon && { pl: 0.75 }),\n ...(endIcon && { pr: 0.75 }),\n ...sx,\n }}\n // theme={theme}\n {...other}\n >\n {startIcon && <Box sx={{ mr: 0.75, ...iconStyles }}> {startIcon} </Box>}\n\n {children}\n\n {endIcon && <Box sx={{ ml: 0.75, ...iconStyles }}> {endIcon} </Box>}\n </StyledLabel>\n );\n }\n);\n\nexport default Label;\n","import dayjs from 'dayjs';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridColType,\n MGHGridComparatorFn,\n MGHGridFilterItem,\n MGHGridFilterOperator,\n MGHGridLocaleText,\n MGHGridRowId,\n MGHGridRowSelectionModel,\n MGHGridRowSelectionModelInput,\n MGHGridValidRowModel,\n MGHGridValueOption,\n MGHGridValueOptionObject,\n} from './MGHGrid.types';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * ----------------------------------------------------------------------------------------------- */\n\nexport const GROUPING_COLUMN_FIELD = '__row_group_by_columns_group__';\nexport const CHECKBOX_FIELD = '__check__';\nexport const DETAIL_PANEL_TOGGLE_FIELD = '__detail_panel_toggle__';\nexport const AGGREGATION_FOOTER_ID = '__aggregation_footer__';\nexport const INTERNAL_FIELDS = new Set<string>([CHECKBOX_FIELD, DETAIL_PANEL_TOGGLE_FIELD]);\n\nexport const DENSITY_FACTORS = { compact: 0.7, standard: 1, comfortable: 1.3 } as const;\nexport const DEFAULT_ROW_HEIGHT = 52;\nexport const DEFAULT_HEADER_HEIGHT = 56;\nexport const DEFAULT_COLUMN_WIDTH = 100;\nexport const DEFAULT_COLUMN_MIN_WIDTH = 50;\nexport const CHECKBOX_COLUMN_WIDTH = 50;\nexport const DETAIL_TOGGLE_COLUMN_WIDTH = 50;\nexport const GROUPING_COLUMN_WIDTH = 220;\n\nexport const isInternalField = (field: string) => INTERNAL_FIELDS.has(field) || field === GROUPING_COLUMN_FIELD;\n\n/* -------------------------------------------------------------------------------------------------\n * Generic helpers\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isNil = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isEmptyValue = (value: unknown) => isNil(value) || value === '' || (Array.isArray(value) && value.length === 0);\n\nexport const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nexport const cx = (...classNames: Array<string | false | null | undefined>) => classNames.filter(Boolean).join(' ');\n\nexport const arraysEqual = <T>(a: T[] | undefined, b: T[] | undefined) => {\n if (a === b) return true;\n if (!a || !b || a.length !== b.length) return false;\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n\nexport const moveItem = <T>(list: T[], from: number, to: number): T[] => {\n const next = list.slice();\n const [item] = next.splice(from, 1);\n next.splice(to, 0, item);\n return next;\n};\n\nexport const uniqueId = (() => {\n let counter = 0;\n return (prefix = 'mgh') => {\n counter += 1;\n return `${prefix}-${counter}`;\n };\n})();\n\n/* -------------------------------------------------------------------------------------------------\n * Local storage\n * ----------------------------------------------------------------------------------------------- */\n\nexport const canUseLocalStorage = () => typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';\n\nexport const readLocalStorage = <T>(key: string): T | null => {\n if (!canUseLocalStorage()) return null;\n try {\n const value = window.localStorage.getItem(key);\n return value ? (JSON.parse(value) as T) : null;\n } catch {\n return null;\n }\n};\n\nexport const writeLocalStorage = (key: string, value: unknown) => {\n if (!canUseLocalStorage()) return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n /* ignore quota / privacy errors */\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Rows\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getRowIdFromRow = <R extends MGHGridValidRowModel>(row: R, getRowId?: (row: R) => MGHGridRowId) =>\n getRowId ? getRowId(row) : (row.id as MGHGridRowId);\n\nexport const normalizeSelectionModel = (\n input: MGHGridRowSelectionModelInput | undefined,\n allIds?: MGHGridRowId[]\n): MGHGridRowSelectionModel => {\n if (!input) return { type: 'include', ids: new Set() };\n if (Array.isArray(input)) return { type: 'include', ids: new Set(input) };\n if (input instanceof Set) return { type: 'include', ids: new Set(input) };\n if (input.type === 'exclude' && allIds) {\n const ids = new Set<MGHGridRowId>();\n allIds.forEach((id) => {\n if (!input.ids.has(id)) ids.add(id);\n });\n return { type: 'include', ids };\n }\n return { type: 'include', ids: new Set(input.ids) };\n};\n\nexport const selectionModelsEqual = (a: MGHGridRowSelectionModel, b: MGHGridRowSelectionModel) => {\n if (a.ids.size !== b.ids.size) return false;\n let equal = true;\n a.ids.forEach((id) => {\n if (!b.ids.has(id)) equal = false;\n });\n return equal;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Dates\n * ----------------------------------------------------------------------------------------------- */\n\nexport const toDate = (value: unknown): Date | null => {\n if (isNil(value) || value === '') return null;\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;\n if (dayjs.isDayjs(value)) return value.isValid() ? value.toDate() : null;\n if (typeof value === 'number') {\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n if (typeof value === 'string') {\n const parsed = dayjs(value);\n return parsed.isValid() ? parsed.toDate() : null;\n }\n return null;\n};\n\nexport const formatDate = (value: unknown, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n return dayjs(date).format(withTime ? 'M/D/YYYY h:mm A' : 'M/D/YYYY');\n};\n\nconst startOfUnit = (date: Date, withTime: boolean) =>\n withTime ? dayjs(date).startOf('minute').valueOf() : dayjs(date).startOf('day').valueOf();\n\n/* -------------------------------------------------------------------------------------------------\n * Value options (singleSelect)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isValueOptionObject = (option: MGHGridValueOption): option is MGHGridValueOptionObject =>\n typeof option === 'object' && option !== null;\n\nexport const getOptionValue = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionValue ? col.getOptionValue(option) : isValueOptionObject(option) ? option.value : option;\n\nexport const getOptionLabel = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionLabel ? col.getOptionLabel(option) : isValueOptionObject(option) ? option.label : String(option);\n\nexport const resolveValueOptions = (col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (!col.valueOptions) return [] as MGHGridValueOption[];\n return typeof col.valueOptions === 'function' ? col.valueOptions({ field: col.field, row, id }) : col.valueOptions;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Cell values\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getCellValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n const raw = row ? row[col.field] : undefined;\n return col.valueGetter ? col.valueGetter(raw, row, col, api) : raw;\n};\n\nexport const getGroupingValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n if (col.groupingValueGetter) return col.groupingValueGetter(row[col.field], row, col, api);\n return getCellValue(row, col, api);\n};\n\nexport const defaultFormatValue = (value: any, col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (isNil(value)) return '';\n switch (col.type) {\n case 'date':\n return formatDate(value, false);\n case 'dateTime':\n return formatDate(value, true);\n case 'boolean':\n return value ? 'Yes' : 'No';\n case 'singleSelect': {\n const options = resolveValueOptions(col, row, id);\n const match = options.find((option) => getOptionValue(col, option) === value);\n return match !== undefined ? getOptionLabel(col, match) : String(value);\n }\n case 'number':\n return typeof value === 'number' ? (Number.isFinite(value) ? String(value) : '') : String(value);\n default:\n if (value instanceof Date) return formatDate(value, true);\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n }\n};\n\nexport const getFormattedValue = (\n value: any,\n row: MGHGridValidRowModel,\n col: MGHGridColDef,\n api: MGHGridApi,\n id?: MGHGridRowId\n) => {\n if (col.valueFormatter) return col.valueFormatter(value, row, col, api);\n return defaultFormatValue(value, col, row, id);\n};\n\nexport const formattedValueToString = (formatted: any): string => {\n if (isNil(formatted)) return '';\n if (typeof formatted === 'string') return formatted;\n if (typeof formatted === 'number' || typeof formatted === 'boolean') return String(formatted);\n if (formatted instanceof Date) return formatDate(formatted, true);\n if (typeof formatted === 'object' && 'props' in formatted) return '';\n return String(formatted);\n};\n\nexport const parseEditValue = (raw: any, col: MGHGridColDef) => {\n switch (col.type) {\n case 'number': {\n if (raw === '' || isNil(raw)) return null;\n const n = Number(raw);\n return Number.isNaN(n) ? raw : n;\n }\n case 'boolean':\n return Boolean(raw);\n case 'date':\n case 'dateTime': {\n if (raw === '' || isNil(raw)) return null;\n const d = toDate(raw);\n return d ?? raw;\n }\n default:\n return raw;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Sorting\n * ----------------------------------------------------------------------------------------------- */\n\nconst collator = typeof Intl !== 'undefined' ? new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }) : null;\n\nconst nilFirst = (v1: any, v2: any): number | null => {\n const n1 = isNil(v1) || v1 === '';\n const n2 = isNil(v2) || v2 === '';\n if (n1 && n2) return 0;\n if (n1) return -1;\n if (n2) return 1;\n return null;\n};\n\nexport const numberComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(v1) - Number(v2);\n};\n\nexport const stringComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n const s1 = String(v1);\n const s2 = String(v2);\n if (collator) return collator.compare(s1, s2);\n return s1 < s2 ? -1 : s1 > s2 ? 1 : 0;\n};\n\nexport const stringOrNumberComparator: MGHGridComparatorFn = (v1, v2, p1, p2) => {\n if (typeof v1 === 'number' && typeof v2 === 'number') return numberComparator(v1, v2, p1, p2);\n return stringComparator(v1, v2, p1, p2);\n};\n\nexport const dateComparator: MGHGridComparatorFn = (v1, v2) => {\n const d1 = toDate(v1);\n const d2 = toDate(v2);\n const nil = nilFirst(d1, d2);\n if (nil !== null) return nil;\n return (d1 as Date).getTime() - (d2 as Date).getTime();\n};\n\nexport const booleanComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(Boolean(v1)) - Number(Boolean(v2));\n};\n\nexport const getDefaultComparator = (type: MGHGridColType | undefined): MGHGridComparatorFn => {\n switch (type) {\n case 'number':\n return numberComparator;\n case 'date':\n case 'dateTime':\n return dateComparator;\n case 'boolean':\n return booleanComparator;\n default:\n return stringOrNumberComparator;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Filter operators\n * ----------------------------------------------------------------------------------------------- */\n\nconst lower = (value: unknown) => (isNil(value) ? '' : String(value).toLowerCase());\n\nconst hasValue = (item: MGHGridFilterItem) => !isEmptyValue(item.value);\n\nexport const stringFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'contains',\n label: 'contains',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) !== -1;\n },\n },\n {\n value: 'doesNotContain',\n label: 'does not contain',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === -1;\n },\n },\n {\n value: 'equals',\n label: 'equals',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) === needle;\n },\n },\n {\n value: 'doesNotEqual',\n label: 'does not equal',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) !== needle;\n },\n },\n {\n value: 'startsWith',\n label: 'starts with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === 0;\n },\n },\n {\n value: 'endsWith',\n label: 'ends with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => {\n const s = lower(value);\n return s.length >= needle.length && s.lastIndexOf(needle) === s.length - needle.length;\n };\n },\n },\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(lower));\n return (value) => set.has(lower(value));\n },\n },\n];\n\nconst numberOperator = (\n value: string,\n label: string,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: 'number',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterValue = Number(item.value);\n if (Number.isNaN(filterValue)) return null;\n return (cell) => {\n if (isNil(cell) || cell === '') return false;\n const n = Number(cell);\n return !Number.isNaN(n) && compare(n, filterValue);\n };\n },\n});\n\nexport const numberFilterOperators: MGHGridFilterOperator[] = [\n numberOperator('=', '=', (a, b) => a === b),\n numberOperator('!=', '!=', (a, b) => a !== b),\n numberOperator('>', '>', (a, b) => a > b),\n numberOperator('>=', '>=', (a, b) => a >= b),\n numberOperator('<', '<', (a, b) => a < b),\n numberOperator('<=', '<=', (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map((v: any) => Number(v)));\n return (value) => !isNil(value) && set.has(Number(value));\n },\n },\n];\n\nconst dateOperator = (\n value: string,\n label: string,\n withTime: boolean,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: withTime ? 'datetime-local' : 'date',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterDate = toDate(item.value);\n if (!filterDate) return null;\n const filterTime = startOfUnit(filterDate, withTime);\n return (cell) => {\n const cellDate = toDate(cell);\n if (!cellDate) return false;\n return compare(startOfUnit(cellDate, withTime), filterTime);\n };\n },\n});\n\nexport const getDateFilterOperators = (withTime: boolean): MGHGridFilterOperator[] => [\n dateOperator('is', 'is', withTime, (a, b) => a === b),\n dateOperator('not', 'is not', withTime, (a, b) => a !== b),\n dateOperator('after', 'is after', withTime, (a, b) => a > b),\n dateOperator('onOrAfter', 'is on or after', withTime, (a, b) => a >= b),\n dateOperator('before', 'is before', withTime, (a, b) => a < b),\n dateOperator('onOrBefore', 'is on or before', withTime, (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) === null,\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) !== null,\n },\n];\n\nexport const booleanFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'boolean',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '' || item.value === 'any') return null;\n const expected = item.value === true || item.value === 'true';\n return (value) => Boolean(value) === expected;\n },\n },\n];\n\nexport const singleSelectFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) === String(item.value);\n },\n },\n {\n value: 'not',\n label: 'is not',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) !== String(item.value);\n },\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(String));\n return (value) => set.has(String(value));\n },\n },\n];\n\nexport const getDefaultFilterOperators = (type: MGHGridColType | undefined): MGHGridFilterOperator[] => {\n switch (type) {\n case 'number':\n return numberFilterOperators;\n case 'date':\n return getDateFilterOperators(false);\n case 'dateTime':\n return getDateFilterOperators(true);\n case 'boolean':\n return booleanFilterOperators;\n case 'singleSelect':\n return singleSelectFilterOperators;\n case 'actions':\n return [];\n default:\n return stringFilterOperators;\n }\n};\n\nexport const getColumnFilterOperators = (col: MGHGridColDef) => col.filterOperators ?? getDefaultFilterOperators(col.type);\n\n/* -------------------------------------------------------------------------------------------------\n * Column normalisation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const normalizeColumn = <R extends MGHGridValidRowModel>(col: MGHGridColDef<R>): MGHGridColDef<R> => {\n const type = col.type ?? 'string';\n const isNumber = type === 'number';\n const isBoolean = type === 'boolean';\n const isActions = type === 'actions';\n return {\n ...col,\n type,\n headerName: col.headerName ?? col.field,\n width: col.width ?? (isActions ? 100 : isBoolean ? 100 : DEFAULT_COLUMN_WIDTH),\n minWidth: col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,\n align: col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n headerAlign: col.headerAlign ?? col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n sortable: isActions ? false : (col.sortable ?? true),\n filterable: isActions ? false : (col.filterable ?? true),\n hideable: col.hideable ?? true,\n resizable: col.resizable ?? true,\n pinnable: col.pinnable ?? true,\n groupable: isActions ? false : (col.groupable ?? true),\n aggregable: isActions ? false : (col.aggregable ?? true),\n editable: col.editable ?? false,\n disableColumnMenu: col.disableColumnMenu ?? isActions,\n disableExport: col.disableExport ?? isActions,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Internal (auto-generated) columns\n * ----------------------------------------------------------------------------------------------- */\n\nconst internalColumn = (field: string, width: number): MGHGridColDef =>\n normalizeColumn({\n field,\n headerName: '',\n width,\n minWidth: width,\n maxWidth: width,\n sortable: false,\n filterable: false,\n hideable: false,\n resizable: false,\n pinnable: false,\n groupable: false,\n aggregable: false,\n disableColumnMenu: true,\n disableExport: true,\n disableReorder: true,\n align: 'center',\n headerAlign: 'center',\n });\n\n/** Definition of the checkbox-selection column (equivalent of MUI's GRID_CHECKBOX_SELECTION_COL_DEF). */\nexport const CHECKBOX_COLUMN_DEF: MGHGridColDef = internalColumn(CHECKBOX_FIELD, CHECKBOX_COLUMN_WIDTH);\n/** Definition of the detail-panel toggle column (equivalent of MUI's GRID_DETAIL_PANEL_TOGGLE_COL_DEF). */\nexport const DETAIL_PANEL_TOGGLE_COLUMN_DEF: MGHGridColDef = internalColumn(\n DETAIL_PANEL_TOGGLE_FIELD,\n DETAIL_TOGGLE_COLUMN_WIDTH\n);\n\n/* -------------------------------------------------------------------------------------------------\n * sx -> scoped CSS\n * ----------------------------------------------------------------------------------------------- */\n\nconst UNITLESS_PROPERTIES = new Set([\n 'animationIterationCount',\n 'borderImageOutset',\n 'borderImageSlice',\n 'borderImageWidth',\n 'boxFlex',\n 'boxFlexGroup',\n 'boxOrdinalGroup',\n 'columnCount',\n 'columns',\n 'flex',\n 'flexGrow',\n 'flexPositive',\n 'flexShrink',\n 'flexNegative',\n 'flexOrder',\n 'gridArea',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowSpan',\n 'gridRowStart',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnSpan',\n 'gridColumnStart',\n 'fontWeight',\n 'lineClamp',\n 'lineHeight',\n 'opacity',\n 'order',\n 'orphans',\n 'tabSize',\n 'widows',\n 'zIndex',\n 'zoom',\n 'fillOpacity',\n 'floodOpacity',\n 'stopOpacity',\n 'strokeDasharray',\n 'strokeDashoffset',\n 'strokeMiterlimit',\n 'strokeOpacity',\n 'strokeWidth',\n]);\n\n/** Keys that are CSS selectors / at-rules rather than CSS properties. */\nexport const isSelectorKey = (key: string) => /[&.:#>\\[\\s*~+,@]/.test(key);\n\nconst toKebabCase = (property: string) => {\n if (property.indexOf('--') === 0) return property;\n const kebab = property.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n return kebab.indexOf('ms-') === 0 ? `-${kebab}` : kebab;\n};\n\nconst formatCssValue = (property: string, value: string | number) =>\n typeof value === 'number' && value !== 0 && !UNITLESS_PROPERTIES.has(property) && property.indexOf('--') !== 0\n ? `${value}px`\n : String(value);\n\nconst serializeDeclarations = (block: Record<string, unknown>) =>\n Object.keys(block)\n .filter((key) => {\n const value = block[key];\n return !isSelectorKey(key) && (typeof value === 'string' || typeof value === 'number');\n })\n .map((key) => `${toKebabCase(key)}:${formatCssValue(key, block[key] as string | number)}`)\n .join(';');\n\nconst scopeSelector = (scope: string, selector: string) =>\n selector\n .split(',')\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => (part.indexOf('&') !== -1 ? part.replace(/&/g, scope) : `${scope} ${part}`))\n .join(',');\n\n/**\n * Compiles the nested-selector part of an `sx`-like object into CSS scoped under `scope`.\n * Top-level plain properties are ignored here (they are applied as inline styles instead).\n */\nexport const buildScopedCss = (scope: string, sx: Record<string, unknown> | undefined, out: string[] = []): string[] => {\n if (!sx) return out;\n Object.keys(sx).forEach((key) => {\n const value = sx[key];\n if (!value || typeof value !== 'object') return;\n const block = value as Record<string, unknown>;\n if (key.charAt(0) === '@') {\n const inner: string[] = [];\n const declarations = serializeDeclarations(block);\n if (declarations) inner.push(`${scope}{${declarations}}`);\n buildScopedCss(scope, block, inner);\n if (inner.length) out.push(`${key}{${inner.join('')}}`);\n return;\n }\n const selector = scopeSelector(scope, key);\n const declarations = serializeDeclarations(block);\n if (declarations) out.push(`${selector}{${declarations}}`);\n buildScopedCss(selector, block, out);\n });\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nconst numericValues = (values: any[]) =>\n values.map((v) => (typeof v === 'number' ? v : Number(v))).filter((n) => !Number.isNaN(n) && n !== null);\n\nexport const BUILT_IN_AGGREGATION_FUNCTIONS: Record<string, MGHGridAggregationFunction> = {\n sum: {\n label: 'sum',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0);\n },\n },\n avg: {\n label: 'avg',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0) / nums.length;\n },\n },\n min: {\n label: 'min',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.min(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.min(...dates.map((d) => (d as Date).getTime())));\n }\n return defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any))[0];\n },\n },\n max: {\n label: 'max',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.max(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.max(...dates.map((d) => (d as Date).getTime())));\n }\n const sorted = defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any));\n return sorted[sorted.length - 1];\n },\n },\n size: {\n label: 'size',\n apply: ({ values }) => values.length,\n },\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Locale\n * ----------------------------------------------------------------------------------------------- */\n\nexport const DEFAULT_LOCALE_TEXT: MGHGridLocaleText = {\n noRowsLabel: 'No rows',\n loadingLabel: 'Loading…',\n toolbarColumns: 'Columns',\n toolbarFilters: 'Filters',\n toolbarExport: 'Export',\n toolbarDensity: 'Density',\n toolbarQuickFilterPlaceholder: 'Search...',\n toolbarQuickFilterLabel: 'Search',\n toolbarExportCSV: 'Download as CSV',\n toolbarExportExcel: 'Download as Excel',\n toolbarExportPrint: 'Print',\n densityCompact: 'Compact',\n densityStandard: 'Standard',\n densityComfortable: 'Comfortable',\n columnsPanelSearchPlaceholder: 'Search',\n columnsPanelShowAll: 'Show all',\n columnsPanelHideAll: 'Hide all',\n columnsPanelReset: 'Reset',\n filterPanelAddFilter: 'Add filter',\n filterPanelRemoveAll: 'Remove all',\n filterPanelDeleteIcon: 'Delete',\n filterPanelColumns: 'Columns',\n filterPanelOperator: 'Operator',\n filterPanelValue: 'Value',\n filterPanelInputPlaceholder: 'Filter value',\n filterPanelLogicOperator: 'Logic operator',\n filterPanelOperatorAnd: 'And',\n filterPanelOperatorOr: 'Or',\n columnMenuSortAsc: 'Sort by ASC',\n columnMenuSortDesc: 'Sort by DESC',\n columnMenuUnsort: 'Unsort',\n columnMenuFilter: 'Filter',\n columnMenuHideColumn: 'Hide column',\n columnMenuManageColumns: 'Manage columns',\n columnMenuPinLeft: 'Pin to left',\n columnMenuPinRight: 'Pin to right',\n columnMenuUnpin: 'Unpin',\n columnMenuGroup: (name) => `Group by ${name}`,\n columnMenuUngroup: (name) => `Stop grouping by ${name}`,\n columnMenuAggregation: 'Aggregation',\n aggregationMenuItemHeader: 'Aggregation',\n aggregationFunctionLabelNone: 'none',\n aggregationFunctionLabelSum: 'sum',\n aggregationFunctionLabelAvg: 'avg',\n aggregationFunctionLabelMin: 'min',\n aggregationFunctionLabelMax: 'max',\n aggregationFunctionLabelSize: 'size',\n footerRowSelected: (count) => (count === 1 ? '1 row selected' : `${count.toLocaleString()} rows selected`),\n footerTotalRows: 'Total Rows:',\n footerPaginationRowsPerPage: 'Rows per page:',\n footerPaginationDisplayedRows: (from, to, count) => `${from}–${to} of ${count.toLocaleString()}`,\n footerPaginationFirstPage: 'First page',\n footerPaginationPreviousPage: 'Previous page',\n footerPaginationNextPage: 'Next page',\n footerPaginationLastPage: 'Last page',\n checkboxSelectionHeaderName: 'Checkbox selection',\n checkboxSelectionSelectAllRows: 'Select all rows',\n checkboxSelectionUnselectAllRows: 'Unselect all rows',\n checkboxSelectionSelectRow: 'Select row',\n checkboxSelectionUnselectRow: 'Unselect row',\n booleanCellTrueLabel: 'yes',\n booleanCellFalseLabel: 'no',\n detailPanelToggle: 'Detail panel toggle',\n expandDetailPanel: 'Expand',\n collapseDetailPanel: 'Collapse',\n groupingColumnHeaderName: 'Group',\n groupColumn: (name) => `Group by ${name}`,\n unGroupColumn: (name) => `Stop grouping by ${name}`,\n actionsCellMore: 'more',\n columnHeaderSortIconLabel: 'Sort',\n columnMenuLabel: 'Menu',\n clearSearch: 'Clear search',\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Text measurement (used for autosize)\n * ----------------------------------------------------------------------------------------------- */\n\nlet measureContext: CanvasRenderingContext2D | null | undefined;\n\nexport const measureText = (text: string, font: string) => {\n if (typeof document === 'undefined') return text.length * 8;\n if (measureContext === undefined) {\n const canvas = document.createElement('canvas');\n measureContext = canvas.getContext('2d');\n }\n if (!measureContext) return text.length * 8;\n measureContext.font = font;\n return measureContext.measureText(text).width;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Downloads\n * ----------------------------------------------------------------------------------------------- */\n\nexport const downloadBlob = (blob: Blob, fileName: string) => {\n if (typeof document === 'undefined') return;\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = fileName;\n anchor.style.display = 'none';\n document.body.appendChild(anchor);\n anchor.click();\n window.setTimeout(() => {\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n }, 0);\n};\n","import React from 'react';\n\nexport const MGH_GRID_STYLE_ID = 'mgh-grid-styles';\n\n/**\n * Stylesheet for MGHGrid. It is injected once into <head> the first time a grid mounts,\n * so consumers do not need a CSS loader. All colours are CSS variables so the look can be\n * customised globally (by redefining `--mgh-grid-*` on `.mgh-grid-card`) or per instance\n * through the `themeVars` prop.\n */\nexport const MGH_GRID_CSS = `\n.mgh-grid-card {\n --mgh-grid-font-family: inherit;\n --mgh-grid-font-size: 14px;\n --mgh-grid-radius: 16px;\n --mgh-grid-inner-radius: 4px;\n --mgh-grid-paper: #ffffff;\n --mgh-grid-bg: #ffffff;\n --mgh-grid-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-fg-secondary: rgba(0, 0, 0, 0.6);\n --mgh-grid-fg-disabled: rgba(0, 0, 0, 0.38);\n --mgh-grid-border: rgba(224, 224, 224, 1);\n --mgh-grid-header-bg: #ffffff;\n --mgh-grid-header-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-hover: rgba(0, 0, 0, 0.04);\n --mgh-grid-hover-strong: rgba(0, 0, 0, 0.08);\n --mgh-grid-selected: rgba(25, 118, 210, 0.08);\n --mgh-grid-selected-hover: rgba(25, 118, 210, 0.12);\n --mgh-grid-primary: #1976d2;\n --mgh-grid-primary-contrast: #ffffff;\n --mgh-grid-focus: #1976d2;\n --mgh-grid-shadow: 0 0 2px rgba(145, 158, 171, 0.2), 0 12px 24px -4px rgba(145, 158, 171, 0.12);\n --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n --mgh-grid-overlay: rgba(255, 255, 255, 0.6);\n --mgh-grid-input-bg: transparent;\n --mgh-grid-input-border: rgba(0, 0, 0, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.12);\n --mgh-grid-group-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-footer-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-badge: #1976d2;\n --mgh-grid-scrollbar: rgba(0, 0, 0, 0.3);\n\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n background: var(--mgh-grid-paper);\n color: var(--mgh-grid-fg);\n border-radius: var(--mgh-grid-radius);\n box-shadow: var(--mgh-grid-shadow);\n font-family: var(--mgh-grid-font-family);\n font-size: var(--mgh-grid-font-size);\n line-height: 1.5;\n overflow: hidden;\n box-sizing: border-box;\n}\n.mgh-grid-card[data-mgh-theme=\"dark\"] {\n --mgh-grid-paper: #212b36;\n --mgh-grid-bg: #212b36;\n --mgh-grid-fg: #ffffff;\n --mgh-grid-fg-secondary: rgba(255, 255, 255, 0.7);\n --mgh-grid-fg-disabled: rgba(255, 255, 255, 0.5);\n --mgh-grid-border: rgba(81, 81, 81, 1);\n --mgh-grid-header-bg: #212b36;\n --mgh-grid-header-fg: #ffffff;\n --mgh-grid-hover: rgba(255, 255, 255, 0.08);\n --mgh-grid-hover-strong: rgba(255, 255, 255, 0.16);\n --mgh-grid-selected: rgba(144, 202, 249, 0.16);\n --mgh-grid-selected-hover: rgba(144, 202, 249, 0.24);\n --mgh-grid-primary: #90caf9;\n --mgh-grid-primary-contrast: rgba(0, 0, 0, 0.87);\n --mgh-grid-focus: #90caf9;\n --mgh-grid-shadow: 0 0 2px rgba(0, 0, 0, 0.2), 0 12px 24px -4px rgba(0, 0, 0, 0.12);\n --mgh-grid-overlay: rgba(33, 43, 54, 0.6);\n --mgh-grid-input-border: rgba(255, 255, 255, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.5);\n --mgh-grid-group-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-footer-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-badge: #90caf9;\n --mgh-grid-scrollbar: rgba(255, 255, 255, 0.3);\n}\n/* Only our own elements get the border-box reset. A blanket descendant reset would leak into\n consumer content rendered through slots (e.g. MUI TextField inputs rely on content-box). */\n[class*=\"mgh-grid\"], [class*=\"mgh-grid\"]::before, [class*=\"mgh-grid\"]::after { box-sizing: border-box; }\n.mgh-grid-card--plain { box-shadow: none; border-radius: 0; background: transparent; }\n\n/* ---- card header ---- */\n/* Title stays on its row; only the end-content group wraps internally (like the legacy MUI card). */\n.mgh-grid-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 16px 16px 16px 0; flex-wrap: nowrap; }\n.mgh-grid-card-title { flex: 0 0 auto; padding: 8px 24px; margin: 0; font-size: 1.125rem; font-weight: 700; line-height: 1.5556; }\n.mgh-grid-card-header-center { flex: 0 1 auto; min-width: 0; display: flex; align-items: center; }\n.mgh-grid-card-header-end { flex: 1 1 auto; min-width: 0; margin-left: auto; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; justify-content: flex-end; }\n@media (max-width: 599.95px) {\n .mgh-grid-card-header { flex-wrap: wrap; }\n .mgh-grid-card-header-end { gap: 8px; }\n}\n\n/* ---- box + root ---- */\n.mgh-grid-box { display: flex; flex-direction: column; flex-grow: 1; min-height: 0; min-width: 0; }\n.mgh-grid {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n min-width: 0;\n border: 1px solid var(--mgh-grid-border);\n border-radius: var(--mgh-grid-inner-radius);\n background: var(--mgh-grid-bg);\n color: var(--mgh-grid-fg);\n outline: none;\n}\n.mgh-grid--auto-height { flex: 0 0 auto; }\n\n/* ---- toolbar ---- */\n.mgh-grid-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 45px; padding: 4px 8px; border-bottom: 1px solid var(--mgh-grid-border); flex-wrap: wrap; }\n.mgh-grid-toolbar-group { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }\n.mgh-grid-toolbar-center { display: flex; align-items: center; flex: 1 1 auto; justify-content: center; }\n\n/* ---- buttons ---- */\n.mgh-grid-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 0; margin: 0; background: transparent; color: var(--mgh-grid-fg-secondary); font: inherit; font-size: 0.8125rem; font-weight: 500; line-height: 1.75; letter-spacing: .02em; padding: 4px 8px; border-radius: 4px; cursor: pointer; user-select: none; transition: background-color .15s, color .15s; text-transform: none; white-space: nowrap; }\n.mgh-grid-btn:hover { background: var(--mgh-grid-hover); color: var(--mgh-grid-fg); }\n.mgh-grid-btn:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 1px; }\n.mgh-grid-btn:disabled { color: var(--mgh-grid-fg-disabled); cursor: default; background: transparent; }\n.mgh-grid-btn--icon { padding: 6px; border-radius: 50%; width: 32px; height: 32px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small { width: 26px; height: 26px; padding: 3px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small .mgh-grid-icon { width: 18px; height: 18px; }\n.mgh-grid-btn--primary { color: var(--mgh-grid-primary); }\n.mgh-grid-btn--primary:hover { background: var(--mgh-grid-selected); color: var(--mgh-grid-primary); }\n.mgh-grid-btn--contained { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); }\n.mgh-grid-btn--contained:hover { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); filter: brightness(0.92); }\n.mgh-grid-btn--active { color: var(--mgh-grid-primary); }\n\n/* ---- badge ---- */\n.mgh-grid-badge { position: relative; display: inline-flex; }\n.mgh-grid-badge-dot { position: absolute; top: 0; right: 0; min-width: 8px; height: 8px; border-radius: 4px; background: var(--mgh-grid-badge); transform: translate(50%, -50%); }\n.mgh-grid-badge-count { position: absolute; top: 0; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--mgh-grid-badge); color: var(--mgh-grid-primary-contrast); font-size: 10px; font-weight: 600; line-height: 16px; text-align: center; transform: translate(50%, -50%); }\n\n/* ---- inputs ---- */\n.mgh-grid-input, .mgh-grid-select { font: inherit; font-size: 0.875rem; color: var(--mgh-grid-fg); background: var(--mgh-grid-input-bg); border: 1px solid var(--mgh-grid-input-border); border-radius: 6px; padding: 6px 10px; height: 36px; min-width: 0; outline: none; transition: border-color .15s, box-shadow .15s; }\n.mgh-grid-input:hover, .mgh-grid-select:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-input:focus, .mgh-grid-select:focus { border-color: var(--mgh-grid-focus); box-shadow: 0 0 0 1px var(--mgh-grid-focus); }\n.mgh-grid-input::placeholder { color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-input--small, .mgh-grid-select--small { height: 32px; padding: 4px 8px; font-size: 0.8125rem; }\n.mgh-grid-select { appearance: none; -webkit-appearance: none; padding-right: 28px; background-image: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23888'><path d='M7 10l5 5 5-5z'/></svg>\"); background-repeat: no-repeat; background-position: right 6px center; background-size: 18px; cursor: pointer; }\n.mgh-grid-select option { color: initial; background: initial; }\n.mgh-grid-card[data-mgh-theme=\"dark\"] .mgh-grid-select option, .mgh-grid-popover[data-mgh-theme=\"dark\"] .mgh-grid-select option { color: #fff; background: #212b36; }\n.mgh-grid-select[multiple] { height: auto; min-height: 36px; background-image: none; padding-right: 10px; }\n.mgh-grid-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n.mgh-grid-field-label { font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-input-adorned { position: relative; display: flex; align-items: center; }\n.mgh-grid-input-adorned .mgh-grid-input { width: 100%; padding-left: 34px; }\n.mgh-grid-input-adorned--clearable .mgh-grid-input { padding-right: 34px; }\n.mgh-grid-input-adornment { position: absolute; left: 10px; display: inline-flex; color: var(--mgh-grid-fg-secondary); pointer-events: none; }\n.mgh-grid-input-adornment--end { left: auto; right: 4px; pointer-events: auto; }\n\n/* ---- checkbox ---- */\n.mgh-grid-checkbox { appearance: none; -webkit-appearance: none; width: 18px; height: 18px; margin: 0; border: 2px solid var(--mgh-grid-fg-secondary); border-radius: 3px; background: transparent; cursor: pointer; display: inline-grid; place-content: center; position: relative; flex: 0 0 auto; transition: background-color .12s, border-color .12s; }\n.mgh-grid-checkbox:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-checkbox:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 2px; }\n.mgh-grid-checkbox:checked, .mgh-grid-checkbox:indeterminate { background: var(--mgh-grid-primary); border-color: var(--mgh-grid-primary); }\n.mgh-grid-checkbox:checked::after { content: \"\"; width: 5px; height: 10px; border: solid var(--mgh-grid-primary-contrast); border-width: 0 2px 2px 0; transform: translateY(-1px) rotate(45deg); }\n.mgh-grid-checkbox:indeterminate::after { content: \"\"; width: 10px; height: 2px; background: var(--mgh-grid-primary-contrast); }\n.mgh-grid-checkbox:disabled { opacity: 0.4; cursor: default; }\n.mgh-grid-checkbox-label { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 0.875rem; padding: 6px 4px; border-radius: 4px; }\n.mgh-grid-checkbox-label:hover { background: var(--mgh-grid-hover); }\n\n/* ---- quick filter ---- */\n.mgh-grid-quick-filter { display: grid; align-items: center; }\n.mgh-grid-quick-filter-trigger { grid-area: 1 / 1; z-index: 1; transition: opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-trigger { opacity: 0; pointer-events: none; }\n.mgh-grid-quick-filter-control { grid-area: 1 / 1; width: 32px; opacity: 0; overflow: hidden; transition: width .2s, opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 260px; opacity: 1; }\n@media (max-width: 599.95px) { .mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 180px; } }\n\n/* ---- main / scroller ---- */\n.mgh-grid-main { position: relative; display: flex; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: hidden; }\n.mgh-grid--auto-height .mgh-grid-main { flex: 0 0 auto; }\n.mgh-grid-scroller { position: relative; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: auto; outline: none; scrollbar-width: thin; }\n.mgh-grid--auto-height .mgh-grid-scroller { overflow-y: hidden; }\n.mgh-grid-scroller::-webkit-scrollbar { width: 10px; height: 10px; }\n.mgh-grid-scroller::-webkit-scrollbar-thumb { background: var(--mgh-grid-scrollbar); border-radius: 5px; border: 2px solid transparent; background-clip: content-box; }\n\n/* ---- column headers ---- */\n.mgh-grid-columns { position: sticky; top: 0; z-index: 3; background: var(--mgh-grid-header-bg); border-bottom: 1px solid var(--mgh-grid-border); min-width: 100%; width: max-content; }\n.mgh-grid-header-row { display: flex; min-width: 100%; }\n.mgh-grid-header-cell { position: relative; display: flex; align-items: center; flex: 0 0 auto; height: var(--mgh-grid-header-height); padding: 0 10px; font-weight: 600; font-size: 0.875rem; color: var(--mgh-grid-header-fg); background: var(--mgh-grid-header-bg); white-space: nowrap; overflow: hidden; user-select: none; outline: none; }\n.mgh-grid-header-cell--sortable { cursor: pointer; }\n.mgh-grid-header-cell:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; }\n.mgh-grid-header-cell--align-center { justify-content: center; }\n.mgh-grid-header-cell--align-right { justify-content: flex-end; }\n.mgh-grid-header-cell--align-right .mgh-grid-header-title-container { flex-direction: row-reverse; }\n.mgh-grid-header-title-container { display: flex; align-items: center; gap: 2px; min-width: 0; flex: 1 1 auto; overflow: hidden; }\n.mgh-grid-header-cell--align-center .mgh-grid-header-title-container { flex: 0 1 auto; }\n.mgh-grid-header-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.mgh-grid-sort-icon { display: inline-flex; align-items: center; color: var(--mgh-grid-fg-secondary); opacity: 0; transition: opacity .15s; flex: 0 0 auto; }\n.mgh-grid-header-cell:hover .mgh-grid-sort-icon, .mgh-grid-sort-icon--active { opacity: 1; }\n.mgh-grid-sort-index { font-size: 10px; margin-left: -2px; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-header-menu-btn { position: absolute; right: 2px; opacity: 0; transition: opacity .15s; background: var(--mgh-grid-header-bg); }\n.mgh-grid-header-cell--align-right .mgh-grid-header-menu-btn { right: auto; left: 2px; }\n.mgh-grid-header-cell:hover .mgh-grid-header-menu-btn, .mgh-grid-header-menu-btn--open, .mgh-grid-header-cell:focus-within .mgh-grid-header-menu-btn { opacity: 1; }\n.mgh-grid-header-cell--menu-open { background: var(--mgh-grid-hover); }\n.mgh-grid-resize-handle { position: absolute; top: 0; right: -4px; width: 9px; height: 100%; cursor: col-resize; z-index: 2; display: flex; justify-content: center; touch-action: none; }\n.mgh-grid-resize-handle::after { content: \"\"; width: 1px; height: 60%; margin-top: 20%; background: var(--mgh-grid-border); transition: background .15s, width .15s; }\n.mgh-grid-resize-handle:hover::after, .mgh-grid-resize-handle--active::after { background: var(--mgh-grid-primary); width: 2px; }\n.mgh-grid-header-cell--last .mgh-grid-resize-handle { right: 0; }\n.mgh-grid-header-cell--dragging { opacity: 0.5; }\n.mgh-grid-header-cell--drop-left::before, .mgh-grid-header-cell--drop-right::before { content: \"\"; position: absolute; top: 4px; bottom: 4px; width: 2px; background: var(--mgh-grid-primary); z-index: 3; }\n.mgh-grid-header-cell--drop-left::before { left: 0; }\n.mgh-grid-header-cell--drop-right::before { right: 0; }\n.mgh-grid-header-filler { flex: 1 1 auto; background: var(--mgh-grid-header-bg); }\n\n/* ---- pinned cells ---- */\n.mgh-grid-cell--pinned-left, .mgh-grid-header-cell--pinned-left { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-cell--pinned-right, .mgh-grid-header-cell--pinned-right { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-header-cell--pinned-left, .mgh-grid-header-cell--pinned-right { z-index: 4; background-color: var(--mgh-grid-header-bg); }\n.mgh-grid-cell--pinned-left-last, .mgh-grid-header-cell--pinned-left-last { box-shadow: 2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-cell--pinned-right-first, .mgh-grid-header-cell--pinned-right-first { box-shadow: -2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid--no-pinned-shadow .mgh-grid-cell--pinned-left-last, .mgh-grid--no-pinned-shadow .mgh-grid-header-cell--pinned-left-last { box-shadow: none; }\n\n/* ---- body & rows ---- */\n.mgh-grid-body { position: relative; min-width: 100%; width: max-content; }\n.mgh-grid-body--flow { display: flex; flex-direction: column; }\n.mgh-grid-row-block { min-width: 100%; }\n.mgh-grid-body--virtual .mgh-grid-row-block { position: absolute; left: 0; }\n.mgh-grid-row { display: flex; min-width: 100%; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); position: relative; }\n.mgh-grid-row--auto-height { align-items: stretch; }\n.mgh-grid-row:hover { background: var(--mgh-grid-hover); }\n.mgh-grid-row--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-row--selected:hover { background: var(--mgh-grid-selected-hover); }\n.mgh-grid-row--clickable { cursor: pointer; }\n.mgh-grid-row--group { background: var(--mgh-grid-group-bg); }\n.mgh-grid-row--pinned { background: var(--mgh-grid-bg); }\n.mgh-grid-row--footer { background: var(--mgh-grid-footer-bg); font-weight: 600; }\n.mgh-grid-row:hover .mgh-grid-cell--pinned-left, .mgh-grid-row:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-hover), var(--mgh-grid-hover)); }\n.mgh-grid-row--selected .mgh-grid-cell--pinned-left, .mgh-grid-row--selected .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected), var(--mgh-grid-selected)); }\n.mgh-grid-row--selected:hover .mgh-grid-cell--pinned-left, .mgh-grid-row--selected:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected-hover), var(--mgh-grid-selected-hover)); }\n.mgh-grid-row--group .mgh-grid-cell--pinned-left, .mgh-grid-row--group .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-group-bg), var(--mgh-grid-group-bg)); }\n.mgh-grid-row--footer .mgh-grid-cell--pinned-left, .mgh-grid-row--footer .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-footer-bg), var(--mgh-grid-footer-bg)); }\n.mgh-grid-row-filler { flex: 1 1 auto; }\n\n.mgh-grid-cell { display: flex; align-items: center; flex: 0 0 auto; padding: 0 10px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 0.875rem; outline: none; min-height: 100%; }\n.mgh-grid-cell > .mgh-grid-cell-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }\n.mgh-grid-row--auto-height .mgh-grid-cell { white-space: normal; align-items: flex-start; padding-top: 8px; padding-bottom: 8px; }\n.mgh-grid-row--auto-height .mgh-grid-cell > .mgh-grid-cell-text { white-space: normal; word-break: break-word; }\n.mgh-grid-cell--align-center { justify-content: center; }\n.mgh-grid-cell--align-right { justify-content: flex-end; }\n.mgh-grid-cell--focused { outline: 1px solid var(--mgh-grid-focus); outline-offset: -1px; }\n.mgh-grid-cell--editable { cursor: text; }\n.mgh-grid-cell--editing { padding: 0 4px; outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; background: var(--mgh-grid-bg); }\n.mgh-grid-cell--editing .mgh-grid-input, .mgh-grid-cell--editing .mgh-grid-select { width: 100%; height: calc(100% - 6px); border: 0; box-shadow: none; padding: 0 6px; background: transparent; }\n.mgh-grid-cell--checkbox, .mgh-grid-header-cell--checkbox, .mgh-grid-cell--detail-toggle, .mgh-grid-header-cell--detail-toggle { justify-content: center; padding: 0; }\n.mgh-grid-cell--boolean .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-cell--actions { gap: 2px; justify-content: center; }\n.mgh-grid-cell--aggregation { flex-direction: column; align-items: stretch; justify-content: center; line-height: 1.2; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-right { align-items: flex-end; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-center { align-items: center; }\n.mgh-grid-aggregation-label { font-size: 0.65rem; font-weight: 500; text-transform: uppercase; color: var(--mgh-grid-fg-secondary); letter-spacing: .04em; }\n.mgh-grid-group-cell { display: flex; align-items: center; gap: 4px; min-width: 0; }\n.mgh-grid-group-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }\n.mgh-grid-group-count { color: var(--mgh-grid-fg-secondary); margin-left: 2px; }\n.mgh-grid-group-toggle { flex: 0 0 auto; }\n.mgh-grid-group-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-group-toggle--expanded .mgh-grid-icon { transform: rotate(90deg); }\n.mgh-grid-detail-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-detail-toggle--expanded .mgh-grid-icon { transform: rotate(180deg); }\n\n/* ---- pinned rows ---- */\n.mgh-grid-pinned-rows { position: sticky; z-index: 2; min-width: 100%; width: max-content; background: var(--mgh-grid-bg); }\n.mgh-grid-pinned-rows--top { box-shadow: 0 2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom { bottom: 0; box-shadow: 0 -2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom .mgh-grid-row { border-bottom: 0; border-top: 1px solid var(--mgh-grid-border); }\n\n/* ---- detail panel ---- */\n.mgh-grid-detail-panel { position: sticky; left: 0; overflow: auto; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); z-index: 1; }\n\n/* ---- overlays ---- */\n.mgh-grid-overlay { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px; z-index: 5; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; pointer-events: none; }\n.mgh-grid-overlay--loading { background: var(--mgh-grid-overlay); pointer-events: auto; }\n.mgh-grid-no-rows { display: flex; align-items: center; justify-content: center; gap: 8px; height: 100%; text-align: center; padding: 16px; }\n.mgh-grid-no-rows img, .mgh-grid-no-rows .mgh-grid-icon { width: 50px; height: 50px; color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-spinner { width: 36px; height: 36px; border-radius: 50%; border: 3px solid var(--mgh-grid-selected); border-top-color: var(--mgh-grid-primary); animation: mgh-grid-spin .8s linear infinite; }\n@keyframes mgh-grid-spin { to { transform: rotate(360deg); } }\n\n/* ---- footer ---- */\n.mgh-grid-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 52px; padding: 0 8px 0 16px; border-top: 1px solid var(--mgh-grid-border); font-size: 0.875rem; color: var(--mgh-grid-fg-secondary); flex-wrap: wrap; }\n.mgh-grid-footer-left { display: flex; align-items: center; gap: 16px; }\n.mgh-grid-pagination { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }\n.mgh-grid-pagination-select { height: 32px; padding: 2px 24px 2px 8px; font-size: 0.875rem; border-color: transparent; }\n.mgh-grid-pagination-select:hover { border-color: transparent; background-color: var(--mgh-grid-hover); }\n.mgh-grid-pagination-actions { display: inline-flex; align-items: center; }\n\n/* ---- popover / menu / panels ---- */\n.mgh-grid-popover {\n --mgh-grid-font-family: inherit; --mgh-grid-font-size: 14px; --mgh-grid-paper: #ffffff; --mgh-grid-bg: #fff; --mgh-grid-fg: rgba(0,0,0,.87); --mgh-grid-fg-secondary: rgba(0,0,0,.6); --mgh-grid-fg-disabled: rgba(0,0,0,.38); --mgh-grid-border: rgba(224,224,224,1); --mgh-grid-hover: rgba(0,0,0,.04); --mgh-grid-selected: rgba(25,118,210,.08); --mgh-grid-primary: #1976d2; --mgh-grid-primary-contrast: #fff; --mgh-grid-focus: #1976d2; --mgh-grid-input-bg: transparent; --mgh-grid-input-border: rgba(0,0,0,.23); --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n position: fixed; z-index: 1300; background: var(--mgh-grid-paper); color: var(--mgh-grid-fg); border-radius: 8px; box-shadow: var(--mgh-grid-popover-shadow); font-family: var(--mgh-grid-font-family); font-size: var(--mgh-grid-font-size); line-height: 1.5; outline: none; max-height: calc(100vh - 16px); overflow: auto; animation: mgh-grid-pop .12s ease-out;\n}\n.mgh-grid-popover[data-mgh-theme=\"dark\"] { --mgh-grid-paper: #212b36; --mgh-grid-bg: #212b36; --mgh-grid-fg: #fff; --mgh-grid-fg-secondary: rgba(255,255,255,.7); --mgh-grid-fg-disabled: rgba(255,255,255,.5); --mgh-grid-border: rgba(81,81,81,1); --mgh-grid-hover: rgba(255,255,255,.08); --mgh-grid-selected: rgba(144,202,249,.16); --mgh-grid-primary: #90caf9; --mgh-grid-primary-contrast: rgba(0,0,0,.87); --mgh-grid-focus: #90caf9; --mgh-grid-input-border: rgba(255,255,255,.23); }\n@keyframes mgh-grid-pop { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }\n.mgh-grid-menu { list-style: none; margin: 0; padding: 6px 0; min-width: 180px; }\n.mgh-grid-menu-item { display: flex; align-items: center; gap: 12px; padding: 6px 16px; min-height: 36px; font-size: 0.875rem; cursor: pointer; white-space: nowrap; color: var(--mgh-grid-fg); background: transparent; border: 0; width: 100%; text-align: left; font-family: inherit; outline: none; }\n.mgh-grid-menu-item:hover, .mgh-grid-menu-item:focus-visible { background: var(--mgh-grid-hover); }\n.mgh-grid-menu-item--disabled { color: var(--mgh-grid-fg-disabled); cursor: default; pointer-events: none; }\n.mgh-grid-menu-item--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-menu-item .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); flex: 0 0 auto; }\n.mgh-grid-menu-divider { height: 1px; margin: 6px 0; background: var(--mgh-grid-border); border: 0; }\n.mgh-grid-menu-header { padding: 6px 16px 2px; font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); text-transform: uppercase; letter-spacing: .04em; }\n.mgh-grid-menu-section { padding: 4px 16px 8px; display: flex; flex-direction: column; gap: 4px; }\n.mgh-grid-panel { display: flex; flex-direction: column; min-width: 300px; max-width: min(640px, calc(100vw - 16px)); }\n.mgh-grid-panel-header { padding: 12px 12px 4px; }\n.mgh-grid-panel-content { padding: 4px 12px; overflow: auto; max-height: 360px; }\n.mgh-grid-panel-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; }\n.mgh-grid-columns-list { display: flex; flex-direction: column; }\n.mgh-grid-filter-row { display: grid; grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); gap: 8px; align-items: end; margin-bottom: 8px; }\n.mgh-grid-filter-row--first { grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row--with-logic { grid-template-columns: 32px 80px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row .mgh-grid-btn--icon { margin-bottom: 4px; }\n.mgh-grid-filter-empty { padding: 8px 4px; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; }\n@media (max-width: 599.95px) { .mgh-grid-filter-row, .mgh-grid-filter-row--with-logic { grid-template-columns: 1fr; } }\n\n/* ---- misc ---- */\n.mgh-grid-tooltip-anchor { display: inline-flex; }\n.mgh-grid-visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); border: 0; }\n@media print { .mgh-grid-toolbar, .mgh-grid-footer { display: none !important; } }\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_GRID_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_GRID_STYLE_ID;\n style.setAttribute('data-mgh-grid', 'true');\n style.textContent = MGH_GRID_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHGrid stylesheet once per document. Safe on the server (no-op). */\nexport const useMGHGridStyles = () => {\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import React from 'react';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridLocaleText,\n MGHGridState,\n MGHGridThemeMode,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\n\nexport interface MGHGridRootProps {\n header?: React.ReactNode;\n pagination: boolean;\n pageSizeOptions: number[];\n hideFooterPagination: boolean;\n hideFooterRowCount: boolean;\n hideFooterSelectedRowCount: boolean;\n disableColumnFilter: boolean;\n disableColumnSelector: boolean;\n disableDensitySelector: boolean;\n disableColumnPinning: boolean;\n disableColumnSorting: boolean;\n disableMultipleColumnsSorting: boolean;\n disableMultipleColumnsFiltering: boolean;\n disableRowGrouping: boolean;\n disableAggregation: boolean;\n checkboxSelection: boolean;\n aggregationFunctions: Record<string, MGHGridAggregationFunction>;\n quickFilterDebounceMs: number;\n}\n\nexport interface MGHGridContextValue {\n api: MGHGridApi;\n state: MGHGridState;\n localeText: MGHGridLocaleText;\n themeMode: MGHGridThemeMode;\n rootProps: MGHGridRootProps;\n /** All user columns (ordered, including hidden). */\n columns: MGHGridColDef[];\n /** Visible user columns. */\n visibleColumns: MGHGridColDef[];\n}\n\nexport const MGHGridContext = React.createContext<MGHGridContextValue | null>(null);\nMGHGridContext.displayName = 'MGHGridContext';\n\nexport const useMGHGridContext = () => {\n const ctx = React.useContext(MGHGridContext);\n if (!ctx) {\n throw new Error('MGHGrid: this component must be rendered inside an <MGHGrid /> (e.g. through a slot).');\n }\n return ctx;\n};\n\n/** Access the grid API from custom toolbars, menu items, cells, etc. */\nexport const useMGHGridApiContext = <R extends MGHGridValidRowModel = any>() => useMGHGridContext().api as MGHGridApi<R>;\n\nexport const useMGHGridLocaleText = () => useMGHGridContext().localeText;\n\n/** Creates a ref to hold the grid API; pass it to `<MGHGrid apiRef={apiRef} />`. */\nexport const useMGHGridApiRef = <R extends MGHGridValidRowModel = any>() =>\n React.useRef<MGHGridApi<R> | null>(null) as React.MutableRefObject<MGHGridApi<R> | null>;\n","import React from 'react';\n\n/** Keeps a ref always pointing at the latest value (assigned during render). */\nexport function useLatestRef<T>(value: T) {\n const ref = React.useRef(value);\n ref.current = value;\n return ref;\n}\n\n/** Returns a stable function that always calls the latest `fn`. */\nexport function useEventCallback<T extends (...args: any[]) => any>(fn: T): T {\n const ref = useLatestRef(fn);\n return React.useCallback(((...args: any[]) => ref.current(...args)) as T, []);\n}\n\n/**\n * Controlled / uncontrolled state helper. When `controlled` is defined the internal state is\n * ignored and every change is reported through `onChange` only.\n */\nexport function useControlledState<T>(\n controlled: T | undefined,\n defaultValue: T,\n onChange?: (value: T) => void\n): [T, (next: T | ((prev: T) => T)) => void] {\n const isControlled = controlled !== undefined;\n const [internal, setInternal] = React.useState<T>(defaultValue);\n const value = isControlled ? (controlled as T) : internal;\n const valueRef = useLatestRef(value);\n const controlledRef = useLatestRef(isControlled);\n const onChangeRef = useLatestRef(onChange);\n\n const setValue = React.useCallback((next: T | ((prev: T) => T)) => {\n const resolved = typeof next === 'function' ? (next as (prev: T) => T)(valueRef.current) : next;\n if (Object.is(resolved, valueRef.current)) return;\n valueRef.current = resolved;\n if (!controlledRef.current) setInternal(resolved);\n onChangeRef.current?.(resolved);\n }, []);\n\n return [value, setValue];\n}\n\nexport interface ElementSize {\n width: number;\n height: number;\n}\n\n/** Observes the client size of an element. */\nexport function useElementSize<T extends HTMLElement>(ref: React.RefObject<T | null>, enabled = true): ElementSize {\n const [size, setSize] = React.useState<ElementSize>({ width: 0, height: 0 });\n\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el || !enabled) return undefined;\n const update = () => {\n const width = el.clientWidth;\n const height = el.clientHeight;\n setSize((prev) => (prev.width === width && prev.height === height ? prev : { width, height }));\n };\n update();\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', update);\n return () => window.removeEventListener('resize', update);\n }\n const observer = new ResizeObserver(update);\n observer.observe(el);\n return () => observer.disconnect();\n }, [ref, enabled]);\n\n return size;\n}\n\n/** `window.matchMedia` as a hook. Always false on the server. */\nexport function useMediaQuery(query: string) {\n const getMatch = () =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia(query).matches : false;\n const [matches, setMatches] = React.useState(getMatch);\n\n React.useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return undefined;\n const media = window.matchMedia(query);\n const listener = () => setMatches(media.matches);\n listener();\n if (media.addEventListener) {\n media.addEventListener('change', listener);\n return () => media.removeEventListener('change', listener);\n }\n media.addListener(listener);\n return () => media.removeListener(listener);\n }, [query]);\n\n return matches;\n}\n\n/** Debounced version of a callback. The returned function is stable. */\nexport function useDebouncedCallback<T extends (...args: any[]) => void>(fn: T, delay: number) {\n const fnRef = useLatestRef(fn);\n const timerRef = React.useRef<number | null>(null);\n\n React.useEffect(\n () => () => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n },\n []\n );\n\n return React.useCallback(\n (...args: Parameters<T>) => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n timerRef.current = window.setTimeout(() => {\n timerRef.current = null;\n fnRef.current(...args);\n }, delay);\n },\n [delay]\n );\n}\n\nexport function useForceUpdate() {\n const [, setTick] = React.useState(0);\n return React.useCallback(() => setTick((t) => t + 1), []);\n}\n\nlet idCounter = 0;\n/** Stable unique id per component instance (React.useId fallback for older Reacts). */\nexport function useStableId(prefix: string) {\n const reactUseId = (React as any).useId as undefined | (() => string);\n if (reactUseId) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const id = reactUseId();\n return `${prefix}-${id.replace(/:/g, '')}`;\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const ref = React.useRef<string | null>(null);\n if (ref.current === null) {\n idCounter += 1;\n ref.current = `${prefix}-${idCounter}`;\n }\n return ref.current;\n}\n","import {\n MGHGridApi,\n MGHGridColDef,\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridExportOptions,\n MGHGridPrintExportOptions,\n MGHGridRowId,\n} from './MGHGrid.types';\nimport {\n downloadBlob,\n formattedValueToString,\n getCellValue,\n getFormattedValue,\n isInternalField,\n isNil,\n toDate,\n} from './utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Shared: resolve the columns & rows to export\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ExportCell {\n raw: any;\n formatted: string;\n col: MGHGridColDef;\n}\n\nexport interface ExportTable {\n columns: MGHGridColDef[];\n headers: string[];\n rows: ExportCell[][];\n}\n\nexport const resolveExportColumns = (api: MGHGridApi, options: MGHGridExportOptions): MGHGridColDef[] => {\n const all = api.getAllColumns();\n let columns: MGHGridColDef[];\n if (options.fields) {\n const byField = new Map<string, MGHGridColDef>();\n all.forEach((c) => byField.set(c.field, c));\n columns = options.fields.map((f) => byField.get(f)).filter(Boolean) as MGHGridColDef[];\n } else if (options.allColumns) {\n columns = all;\n } else {\n columns = api.getVisibleColumns();\n }\n return columns.filter((c) => !c.disableExport && !isInternalField(c.field) && c.type !== 'actions');\n};\n\nexport const buildExportTable = (api: MGHGridApi, options: MGHGridExportOptions): ExportTable => {\n const columns = resolveExportColumns(api, options);\n const ids: MGHGridRowId[] = options.getRowsToExport ? options.getRowsToExport({ api }) : api.getSortedRowIds();\n const rows: ExportCell[][] = [];\n ids.forEach((id) => {\n const row = api.getRow(id);\n if (!row) return;\n rows.push(\n columns.map((col) => {\n const raw = getCellValue(row, col, api);\n const formatted = formattedValueToString(getFormattedValue(raw, row, col, api, id));\n return { raw, formatted, col };\n })\n );\n });\n return { columns, headers: columns.map((c) => c.headerName ?? c.field), rows };\n};\n\nconst sanitizeFileName = (name: string | undefined, fallback: string, extension: string) => {\n const base = (name && name.trim()) || fallback;\n return base.toLowerCase().endsWith(`.${extension}`) ? base : `${base}.${extension}`;\n};\n\nconst defaultFileBase = () => {\n const title = typeof document !== 'undefined' && document.title ? document.title.trim() : '';\n return (title || 'export').replace(/[\\\\/:*?\"<>|]+/g, '-');\n};\n\n/* -------------------------------------------------------------------------------------------------\n * CSV\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeCsvCell = (value: string, delimiter: string) => {\n let text = value;\n // Guard against formula injection when opening in spreadsheet software.\n if (/^[=+\\-@\\t\\r]/.test(text)) text = `'${text}`;\n if (text.indexOf('\"') !== -1 || text.indexOf(delimiter) !== -1 || /[\\r\\n]/.test(text)) {\n return `\"${text.replace(/\"/g, '\"\"')}\"`;\n }\n return text;\n};\n\nexport const getDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const delimiter = options.delimiter ?? ',';\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const lines: string[] = [];\n if (includeHeaders) {\n lines.push(table.headers.map((h) => escapeCsvCell(h, delimiter)).join(delimiter));\n }\n table.rows.forEach((cells) => {\n lines.push(\n cells\n .map((cell) => {\n const text = options.useRawValues ? (isNil(cell.raw) ? '' : String(cell.raw)) : cell.formatted;\n return escapeCsvCell(text, delimiter);\n })\n .join(delimiter)\n );\n });\n return lines.join('\\r\\n');\n};\n\nconst UTF8_BOM = String.fromCharCode(0xfeff);\n\nexport const exportDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const csv = getDataAsCsv(api, options);\n const bom = options.utf8WithBom ? UTF8_BOM : '';\n const blob = new Blob([bom + csv], { type: 'text/csv;charset=utf-8;' });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'csv'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * XLSX (minimal OOXML writer + store-only ZIP, no dependencies)\n * ----------------------------------------------------------------------------------------------- */\n\nconst CRC_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n += 1) {\n let c = n;\n for (let k = 0; k < 8; k += 1) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\nconst crc32 = (bytes: Uint8Array) => {\n let crc = 0xffffffff;\n for (let i = 0; i < bytes.length; i += 1) {\n crc = CRC_TABLE[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n};\n\nconst textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null;\n\nconst encodeUtf8 = (text: string): Uint8Array => {\n if (textEncoder) return textEncoder.encode(text);\n // Fallback for very old environments.\n const utf8 = unescape(encodeURIComponent(text));\n const out = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i += 1) out[i] = utf8.charCodeAt(i);\n return out;\n};\n\ninterface ZipEntry {\n name: string;\n data: Uint8Array;\n}\n\nconst concatBytes = (chunks: Uint8Array[]) => {\n const total = chunks.reduce((acc, c) => acc + c.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n chunks.forEach((c) => {\n out.set(c, offset);\n offset += c.length;\n });\n return out;\n};\n\nconst zipStore = (entries: ZipEntry[]): Uint8Array => {\n const localChunks: Uint8Array[] = [];\n const centralChunks: Uint8Array[] = [];\n let offset = 0;\n // 1980-01-01 00:00 in DOS date/time format.\n const dosTime = 0;\n const dosDate = (1 << 5) | 1;\n\n entries.forEach((entry) => {\n const nameBytes = encodeUtf8(entry.name);\n const crc = crc32(entry.data);\n const size = entry.data.length;\n\n const local = new Uint8Array(30 + nameBytes.length);\n const lv = new DataView(local.buffer);\n lv.setUint32(0, 0x04034b50, true);\n lv.setUint16(4, 20, true);\n lv.setUint16(6, 0x0800, true); // UTF-8 names\n lv.setUint16(8, 0, true); // store\n lv.setUint16(10, dosTime, true);\n lv.setUint16(12, dosDate, true);\n lv.setUint32(14, crc, true);\n lv.setUint32(18, size, true);\n lv.setUint32(22, size, true);\n lv.setUint16(26, nameBytes.length, true);\n lv.setUint16(28, 0, true);\n local.set(nameBytes, 30);\n\n const central = new Uint8Array(46 + nameBytes.length);\n const cv = new DataView(central.buffer);\n cv.setUint32(0, 0x02014b50, true);\n cv.setUint16(4, 20, true);\n cv.setUint16(6, 20, true);\n cv.setUint16(8, 0x0800, true);\n cv.setUint16(10, 0, true);\n cv.setUint16(12, dosTime, true);\n cv.setUint16(14, dosDate, true);\n cv.setUint32(16, crc, true);\n cv.setUint32(20, size, true);\n cv.setUint32(24, size, true);\n cv.setUint16(28, nameBytes.length, true);\n cv.setUint16(30, 0, true);\n cv.setUint16(32, 0, true);\n cv.setUint16(34, 0, true);\n cv.setUint16(36, 0, true);\n cv.setUint32(38, 0, true);\n cv.setUint32(42, offset, true);\n central.set(nameBytes, 46);\n\n localChunks.push(local, entry.data);\n centralChunks.push(central);\n offset += local.length + size;\n });\n\n const centralDirectory = concatBytes(centralChunks);\n const eocd = new Uint8Array(22);\n const ev = new DataView(eocd.buffer);\n ev.setUint32(0, 0x06054b50, true);\n ev.setUint16(4, 0, true);\n ev.setUint16(6, 0, true);\n ev.setUint16(8, entries.length, true);\n ev.setUint16(10, entries.length, true);\n ev.setUint32(12, centralDirectory.length, true);\n ev.setUint32(16, offset, true);\n ev.setUint16(20, 0, true);\n\n return concatBytes(localChunks.concat([centralDirectory, eocd]));\n};\n\n// Characters that are illegal in XML 1.0 (built without literal control characters in source).\nconst INVALID_XML_CHARS = new RegExp(\n '[' +\n String.fromCharCode(0x00) +\n '-' +\n String.fromCharCode(0x08) +\n String.fromCharCode(0x0b) +\n String.fromCharCode(0x0c) +\n String.fromCharCode(0x0e) +\n '-' +\n String.fromCharCode(0x1f) +\n String.fromCharCode(0xfffe) +\n String.fromCharCode(0xffff) +\n ']',\n 'g'\n);\nconst stripInvalidXml = (text: string) => text.replace(INVALID_XML_CHARS, '');\n\nconst escapeXml = (text: string) =>\n stripInvalidXml(text)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n\nconst columnLetter = (index: number) => {\n let n = index + 1;\n let letters = '';\n while (n > 0) {\n const rem = (n - 1) % 26;\n letters = String.fromCharCode(65 + rem) + letters;\n n = Math.floor((n - 1) / 26);\n }\n return letters;\n};\n\nconst sanitizeSheetName = (name: string | undefined) => {\n const cleaned = (name || 'Sheet1').replace(/[\\[\\]:*?/\\\\]/g, ' ').trim() || 'Sheet1';\n return cleaned.length > 31 ? cleaned.slice(0, 31) : cleaned;\n};\n\nconst XML_HEADER = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n';\n\nconst buildSheetXml = (table: ExportTable, includeHeaders: boolean, columnWidths: number[]) => {\n const rowsXml: string[] = [];\n let rowIndex = 1;\n\n const inlineString = (ref: string, text: string, style?: number) =>\n `<c r=\"${ref}\" t=\"inlineStr\"${style ? ` s=\"${style}\"` : ''}><is><t xml:space=\"preserve\">${escapeXml(\n text\n )}</t></is></c>`;\n\n if (includeHeaders) {\n const cells = table.headers.map((h, i) => inlineString(`${columnLetter(i)}${rowIndex}`, h, 1)).join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${cells}</row>`);\n rowIndex += 1;\n }\n\n table.rows.forEach((cells) => {\n const xmlCells = cells\n .map((cell, i) => {\n const ref = `${columnLetter(i)}${rowIndex}`;\n const type = cell.col.type;\n if (isNil(cell.raw) || cell.raw === '') return '';\n if (type === 'number' && typeof cell.raw === 'number' && Number.isFinite(cell.raw)) {\n return `<c r=\"${ref}\"><v>${cell.raw}</v></c>`;\n }\n if (type === 'boolean') {\n return `<c r=\"${ref}\" t=\"b\"><v>${cell.raw ? 1 : 0}</v></c>`;\n }\n if ((type === 'date' || type === 'dateTime') && toDate(cell.raw)) {\n // Excel serial date (days since 1899-12-30), written in local time with a date style.\n const d = toDate(cell.raw) as Date;\n const utc = Date.UTC(\n d.getFullYear(),\n d.getMonth(),\n d.getDate(),\n d.getHours(),\n d.getMinutes(),\n d.getSeconds()\n );\n const serial = utc / 86400000 + 25569;\n return `<c r=\"${ref}\" s=\"${type === 'dateTime' ? 3 : 2}\"><v>${serial}</v></c>`;\n }\n return inlineString(ref, cell.formatted);\n })\n .join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${xmlCells}</row>`);\n rowIndex += 1;\n });\n\n const lastCol = columnLetter(Math.max(table.columns.length - 1, 0));\n const lastRow = Math.max(rowIndex - 1, 1);\n const cols = columnWidths.map((w, i) => `<col min=\"${i + 1}\" max=\"${i + 1}\" width=\"${w}\" customWidth=\"1\"/>`).join('');\n\n return (\n XML_HEADER +\n '<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<dimension ref=\"A1:${lastCol}${lastRow}\"/>` +\n '<sheetViews><sheetView workbookViewId=\"0\">' +\n (includeHeaders ? '<pane ySplit=\"1\" topLeftCell=\"A2\" activePane=\"bottomLeft\" state=\"frozen\"/>' : '') +\n '</sheetView></sheetViews>' +\n '<sheetFormatPr defaultRowHeight=\"15\"/>' +\n (cols ? `<cols>${cols}</cols>` : '') +\n `<sheetData>${rowsXml.join('')}</sheetData>` +\n (includeHeaders && table.rows.length > 0 ? `<autoFilter ref=\"A1:${lastCol}${lastRow}\"/>` : '') +\n '</worksheet>'\n );\n};\n\nconst STYLES_XML =\n XML_HEADER +\n '<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">' +\n '<numFmts count=\"2\"><numFmt numFmtId=\"164\" formatCode=\"m/d/yyyy\"/><numFmt numFmtId=\"165\" formatCode=\"m/d/yyyy h:mm AM/PM\"/></numFmts>' +\n '<fonts count=\"2\"><font><sz val=\"11\"/><name val=\"Calibri\"/></font><font><b/><sz val=\"11\"/><name val=\"Calibri\"/></font></fonts>' +\n '<fills count=\"2\"><fill><patternFill patternType=\"none\"/></fill><fill><patternFill patternType=\"gray125\"/></fill></fills>' +\n '<borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>' +\n '<cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>' +\n '<cellXfs count=\"4\">' +\n '<xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>' +\n '<xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>' +\n '<xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '<xf numFmtId=\"165\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '</cellXfs>' +\n '<cellStyles count=\"1\"><cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/></cellStyles>' +\n '</styleSheet>';\n\nconst CONTENT_TYPES_XML =\n XML_HEADER +\n '<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">' +\n '<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>' +\n '<Default Extension=\"xml\" ContentType=\"application/xml\"/>' +\n '<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>' +\n '<Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>' +\n '<Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>' +\n '<Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>' +\n '<Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>' +\n '</Types>';\n\nconst ROOT_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>' +\n '<Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>' +\n '</Relationships>';\n\nconst WORKBOOK_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>' +\n '</Relationships>';\n\nconst buildWorkbookXml = (sheetName: string) =>\n XML_HEADER +\n '<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<sheets><sheet name=\"${escapeXml(sheetName)}\" sheetId=\"1\" r:id=\"rId1\"/></sheets>` +\n '</workbook>';\n\nconst buildCoreXml = () => {\n const now = new Date().toISOString();\n return (\n XML_HEADER +\n '<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" ' +\n 'xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" ' +\n 'xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n '<dc:creator>MGH Grid</dc:creator>' +\n `<dcterms:created xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:created>` +\n `<dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified>` +\n '</cp:coreProperties>'\n );\n};\n\nconst APP_XML =\n XML_HEADER +\n '<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" ' +\n 'xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">' +\n '<Application>MGH Grid</Application></Properties>';\n\nexport const buildXlsx = (api: MGHGridApi, options: MGHGridExcelExportOptions = {}): Uint8Array => {\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const widths = table.columns.map((col, i) => {\n const explicit = options.columnsStyles?.[col.field]?.width;\n if (explicit) return explicit;\n let max = table.headers[i].length;\n for (let r = 0; r < Math.min(table.rows.length, 500); r += 1) {\n const len = table.rows[r][i].formatted.length;\n if (len > max) max = len;\n }\n return Math.min(Math.max(max + 2, 8), 60);\n });\n const sheetName = sanitizeSheetName(options.sheetName);\n const entries: ZipEntry[] = [\n { name: '[Content_Types].xml', data: encodeUtf8(CONTENT_TYPES_XML) },\n { name: '_rels/.rels', data: encodeUtf8(ROOT_RELS_XML) },\n { name: 'docProps/core.xml', data: encodeUtf8(buildCoreXml()) },\n { name: 'docProps/app.xml', data: encodeUtf8(APP_XML) },\n { name: 'xl/workbook.xml', data: encodeUtf8(buildWorkbookXml(sheetName)) },\n { name: 'xl/_rels/workbook.xml.rels', data: encodeUtf8(WORKBOOK_RELS_XML) },\n { name: 'xl/styles.xml', data: encodeUtf8(STYLES_XML) },\n { name: 'xl/worksheets/sheet1.xml', data: encodeUtf8(buildSheetXml(table, includeHeaders, widths)) },\n ];\n return zipStore(entries);\n};\n\nexport const exportDataAsExcel = async (api: MGHGridApi, options: MGHGridExcelExportOptions = {}) => {\n const bytes = buildXlsx(api, options);\n const blob = new Blob([bytes as BlobPart], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'xlsx'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Print\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\nexport const exportDataAsPrint = (api: MGHGridApi, options: MGHGridPrintExportOptions = {}) => {\n if (typeof document === 'undefined') return;\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const title = options.title ?? options.fileName ?? document.title ?? '';\n\n const headerHtml = includeHeaders\n ? `<thead><tr>${table.headers\n .map((h, i) => `<th class=\"${table.columns[i].align ?? 'left'}\">${escapeHtml(h)}</th>`)\n .join('')}</tr></thead>`\n : '';\n const bodyHtml = `<tbody>${table.rows\n .map(\n (cells) =>\n `<tr>${cells\n .map((cell) => `<td class=\"${cell.col.align ?? 'left'}\">${escapeHtml(cell.formatted)}</td>`)\n .join('')}</tr>`\n )\n .join('')}</tbody>`;\n\n const html =\n '<!doctype html><html><head><meta charset=\"utf-8\" />' +\n `<title>${escapeHtml(title)}</title>` +\n '<style>' +\n 'body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif;font-size:12px;color:#111;margin:16px;}' +\n 'h1{font-size:16px;margin:0 0 12px;}' +\n 'table{border-collapse:collapse;width:100%;}' +\n 'th,td{border:1px solid #ccc;padding:4px 8px;text-align:left;vertical-align:top;}' +\n 'th{background:#f3f3f3;font-weight:600;}' +\n 'td.right,th.right{text-align:right;} td.center,th.center{text-align:center;}' +\n 'tr{page-break-inside:avoid;} thead{display:table-header-group;}' +\n (options.pageStyle ?? '') +\n '</style></head><body>' +\n (title ? `<h1>${escapeHtml(title)}</h1>` : '') +\n `<table>${headerHtml}${bodyHtml}</table>` +\n '</body></html>';\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.style.position = 'fixed';\n iframe.style.right = '0';\n iframe.style.bottom = '0';\n iframe.style.width = '0';\n iframe.style.height = '0';\n iframe.style.border = '0';\n iframe.style.opacity = '0';\n document.body.appendChild(iframe);\n\n const cleanup = () => {\n window.setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n }, 1000);\n };\n\n iframe.onload = () => {\n const win = iframe.contentWindow;\n if (!win) {\n cleanup();\n return;\n }\n try {\n win.focus();\n win.onafterprint = cleanup;\n win.print();\n } catch {\n cleanup();\n }\n };\n\n const doc = iframe.contentDocument || iframe.contentWindow?.document;\n if (doc) {\n doc.open();\n doc.write(html);\n doc.close();\n } else {\n iframe.srcdoc = html;\n }\n};\n","import {\n MGHGridAggregationFunction,\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridColDef,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridRowId,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport { formattedValueToString, getCellValue, getFormattedValue, getGroupingValue, isNil } from './utils';\n\nexport interface RowEntry<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n row: R;\n}\n\n/** Internal tree node used while grouping. */\nexport interface GroupTreeNode<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n depth: number;\n parent: MGHGridRowId | null;\n groupingField: string;\n groupingKey: any;\n groupingLabel: string;\n childGroups: GroupTreeNode<R>[];\n /** Direct leaf children (only populated at the deepest level). */\n leaves: RowEntry<R>[];\n /** Every descendant leaf, in display order after sorting. */\n descendants: RowEntry<R>[];\n}\n\nexport interface DisplayRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n type: 'leaf' | 'group';\n row: R | null;\n node: MGHGridLeafNode | MGHGridGroupNode;\n depth: number;\n group?: GroupTreeNode<R>;\n}\n\nexport const GROUP_ID_PREFIX = 'auto-generated-row-';\n\nconst keyToString = (key: any) => (isNil(key) ? '' : key instanceof Date ? String(key.getTime()) : String(key));\n\nexport const buildGroupTree = <R extends MGHGridValidRowModel>(\n entries: RowEntry<R>[],\n groupingFields: string[],\n columnsByField: Map<string, MGHGridColDef<R>>,\n api: MGHGridApi<R>,\n emptyLabel = '(empty)'\n): GroupTreeNode<R>[] => {\n const build = (items: RowEntry<R>[], depth: number, parentId: MGHGridRowId | null, path: string): GroupTreeNode<R>[] => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return [];\n const buckets = new Map<string, GroupTreeNode<R>>();\n items.forEach((entry) => {\n const key = getGroupingValue(entry.row, col, api);\n const keyStr = keyToString(key);\n let node = buckets.get(keyStr);\n if (!node) {\n const label = formattedValueToString(getFormattedValue(key, entry.row, col, api, entry.id)) || emptyLabel;\n const id = `${GROUP_ID_PREFIX}${path}${field}/${keyStr}`;\n node = {\n id,\n depth,\n parent: parentId,\n groupingField: field,\n groupingKey: key,\n groupingLabel: label,\n childGroups: [],\n leaves: [],\n descendants: [],\n };\n buckets.set(keyStr, node);\n }\n node.leaves.push(entry);\n });\n const nodes: GroupTreeNode<R>[] = [];\n buckets.forEach((node) => {\n if (depth < groupingFields.length - 1) {\n node.childGroups = build(\n node.leaves,\n depth + 1,\n node.id,\n `${path}${field}/${keyToString(node.groupingKey)}|`\n );\n node.descendants = node.leaves;\n node.leaves = [];\n } else {\n node.descendants = node.leaves;\n }\n nodes.push(node);\n });\n return nodes;\n };\n return build(entries, 0, null, '');\n};\n\nexport type GroupComparator<R extends MGHGridValidRowModel = any> = (a: GroupTreeNode<R>, b: GroupTreeNode<R>) => number;\n\n/** Sorts groups (with the given comparator) and leaves (with the given sorter), recursively. */\nexport const sortGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n compareGroups: ((depth: number) => GroupComparator<R> | null) | null,\n sortLeaves: (leaves: RowEntry<R>[]) => RowEntry<R>[]\n): GroupTreeNode<R>[] => {\n const sortLevel = (nodes: GroupTreeNode<R>[], depth: number): GroupTreeNode<R>[] => {\n const comparator = compareGroups ? compareGroups(depth) : null;\n const sorted = comparator\n ? nodes\n .map((node, index) => ({ node, index }))\n .sort((a, b) => comparator(a.node, b.node) || a.index - b.index)\n .map((item) => item.node)\n : nodes;\n sorted.forEach((node) => {\n if (node.childGroups.length > 0) {\n node.childGroups = sortLevel(node.childGroups, depth + 1);\n const descendants: RowEntry<R>[] = [];\n node.childGroups.forEach((child) => child.descendants.forEach((d) => descendants.push(d)));\n node.descendants = descendants;\n } else {\n node.leaves = sortLeaves(node.leaves);\n node.descendants = node.leaves;\n }\n });\n return sorted;\n };\n return sortLevel(roots, 0);\n};\n\nexport const collectTreeLeaves = <R extends MGHGridValidRowModel>(roots: GroupTreeNode<R>[]): RowEntry<R>[] => {\n const out: RowEntry<R>[] = [];\n roots.forEach((root) => root.descendants.forEach((d) => out.push(d)));\n return out;\n};\n\nexport const toGroupNode = <R extends MGHGridValidRowModel>(\n node: GroupTreeNode<R>,\n isExpanded: boolean\n): MGHGridGroupNode => ({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: node.childGroups.length > 0 ? node.childGroups.map((c) => c.id) : node.leaves.map((l) => l.id),\n leafIds: node.descendants.map((d) => d.id),\n isExpanded,\n});\n\n/** Flattens the tree into display rows, honouring expansion state. Also fills `nodesById` with every node. */\nexport const flattenGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n isExpanded: (node: GroupTreeNode<R>) => boolean,\n nodesById: Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>,\n groupsById: Map<MGHGridRowId, GroupTreeNode<R>>\n): DisplayRow<R>[] => {\n const out: DisplayRow<R>[] = [];\n const visit = (nodes: GroupTreeNode<R>[], visible: boolean) => {\n nodes.forEach((node) => {\n const expanded = isExpanded(node);\n const groupNode = toGroupNode(node, expanded);\n nodesById.set(node.id, groupNode);\n groupsById.set(node.id, node);\n if (visible)\n out.push({ id: node.id, type: 'group', row: null, node: groupNode, depth: node.depth, group: node });\n const childVisible = visible && expanded;\n if (node.childGroups.length > 0) {\n visit(node.childGroups, childVisible);\n } else {\n node.leaves.forEach((leaf) => {\n const leafNode: MGHGridLeafNode = { type: 'leaf', id: leaf.id, depth: node.depth + 1, parent: node.id };\n nodesById.set(leaf.id, leafNode);\n if (childVisible)\n out.push({ id: leaf.id, type: 'leaf', row: leaf.row, node: leafNode, depth: node.depth + 1 });\n });\n }\n });\n };\n visit(roots, true);\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const aggregateRows = <R extends MGHGridValidRowModel>(\n rows: R[],\n aggregationModel: MGHGridAggregationModel,\n columnsByField: Map<string, MGHGridColDef<R>>,\n functions: Record<string, MGHGridAggregationFunction>,\n api: MGHGridApi<R>\n): Record<string, { value: any; fn: string }> => {\n const result: Record<string, { value: any; fn: string }> = {};\n Object.keys(aggregationModel).forEach((field) => {\n const fnName = aggregationModel[field];\n const fn = functions[fnName];\n const col = columnsByField.get(field);\n if (!fn || !col || col.aggregable === false) return;\n const values = rows.map((row) => getCellValue(row, col, api));\n result[field] = { value: fn.apply({ values, field }), fn: fnName };\n });\n return result;\n};\n","import React from 'react';\n\n/* Small inline SVG icon set (Material Design icon paths, Apache-2.0). No external dependencies. */\n\nexport interface MGHGridIconProps extends React.SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nconst createIcon = (path: React.ReactNode, displayName: string) => {\n const Icon = React.forwardRef<SVGSVGElement, MGHGridIconProps>(({ size = 20, className, style, ...rest }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"currentColor\"\n focusable=\"false\"\n aria-hidden=\"true\"\n className={['mgh-grid-icon', className].filter(Boolean).join(' ')}\n style={style}\n {...rest}\n >\n {path}\n </svg>\n ));\n Icon.displayName = displayName;\n return Icon;\n};\n\nexport const ViewColumnIcon = createIcon(\n <path d=\"M14.67 5v14H9.33V5h5.34zm1 14H21V5h-5.33v14zm-7.34 0V5H3v14h5.33z\" />,\n 'ViewColumnIcon'\n);\nexport const FilterListIcon = createIcon(<path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\" />, 'FilterListIcon');\nexport const SearchIcon = createIcon(\n <path d=\"M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\" />,\n 'SearchIcon'\n);\nexport const CloseIcon = createIcon(\n <path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />,\n 'CloseIcon'\n);\nexport const DownloadIcon = createIcon(\n <path d=\"M19 12v7H5v-7H3v7c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zm-6 .67 2.59-2.58L17 11.5l-5 5-5-5 1.41-1.41L11 12.67V3h2z\" />,\n 'DownloadIcon'\n);\nexport const ArrowUpwardIcon = createIcon(\n <path d=\"m4 12 1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z\" />,\n 'ArrowUpwardIcon'\n);\nexport const ArrowDownwardIcon = createIcon(\n <path d=\"m20 12-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z\" />,\n 'ArrowDownwardIcon'\n);\nexport const MoreVertIcon = createIcon(\n <path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'MoreVertIcon'\n);\nexport const CheckIcon = createIcon(<path d=\"M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" />, 'CheckIcon');\nexport const ExpandMoreIcon = createIcon(<path d=\"M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z\" />, 'ExpandMoreIcon');\nexport const ChevronRightIcon = createIcon(<path d=\"M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\" />, 'ChevronRightIcon');\nexport const ChevronLeftIcon = createIcon(<path d=\"M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z\" />, 'ChevronLeftIcon');\nexport const FirstPageIcon = createIcon(\n <path d=\"M18.41 16.59 13.82 12l4.59-4.59L17 6l-6 6 6 6zM6 6h2v12H6z\" />,\n 'FirstPageIcon'\n);\nexport const LastPageIcon = createIcon(\n <path d=\"M5.59 7.41 10.18 12l-4.59 4.59L7 18l6-6-6-6zM16 6h2v12h-2z\" />,\n 'LastPageIcon'\n);\nexport const PushPinIcon = createIcon(\n <path d=\"M16 9V4h1c.55 0 1-.45 1-1s-.45-1-1-1H7c-.55 0-1 .45-1 1s.45 1 1 1h1v5c0 1.66-1.34 3-3 3v2h5.97v7l1 1 1-1v-7H19v-2c-1.66 0-3-1.34-3-3z\" />,\n 'PushPinIcon'\n);\nexport const DeleteIcon = createIcon(\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />,\n 'DeleteIcon'\n);\nexport const AddIcon = createIcon(<path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" />, 'AddIcon');\nexport const DensitySmallIcon = createIcon(\n <path d=\"M3 2h18v2H3zm0 18h18v2H3zm0-6h18v2H3zm0-6h18v2H3z\" />,\n 'DensitySmallIcon'\n);\nexport const DensityMediumIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3zm0-8h18v2H3z\" />, 'DensityMediumIcon');\nexport const DensityLargeIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3z\" />, 'DensityLargeIcon');\nexport const DragIndicatorIcon = createIcon(\n <path d=\"M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'DragIndicatorIcon'\n);\nexport const PrintIcon = createIcon(\n <path d=\"M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z\" />,\n 'PrintIcon'\n);\nexport const TableChartIcon = createIcon(\n <path d=\"M10 10.02h5V21h-5zM17 21h3c1.1 0 2-.9 2-2v-9h-5v11zm3-18H5c-1.1 0-2 .9-2 2v3h19V5c0-1.1-.9-2-2-2zM3 19c0 1.1.9 2 2 2h3V10H3v9z\" />,\n 'TableChartIcon'\n);\nexport const DescriptionIcon = createIcon(\n <path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\" />,\n 'DescriptionIcon'\n);\nexport const VisibilityOffIcon = createIcon(\n <path d=\"M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46A11.804 11.804 0 0 0 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78 3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z\" />,\n 'VisibilityOffIcon'\n);\nexport const FunctionsIcon = createIcon(<path d=\"M18 4H6v2l6.5 6L6 18v2h12v-3h-7l5-5-5-5h7z\" />, 'FunctionsIcon');\nexport const WorkspacesIcon = createIcon(\n <path d=\"M6 13c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6-10C9.8 3 8 4.8 8 7s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6 10c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4z\" />,\n 'WorkspacesIcon'\n);\nexport const EmptyBoxIcon = createIcon(\n <>\n <path\n d=\"M20 6h-2.18c.11-.31.18-.65.18-1a2.996 2.996 0 0 0-5.5-1.65l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2z\"\n opacity=\".25\"\n />\n <path d=\"M4 8h16v11H4z\" opacity=\".15\" />\n </>,\n 'EmptyBoxIcon'\n);\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { clamp, cx } from '../utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Button / IconButton\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'text' | 'primary' | 'contained';\n size?: 'small' | 'medium';\n startIcon?: React.ReactNode;\n endIcon?: React.ReactNode;\n active?: boolean;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n { variant = 'text', size = 'medium', startIcon, endIcon, active, className, children, type = 'button', ...rest },\n ref\n ) => (\n <button\n ref={ref}\n type={type}\n className={cx(\n 'mgh-grid-btn',\n variant === 'primary' && 'mgh-grid-btn--primary',\n variant === 'contained' && 'mgh-grid-btn--contained',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {startIcon}\n {children}\n {endIcon}\n </button>\n )\n);\nButton.displayName = 'MGHGridButton';\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n size?: 'small' | 'medium';\n active?: boolean;\n /** Tooltip (native title) and aria-label. */\n label?: string;\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ size = 'medium', active, label, className, children, type = 'button', ...rest }, ref) => (\n <button\n ref={ref}\n type={type}\n title={label}\n aria-label={label}\n className={cx(\n 'mgh-grid-btn mgh-grid-btn--icon',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {children}\n </button>\n )\n);\nIconButton.displayName = 'MGHGridIconButton';\n\n/* -------------------------------------------------------------------------------------------------\n * Badge\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface BadgeProps {\n count?: number;\n variant?: 'dot' | 'count';\n children: React.ReactNode;\n}\n\nexport const Badge = ({ count = 0, variant = 'dot', children }: BadgeProps) => (\n <span className=\"mgh-grid-badge\">\n {children}\n {count > 0 &&\n (variant === 'dot' ? (\n <span className=\"mgh-grid-badge-dot\" />\n ) : (\n <span className=\"mgh-grid-badge-count\">{count > 99 ? '99+' : count}</span>\n ))}\n </span>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Inputs\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const TextInput = React.forwardRef<HTMLInputElement, TextInputProps>(\n ({ size = 'medium', className, ...rest }, ref) => (\n <input\n ref={ref}\n className={cx('mgh-grid-input', size === 'small' && 'mgh-grid-input--small', className)}\n {...rest}\n />\n )\n);\nTextInput.displayName = 'MGHGridTextInput';\n\nexport interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(({ size = 'medium', className, ...rest }, ref) => (\n <select ref={ref} className={cx('mgh-grid-select', size === 'small' && 'mgh-grid-select--small', className)} {...rest} />\n));\nSelect.displayName = 'MGHGridSelect';\n\nexport interface FieldProps {\n label?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n htmlFor?: string;\n}\n\nexport const Field = ({ label, children, className, htmlFor }: FieldProps) => (\n <div className={cx('mgh-grid-field', className)}>\n {label && (\n <label className=\"mgh-grid-field-label\" htmlFor={htmlFor}>\n {label}\n </label>\n )}\n {children}\n </div>\n);\n\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n indeterminate?: boolean;\n label?: string;\n}\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ indeterminate = false, label, className, ...rest }, forwardedRef) => {\n const innerRef = React.useRef<HTMLInputElement | null>(null);\n const setRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) (forwardedRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n },\n [forwardedRef]\n );\n React.useEffect(() => {\n if (innerRef.current) innerRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n return (\n <input\n ref={setRef}\n type=\"checkbox\"\n title={label}\n aria-label={label}\n className={cx('mgh-grid-checkbox', className)}\n {...rest}\n />\n );\n }\n);\nCheckbox.displayName = 'MGHGridCheckbox';\n\n/* -------------------------------------------------------------------------------------------------\n * Spinner\n * ----------------------------------------------------------------------------------------------- */\n\nexport const Spinner = ({ className }: { className?: string }) => (\n <div className={cx('mgh-grid-spinner', className)} role=\"progressbar\" aria-label=\"Loading\" />\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Popover (portal, anchored)\n * ----------------------------------------------------------------------------------------------- */\n\nexport type PopoverPlacement = 'bottom-start' | 'bottom-end' | 'bottom' | 'right-start';\n\nexport interface PopoverProps {\n open: boolean;\n anchorEl: HTMLElement | null | undefined;\n onClose: (reason: 'backdrop' | 'escape') => void;\n children: React.ReactNode;\n placement?: PopoverPlacement;\n themeMode?: MGHGridThemeMode;\n className?: string;\n style?: React.CSSProperties;\n offset?: number;\n role?: string;\n autoFocus?: boolean;\n /** Additional elements considered \"inside\" for outside-click detection. */\n ignoreOutsideClickOn?: Array<React.RefObject<HTMLElement | null>>;\n}\n\nexport function Popover({\n open,\n anchorEl,\n onClose,\n children,\n placement = 'bottom-start',\n themeMode = 'light',\n className,\n style,\n offset = 4,\n role = 'dialog',\n autoFocus = false,\n ignoreOutsideClickOn,\n}: PopoverProps) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const [position, setPosition] = React.useState<{ top: number; left: number; ready: boolean }>({\n top: 0,\n left: 0,\n ready: false,\n });\n\n const update = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n let top: number;\n let left: number;\n if (anchorEl && anchorEl.isConnected) {\n const a = anchorEl.getBoundingClientRect();\n if (placement === 'right-start') {\n top = a.top;\n left = a.right + offset;\n if (left + w > vw - 8) left = a.left - offset - w;\n } else {\n top = a.bottom + offset;\n if (top + h > vh - 8 && a.top - offset - h >= 8) top = a.top - offset - h;\n left =\n placement === 'bottom-end'\n ? a.right - w\n : placement === 'bottom'\n ? a.left + a.width / 2 - w / 2\n : a.left;\n }\n } else {\n top = vh / 2 - h / 2;\n left = vw / 2 - w / 2;\n }\n top = clamp(top, 8, Math.max(8, vh - h - 8));\n left = clamp(left, 8, Math.max(8, vw - w - 8));\n setPosition((prev) => (prev.ready && prev.top === top && prev.left === left ? prev : { top, left, ready: true }));\n }, [anchorEl, placement, offset]);\n\n React.useLayoutEffect(() => {\n if (!open) {\n setPosition((prev) => (prev.ready ? { ...prev, ready: false } : prev));\n return undefined;\n }\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n let observer: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined' && ref.current) {\n observer = new ResizeObserver(() => update());\n observer.observe(ref.current);\n }\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n observer?.disconnect();\n };\n }, [open, update]);\n\n React.useEffect(() => {\n if (!open) return undefined;\n const handlePointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (ref.current?.contains(target)) return;\n if (anchorEl?.contains(target)) return;\n if (ignoreOutsideClickOn?.some((r) => r.current?.contains(target))) return;\n // Clicks inside other popovers (nested menus) should not close this one.\n if ((target as HTMLElement).closest?.('.mgh-grid-popover')) return;\n onClose('backdrop');\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose('escape');\n };\n document.addEventListener('mousedown', handlePointerDown, true);\n document.addEventListener('touchstart', handlePointerDown, true);\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown, true);\n document.removeEventListener('touchstart', handlePointerDown, true);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [open, onClose, anchorEl, ignoreOutsideClickOn]);\n\n React.useEffect(() => {\n if (open && autoFocus && ref.current) {\n const focusable = ref.current.querySelector<HTMLElement>(\n 'input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])'\n );\n (focusable ?? ref.current).focus();\n }\n }, [open, autoFocus]);\n\n if (!open || typeof document === 'undefined') return null;\n\n const stop = (event: React.SyntheticEvent) => event.stopPropagation();\n\n return createPortal(\n <div\n ref={ref}\n role={role}\n tabIndex={-1}\n className={cx('mgh-grid-popover', className)}\n data-mgh-theme={themeMode}\n style={{\n top: position.top,\n left: position.left,\n visibility: position.ready ? 'visible' : 'hidden',\n ...style,\n }}\n onClick={stop}\n onDoubleClick={stop}\n onMouseDown={stop}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n onClose('escape');\n return;\n }\n event.stopPropagation();\n }}\n >\n {children}\n </div>,\n document.body\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {\n children: React.ReactNode;\n}\n\nexport const Menu = ({ children, className, onKeyDown, ...rest }: MenuProps) => {\n const ref = React.useRef<HTMLUListElement | null>(null);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLUListElement>) => {\n onKeyDown?.(event);\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp' && event.key !== 'Home' && event.key !== 'End') return;\n const items = Array.from(\n ref.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])') ?? []\n );\n if (items.length === 0) return;\n event.preventDefault();\n const currentIndex = items.indexOf(document.activeElement as HTMLElement);\n let next = 0;\n if (event.key === 'ArrowDown') next = currentIndex < 0 ? 0 : (currentIndex + 1) % items.length;\n else if (event.key === 'ArrowUp')\n next = currentIndex < 0 ? items.length - 1 : (currentIndex - 1 + items.length) % items.length;\n else if (event.key === 'Home') next = 0;\n else next = items.length - 1;\n items[next].focus();\n };\n\n React.useEffect(() => {\n const first = ref.current?.querySelector<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])');\n first?.focus();\n }, []);\n\n return (\n <ul ref={ref} role=\"menu\" className={cx('mgh-grid-menu', className)} onKeyDown={handleKeyDown} {...rest}>\n {children}\n </ul>\n );\n};\n\nexport interface MenuItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {\n icon?: React.ReactNode;\n selected?: boolean;\n /** Injected by menus that should close after the click. */\n hideMenu?: () => void;\n}\n\nexport const MenuItem = React.forwardRef<HTMLButtonElement, MenuItemProps>(\n ({ icon, selected, disabled, className, children, onClick, hideMenu, ...rest }, ref) => (\n <li role=\"none\">\n <button\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n aria-disabled={disabled || undefined}\n disabled={disabled}\n tabIndex={-1}\n className={cx(\n 'mgh-grid-menu-item',\n disabled && 'mgh-grid-menu-item--disabled',\n selected && 'mgh-grid-menu-item--selected',\n className\n )}\n onClick={(event) => {\n if (disabled) return;\n onClick?.(event);\n hideMenu?.();\n }}\n {...rest}\n >\n {icon}\n <span>{children}</span>\n </button>\n </li>\n )\n);\nMenuItem.displayName = 'MGHGridMenuItem';\n\nexport const MenuDivider = () => <li role=\"separator\" className=\"mgh-grid-menu-divider\" />;\n\nexport const MenuHeader = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-header\">\n {children}\n </li>\n);\n\nexport const MenuSection = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-section\">\n {children}\n </li>\n);\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport {\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridPrintExportOptions,\n MGHGridToolbarProps,\n} from '../MGHGrid.types';\nimport {\n CloseIcon,\n DensityLargeIcon,\n DensityMediumIcon,\n DensitySmallIcon,\n DescriptionIcon,\n DownloadIcon,\n FilterListIcon,\n PrintIcon,\n SearchIcon,\n TableChartIcon,\n ViewColumnIcon,\n} from '../icons';\nimport { cx } from '../utils';\nimport { Badge, IconButton, Menu, MenuItem, MenuItemProps, Popover, TextInput } from './primitives';\n\n/* -------------------------------------------------------------------------------------------------\n * Buttons\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridColumnsButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'columns';\n return (\n <IconButton\n label={localeText.toolbarColumns}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('columns', event.currentTarget))}\n >\n <ViewColumnIcon />\n </IconButton>\n );\n}\n\nexport function MGHGridFiltersButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'filters';\n return (\n <IconButton\n label={localeText.toolbarFilters}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('filters', event.currentTarget))}\n >\n <Badge count={state.filterCount} variant=\"dot\">\n <FilterListIcon />\n </Badge>\n </IconButton>\n );\n}\n\nexport function MGHGridDensitySelector() {\n const { api, state, localeText, themeMode } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const options = [\n { value: 'compact', label: localeText.densityCompact, icon: <DensitySmallIcon /> },\n { value: 'standard', label: localeText.densityStandard, icon: <DensityMediumIcon /> },\n { value: 'comfortable', label: localeText.densityComfortable, icon: <DensityLargeIcon /> },\n ] as const;\n const current = options.find((o) => o.value === state.density) ?? options[1];\n return (\n <>\n <IconButton\n label={localeText.toolbarDensity}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n {current.icon}\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n role=\"menu\"\n >\n <Menu>\n {options.map((option) => (\n <MenuItem\n key={option.value}\n icon={option.icon}\n selected={option.value === state.density}\n onClick={() => api.setDensity(option.value)}\n hideMenu={() => setAnchor(null)}\n >\n {option.label}\n </MenuItem>\n ))}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Export menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridExportMenuItemProps extends MenuItemProps {\n /** Injected by MGHGridExportMenu; call it to close the menu after your action. */\n hideMenu?: () => void;\n}\n\n/** Menu item for custom export actions. Drop-in for MUI's GridExportMenuItemProps pattern. */\nexport const MGHGridExportMenuItem = MenuItem as React.ForwardRefExoticComponent<\n MGHGridExportMenuItemProps & React.RefAttributes<HTMLButtonElement>\n>;\n\nexport interface MGHGridExportMenuProps {\n csvOptions?: MGHGridCsvExportOptions;\n excelOptions?: MGHGridExcelExportOptions;\n printOptions?: MGHGridPrintExportOptions;\n showCsvOption?: boolean;\n showExcelOption?: boolean;\n showPrintOption?: boolean;\n customMenuItem?: React.ReactNode;\n}\n\nexport function MGHGridExportMenu({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n customMenuItem,\n}: MGHGridExportMenuProps) {\n const { api, localeText, themeMode, rootProps } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const hideMenu = () => setAnchor(null);\n\n const customItems = React.Children.map(customMenuItem, (child) =>\n React.isValidElement(child) ? React.cloneElement(child as React.ReactElement<any>, { hideMenu }) : child\n );\n\n const resolvedPrintOptions: MGHGridPrintExportOptions = {\n title: typeof rootProps.header === 'string' ? rootProps.header : undefined,\n ...printOptions,\n };\n\n return (\n <>\n <IconButton\n label={localeText.toolbarExport}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n <DownloadIcon />\n </IconButton>\n <Popover open={Boolean(anchor)} anchorEl={anchor} onClose={hideMenu} themeMode={themeMode} role=\"menu\">\n <Menu>\n {customItems}\n {showCsvOption && (\n <MenuItem\n icon={<DescriptionIcon />}\n onClick={() => api.exportDataAsCsv(csvOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportCSV}\n </MenuItem>\n )}\n {showExcelOption && (\n <MenuItem\n icon={<TableChartIcon />}\n onClick={() => {\n void api.exportDataAsExcel(excelOptions);\n }}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportExcel}\n </MenuItem>\n )}\n {showPrintOption && (\n <MenuItem\n icon={<PrintIcon />}\n onClick={() => api.exportDataAsPrint(resolvedPrintOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportPrint}\n </MenuItem>\n )}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Quick filter\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridQuickFilterProps {\n placeholder?: string;\n debounceMs?: number;\n /** Always show the expanded input. */\n alwaysExpanded?: boolean;\n}\n\nexport function MGHGridQuickFilter({ placeholder, debounceMs, alwaysExpanded = false }: MGHGridQuickFilterProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const externalValue = (state.quickFilterValues ?? []).join(' ');\n const [text, setText] = React.useState(externalValue);\n const [expanded, setExpanded] = React.useState(alwaysExpanded || externalValue !== '');\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const timer = React.useRef<number | null>(null);\n const delay = debounceMs ?? rootProps.quickFilterDebounceMs;\n\n // Sync when the model is changed from outside (e.g. api.setQuickFilterValues).\n const lastExternal = React.useRef(externalValue);\n React.useEffect(() => {\n if (externalValue !== lastExternal.current) {\n lastExternal.current = externalValue;\n setText(externalValue);\n if (externalValue !== '') setExpanded(true);\n }\n }, [externalValue]);\n\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n\n const commit = (value: string) => {\n const values = value.split(/\\s+/).filter((v) => v !== '');\n lastExternal.current = values.join(' ');\n api.setQuickFilterValues(values);\n };\n\n const handleChange = (value: string) => {\n setText(value);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => commit(value), delay);\n };\n\n const clear = () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n setText('');\n commit('');\n inputRef.current?.focus();\n };\n\n const expand = () => {\n setExpanded(true);\n window.setTimeout(() => inputRef.current?.focus(), 0);\n };\n\n const isExpanded = alwaysExpanded || expanded;\n\n return (\n <div className={cx('mgh-grid-quick-filter', isExpanded && 'mgh-grid-quick-filter--expanded')}>\n <IconButton\n className=\"mgh-grid-quick-filter-trigger\"\n label={localeText.toolbarQuickFilterLabel}\n aria-disabled={isExpanded}\n tabIndex={isExpanded ? -1 : 0}\n onClick={expand}\n >\n <SearchIcon />\n </IconButton>\n <div\n className={cx(\n 'mgh-grid-quick-filter-control mgh-grid-input-adorned',\n text && 'mgh-grid-input-adorned--clearable'\n )}\n >\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n ref={inputRef}\n size=\"small\"\n type=\"search\"\n value={text}\n tabIndex={isExpanded ? 0 : -1}\n placeholder={placeholder ?? localeText.toolbarQuickFilterPlaceholder}\n aria-label={localeText.toolbarQuickFilterLabel}\n onChange={(event) => handleChange(event.target.value)}\n onBlur={() => {\n if (!alwaysExpanded && text.trim() === '') setExpanded(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n if (text) clear();\n else if (!alwaysExpanded) {\n setExpanded(false);\n inputRef.current?.blur();\n }\n }\n if (event.key === 'Enter') {\n if (timer.current !== null) window.clearTimeout(timer.current);\n commit(text);\n }\n }}\n />\n {text && (\n <span className=\"mgh-grid-input-adornment mgh-grid-input-adornment--end\">\n <IconButton size=\"small\" label={localeText.clearSearch} onClick={clear} tabIndex={-1}>\n <CloseIcon />\n </IconButton>\n </span>\n )}\n </div>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Default toolbar\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridToolbar({\n showColumnsButton = true,\n showFilterButton = true,\n showExportButton = true,\n showQuickFilter = true,\n showDensitySelector = false,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n csvOptions,\n excelOptions,\n printOptions,\n renderOtherButtons,\n renderDateRange,\n customMenuItem,\n quickFilterPlaceholder,\n quickFilterDebounceMs,\n}: MGHGridToolbarProps) {\n const { rootProps } = useMGHGridContext();\n const showColumns = showColumnsButton && !rootProps.disableColumnSelector;\n const showFilters = showFilterButton && !rootProps.disableColumnFilter;\n const showDensity = showDensitySelector && !rootProps.disableDensitySelector;\n\n return (\n <div className=\"mgh-grid-toolbar\" role=\"toolbar\">\n <div className=\"mgh-grid-toolbar-group\">\n {showColumns && <MGHGridColumnsButton />}\n {showFilters && <MGHGridFiltersButton />}\n {showDensity && <MGHGridDensitySelector />}\n {showExportButton && (\n <MGHGridExportMenu\n csvOptions={csvOptions}\n excelOptions={excelOptions}\n printOptions={printOptions}\n showCsvOption={showCsvOption}\n showExcelOption={showExcelOption}\n showPrintOption={showPrintOption}\n customMenuItem={customMenuItem}\n />\n )}\n </div>\n {renderDateRange && <div className=\"mgh-grid-toolbar-center\">{renderDateRange}</div>}\n <div className=\"mgh-grid-toolbar-group\">\n {renderOtherButtons}\n {showQuickFilter && (\n <MGHGridQuickFilter placeholder={quickFilterPlaceholder} debounceMs={quickFilterDebounceMs} />\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { ChevronLeftIcon, ChevronRightIcon, FirstPageIcon, LastPageIcon } from '../icons';\nimport { IconButton, Select } from './primitives';\n\nexport function MGHGridPagination() {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const { page, pageSize } = state.paginationModel;\n const count = state.rowCount;\n const pageCount = state.pageCount;\n const from = count === 0 ? 0 : page * pageSize + 1;\n const to = Math.min(count, (page + 1) * pageSize);\n const options =\n rootProps.pageSizeOptions.indexOf(pageSize) === -1\n ? rootProps.pageSizeOptions.concat([pageSize]).sort((a, b) => a - b)\n : rootProps.pageSizeOptions;\n\n return (\n <div className=\"mgh-grid-pagination\" role=\"navigation\" aria-label=\"Pagination\">\n <span>{localeText.footerPaginationRowsPerPage}</span>\n <Select\n className=\"mgh-grid-pagination-select\"\n value={pageSize}\n aria-label={localeText.footerPaginationRowsPerPage}\n onChange={(event) => api.setPageSize(Number(event.target.value))}\n >\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </Select>\n <span>{localeText.footerPaginationDisplayedRows(from, to, count)}</span>\n <div className=\"mgh-grid-pagination-actions\">\n <IconButton label={localeText.footerPaginationFirstPage} disabled={page <= 0} onClick={() => api.setPage(0)}>\n <FirstPageIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationPreviousPage}\n disabled={page <= 0}\n onClick={() => api.setPage(page - 1)}\n >\n <ChevronLeftIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationNextPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(page + 1)}\n >\n <ChevronRightIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationLastPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(Math.max(pageCount - 1, 0))}\n >\n <LastPageIcon />\n </IconButton>\n </div>\n </div>\n );\n}\n\nexport function MGHGridFooter() {\n const { state, localeText, rootProps } = useMGHGridContext();\n const selectedCount = state.rowSelectionModel.ids.size;\n const showSelected = selectedCount > 0 && !rootProps.hideFooterSelectedRowCount;\n const showPagination = rootProps.pagination && !rootProps.hideFooterPagination;\n const showRowCount = !showPagination && !rootProps.hideFooterRowCount;\n\n return (\n <div className=\"mgh-grid-footer\">\n <div className=\"mgh-grid-footer-left\">\n {showSelected && <span>{localeText.footerRowSelected(selectedCount)}</span>}\n </div>\n {showRowCount && (\n <span>\n {localeText.footerTotalRows} {state.rowCount.toLocaleString()}\n </span>\n )}\n {showPagination && <MGHGridPagination />}\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { SearchIcon } from '../icons';\nimport { Button, Checkbox, TextInput } from './primitives';\n\nexport function MGHGridColumnsPanel() {\n const { api, state, localeText, columns, visibleColumns } = useMGHGridContext();\n const visibleFields = React.useMemo(() => new Set(visibleColumns.map((col) => col.field)), [visibleColumns]);\n const [search, setSearch] = React.useState('');\n const model = state.columnVisibilityModel;\n\n const hideable = columns.filter((col) => col.hideable !== false);\n const needle = search.trim().toLowerCase();\n const filtered = needle\n ? hideable.filter((col) => (col.headerName ?? col.field).toLowerCase().indexOf(needle) !== -1)\n : hideable;\n\n const setAll = (visible: boolean) => {\n const next = { ...model };\n hideable.forEach((col) => {\n next[col.field] = visible;\n });\n api.setColumnVisibilityModel(next);\n };\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarColumns}>\n <div className=\"mgh-grid-panel-header\">\n <div className=\"mgh-grid-input-adorned\">\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n autoFocus\n size=\"small\"\n value={search}\n placeholder={localeText.columnsPanelSearchPlaceholder}\n aria-label={localeText.columnsPanelSearchPlaceholder}\n onChange={(event) => setSearch(event.target.value)}\n />\n </div>\n </div>\n <div className=\"mgh-grid-panel-content\">\n <div className=\"mgh-grid-columns-list\">\n {filtered.map((col) => {\n const visible = visibleFields.has(col.field);\n return (\n <label key={col.field} className=\"mgh-grid-checkbox-label\">\n <Checkbox checked={visible} onChange={() => api.setColumnVisibility(col.field, !visible)} />\n <span>{col.headerName ?? col.field}</span>\n </label>\n );\n })}\n {filtered.length === 0 && <div className=\"mgh-grid-filter-empty\">No columns</div>}\n </div>\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(true)}>\n {localeText.columnsPanelShowAll}\n </Button>\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(false)}>\n {localeText.columnsPanelHideAll}\n </Button>\n <Button size=\"small\" onClick={() => api.setColumnVisibilityModel({})}>\n {localeText.columnsPanelReset}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridFilterItem, MGHGridFilterOperator } from '../MGHGrid.types';\nimport { AddIcon, DeleteIcon } from '../icons';\nimport { getColumnFilterOperators, getOptionLabel, getOptionValue, resolveValueOptions, uniqueId } from '../utils';\nimport { Button, Field, IconButton, Select, TextInput } from './primitives';\n\ninterface FilterValueInputProps {\n item: MGHGridFilterItem;\n column: MGHGridColDef;\n operator: MGHGridFilterOperator | undefined;\n onChange: (value: any) => void;\n placeholder: string;\n}\n\nconst useDebouncedValue = (value: any, onCommit: (value: any) => void, delay = 250) => {\n const [local, setLocal] = React.useState(value ?? '');\n const timer = React.useRef<number | null>(null);\n React.useEffect(() => {\n setLocal(value ?? '');\n }, [value]);\n const update = (next: any) => {\n setLocal(next);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => onCommit(next), delay);\n };\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n return [local, update] as const;\n};\n\nfunction TextValueInput({ item, onChange, placeholder, type }: FilterValueInputProps & { type: string }) {\n const [local, update] = useDebouncedValue(item.value, onChange);\n return (\n <TextInput\n size=\"small\"\n type={type}\n value={local}\n placeholder={placeholder}\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction MultiValueInput({ item, column, onChange, placeholder }: FilterValueInputProps) {\n const joined = Array.isArray(item.value) ? item.value.join(', ') : (item.value ?? '');\n const [local, update] = useDebouncedValue(joined, (text: string) =>\n onChange(\n String(text)\n .split(',')\n .map((v) => v.trim())\n .filter((v) => v !== '')\n )\n );\n if (column.type === 'singleSelect') {\n const options = resolveValueOptions(column);\n const selected: string[] = Array.isArray(item.value) ? item.value.map(String) : [];\n return (\n <Select\n multiple\n size=\"small\"\n value={selected}\n aria-label={placeholder}\n onChange={(event) => {\n const values = Array.from(event.target.selectedOptions).map((option) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === option.value);\n return match !== undefined ? getOptionValue(column, match) : option.value;\n });\n onChange(values);\n }}\n >\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n return (\n <TextInput\n size=\"small\"\n value={local}\n placeholder=\"Comma separated values\"\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction FilterValueInput(props: FilterValueInputProps) {\n const { item, column, operator, onChange, placeholder } = props;\n const { api } = useMGHGridContext();\n const inputType = operator?.inputType ?? 'text';\n\n if (operator?.InputComponent) {\n const Component = operator.InputComponent;\n return <Component item={item} column={column} applyValue={(next) => onChange(next.value)} api={api} />;\n }\n\n switch (inputType) {\n case 'none':\n return <div />;\n case 'boolean':\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => onChange(event.target.value === '' ? undefined : event.target.value)}\n >\n <option value=\"\">any</option>\n <option value=\"true\">yes</option>\n <option value=\"false\">no</option>\n </Select>\n );\n case 'select': {\n const options = resolveValueOptions(column);\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === event.target.value);\n onChange(\n event.target.value === ''\n ? undefined\n : match !== undefined\n ? getOptionValue(column, match)\n : event.target.value\n );\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'multiselect':\n return <MultiValueInput {...props} />;\n case 'number':\n return <TextValueInput {...props} type=\"number\" />;\n case 'date':\n return <TextValueInput {...props} type=\"date\" />;\n case 'datetime-local':\n return <TextValueInput {...props} type=\"datetime-local\" />;\n default:\n return <TextValueInput {...props} type=\"text\" />;\n }\n}\n\nconst createFilterItem = (column: MGHGridColDef | undefined): MGHGridFilterItem => ({\n id: uniqueId('filter'),\n field: column?.field ?? '',\n operator: column ? (getColumnFilterOperators(column)[0]?.value ?? 'contains') : 'contains',\n value: undefined,\n});\n\nexport function MGHGridFilterPanel() {\n const { api, state, localeText, columns, rootProps } = useMGHGridContext();\n const filterableColumns = React.useMemo(() => columns.filter((col) => col.filterable !== false), [columns]);\n const byField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n filterableColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [filterableColumns]);\n\n const items = state.filterModel.items;\n const logicOperator = state.filterModel.logicOperator ?? 'and';\n const targetField = state.preferencePanel.targetField;\n\n // Ensure at least one (possibly empty) item is displayed when the panel opens, like MUI does.\n const seeded = React.useRef(false);\n React.useEffect(() => {\n if (seeded.current) return;\n seeded.current = true;\n if (targetField && byField.has(targetField)) {\n const existing = items.find((item) => item.field === targetField);\n if (!existing) api.upsertFilterItem(createFilterItem(byField.get(targetField)));\n } else if (items.length === 0 && filterableColumns.length > 0) {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n }\n }, [api, byField, filterableColumns, items, targetField]);\n\n const updateItem = (item: MGHGridFilterItem, patch: Partial<MGHGridFilterItem>) => {\n api.upsertFilterItem({ ...item, ...patch });\n };\n\n const addItem = () => {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n };\n\n const canAddMore = !rootProps.disableMultipleColumnsFiltering || items.length === 0;\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarFilters}>\n <div className=\"mgh-grid-panel-content\" style={{ paddingTop: 12 }}>\n {items.length === 0 && <div className=\"mgh-grid-filter-empty\">No filters</div>}\n {items.map((item, index) => {\n const column = byField.get(item.field) ?? filterableColumns[0];\n const operators = column ? getColumnFilterOperators(column) : [];\n const operator = operators.find((op) => op.value === item.operator) ?? operators[0];\n const showLogic = items.length > 1;\n return (\n <div\n key={String(item.id ?? index)}\n className={\n showLogic ? 'mgh-grid-filter-row mgh-grid-filter-row--with-logic' : 'mgh-grid-filter-row'\n }\n >\n <IconButton\n size=\"small\"\n label={localeText.filterPanelDeleteIcon}\n onClick={() => api.deleteFilterItem(item)}\n >\n <DeleteIcon />\n </IconButton>\n {showLogic && (\n <Field label={index === 1 ? localeText.filterPanelLogicOperator : ' '}>\n {index === 0 ? (\n <div style={{ height: 32 }} />\n ) : (\n <Select\n size=\"small\"\n value={logicOperator}\n disabled={index > 1}\n aria-label={localeText.filterPanelLogicOperator}\n onChange={(event) =>\n api.setFilterLogicOperator(event.target.value as 'and' | 'or')\n }\n >\n <option value=\"and\">{localeText.filterPanelOperatorAnd}</option>\n <option value=\"or\">{localeText.filterPanelOperatorOr}</option>\n </Select>\n )}\n </Field>\n )}\n <Field label={localeText.filterPanelColumns}>\n <Select\n size=\"small\"\n value={column?.field ?? ''}\n aria-label={localeText.filterPanelColumns}\n onChange={(event) => {\n const nextColumn = byField.get(event.target.value);\n const nextOperators = nextColumn ? getColumnFilterOperators(nextColumn) : [];\n const keepOperator = nextOperators.some((op) => op.value === item.operator);\n updateItem(item, {\n field: event.target.value,\n operator: keepOperator ? item.operator : (nextOperators[0]?.value ?? 'contains'),\n value: undefined,\n });\n }}\n >\n {filterableColumns.map((col) => (\n <option key={col.field} value={col.field}>\n {col.headerName ?? col.field}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelOperator}>\n <Select\n size=\"small\"\n value={operator?.value ?? ''}\n aria-label={localeText.filterPanelOperator}\n onChange={(event) => {\n const nextOperator = operators.find((op) => op.value === event.target.value);\n const nextIsMulti = nextOperator?.inputType === 'multiselect';\n const currentIsMulti = operator?.inputType === 'multiselect';\n updateItem(item, {\n operator: event.target.value,\n value: nextIsMulti !== currentIsMulti ? undefined : item.value,\n });\n }}\n >\n {operators.map((op) => (\n <option key={op.value} value={op.value}>\n {op.label ?? op.value}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelValue}>\n {column ? (\n <FilterValueInput\n item={item}\n column={column}\n operator={operator}\n placeholder={localeText.filterPanelInputPlaceholder}\n onChange={(value) => updateItem(item, { value })}\n />\n ) : (\n <div />\n )}\n </Field>\n </div>\n );\n })}\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button\n variant=\"primary\"\n size=\"small\"\n startIcon={<AddIcon size={18} />}\n onClick={addItem}\n disabled={!canAddMore}\n >\n {localeText.filterPanelAddFilter}\n </Button>\n <Button\n size=\"small\"\n startIcon={<DeleteIcon size={18} />}\n disabled={items.length === 0}\n onClick={() => api.setFilterModel({ ...state.filterModel, items: [] })}\n >\n {localeText.filterPanelRemoveAll}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridThemeMode } from '../MGHGrid.types';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n FilterListIcon,\n FunctionsIcon,\n PushPinIcon,\n ViewColumnIcon,\n VisibilityOffIcon,\n WorkspacesIcon,\n} from '../icons';\nimport { GROUPING_COLUMN_FIELD } from '../utils';\nimport { Menu, MenuDivider, MenuItem, MenuSection, Popover, Select } from './primitives';\n\nexport interface MGHGridColumnMenuProps {\n column: MGHGridColDef;\n anchorEl: HTMLElement | null;\n open: boolean;\n onClose: () => void;\n themeMode: MGHGridThemeMode;\n /** Anchor for panels opened from the menu (usually the toolbar button or the header cell). */\n panelAnchorEl?: HTMLElement | null;\n}\n\nexport function MGHGridColumnMenu({ column, anchorEl, open, onClose, themeMode, panelAnchorEl }: MGHGridColumnMenuProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const field = column.field;\n const isGroupingColumn = field === GROUPING_COLUMN_FIELD;\n const sortItem = state.sortModel.find((item) => item.field === field);\n const pinned = api.isColumnPinned(field);\n const isGrouped = state.rowGroupingModel.indexOf(field) !== -1;\n const aggregation = state.aggregationModel[field];\n\n const canSort = column.sortable !== false && !rootProps.disableColumnSorting;\n const canFilter = column.filterable !== false && !rootProps.disableColumnFilter && !isGroupingColumn;\n const canHide = column.hideable !== false;\n const canPin = column.pinnable !== false && !rootProps.disableColumnPinning;\n const canGroup = column.groupable !== false && !rootProps.disableRowGrouping && !isGroupingColumn;\n const aggregationFunctions = Object.keys(rootProps.aggregationFunctions).filter((name) => {\n const fn = rootProps.aggregationFunctions[name];\n if (column.availableAggregationFunctions && column.availableAggregationFunctions.indexOf(name) === -1) return false;\n if (fn.columnTypes && column.type && fn.columnTypes.indexOf(column.type) === -1) return false;\n return true;\n });\n const canAggregate =\n column.aggregable !== false && !rootProps.disableAggregation && !isGroupingColumn && aggregationFunctions.length > 0;\n\n const anchorForPanel = panelAnchorEl ?? anchorEl;\n const name = column.headerName ?? column.field;\n\n return (\n <Popover open={open} anchorEl={anchorEl} onClose={onClose} themeMode={themeMode} placement=\"bottom-end\" role=\"menu\">\n <Menu aria-label={localeText.columnMenuLabel}>\n {canSort && (\n <>\n <MenuItem\n icon={<ArrowUpwardIcon />}\n selected={sortItem?.sort === 'asc'}\n onClick={() => api.sortColumn(field, 'asc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortAsc}\n </MenuItem>\n <MenuItem\n icon={<ArrowDownwardIcon />}\n selected={sortItem?.sort === 'desc'}\n onClick={() => api.sortColumn(field, 'desc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortDesc}\n </MenuItem>\n {sortItem && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.sortColumn(field, null)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnsort}\n </MenuItem>\n )}\n </>\n )}\n {canFilter && (\n <>\n {canSort && <MenuDivider />}\n <MenuItem\n icon={<FilterListIcon />}\n onClick={() => api.showFilterPanel(field, anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuFilter}\n </MenuItem>\n </>\n )}\n {(canHide || !rootProps.disableColumnSelector) && (\n <>\n {(canSort || canFilter) && <MenuDivider />}\n {canHide && (\n <MenuItem\n icon={<VisibilityOffIcon />}\n onClick={() => api.setColumnVisibility(field, false)}\n hideMenu={onClose}\n >\n {localeText.columnMenuHideColumn}\n </MenuItem>\n )}\n {!rootProps.disableColumnSelector && (\n <MenuItem\n icon={<ViewColumnIcon />}\n onClick={() => api.showPreferences('columns', anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuManageColumns}\n </MenuItem>\n )}\n </>\n )}\n {canPin && (\n <>\n <MenuDivider />\n {pinned !== 'left' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(30deg)' }} />}\n onClick={() => api.pinColumn(field, 'left')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinLeft}\n </MenuItem>\n )}\n {pinned !== 'right' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(-30deg)' }} />}\n onClick={() => api.pinColumn(field, 'right')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinRight}\n </MenuItem>\n )}\n {pinned && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.unpinColumn(field)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnpin}\n </MenuItem>\n )}\n </>\n )}\n {canGroup && (\n <>\n <MenuDivider />\n <MenuItem\n icon={<WorkspacesIcon />}\n onClick={() =>\n isGrouped ? api.removeRowGroupingCriteria(field) : api.addRowGroupingCriteria(field)\n }\n hideMenu={onClose}\n >\n {isGrouped ? localeText.columnMenuUngroup(name) : localeText.columnMenuGroup(name)}\n </MenuItem>\n </>\n )}\n {canAggregate && (\n <>\n <MenuDivider />\n <MenuSection>\n <label\n className=\"mgh-grid-field-label\"\n style={{ display: 'flex', alignItems: 'center', gap: 6 }}\n >\n <FunctionsIcon size={16} /> {localeText.columnMenuAggregation}\n </label>\n <Select\n size=\"small\"\n value={aggregation ?? ''}\n aria-label={localeText.columnMenuAggregation}\n onChange={(event) => {\n const next = { ...state.aggregationModel };\n if (event.target.value === '') delete next[field];\n else next[field] = event.target.value;\n api.setAggregationModel(next);\n }}\n >\n <option value=\"\">{localeText.aggregationFunctionLabelNone}</option>\n {aggregationFunctions.map((fnName) => (\n <option key={fnName} value={fnName}>\n {rootProps.aggregationFunctions[fnName].label ?? fnName}\n </option>\n ))}\n </Select>\n </MenuSection>\n </>\n )}\n </Menu>\n </Popover>\n );\n}\n","import React from 'react';\nimport { MGHGridLoadingOverlayProps, MGHGridNoRowsOverlayProps } from '../MGHGrid.types';\nimport { EmptyBoxIcon } from '../icons';\nimport { Spinner } from './primitives';\n\n/** Default \"no rows\" overlay. Mirrors the legacy CustomNoRowsOverlay but has no MUI dependency. */\nexport function MGHGridNoRowsOverlay({ text = 'No rows', imageSrc }: MGHGridNoRowsOverlayProps) {\n return (\n <div className=\"mgh-grid-no-rows\" role=\"status\">\n {imageSrc ? <img alt=\"\" src={imageSrc} /> : <EmptyBoxIcon size={50} />}\n <div>{text}</div>\n </div>\n );\n}\n\nexport function MGHGridLoadingOverlay({ text }: MGHGridLoadingOverlayProps) {\n return (\n <>\n <Spinner />\n {text && <div>{text}</div>}\n </>\n );\n}\n","import React from 'react';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { MoreVertIcon } from '../icons';\nimport { IconButton, Menu, MenuItem, Popover } from './primitives';\n\nexport interface MGHGridActionsCellItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {\n icon?: React.ReactElement;\n label: string;\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** Render the action inside the \"more\" menu instead of inline. */\n showInMenu?: boolean;\n disabled?: boolean;\n}\n\n/** Drop-in replacement for MUI's GridActionsCellItem. Use it from `colDef.getActions`. */\nexport function MGHGridActionsCellItem({\n icon,\n label,\n onClick,\n showInMenu,\n disabled,\n className,\n ...rest\n}: MGHGridActionsCellItemProps) {\n return (\n <IconButton\n size=\"small\"\n label={label}\n disabled={disabled}\n className={className}\n onClick={(event) => {\n event.stopPropagation();\n onClick?.(event);\n }}\n {...rest}\n >\n {icon}\n </IconButton>\n );\n}\nMGHGridActionsCellItem.displayName = 'MGHGridActionsCellItem';\n\ninterface ActionsCellProps {\n actions: React.ReactElement[];\n themeMode: MGHGridThemeMode;\n moreLabel: string;\n}\n\nexport function ActionsCell({ actions, themeMode, moreLabel }: ActionsCellProps) {\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const inline: React.ReactElement[] = [];\n const inMenu: React.ReactElement[] = [];\n actions.forEach((action) => {\n if (!React.isValidElement(action)) return;\n if ((action.props as MGHGridActionsCellItemProps)?.showInMenu) inMenu.push(action);\n else inline.push(action);\n });\n\n return (\n <>\n {inline.map((action, index) => (\n <React.Fragment key={action.key ?? index}>{action}</React.Fragment>\n ))}\n {inMenu.length > 0 && (\n <>\n <IconButton\n size=\"small\"\n label={moreLabel}\n active={Boolean(anchor)}\n onClick={(event) => {\n event.stopPropagation();\n setAnchor((prev) => (prev ? null : event.currentTarget));\n }}\n >\n <MoreVertIcon />\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n placement=\"bottom-end\"\n role=\"menu\"\n >\n <Menu>\n {inMenu.map((action, index) => {\n const props = action.props as MGHGridActionsCellItemProps;\n return (\n <MenuItem\n key={action.key ?? index}\n icon={props.icon}\n disabled={props.disabled}\n onClick={(event) => {\n props.onClick?.(event);\n setAnchor(null);\n }}\n >\n {props.label}\n </MenuItem>\n );\n })}\n </Menu>\n </Popover>\n </>\n )}\n </>\n );\n}\n","import React from 'react';\nimport {\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridApplyFilterFn,\n MGHGridCallbackDetails,\n MGHGridCellParams,\n MGHGridColDef,\n MGHGridColumnVisibilityModel,\n MGHGridDensity,\n MGHGridFilterItem,\n MGHGridFilterModel,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridLocaleText,\n MGHGridPaginationModel,\n MGHGridPinnedColumns,\n MGHGridPinnedSide,\n MGHGridPreferencePanelState,\n MGHGridProps,\n MGHGridRowGroupingModel,\n MGHGridRowId,\n MGHGridRowNode,\n MGHGridRowParams,\n MGHGridRowSelectionModel,\n MGHGridSortDirection,\n MGHGridSortModel,\n MGHGridState,\n MGHGridSxProps,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport {\n AGGREGATION_FOOTER_ID,\n BUILT_IN_AGGREGATION_FUNCTIONS,\n CHECKBOX_COLUMN_DEF,\n CHECKBOX_FIELD,\n DEFAULT_COLUMN_MIN_WIDTH,\n DEFAULT_HEADER_HEIGHT,\n DEFAULT_LOCALE_TEXT,\n DEFAULT_ROW_HEIGHT,\n DENSITY_FACTORS,\n DETAIL_PANEL_TOGGLE_COLUMN_DEF,\n DETAIL_PANEL_TOGGLE_FIELD,\n GROUPING_COLUMN_FIELD,\n GROUPING_COLUMN_WIDTH,\n clamp,\n cx,\n defaultFormatValue,\n formattedValueToString,\n getCellValue,\n getColumnFilterOperators,\n getDefaultComparator,\n getFormattedValue,\n getOptionLabel,\n getOptionValue,\n getRowIdFromRow,\n buildScopedCss,\n isInternalField,\n isNil,\n isSelectorKey,\n measureText,\n moveItem,\n normalizeColumn,\n normalizeSelectionModel,\n parseEditValue,\n readLocalStorage,\n resolveValueOptions,\n selectionModelsEqual,\n toDate,\n writeLocalStorage,\n} from './utils';\nimport { useMGHGridStyles } from './MGHGrid.styles';\nimport { MGHGridContext, MGHGridContextValue, MGHGridRootProps } from './context';\nimport { useControlledState, useElementSize, useForceUpdate, useLatestRef, useStableId } from './hooks';\nimport { exportDataAsCsv, exportDataAsExcel, exportDataAsPrint, getDataAsCsv } from './export';\nimport {\n DisplayRow,\n GroupTreeNode,\n RowEntry,\n aggregateRows,\n buildGroupTree,\n collectTreeLeaves,\n flattenGroupTree,\n sortGroupTree,\n} from './grouping';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n CheckIcon,\n ChevronRightIcon,\n CloseIcon,\n ExpandMoreIcon,\n MoreVertIcon,\n} from './icons';\nimport { Checkbox, IconButton, Popover, Select, TextInput } from './components/primitives';\nimport { MGHGridToolbar } from './components/Toolbar';\nimport { MGHGridFooter } from './components/Footer';\nimport { MGHGridColumnsPanel } from './components/ColumnsPanel';\nimport { MGHGridFilterPanel } from './components/FilterPanel';\nimport { MGHGridColumnMenu } from './components/ColumnMenu';\nimport { MGHGridLoadingOverlay, MGHGridNoRowsOverlay } from './components/Overlays';\nimport { ActionsCell } from './components/ActionsCell';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants & helpers\n * ----------------------------------------------------------------------------------------------- */\n\nconst EMPTY_ARRAY: any[] = [];\nconst EMPTY_OBJECT: Record<string, any> = {};\nconst EMPTY_MAP = new Map<any, any>();\nconst DEFAULT_SORTING_ORDER: MGHGridSortDirection[] = ['asc', 'desc', null];\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\nconst DEFAULT_FILTER_MODEL: MGHGridFilterModel = { items: [], quickFilterExcludeHiddenColumns: false };\nconst OVERSCAN_ROWS = 6;\nconst DEFAULT_DETAIL_PANEL_HEIGHT = 500;\n\ninterface ColumnLayout {\n col: MGHGridColDef;\n width: number;\n pinned: MGHGridPinnedSide | null;\n /** Sticky offset (left or right) for pinned columns. */\n offset: number;\n /** X position from the start of the row. */\n x: number;\n isLastLeft: boolean;\n isFirstRight: boolean;\n}\n\ntype RenderRowKind = 'leaf' | 'group' | 'pinnedRow' | 'footer';\n\ninterface RenderRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n kind: RenderRowKind;\n row: R | null;\n node: MGHGridRowNode;\n depth: number;\n group?: GroupTreeNode<R>;\n aggregates?: Record<string, { value: any; fn: string }>;\n}\n\ninterface CellCoords {\n id: MGHGridRowId;\n field: string;\n}\n\n/** Keeps only the inline-applicable part of an sx-like object (nested selectors are compiled to CSS). */\nconst sanitizeStyle = (style: MGHGridSxProps | undefined): React.CSSProperties | undefined => {\n if (!style) return undefined;\n const out: Record<string, any> = {};\n Object.keys(style).forEach((key) => {\n if (isSelectorKey(key)) return;\n const value = (style as any)[key];\n if (typeof value !== 'string' && typeof value !== 'number') return;\n out[key] = value;\n });\n return out;\n};\n\nconst computeWidths = (cols: MGHGridColDef[], available: number, overrides: Record<string, number>) => {\n const result: Array<number | null> = cols.map((col) => {\n const min = col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const max = col.maxWidth ?? Infinity;\n const override = overrides[col.field];\n if (override) return clamp(override, min, max);\n if (col.flex && col.flex > 0) return null;\n return clamp(col.width ?? 100, min, max);\n });\n const pool: number[] = [];\n let fixedTotal = 0;\n result.forEach((w, i) => {\n if (w === null) pool.push(i);\n else fixedTotal += w;\n });\n if (pool.length > 0) {\n let remainingSpace = Math.max(0, available - fixedTotal);\n let remainingFlex = pool.reduce((acc, i) => acc + (cols[i].flex as number), 0);\n let active = pool.slice();\n let changed = true;\n while (changed && active.length > 0) {\n changed = false;\n for (let k = 0; k < active.length; k += 1) {\n const i = active[k];\n const col = cols[i];\n const min = col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const max = col.maxWidth ?? Infinity;\n const share = remainingFlex > 0 ? (remainingSpace * (col.flex as number)) / remainingFlex : 0;\n if (share < min || share > max) {\n const fixed = share < min ? min : max;\n result[i] = fixed;\n remainingSpace = Math.max(0, remainingSpace - fixed);\n remainingFlex -= col.flex as number;\n active = active.filter((idx) => idx !== i);\n changed = true;\n break;\n }\n }\n }\n active.forEach((i) => {\n const col = cols[i];\n result[i] =\n remainingFlex > 0\n ? Math.floor((remainingSpace * (col.flex as number)) / remainingFlex)\n : (col.minWidth ?? 50);\n });\n }\n return result as number[];\n};\n\nconst toDateInputValue = (value: any, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n const pad = (n: number) => String(n).padStart(2, '0');\n const base = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n return withTime ? `${base}T${pad(date.getHours())}:${pad(date.getMinutes())}` : base;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Component\n * ----------------------------------------------------------------------------------------------- */\n\nexport default function MGHGrid<R extends MGHGridValidRowModel = any>(props: MGHGridProps<R>) {\n const {\n rows,\n columns: columnsProp,\n getRowId,\n loading = false,\n header,\n renderHeaderEndContent,\n renderHeaderCenterContent,\n disableCard = false,\n className,\n cardClassName,\n boxClassName,\n cardStyle,\n cardSx,\n boxStyle,\n boxSx,\n style,\n sx,\n themeMode = 'light',\n themeVars,\n showToolbar = true,\n toolbarProps,\n slots = EMPTY_OBJECT,\n slotProps = EMPTY_OBJECT,\n noRowsText = 'No data found within selected parameters.',\n localeText: localeTextProp,\n rowHeight: rowHeightProp = DEFAULT_ROW_HEIGHT,\n columnHeaderHeight = DEFAULT_HEADER_HEIGHT,\n getRowHeight,\n autoHeight = false,\n disableVirtualization = false,\n density: densityProp,\n onDensityChange,\n disableDensitySelector = false,\n pagination = true,\n pageSize = 25,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n paginationModel: paginationModelProp,\n onPaginationModelChange,\n hideFooter = false,\n hideFooterPagination = false,\n hideFooterRowCount = false,\n hideFooterSelectedRowCount = false,\n sortModel: sortModelProp,\n onSortModelChange,\n sortingOrder = DEFAULT_SORTING_ORDER,\n disableMultipleColumnsSorting = false,\n disableColumnSorting = false,\n filterModel: filterModelProp,\n onFilterModelChange,\n disableColumnFilter = false,\n disableMultipleColumnsFiltering = false,\n quickFilterDebounceMs = 150,\n columnVisibilityModel: columnVisibilityModelProp,\n onColumnVisibilityModelChange,\n columnVisibilityStorageKey,\n columnOrderStorageKey,\n columnWidthStorageKey,\n pinnedColumnsStorageKey,\n onColumnOrderChange,\n onColumnWidthChange,\n disableColumnMenu = false,\n disableColumnSelector = false,\n disableColumnResize = false,\n disableColumnReorder = false,\n disableColumnPinning = false,\n pinnedColumns: pinnedColumnsProp,\n onPinnedColumnsChange,\n checkboxSelection = false,\n checkboxSelectionVisibleOnly = false,\n disableRowSelectionOnClick = true,\n disableMultipleRowSelection = false,\n rowSelectionModel: rowSelectionModelProp,\n onRowSelectionModelChange,\n isRowSelectable,\n keepNonExistentRowsSelected = true,\n getRowClassName,\n onRowClick,\n onRowDoubleClick,\n onCellClick,\n onCellDoubleClick,\n pinnedRows,\n getDetailPanelContent,\n getDetailPanelHeight,\n detailPanelExpandedRowIds: detailPanelExpandedRowIdsProp,\n onDetailPanelExpandedRowIdsChange,\n rowGroupingModel: rowGroupingModelProp,\n onRowGroupingModelChange,\n defaultGroupingExpansionDepth = 0,\n groupingColDef,\n disableRowGrouping = false,\n isGroupExpandedByDefault,\n aggregationModel: aggregationModelProp,\n onAggregationModelChange,\n aggregationFunctions: aggregationFunctionsProp,\n disableAggregation = false,\n aggregationPosition = 'both',\n processRowUpdate,\n onProcessRowUpdateError,\n onCellEditStop,\n isCellEditable,\n initialState,\n apiRef,\n onStateChange,\n } = props;\n\n useMGHGridStyles();\n\n const gridId = useStableId('mgh-grid');\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const scrollerRef = React.useRef<HTMLDivElement | null>(null);\n const toolbarRef = React.useRef<HTMLDivElement | null>(null);\n const forceUpdate = useForceUpdate();\n\n const localeText = React.useMemo<MGHGridLocaleText>(\n () => ({ ...DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n\n /* ------------------------------------------------------------------ latest ref + api shell */\n\n const latest = React.useRef<any>({});\n const getDetails = React.useCallback((): MGHGridCallbackDetails => ({ api: latest.current.api }), []);\n\n const apiObject = React.useMemo<MGHGridApi<R>>(() => {\n const L = () => latest.current;\n const apiImpl: MGHGridApi<R> = {\n getRow: (id) => L().rowsById.get(id) ?? null,\n getRowModels: () => new Map(L().rowsById),\n getAllRowIds: () => L().rowEntries.map((e: RowEntry<R>) => e.id),\n getRowNode: (id) => L().nodesById.get(id) ?? null,\n getSortedRows: () => L().sortedLeaves.map((e: RowEntry<R>) => e.row),\n getSortedRowIds: () => L().sortedLeaves.map((e: RowEntry<R>) => e.id),\n getVisibleRows: () =>\n L()\n .pagedRows.filter((dr: DisplayRow<R>) => dr.type === 'leaf' && dr.row)\n .map((dr: DisplayRow<R>) => ({ id: dr.id, model: dr.row as R })),\n getRowIndexRelativeToVisibleRows: (id) => L().pagedRows.findIndex((dr: DisplayRow<R>) => dr.id === id),\n updateRows: (updates) => {\n updates.forEach((update) => {\n const id = getRowIdFromRow(update as R, L().getRowId);\n const existing = L().rowsById.get(id);\n if (existing) L().setRowOverride(id, { ...existing, ...update });\n });\n },\n\n getAllColumns: () => L().orderedUserColumns,\n getVisibleColumns: () => L().visibleUserColumns,\n getColumn: (field) => L().getColumn(field),\n getColumnIndex: (field, useVisibleColumns = true) =>\n (useVisibleColumns ? L().visibleUserColumns : L().orderedUserColumns).findIndex(\n (c: MGHGridColDef) => c.field === field\n ),\n getColumnVisibilityModel: () => L().columnVisibilityModel,\n setColumnVisibility: (field, isVisible) =>\n L().setColumnVisibilityModel({ ...L().columnVisibilityModel, [field]: isVisible }),\n setColumnVisibilityModel: (model) => L().setColumnVisibilityModel(model),\n setColumnWidth: (field, width) => L().setColumnWidth(field, width),\n setColumnIndex: (field, targetIndex) => L().setColumnIndex(field, targetIndex),\n autosizeColumns: (options) => L().autosizeColumns(options),\n pinColumn: (field, side) => L().pinColumn(field, side),\n unpinColumn: (field) => L().unpinColumn(field),\n isColumnPinned: (field) => L().isColumnPinned(field),\n getPinnedColumns: () => L().pinnedColumns,\n setPinnedColumns: (model) => L().setPinnedColumns(model),\n\n getSortModel: () => L().sortModel,\n setSortModel: (model) => L().setSortModel(model),\n sortColumn: (field, direction, allowMultipleSorting) => L().sortColumn(field, direction, allowMultipleSorting),\n\n getFilterModel: () => L().filterModel,\n setFilterModel: (model) => L().setFilterModel(model),\n upsertFilterItem: (item) => L().upsertFilterItems([item]),\n upsertFilterItems: (items) => L().upsertFilterItems(items),\n deleteFilterItem: (item) => L().deleteFilterItem(item),\n setFilterLogicOperator: (operator) => L().setFilterModel({ ...L().filterModel, logicOperator: operator }),\n setQuickFilterValues: (values) => L().setFilterModel({ ...L().filterModel, quickFilterValues: values }),\n showFilterPanel: (targetColumnField, anchorEl) => L().showPreferences('filters', anchorEl, targetColumnField),\n hideFilterPanel: () => L().hidePreferences(),\n showPreferences: (panel, anchorEl, targetField) => L().showPreferences(panel, anchorEl, targetField),\n hidePreferences: () => L().hidePreferences(),\n\n getSelectedRows: () => {\n const map = new Map<MGHGridRowId, R>();\n L().selectedIds.forEach((id: MGHGridRowId) => {\n const row = L().rowsById.get(id);\n if (row) map.set(id, row);\n });\n return map;\n },\n getRowSelectionModel: () => ({ type: 'include', ids: L().selectedIds }),\n setRowSelectionModel: (model) => {\n const normalized = normalizeSelectionModel(\n model,\n L().rowEntries.map((e: RowEntry<R>) => e.id)\n );\n L().setSelectedIds(normalized.ids);\n },\n selectRow: (id, isSelected = true, resetSelection = false) => L().selectRows([id], isSelected, resetSelection),\n selectRows: (ids, isSelected = true, resetSelection = false) => L().selectRows(ids, isSelected, resetSelection),\n isRowSelected: (id) => L().selectedIds.has(id),\n isRowSelectable: (id) => L().isRowSelectableFn(id, L().rowsById.get(id)),\n\n setPage: (nextPage) => L().setPaginationModel({ ...L().paginationModel, page: Math.max(0, nextPage) }),\n setPageSize: (nextPageSize) => L().setPaginationModel({ page: 0, pageSize: Math.max(1, nextPageSize) }),\n setPaginationModel: (model) => L().setPaginationModel(model),\n\n setDensity: (value) => L().setDensity(value),\n\n getDataAsCsv: (options) => getDataAsCsv(apiImpl, options),\n exportDataAsCsv: (options) => exportDataAsCsv(apiImpl, options),\n exportDataAsExcel: (options) => exportDataAsExcel(apiImpl, options),\n exportDataAsPrint: (options) => exportDataAsPrint(apiImpl, options),\n\n toggleDetailPanel: (id) => L().toggleDetailPanel(id),\n setExpandedDetailPanels: (ids) => L().setExpandedDetailPanels(new Set(ids)),\n getExpandedDetailPanels: () => Array.from(L().expandedDetailPanels as Set<MGHGridRowId>),\n\n getRowGroupingModel: () => L().rowGroupingModel,\n setRowGroupingModel: (model) => L().setRowGroupingModel(model),\n addRowGroupingCriteria: (field, groupingIndex) => {\n const current: string[] = L().rowGroupingModel.filter((f: string) => f !== field);\n if (groupingIndex === undefined) current.push(field);\n else current.splice(clamp(groupingIndex, 0, current.length), 0, field);\n L().setRowGroupingModel(current);\n },\n removeRowGroupingCriteria: (field) =>\n L().setRowGroupingModel(L().rowGroupingModel.filter((f: string) => f !== field)),\n setRowChildrenExpansion: (id, isExpanded) => L().setRowChildrenExpansion(id, isExpanded),\n getRowGroupChildren: ({ groupId }) => {\n const group = L().groupsById.get(groupId) as GroupTreeNode<R> | undefined;\n return group ? group.descendants.map((d) => d.id) : [];\n },\n\n getAggregationModel: () => L().aggregationModel,\n setAggregationModel: (model) => L().setAggregationModel(model),\n\n startCellEditMode: ({ id, field }) => L().startCellEditMode(id, field),\n stopCellEditMode: ({ id, field, ignoreModifications }) =>\n L().stopCellEditMode(id, field, ignoreModifications, 'api'),\n getCellMode: (id, field) => {\n const editing = L().editingCell as CellCoords | null;\n return editing && editing.id === id && editing.field === field ? 'edit' : 'view';\n },\n setEditCellValue: ({ id, field, value }) => {\n const editing = L().editingCell as CellCoords | null;\n if (editing && editing.id === id && editing.field === field) L().setEditValue(value);\n },\n\n getCellValue: (id, field) => {\n const row = L().rowsById.get(id);\n const col = L().getColumn(field);\n return row && col ? getCellValue(row, col, apiImpl) : undefined;\n },\n getCellParams: (id, field) => {\n const row = L().rowsById.get(id);\n return L().buildCellParams(\n id,\n field,\n row,\n L().nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null }\n );\n },\n setCellFocus: (id, field) => {\n pendingFocusRef.current = true;\n L().setFocusedCell({ id, field });\n },\n\n scrollToIndexes: (params) => L().scrollToIndexes(params),\n scroll: ({ left, top }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return;\n if (left !== undefined) scroller.scrollLeft = left;\n if (top !== undefined) scroller.scrollTop = top;\n },\n getScrollPosition: () => ({\n left: scrollerRef.current?.scrollLeft ?? 0,\n top: scrollerRef.current?.scrollTop ?? 0,\n }),\n\n get state() {\n return L().state as MGHGridState;\n },\n forceUpdate: () => L().forceUpdate(),\n rootElementRef: rootRef,\n };\n return apiImpl;\n }, []);\n if (!latest.current.api) latest.current.api = apiObject;\n\n /* ------------------------------------------------------------------ persisted state */\n\n const persisted = React.useMemo(\n () => ({\n visibility: columnVisibilityStorageKey\n ? readLocalStorage<MGHGridColumnVisibilityModel>(columnVisibilityStorageKey)\n : null,\n order: columnOrderStorageKey ? readLocalStorage<string[]>(columnOrderStorageKey) : null,\n widths: columnWidthStorageKey ? readLocalStorage<Record<string, number>>(columnWidthStorageKey) : null,\n pinned: pinnedColumnsStorageKey ? readLocalStorage<MGHGridPinnedColumns>(pinnedColumnsStorageKey) : null,\n }),\n [columnVisibilityStorageKey, columnOrderStorageKey, columnWidthStorageKey, pinnedColumnsStorageKey]\n );\n\n /* ------------------------------------------------------------------ models */\n\n const [sortModel, setSortModel] = useControlledState<MGHGridSortModel>(\n sortModelProp,\n initialState?.sorting?.sortModel ?? EMPTY_ARRAY,\n (model) => onSortModelChange?.(model, getDetails())\n );\n\n const [filterModel, setFilterModel] = useControlledState<MGHGridFilterModel>(\n filterModelProp,\n initialState?.filter?.filterModel ?? DEFAULT_FILTER_MODEL,\n (model) => onFilterModelChange?.(model, getDetails())\n );\n\n const [paginationModel, setPaginationModel] = useControlledState<MGHGridPaginationModel>(\n paginationModelProp,\n {\n page: initialState?.pagination?.paginationModel?.page ?? 0,\n pageSize: initialState?.pagination?.paginationModel?.pageSize ?? pageSize,\n },\n (model) => onPaginationModelChange?.(model, getDetails())\n );\n\n const [columnVisibilityModel, setColumnVisibilityModel] = useControlledState<MGHGridColumnVisibilityModel>(\n columnVisibilityModelProp,\n persisted.visibility ?? initialState?.columns?.columnVisibilityModel ?? EMPTY_OBJECT,\n (model) => {\n if (columnVisibilityStorageKey) writeLocalStorage(columnVisibilityStorageKey, model);\n onColumnVisibilityModelChange?.(model, getDetails());\n }\n );\n\n const [density, setDensity] = useControlledState<MGHGridDensity>(\n densityProp,\n initialState?.density ?? 'compact',\n (value) => onDensityChange?.(value, getDetails())\n );\n\n const [pinnedColumns, setPinnedColumns] = useControlledState<MGHGridPinnedColumns>(\n pinnedColumnsProp,\n persisted.pinned ?? initialState?.pinnedColumns ?? EMPTY_OBJECT,\n (model) => {\n if (pinnedColumnsStorageKey) writeLocalStorage(pinnedColumnsStorageKey, model);\n onPinnedColumnsChange?.(model, getDetails());\n }\n );\n\n const [rowGroupingModel, setRowGroupingModel] = useControlledState<MGHGridRowGroupingModel>(\n rowGroupingModelProp,\n initialState?.rowGrouping?.model ?? EMPTY_ARRAY,\n (model) => onRowGroupingModelChange?.(model, getDetails())\n );\n\n const [aggregationModel, setAggregationModel] = useControlledState<MGHGridAggregationModel>(\n aggregationModelProp,\n initialState?.aggregation?.model ?? EMPTY_OBJECT,\n (model) => onAggregationModelChange?.(model, getDetails())\n );\n\n const controlledExpandedDetail = React.useMemo(\n () => (detailPanelExpandedRowIdsProp ? new Set<MGHGridRowId>(detailPanelExpandedRowIdsProp) : undefined),\n [detailPanelExpandedRowIdsProp]\n );\n const [expandedDetailPanels, setExpandedDetailPanels] = useControlledState<Set<MGHGridRowId>>(\n controlledExpandedDetail,\n React.useMemo(() => new Set<MGHGridRowId>(initialState?.detailPanel?.expandedRowIds ?? []), []),\n (ids) => onDetailPanelExpandedRowIdsChange?.(Array.from(ids), getDetails())\n );\n\n const controlledSelection = React.useMemo(\n () => (rowSelectionModelProp !== undefined ? normalizeSelectionModel(rowSelectionModelProp).ids : undefined),\n [rowSelectionModelProp]\n );\n const [selectedIds, setSelectedIds] = useControlledState<Set<MGHGridRowId>>(\n controlledSelection,\n React.useMemo(() => new Set<MGHGridRowId>(), []),\n (ids) => onRowSelectionModelChange?.({ type: 'include', ids }, getDetails())\n );\n\n /* ------------------------------------------------------------------ internal state */\n\n const [orderedFields, setOrderedFields] = React.useState<string[] | null>(\n () => persisted.order ?? initialState?.columns?.orderedFields ?? null\n );\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>(() => {\n if (persisted.widths) return persisted.widths;\n const dims = initialState?.columns?.dimensions;\n if (!dims) return {};\n const out: Record<string, number> = {};\n Object.keys(dims).forEach((field) => {\n if (dims[field].width) out[field] = dims[field].width as number;\n });\n return out;\n });\n const [groupExpansion, setGroupExpansion] = React.useState<Map<MGHGridRowId, boolean>>(() => new Map());\n const [editingCell, setEditingCell] = React.useState<CellCoords | null>(null);\n const [editValue, setEditValue] = React.useState<any>(undefined);\n const [focusedCell, setFocusedCell] = React.useState<CellCoords | null>(null);\n const pendingFocusRef = React.useRef(false);\n const [preferencePanel, setPreferencePanel] = React.useState<\n MGHGridPreferencePanelState & { anchorEl: HTMLElement | null }\n >({\n open: false,\n anchorEl: null,\n });\n const [columnMenu, setColumnMenu] = React.useState<{ field: string; anchorEl: HTMLElement } | null>(null);\n const [resizingField, setResizingField] = React.useState<string | null>(null);\n const [drag, setDrag] = React.useState<{ field: string; overField: string | null; side: 'left' | 'right' } | null>(null);\n const [scrollTop, setScrollTop] = React.useState(0);\n const scrollRaf = React.useRef(0);\n const lastClickedIdRef = React.useRef<MGHGridRowId | null>(null);\n\n // Row updates (editing / api.updateRows) are kept until the `rows` prop identity changes.\n const [overrideState, setOverrideState] = React.useState<{ rows: R[]; map: Map<MGHGridRowId, R> }>(() => ({\n rows,\n map: new Map(),\n }));\n const rowOverrides: Map<MGHGridRowId, R> = overrideState.rows === rows ? overrideState.map : EMPTY_MAP;\n const setRowOverride = React.useCallback(\n (id: MGHGridRowId, row: R) => {\n setOverrideState((prev) => {\n const map = new Map(prev.rows === rows ? prev.map : []);\n map.set(id, row);\n return { rows, map };\n });\n },\n [rows]\n );\n\n /* ------------------------------------------------------------------ sizes */\n\n const { width: viewportWidth, height: viewportHeight } = useElementSize(scrollerRef);\n const densityFactor = DENSITY_FACTORS[density] ?? 1;\n const rowHeight = Math.round(rowHeightProp * densityFactor);\n const headerHeight = Math.round(columnHeaderHeight * densityFactor);\n\n /* ------------------------------------------------------------------ rows */\n\n const rowEntries = React.useMemo<RowEntry<R>[]>(() => {\n const out: RowEntry<R>[] = [];\n rows.forEach((raw) => {\n const id = getRowIdFromRow(raw, getRowId);\n if (id === undefined || id === null) return;\n out.push({ id, row: rowOverrides.get(id) ?? raw });\n });\n return out;\n }, [rows, getRowId, rowOverrides]);\n\n const rowsById = React.useMemo(() => {\n const map = new Map<MGHGridRowId, R>();\n rowEntries.forEach((entry) => map.set(entry.id, entry.row));\n (pinnedRows?.top ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n (pinnedRows?.bottom ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n return map;\n }, [rowEntries, pinnedRows, getRowId]);\n\n /* ------------------------------------------------------------------ columns */\n\n const userColumns = React.useMemo(() => columnsProp.map((col) => normalizeColumn(col)), [columnsProp]);\n\n const columnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef<R>>();\n userColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [userColumns]);\n\n const groupingFields = React.useMemo(\n () => (disableRowGrouping ? [] : rowGroupingModel.filter((field) => columnsByField.has(field))),\n [rowGroupingModel, columnsByField, disableRowGrouping]\n );\n const groupingActive = groupingFields.length > 0;\n\n const groupingColumn = React.useMemo<MGHGridColDef<R> | null>(() => {\n if (!groupingActive) return null;\n const single = groupingFields.length === 1 ? columnsByField.get(groupingFields[0]) : undefined;\n return normalizeColumn<R>({\n field: GROUPING_COLUMN_FIELD,\n headerName: single ? (single.headerName ?? single.field) : localeText.groupingColumnHeaderName,\n width: GROUPING_COLUMN_WIDTH,\n minWidth: 120,\n sortable: true,\n filterable: false,\n hideable: false,\n groupable: false,\n aggregable: false,\n editable: false,\n disableExport: true,\n disableReorder: true,\n ...(groupingColDef as any),\n });\n }, [groupingActive, groupingFields, columnsByField, localeText.groupingColumnHeaderName, groupingColDef]);\n\n const orderedUserColumns = React.useMemo(() => {\n if (!orderedFields || orderedFields.length === 0) return userColumns;\n const seen = new Set<string>();\n const out: MGHGridColDef<R>[] = [];\n orderedFields.forEach((field) => {\n const col = columnsByField.get(field);\n if (col && !seen.has(field)) {\n seen.add(field);\n out.push(col);\n }\n });\n userColumns.forEach((col) => {\n if (!seen.has(col.field)) out.push(col);\n });\n return out;\n }, [orderedFields, userColumns, columnsByField]);\n\n const isColumnVisible = React.useCallback(\n (field: string) => {\n const value = columnVisibilityModel[field];\n if (value === false) return false;\n if (value === undefined && groupingFields.indexOf(field) !== -1) return false;\n return true;\n },\n [columnVisibilityModel, groupingFields]\n );\n\n const visibleUserColumns = React.useMemo(\n () => orderedUserColumns.filter((col) => isColumnVisible(col.field)),\n [orderedUserColumns, isColumnVisible]\n );\n\n const layout = React.useMemo(() => {\n const internal: MGHGridColDef[] = [];\n if (checkboxSelection) internal.push(CHECKBOX_COLUMN_DEF);\n if (getDetailPanelContent) internal.push(DETAIL_PANEL_TOGGLE_COLUMN_DEF);\n const leftFields = disableColumnPinning ? [] : (pinnedColumns.left ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const rightFields = disableColumnPinning\n ? []\n : (pinnedColumns.right ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const visibleByField = new Map<string, MGHGridColDef>();\n visibleUserColumns.forEach((col) => visibleByField.set(col.field, col));\n const left: MGHGridColDef[] = internal.slice();\n if (groupingColumn) left.push(groupingColumn);\n leftFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col) left.push(col);\n });\n const right: MGHGridColDef[] = [];\n rightFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col && leftFields.indexOf(f) === -1) right.push(col);\n });\n const center = visibleUserColumns.filter(\n (col) => leftFields.indexOf(col.field) === -1 && rightFields.indexOf(col.field) === -1\n );\n const ordered = left.concat(center, right);\n const widths = computeWidths(ordered, viewportWidth, columnWidths);\n const hasPinning = left.length > internal.length + (groupingColumn ? 1 : 0) || right.length > 0;\n const columns: ColumnLayout[] = [];\n let x = 0;\n let leftOffset = 0;\n ordered.forEach((col, i) => {\n const width = widths[i];\n const isLeft = i < left.length;\n const isRight = i >= left.length + center.length;\n columns.push({\n col,\n width,\n pinned: isLeft ? 'left' : isRight ? 'right' : null,\n offset: isLeft ? leftOffset : 0,\n x,\n isLastLeft: isLeft && i === left.length - 1,\n isFirstRight: isRight && i === left.length + center.length,\n });\n if (isLeft) leftOffset += width;\n x += width;\n });\n let rightOffset = 0;\n for (let i = columns.length - 1; i >= 0; i -= 1) {\n if (columns[i].pinned !== 'right') break;\n columns[i].offset = rightOffset;\n rightOffset += columns[i].width;\n }\n return { columns, totalWidth: x, hasPinning, leftCount: left.length, rightCount: right.length };\n }, [\n checkboxSelection,\n getDetailPanelContent,\n pinnedColumns,\n disableColumnPinning,\n visibleUserColumns,\n groupingColumn,\n viewportWidth,\n columnWidths,\n ]);\n\n const allDisplayColumnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n layout.columns.forEach((c) => map.set(c.col.field, c.col));\n if (groupingColumn) map.set(GROUPING_COLUMN_FIELD, groupingColumn);\n return map;\n }, [layout.columns, groupingColumn]);\n\n const getColumn = React.useCallback(\n (field: string): MGHGridColDef<R> | undefined =>\n columnsByField.get(field) ?? (allDisplayColumnsByField.get(field) as any),\n [columnsByField, allDisplayColumnsByField]\n );\n\n /* ------------------------------------------------------------------ filtering */\n\n const activeFilters = React.useMemo(() => {\n const out: Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }> = [];\n filterModel.items.forEach((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.filterable === false) return;\n const operator = getColumnFilterOperators(col).find((op) => op.value === item.operator);\n if (!operator) return;\n const fn = operator.getApplyFilterFn(item, col);\n if (fn) out.push({ col, fn });\n });\n return out;\n }, [filterModel.items, columnsByField]);\n\n const quickFilterValues = React.useMemo(\n () => (filterModel.quickFilterValues ?? []).map((v) => String(v).trim()).filter((v) => v !== ''),\n [filterModel.quickFilterValues]\n );\n\n const quickFilterColumns = React.useMemo(() => {\n const base = filterModel.quickFilterExcludeHiddenColumns ? visibleUserColumns : orderedUserColumns;\n return base.filter((col) => col.filterable !== false && col.type !== 'actions');\n }, [filterModel.quickFilterExcludeHiddenColumns, visibleUserColumns, orderedUserColumns]);\n\n const filteredEntries = React.useMemo(() => {\n if (activeFilters.length === 0 && quickFilterValues.length === 0) return rowEntries;\n const logicAnd = (filterModel.logicOperator ?? 'and') === 'and';\n const quickAnd = (filterModel.quickFilterLogicOperator ?? 'and') === 'and';\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const quickFns = quickFilterValues.map((needle) => {\n const lowered = needle.toLowerCase();\n const perColumn = quickFilterColumns.map((col) => {\n if (col.getApplyQuickFilterFn) {\n const custom = col.getApplyQuickFilterFn(needle, col, apiRefLocal);\n return custom ? { col, fn: custom } : null;\n }\n const fn: MGHGridApplyFilterFn<R> = (value, row) => {\n if (isNil(value)) return false;\n const formatted = formattedValueToString(getFormattedValue(value, row, col, apiRefLocal)).toLowerCase();\n if (formatted.indexOf(lowered) !== -1) return true;\n const raw = typeof value === 'object' ? '' : String(value).toLowerCase();\n return raw.indexOf(lowered) !== -1;\n };\n return { col, fn };\n });\n const active = perColumn.filter(Boolean) as Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }>;\n return (row: R) => active.some(({ col, fn }) => fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal));\n });\n return rowEntries.filter(({ row }) => {\n if (activeFilters.length > 0) {\n const results = activeFilters.map(({ col, fn }) =>\n fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal)\n );\n const pass = logicAnd ? results.every(Boolean) : results.some(Boolean);\n if (!pass) return false;\n }\n if (quickFns.length > 0) {\n const results = quickFns.map((fn) => fn(row));\n return quickAnd ? results.every(Boolean) : results.some(Boolean);\n }\n return true;\n });\n }, [\n rowEntries,\n activeFilters,\n quickFilterValues,\n quickFilterColumns,\n filterModel.logicOperator,\n filterModel.quickFilterLogicOperator,\n ]);\n\n /* ------------------------------------------------------------------ sorting */\n\n const compareEntries = React.useMemo(() => {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sorters = sortModel\n .filter((item) => item.sort && item.field !== GROUPING_COLUMN_FIELD)\n .map((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.sortable === false) return null;\n return {\n col,\n dir: item.sort === 'desc' ? -1 : 1,\n comparator: col.sortComparator ?? getDefaultComparator(col.type),\n };\n })\n .filter(Boolean) as Array<{ col: MGHGridColDef<R>; dir: number; comparator: any }>;\n if (sorters.length === 0) return null;\n return (a: RowEntry<R>, b: RowEntry<R>) => {\n for (let i = 0; i < sorters.length; i += 1) {\n const { col, dir, comparator } = sorters[i];\n const v1 = getCellValue(a.row, col, apiRefLocal);\n const v2 = getCellValue(b.row, col, apiRefLocal);\n const result = comparator(\n v1,\n v2,\n { id: a.id, field: col.field, value: v1, row: a.row, api: apiRefLocal },\n { id: b.id, field: col.field, value: v2, row: b.row, api: apiRefLocal }\n );\n if (result !== 0) return result * dir;\n }\n return 0;\n };\n }, [sortModel, columnsByField]);\n\n const sortEntries = React.useCallback(\n (entries: RowEntry<R>[]) => {\n if (!compareEntries) return entries;\n return entries\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => compareEntries(a.entry, b.entry) || a.index - b.index)\n .map((item) => item.entry);\n },\n [compareEntries]\n );\n\n /* ------------------------------------------------------------------ grouping + display rows */\n\n const aggregationFunctions = React.useMemo(\n () => ({ ...BUILT_IN_AGGREGATION_FUNCTIONS, ...aggregationFunctionsProp }),\n [aggregationFunctionsProp]\n );\n const aggregationActive = !disableAggregation && Object.keys(aggregationModel).length > 0;\n\n const isGroupExpanded = React.useCallback(\n (node: GroupTreeNode<R>) => {\n const override = groupExpansion.get(node.id);\n if (override !== undefined) return override;\n if (isGroupExpandedByDefault) {\n return isGroupExpandedByDefault({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: [],\n leafIds: [],\n isExpanded: false,\n });\n }\n return defaultGroupingExpansionDepth === -1 || node.depth < defaultGroupingExpansionDepth;\n },\n [groupExpansion, isGroupExpandedByDefault, defaultGroupingExpansionDepth]\n );\n\n const processed = React.useMemo(() => {\n const nodesById = new Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>();\n const groupsById = new Map<MGHGridRowId, GroupTreeNode<R>>();\n if (!groupingActive) {\n const sorted = sortEntries(filteredEntries);\n const displayRows: DisplayRow<R>[] = sorted.map((entry) => {\n const node: MGHGridLeafNode = { type: 'leaf', id: entry.id, depth: 0, parent: null };\n nodesById.set(entry.id, node);\n return { id: entry.id, type: 'leaf', row: entry.row, node, depth: 0 };\n });\n return { displayRows, sortedLeaves: sorted, nodesById, groupsById, tree: [] as GroupTreeNode<R>[] };\n }\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n let tree = buildGroupTree(filteredEntries, groupingFields, columnsByField, apiRefLocal);\n const groupingSort = sortModel.find((item) => item.field === GROUPING_COLUMN_FIELD && item.sort);\n const compareGroups = (depth: number) => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return null;\n const sortItem = groupingSort ?? sortModel.find((item) => item.field === field && item.sort);\n if (!sortItem) return null;\n const comparator = col.sortComparator ?? getDefaultComparator(col.type);\n const dir = sortItem.sort === 'desc' ? -1 : 1;\n return (a: GroupTreeNode<R>, b: GroupTreeNode<R>) =>\n comparator(\n a.groupingKey,\n b.groupingKey,\n { id: a.id, field, value: a.groupingKey, row: a.descendants[0]?.row, api: apiRefLocal },\n { id: b.id, field, value: b.groupingKey, row: b.descendants[0]?.row, api: apiRefLocal }\n ) * dir;\n };\n tree = sortGroupTree(tree, compareGroups, sortEntries);\n const displayRows = flattenGroupTree(tree, isGroupExpanded, nodesById, groupsById);\n return { displayRows, sortedLeaves: collectTreeLeaves(tree), nodesById, groupsById, tree };\n }, [groupingActive, filteredEntries, sortEntries, groupingFields, columnsByField, sortModel, isGroupExpanded]);\n\n const { displayRows, sortedLeaves, nodesById, groupsById } = processed;\n\n /* ------------------------------------------------------------------ pagination */\n\n const totalDisplayRows = displayRows.length;\n const pageCount = pagination ? Math.max(1, Math.ceil(totalDisplayRows / Math.max(paginationModel.pageSize, 1))) : 1;\n const page = pagination ? clamp(paginationModel.page, 0, pageCount - 1) : 0;\n\n React.useEffect(() => {\n if (pagination && paginationModel.page !== page) {\n setPaginationModel({ ...paginationModel, page });\n }\n }, [pagination, paginationModel, page, setPaginationModel]);\n\n const pagedRows = React.useMemo(\n () =>\n pagination\n ? displayRows.slice(page * paginationModel.pageSize, (page + 1) * paginationModel.pageSize)\n : displayRows,\n [displayRows, pagination, page, paginationModel.pageSize]\n );\n\n /* ------------------------------------------------------------------ aggregation values */\n\n const footerAggregates = React.useMemo(() => {\n if (!aggregationActive || aggregationPosition === 'inline') return null;\n const rowsForFooter = sortedLeaves.map((entry) => entry.row);\n return aggregateRows(rowsForFooter, aggregationModel, columnsByField, aggregationFunctions, latest.current.api);\n }, [aggregationActive, aggregationPosition, sortedLeaves, aggregationModel, columnsByField, aggregationFunctions]);\n\n const groupAggregatesCache = React.useMemo(\n () => new Map<MGHGridRowId, Record<string, { value: any; fn: string }>>(),\n [pagedRows, aggregationModel, aggregationFunctions]\n );\n const getGroupAggregates = (group: GroupTreeNode<R>) => {\n if (!aggregationActive || aggregationPosition === 'footer') return undefined;\n let cached = groupAggregatesCache.get(group.id);\n if (!cached) {\n cached = aggregateRows(\n group.descendants.map((d) => d.row),\n aggregationModel,\n columnsByField,\n aggregationFunctions,\n latest.current.api\n );\n groupAggregatesCache.set(group.id, cached);\n }\n return cached;\n };\n\n /* ------------------------------------------------------------------ row heights + virtualization */\n\n const heights = React.useMemo(() => {\n const rowHeights: number[] = [];\n const detailHeights: number[] = [];\n const offsets: number[] = [];\n let total = 0;\n let hasAuto = autoHeight || disableVirtualization;\n pagedRows.forEach((dr) => {\n let h = rowHeight;\n if (getRowHeight && dr.type === 'leaf' && dr.row) {\n const result = getRowHeight({ id: dr.id, model: dr.row, densityFactor });\n if (result === 'auto') hasAuto = true;\n else if (typeof result === 'number' && result > 0) h = result;\n }\n let d = 0;\n if (dr.type === 'leaf' && getDetailPanelContent && expandedDetailPanels.has(dr.id) && dr.row) {\n const dh = getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row })\n : DEFAULT_DETAIL_PANEL_HEIGHT;\n if (dh === 'auto') hasAuto = true;\n else d = dh;\n }\n rowHeights.push(h);\n detailHeights.push(d);\n offsets.push(total);\n total += h + d;\n });\n return { rowHeights, detailHeights, offsets, total, hasAuto };\n }, [\n pagedRows,\n rowHeight,\n getRowHeight,\n densityFactor,\n getDetailPanelContent,\n getDetailPanelHeight,\n expandedDetailPanels,\n autoHeight,\n disableVirtualization,\n ]);\n\n const virtual = !heights.hasAuto;\n\n const virtualRange = React.useMemo(() => {\n const count = pagedRows.length;\n if (!virtual || count === 0) return { start: 0, end: count };\n const overscan = OVERSCAN_ROWS * rowHeight;\n const viewTop = Math.max(0, scrollTop - headerHeight - overscan);\n const viewBottom = scrollTop + Math.max(viewportHeight, rowHeight) + overscan;\n const { offsets } = heights;\n let lo = 0;\n let hi = count - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid] + heights.rowHeights[mid] + heights.detailHeights[mid] < viewTop) lo = mid + 1;\n else hi = mid;\n }\n const start = lo;\n let end = start;\n while (end < count && offsets[end] < viewBottom) end += 1;\n return { start, end };\n }, [virtual, pagedRows.length, scrollTop, viewportHeight, rowHeight, headerHeight, heights]);\n\n const handleScroll = React.useCallback(() => {\n if (!latest.current.virtual) return;\n if (scrollRaf.current) return;\n scrollRaf.current = window.requestAnimationFrame(() => {\n scrollRaf.current = 0;\n if (scrollerRef.current) setScrollTop(scrollerRef.current.scrollTop);\n });\n }, []);\n\n React.useEffect(\n () => () => {\n if (scrollRaf.current) window.cancelAnimationFrame(scrollRaf.current);\n },\n []\n );\n\n /* ------------------------------------------------------------------ selection */\n\n const isRowSelectableFn = React.useCallback(\n (id: MGHGridRowId, row: R | null | undefined) => {\n if (!row) return false;\n if (!isRowSelectable) return true;\n return isRowSelectable({ id, row, columns: orderedUserColumns, api: latest.current.api });\n },\n [isRowSelectable, orderedUserColumns]\n );\n\n const selectionCandidates = React.useMemo(() => {\n const source: RowEntry<R>[] = checkboxSelectionVisibleOnly\n ? (pagedRows\n .filter((dr) => dr.type === 'leaf' && dr.row)\n .map((dr) => ({ id: dr.id, row: dr.row as R })) as RowEntry<R>[])\n : sortedLeaves;\n return source.filter((entry) => isRowSelectableFn(entry.id, entry.row)).map((entry) => entry.id);\n }, [checkboxSelectionVisibleOnly, pagedRows, sortedLeaves, isRowSelectableFn]);\n\n const selectedCandidateCount = React.useMemo(\n () => selectionCandidates.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0),\n [selectionCandidates, selectedIds]\n );\n const allCandidatesSelected = selectionCandidates.length > 0 && selectedCandidateCount === selectionCandidates.length;\n const someCandidatesSelected = selectedCandidateCount > 0 && !allCandidatesSelected;\n\n const updateSelection = React.useCallback(\n (updater: (prev: Set<MGHGridRowId>) => Set<MGHGridRowId>) => {\n setSelectedIds((prev) => {\n const next = updater(prev);\n return selectionModelsEqual({ type: 'include', ids: prev }, { type: 'include', ids: next }) ? prev : next;\n });\n },\n [setSelectedIds]\n );\n\n const selectRows = React.useCallback(\n (ids: MGHGridRowId[], isSelected = true, resetSelection = false) => {\n updateSelection((prev) => {\n const next = resetSelection ? new Set<MGHGridRowId>() : new Set(prev);\n ids.forEach((id) => {\n if (isSelected) {\n if (isRowSelectableFn(id, rowsById.get(id))) next.add(id);\n } else next.delete(id);\n });\n if (disableMultipleRowSelection && next.size > 1) {\n const lastId = ids[ids.length - 1];\n return new Set<MGHGridRowId>(isSelected && next.has(lastId) ? [lastId] : []);\n }\n return next;\n });\n },\n [updateSelection, isRowSelectableFn, rowsById, disableMultipleRowSelection]\n );\n\n React.useEffect(() => {\n if (keepNonExistentRowsSelected || selectedIds.size === 0) return;\n let changed = false;\n const next = new Set<MGHGridRowId>();\n selectedIds.forEach((id) => {\n if (rowsById.has(id)) next.add(id);\n else changed = true;\n });\n if (changed) setSelectedIds(next);\n }, [rowsById, keepNonExistentRowsSelected, selectedIds, setSelectedIds]);\n\n const toggleAllCandidates = () => {\n if (allCandidatesSelected) selectRows(selectionCandidates, false);\n else selectRows(selectionCandidates, true);\n };\n\n const handleRowSelectionClick = (renderRow: RenderRow<R>, event: React.MouseEvent) => {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const allSelected = leafIds.every((id) => selectedIds.has(id));\n selectRows(leafIds, !allSelected, false);\n return;\n }\n if (renderRow.kind !== 'leaf') return;\n const id = renderRow.id;\n if (!isRowSelectableFn(id, renderRow.row)) return;\n const multiple = !disableMultipleRowSelection;\n if (event.shiftKey && multiple && lastClickedIdRef.current !== null) {\n const ids = pagedRows.filter((dr) => dr.type === 'leaf').map((dr) => dr.id);\n const from = ids.indexOf(lastClickedIdRef.current);\n const to = ids.indexOf(id);\n if (from !== -1 && to !== -1) {\n const [a, b] = from < to ? [from, to] : [to, from];\n selectRows(ids.slice(a, b + 1), true, !checkboxSelection && !event.ctrlKey && !event.metaKey);\n return;\n }\n }\n lastClickedIdRef.current = id;\n const isSelected = selectedIds.has(id);\n const resetSelection = !checkboxSelection && !event.ctrlKey && !event.metaKey;\n if (resetSelection) {\n if (isSelected && selectedIds.size === 1) selectRows([id], false, true);\n else selectRows([id], true, true);\n } else {\n selectRows([id], !isSelected, false);\n }\n };\n\n /* ------------------------------------------------------------------ sorting helpers */\n\n const sortColumn = (field: string, direction?: MGHGridSortDirection, allowMultiple = false) => {\n const col = getColumn(field);\n if (!col || col.sortable === false || disableColumnSorting) return;\n const current = sortModel.find((item) => item.field === field);\n let next: MGHGridSortDirection;\n if (direction === undefined) {\n const order = col.sortingOrder ?? sortingOrder;\n const index = order.indexOf(current?.sort ?? null);\n next = order[(index + 1) % order.length];\n } else {\n next = direction;\n }\n let model: MGHGridSortModel;\n if (allowMultiple && !disableMultipleColumnsSorting) {\n model = sortModel.filter((item) => item.field !== field);\n if (next)\n model = current\n ? sortModel.map((item) => (item.field === field ? { field, sort: next } : item))\n : model.concat([{ field, sort: next }]);\n } else {\n model = next ? [{ field, sort: next }] : [];\n }\n setSortModel(model);\n };\n\n /* ------------------------------------------------------------------ column helpers */\n\n const persistOrder = (fields: string[]) => {\n if (columnOrderStorageKey) writeLocalStorage(columnOrderStorageKey, fields);\n };\n\n const persistWidths = (widths: Record<string, number>) => {\n if (columnWidthStorageKey) writeLocalStorage(columnWidthStorageKey, widths);\n };\n\n const setColumnIndex = (field: string, targetIndex: number, event: React.DragEvent | null = null) => {\n const fields = orderedUserColumns.map((c) => c.field);\n const oldIndex = fields.indexOf(field);\n if (oldIndex === -1) return;\n const next = moveItem(fields, oldIndex, clamp(targetIndex, 0, fields.length - 1));\n setOrderedFields(next);\n persistOrder(next);\n const col = columnsByField.get(field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex, oldIndex }, event, getDetails());\n };\n\n const setColumnWidth = (field: string, width: number) => {\n const col = getColumn(field);\n if (!col) return;\n const clamped = clamp(width, col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n setColumnWidths((prev) => {\n const next = { ...prev, [field]: clamped };\n persistWidths(next);\n return next;\n });\n onColumnWidthChange?.({ colDef: col, width: clamped }, getDetails());\n };\n\n const autosizeColumns = (options: { columns?: string[]; includeHeaders?: boolean; expand?: boolean } = {}) => {\n const includeHeaders = options.includeHeaders ?? true;\n const targets = layout.columns.filter(\n (lc) => !isInternalField(lc.col.field) && (!options.columns || options.columns.indexOf(lc.col.field) !== -1)\n );\n if (targets.length === 0) return;\n const root = rootRef.current;\n const computed = root && typeof window !== 'undefined' ? window.getComputedStyle(root) : null;\n const fontFamily = computed?.fontFamily || 'sans-serif';\n const cellFont = `400 14px ${fontFamily}`;\n const headerFont = `600 14px ${fontFamily}`;\n const sample = sortedLeaves.slice(0, 500);\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const next = { ...columnWidths };\n targets.forEach(({ col }) => {\n let max = includeHeaders ? measureText(col.headerName ?? col.field, headerFont) + 64 : 0;\n sample.forEach((entry) => {\n const value = getCellValue(entry.row, col, apiRefLocal);\n const text = formattedValueToString(getFormattedValue(value, entry.row, col, apiRefLocal, entry.id));\n const w = measureText(text, cellFont) + 24;\n if (w > max) max = w;\n });\n next[col.field] = clamp(Math.ceil(max), col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n });\n setColumnWidths(next);\n persistWidths(next);\n };\n\n const pinColumn = (field: string, side: MGHGridPinnedSide) => {\n if (disableColumnPinning) return;\n const left = (pinnedColumns.left ?? []).filter((f) => f !== field);\n const right = (pinnedColumns.right ?? []).filter((f) => f !== field);\n if (side === 'left') left.push(field);\n else right.unshift(field);\n setPinnedColumns({ left, right });\n };\n\n const unpinColumn = (field: string) => {\n setPinnedColumns({\n left: (pinnedColumns.left ?? []).filter((f) => f !== field),\n right: (pinnedColumns.right ?? []).filter((f) => f !== field),\n });\n };\n\n const isColumnPinned = (field: string): MGHGridPinnedSide | false => {\n if (disableColumnPinning) return false;\n if ((pinnedColumns.left ?? []).indexOf(field) !== -1) return 'left';\n if ((pinnedColumns.right ?? []).indexOf(field) !== -1) return 'right';\n return false;\n };\n\n /* ------------------------------------------------------------------ filter helpers */\n\n const upsertFilterItems = (items: MGHGridFilterItem[]) => {\n let nextItems = filterModel.items.slice();\n items.forEach((item) => {\n const withId =\n item.id === undefined ? { ...item, id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}` } : item;\n const index = nextItems.findIndex((existing) => existing.id !== undefined && existing.id === withId.id);\n if (index === -1) nextItems.push(withId);\n else nextItems[index] = withId;\n });\n if (disableMultipleColumnsFiltering && nextItems.length > 1) nextItems = nextItems.slice(-1);\n setFilterModel({ ...filterModel, items: nextItems });\n };\n\n const deleteFilterItem = (item: MGHGridFilterItem) => {\n setFilterModel({\n ...filterModel,\n items: filterModel.items.filter((existing) =>\n item.id !== undefined ? existing.id !== item.id : existing !== item\n ),\n });\n };\n\n const showPreferences = (panel: 'columns' | 'filters', anchorEl?: HTMLElement | null, targetField?: string) => {\n setColumnMenu(null);\n setPreferencePanel({\n open: true,\n openedPanelValue: panel,\n targetField,\n anchorEl: anchorEl ?? toolbarRef.current ?? rootRef.current,\n });\n };\n\n const hidePreferences = React.useCallback(() => {\n setPreferencePanel((prev) => (prev.open ? { open: false, anchorEl: null } : prev));\n }, []);\n\n /* ------------------------------------------------------------------ editing */\n\n const isCellEditableFn = (params: MGHGridCellParams<R>) => {\n if (!params.colDef.editable) return false;\n if (params.rowNode.type !== 'leaf') return false;\n return isCellEditable ? isCellEditable(params) : true;\n };\n\n const startCellEditMode = (id: MGHGridRowId, field: string) => {\n const row = rowsById.get(id);\n const col = getColumn(field);\n if (!row || !col) return;\n const params = buildCellParams(id, field, row, nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null });\n if (!isCellEditableFn(params)) return;\n setEditingCell({ id, field });\n setEditValue(params.value);\n setFocusedCell({ id, field });\n };\n\n const applyRowUpdate = (id: MGHGridRowId, newRow: R, oldRow: R) => {\n if (processRowUpdate) {\n Promise.resolve()\n .then(() => processRowUpdate(newRow, oldRow, { rowId: id }))\n .then((result) => setRowOverride(id, (result ?? newRow) as R))\n .catch((error) => {\n if (onProcessRowUpdateError) onProcessRowUpdateError(error);\n else console.error('MGHGrid: processRowUpdate failed', error);\n });\n } else {\n setRowOverride(id, newRow);\n }\n };\n\n const stopCellEditMode = (\n id: MGHGridRowId,\n field: string,\n ignoreModifications = false,\n reason: 'enterKeyDown' | 'escapeKeyDown' | 'cellFocusOut' | 'tabKeyDown' | 'api' = 'api'\n ) => {\n if (!editingCell || editingCell.id !== id || editingCell.field !== field) return;\n const row = rowsById.get(id);\n const col = getColumn(field);\n setEditingCell(null);\n if (!row || !col) return;\n if (!ignoreModifications) {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const parsed = col.valueParser\n ? col.valueParser(editValue, row, col, apiRefLocal)\n : parseEditValue(editValue, col);\n const currentValue = getCellValue(row, col, apiRefLocal);\n if (!Object.is(parsed, currentValue)) {\n const newRow = col.valueSetter\n ? col.valueSetter(parsed, row, col, apiRefLocal)\n : ({ ...row, [field]: parsed } as R);\n applyRowUpdate(id, newRow, row);\n }\n }\n onCellEditStop?.({ id, field, row, reason }, getDetails());\n pendingFocusRef.current = true;\n setFocusedCell({ id, field });\n };\n\n /* ------------------------------------------------------------------ detail panel & grouping helpers */\n\n const toggleDetailPanel = (id: MGHGridRowId) => {\n setExpandedDetailPanels((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const setRowChildrenExpansion = (id: MGHGridRowId, isExpanded: boolean) => {\n setGroupExpansion((prev) => {\n const next = new Map(prev);\n next.set(id, isExpanded);\n return next;\n });\n };\n\n const groupingKey = groupingFields.join('|');\n const previousGroupingKey = React.useRef(groupingKey);\n React.useEffect(() => {\n if (previousGroupingKey.current === groupingKey) return;\n previousGroupingKey.current = groupingKey;\n setGroupExpansion(new Map());\n }, [groupingKey]);\n\n /* ------------------------------------------------------------------ cell params */\n\n const buildCellParams = (id: MGHGridRowId, field: string, row: R, node: MGHGridRowNode): MGHGridCellParams<R> => {\n const col = getColumn(field) as MGHGridColDef<R>;\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const value = getCellValue(row, col, apiRefLocal);\n const formattedValue = getFormattedValue(value, row, col, apiRefLocal, id);\n const hasFocus = Boolean(focusedCell && focusedCell.id === id && focusedCell.field === field);\n const cellMode = editingCell && editingCell.id === id && editingCell.field === field ? 'edit' : 'view';\n return {\n id,\n field,\n value,\n formattedValue,\n row,\n rowNode: node,\n colDef: col,\n api: apiRefLocal,\n hasFocus,\n tabIndex: hasFocus ? 0 : -1,\n cellMode,\n isEditable: Boolean(col.editable) && node.type === 'leaf',\n };\n };\n\n const buildRowParams = (id: MGHGridRowId, row: R): MGHGridRowParams<R> => ({\n id,\n row,\n columns: orderedUserColumns,\n api: latest.current.api,\n });\n\n /* ------------------------------------------------------------------ keyboard navigation */\n\n React.useEffect(() => {\n if (!pendingFocusRef.current || !focusedCell || !rootRef.current) return;\n pendingFocusRef.current = false;\n const selector = `[data-mgh-row-id=\"${String(focusedCell.id).replace(/\"/g, '\\\\\"')}\"] [data-mgh-field=\"${focusedCell.field.replace(/\"/g, '\\\\\"')}\"]`;\n const el = rootRef.current.querySelector<HTMLElement>(selector);\n if (el && document.activeElement !== el && !el.contains(document.activeElement)) el.focus({ preventScroll: true });\n }, [focusedCell, virtualRange.start, virtualRange.end]);\n\n const scrollToIndexes = (params: { rowIndex?: number; colIndex?: number }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return false;\n if (params.rowIndex !== undefined && virtual) {\n const index = clamp(params.rowIndex, 0, Math.max(pagedRows.length - 1, 0));\n const top = heights.offsets[index] ?? 0;\n const bottom = top + (heights.rowHeights[index] ?? rowHeight);\n const visibleTop = scroller.scrollTop;\n const visibleBottom = scroller.scrollTop + scroller.clientHeight - headerHeight;\n if (top < visibleTop) scroller.scrollTop = top;\n else if (bottom > visibleBottom) scroller.scrollTop = bottom - (scroller.clientHeight - headerHeight);\n } else if (params.rowIndex !== undefined) {\n const el = scroller.querySelector(`[data-mgh-row-index=\"${params.rowIndex}\"]`) as HTMLElement | null | undefined;\n el?.scrollIntoView?.({ block: 'nearest' });\n }\n if (params.colIndex !== undefined) {\n const lc = layout.columns[clamp(params.colIndex, 0, layout.columns.length - 1)];\n if (lc && !lc.pinned) {\n const leftPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'left')\n .reduce((acc, c) => acc + c.width, 0);\n const rightPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'right')\n .reduce((acc, c) => acc + c.width, 0);\n const visibleLeft = scroller.scrollLeft + leftPinnedWidth;\n const visibleRight = scroller.scrollLeft + scroller.clientWidth - rightPinnedWidth;\n if (lc.x < visibleLeft) scroller.scrollLeft = lc.x - leftPinnedWidth;\n else if (lc.x + lc.width > visibleRight)\n scroller.scrollLeft = lc.x + lc.width - scroller.clientWidth + rightPinnedWidth;\n }\n }\n return true;\n };\n\n const moveFocus = (\n rowDelta: number,\n colDelta: number,\n absolute?: { row?: 'first' | 'last'; col?: 'first' | 'last' }\n ) => {\n if (pagedRows.length === 0 || layout.columns.length === 0) return;\n let rowIndex = focusedCell ? pagedRows.findIndex((dr) => dr.id === focusedCell.id) : -1;\n let colIndex = focusedCell ? layout.columns.findIndex((lc) => lc.col.field === focusedCell.field) : -1;\n if (rowIndex === -1) rowIndex = 0;\n if (colIndex === -1) colIndex = 0;\n if (absolute?.row === 'first') rowIndex = 0;\n else if (absolute?.row === 'last') rowIndex = pagedRows.length - 1;\n else rowIndex = clamp(rowIndex + rowDelta, 0, pagedRows.length - 1);\n if (absolute?.col === 'first') colIndex = 0;\n else if (absolute?.col === 'last') colIndex = layout.columns.length - 1;\n else colIndex = clamp(colIndex + colDelta, 0, layout.columns.length - 1);\n const target = { id: pagedRows[rowIndex].id, field: layout.columns[colIndex].col.field };\n pendingFocusRef.current = true;\n setFocusedCell(target);\n scrollToIndexes({ rowIndex, colIndex });\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (editingCell) return;\n const target = event.target as HTMLElement;\n if (\n target &&\n (target.tagName === 'INPUT' ||\n target.tagName === 'SELECT' ||\n target.tagName === 'TEXTAREA' ||\n target.tagName === 'BUTTON')\n ) {\n return;\n }\n const pageRows = Math.max(1, Math.floor(Math.max(viewportHeight - headerHeight, rowHeight) / rowHeight));\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1, 0);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1, 0);\n break;\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(0, -1);\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(0, 1);\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(pageRows, 0);\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(-pageRows, 0);\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'first', col: 'first' } : { col: 'first' });\n break;\n case 'End':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'last', col: 'last' } : { col: 'last' });\n break;\n case 'Enter':\n case 'F2':\n if (focusedCell) {\n const node = nodesById.get(focusedCell.id);\n if (node?.type === 'group' && focusedCell.field === GROUPING_COLUMN_FIELD) {\n const group = groupsById.get(focusedCell.id);\n if (group) setRowChildrenExpansion(group.id, !isGroupExpanded(group));\n } else {\n event.preventDefault();\n startCellEditMode(focusedCell.id, focusedCell.field);\n }\n }\n break;\n case ' ':\n if (focusedCell && (checkboxSelection || !disableRowSelectionOnClick)) {\n const dr = pagedRows.find((r) => r.id === focusedCell.id);\n if (dr && dr.type === 'leaf' && dr.row) {\n event.preventDefault();\n selectRows([dr.id], !selectedIds.has(dr.id), false);\n }\n }\n break;\n case 'Escape':\n if (preferencePanel.open) hidePreferences();\n if (columnMenu) setColumnMenu(null);\n break;\n default:\n if (\n (event.ctrlKey || event.metaKey) &&\n event.key.toLowerCase() === 'a' &&\n checkboxSelection &&\n !disableMultipleRowSelection\n ) {\n event.preventDefault();\n selectRows(selectionCandidates, true);\n }\n }\n };\n\n /* ------------------------------------------------------------------ drag & drop (reorder) */\n\n const canReorder = (col: MGHGridColDef) => !disableColumnReorder && !col.disableReorder && !isInternalField(col.field);\n\n const handleDrop = (targetLc: ColumnLayout, event: React.DragEvent) => {\n event.preventDefault();\n const current = drag;\n setDrag(null);\n if (!current || current.field === targetLc.col.field) return;\n const sourceLc = layout.columns.find((lc) => lc.col.field === current.field);\n if (!sourceLc || sourceLc.pinned !== targetLc.pinned || !canReorder(targetLc.col)) return;\n const side = current.side;\n if (sourceLc.pinned) {\n const key = sourceLc.pinned;\n const list = (pinnedColumns[key] ?? []).slice();\n const from = list.indexOf(current.field);\n let to = list.indexOf(targetLc.col.field);\n if (from === -1 || to === -1) return;\n list.splice(from, 1);\n to = list.indexOf(targetLc.col.field);\n list.splice(side === 'right' ? to + 1 : to, 0, current.field);\n setPinnedColumns({ ...pinnedColumns, [key]: list });\n return;\n }\n const fields = orderedUserColumns.map((c) => c.field);\n const from = fields.indexOf(current.field);\n const without = fields.filter((f) => f !== current.field);\n let to = without.indexOf(targetLc.col.field);\n if (side === 'right') to += 1;\n without.splice(to, 0, current.field);\n setOrderedFields(without);\n persistOrder(without);\n const col = columnsByField.get(current.field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex: to, oldIndex: from }, event, getDetails());\n };\n\n /* ------------------------------------------------------------------ resize */\n\n const resizeRef = React.useRef<{\n field: string;\n startX: number;\n startWidth: number;\n lastWidth: number;\n min: number;\n max: number;\n } | null>(null);\n\n const handleResizeStart = (lc: ColumnLayout, event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n resizeRef.current = {\n field: lc.col.field,\n startX: event.clientX,\n startWidth: lc.width,\n lastWidth: lc.width,\n min: lc.col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,\n max: lc.col.maxWidth ?? Infinity,\n };\n setResizingField(lc.col.field);\n const onMove = (e: PointerEvent) => {\n const r = resizeRef.current;\n if (!r) return;\n const width = clamp(r.startWidth + (e.clientX - r.startX), r.min, r.max);\n r.lastWidth = width;\n setColumnWidths((prev) => (prev[r.field] === width ? prev : { ...prev, [r.field]: width }));\n };\n const onUp = () => {\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n const r = resizeRef.current;\n resizeRef.current = null;\n setResizingField(null);\n if (!r) return;\n const next = { ...(latest.current.columnWidths as Record<string, number>), [r.field]: r.lastWidth };\n setColumnWidths(next);\n persistWidths(next);\n const col = latest.current.getColumn(r.field);\n if (col && r.lastWidth !== r.startWidth)\n onColumnWidthChange?.({ colDef: col, width: r.lastWidth }, getDetails());\n };\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n };\n\n /* ------------------------------------------------------------------ state snapshot & API */\n\n const filterCount = activeFilters.length;\n const rowCount = groupingActive ? totalDisplayRows : filteredEntries.length;\n\n const state = React.useMemo<MGHGridState>(\n () => ({\n sortModel,\n filterModel,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n pageCount,\n rowCount,\n totalRowCount: rowEntries.length,\n columnVisibilityModel,\n orderedFields: orderedUserColumns.map((c) => c.field),\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n rowSelectionModel: { type: 'include', ids: selectedIds },\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel: {\n open: preferencePanel.open,\n openedPanelValue: preferencePanel.openedPanelValue,\n targetField: preferencePanel.targetField,\n },\n filterCount,\n quickFilterValues,\n }),\n [\n sortModel,\n filterModel,\n page,\n paginationModel.pageSize,\n pageCount,\n rowCount,\n rowEntries.length,\n columnVisibilityModel,\n orderedUserColumns,\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n selectedIds,\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel.open,\n preferencePanel.openedPanelValue,\n preferencePanel.targetField,\n filterCount,\n quickFilterValues,\n ]\n );\n\n latest.current = {\n api: apiObject,\n state,\n rowsById,\n rowEntries,\n nodesById,\n groupsById,\n sortedLeaves,\n pagedRows,\n getRowId,\n setRowOverride,\n orderedUserColumns,\n visibleUserColumns,\n getColumn,\n columnVisibilityModel,\n setColumnVisibilityModel,\n setColumnWidth,\n setColumnIndex,\n columnWidths,\n autosizeColumns,\n pinColumn,\n unpinColumn,\n isColumnPinned,\n pinnedColumns,\n setPinnedColumns,\n sortModel,\n setSortModel,\n sortColumn,\n filterModel,\n setFilterModel,\n upsertFilterItems,\n deleteFilterItem,\n showPreferences,\n hidePreferences,\n selectedIds,\n setSelectedIds,\n selectRows,\n isRowSelectableFn,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n setPaginationModel,\n setDensity,\n toggleDetailPanel,\n expandedDetailPanels,\n setExpandedDetailPanels,\n rowGroupingModel,\n setRowGroupingModel,\n setRowChildrenExpansion,\n aggregationModel,\n setAggregationModel,\n startCellEditMode,\n stopCellEditMode,\n editingCell,\n setEditValue,\n buildCellParams,\n setFocusedCell,\n scrollToIndexes,\n forceUpdate,\n virtual,\n };\n\n if (apiRef) apiRef.current = apiObject;\n\n React.useEffect(() => {\n onStateChange?.(state, { api: apiObject });\n }, [state, onStateChange, apiObject]);\n\n /* ------------------------------------------------------------------ context */\n\n const rootProps = React.useMemo<MGHGridRootProps>(\n () => ({\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n }),\n [\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n ]\n );\n\n const contextValue = React.useMemo<MGHGridContextValue>(\n () => ({\n api: apiObject,\n state,\n localeText,\n themeMode,\n rootProps,\n columns: orderedUserColumns,\n visibleColumns: visibleUserColumns,\n }),\n [apiObject, state, localeText, themeMode, rootProps, orderedUserColumns, visibleUserColumns]\n );\n\n /* ------------------------------------------------------------------ rendering: cells */\n\n const renderEditor = (params: MGHGridCellParams<R>) => {\n const col = params.colDef;\n const commit = (reason: 'enterKeyDown' | 'cellFocusOut' | 'tabKeyDown') =>\n stopCellEditMode(params.id, params.field, false, reason);\n const cancel = () => stopCellEditMode(params.id, params.field, true, 'escapeKeyDown');\n const keyHandler = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n commit('enterKeyDown');\n } else if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n cancel();\n } else if (event.key === 'Tab') {\n commit('tabKeyDown');\n } else {\n event.stopPropagation();\n }\n };\n if (col.renderEditCell) {\n return col.renderEditCell({\n ...params,\n editValue,\n onValueChange: setEditValue,\n commit: () => commit('enterKeyDown'),\n cancel,\n });\n }\n const common = {\n autoFocus: true,\n onKeyDown: keyHandler,\n onBlur: () => commit('cellFocusOut'),\n onClick: (event: React.MouseEvent) => event.stopPropagation(),\n };\n switch (col.type) {\n case 'boolean':\n return (\n <Checkbox\n {...common}\n checked={Boolean(editValue)}\n onChange={(event) => setEditValue(event.target.checked)}\n />\n );\n case 'singleSelect': {\n const options = resolveValueOptions(col, params.row, params.id);\n return (\n <Select\n {...common}\n size=\"small\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(col, o)) === event.target.value);\n setEditValue(match !== undefined ? getOptionValue(col, match) : event.target.value);\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(col, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(col, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'number':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"number\"\n value={editValue === undefined || editValue === null ? '' : editValue}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n case 'date':\n case 'dateTime':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type={col.type === 'date' ? 'date' : 'datetime-local'}\n value={\n typeof editValue === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(editValue)\n ? editValue\n : toDateInputValue(editValue, col.type === 'dateTime')\n }\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n default:\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"text\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n }\n };\n\n const renderCellContent = (lc: ColumnLayout, renderRow: RenderRow<R>): React.ReactNode => {\n const { col } = lc;\n const field = col.field;\n\n if (field === CHECKBOX_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const selectedCount = leafIds.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0);\n return (\n <Checkbox\n checked={leafIds.length > 0 && selectedCount === leafIds.length}\n indeterminate={selectedCount > 0 && selectedCount < leafIds.length}\n label={localeText.checkboxSelectionSelectRow}\n onClick={(event) => event.stopPropagation()}\n onChange={() => selectRows(leafIds, selectedCount !== leafIds.length, false)}\n />\n );\n }\n if (renderRow.kind !== 'leaf') return null;\n const selectable = isRowSelectableFn(renderRow.id, renderRow.row);\n const checked = selectedIds.has(renderRow.id);\n return (\n <Checkbox\n checked={checked}\n disabled={!selectable}\n label={checked ? localeText.checkboxSelectionUnselectRow : localeText.checkboxSelectionSelectRow}\n tabIndex={-1}\n onClick={(event) => event.stopPropagation()}\n onChange={() => {\n lastClickedIdRef.current = renderRow.id;\n selectRows([renderRow.id], !checked, disableMultipleRowSelection);\n }}\n />\n );\n }\n\n if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n if (renderRow.kind !== 'leaf' || !renderRow.row) return null;\n const expanded = expandedDetailPanels.has(renderRow.id);\n const content = getDetailPanelContent?.(buildRowParams(renderRow.id, renderRow.row));\n if (content === null || content === undefined || content === false) return null;\n return (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-detail-toggle', expanded && 'mgh-grid-detail-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n toggleDetailPanel(renderRow.id);\n }}\n >\n <ExpandMoreIcon />\n </IconButton>\n );\n }\n\n if (field === GROUPING_COLUMN_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const group = renderRow.group;\n const expanded = isGroupExpanded(group);\n const hideCount = (groupingColDef as any)?.hideDescendantCount;\n return (\n <div className=\"mgh-grid-group-cell\" style={{ paddingLeft: renderRow.depth * 20 }}>\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-group-toggle', expanded && 'mgh-grid-group-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setRowChildrenExpansion(group.id, !expanded);\n }}\n >\n <ChevronRightIcon />\n </IconButton>\n <span className=\"mgh-grid-group-label\" title={group.groupingLabel}>\n {group.groupingLabel}\n </span>\n {!hideCount && <span className=\"mgh-grid-group-count\">({group.descendants.length})</span>}\n </div>\n );\n }\n return null;\n }\n\n if (renderRow.kind === 'group' || renderRow.kind === 'footer') {\n const agg = renderRow.aggregates?.[field];\n if (!agg || isNil(agg.value)) return null;\n const fn = aggregationFunctions[agg.fn];\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sampleRow = (renderRow.group?.descendants[0]?.row ?? latest.current.sortedLeaves[0]?.row ?? {}) as R;\n const formatted = fn?.valueFormatter\n ? fn.valueFormatter(agg.value)\n : col.valueFormatter\n ? col.valueFormatter(agg.value, sampleRow, col as MGHGridColDef<R>, apiRefLocal)\n : defaultFormatValue(agg.value, col);\n return (\n <>\n <span className=\"mgh-grid-aggregation-label\">{fn?.label ?? agg.fn}</span>\n <span className=\"mgh-grid-cell-text\">{formattedValueToString(formatted)}</span>\n </>\n );\n }\n\n if (!renderRow.row) return null;\n const params = buildCellParams(renderRow.id, field, renderRow.row, renderRow.node);\n\n if (params.cellMode === 'edit') return renderEditor(params);\n\n if (col.renderCell) return col.renderCell(params);\n\n if (col.type === 'actions') {\n const actions = col.getActions ? col.getActions(buildRowParams(renderRow.id, renderRow.row)) : [];\n return <ActionsCell actions={actions} themeMode={themeMode} moreLabel={localeText.actionsCellMore} />;\n }\n\n if (col.type === 'boolean') {\n if (isNil(params.value)) return null;\n return params.value ? (\n <CheckIcon aria-label={localeText.booleanCellTrueLabel} />\n ) : (\n <CloseIcon aria-label={localeText.booleanCellFalseLabel} />\n );\n }\n\n const formatted = params.formattedValue;\n if (formatted === null || formatted === undefined) return null;\n if (React.isValidElement(formatted)) return formatted;\n const text = formattedValueToString(formatted);\n return (\n <span className=\"mgh-grid-cell-text\" title={text.length > 20 ? text : undefined}>\n {text}\n </span>\n );\n };\n\n const cellStyle = (lc: ColumnLayout): React.CSSProperties => ({\n width: lc.width,\n minWidth: lc.width,\n maxWidth: lc.width,\n left: lc.pinned === 'left' ? lc.offset : undefined,\n right: lc.pinned === 'right' ? lc.offset : undefined,\n });\n\n const pinnedClasses = (lc: ColumnLayout, prefix: string) =>\n cx(\n lc.pinned === 'left' && `${prefix}--pinned-left`,\n lc.pinned === 'right' && `${prefix}--pinned-right`,\n lc.isLastLeft && layout.hasPinning && `${prefix}--pinned-left-last`,\n lc.isFirstRight && `${prefix}--pinned-right-first`\n );\n\n const renderCell = (lc: ColumnLayout, renderRow: RenderRow<R>, isAutoRow: boolean) => {\n const { col } = lc;\n const field = col.field;\n const isFocused = Boolean(focusedCell && focusedCell.id === renderRow.id && focusedCell.field === field);\n const isEditing = Boolean(editingCell && editingCell.id === renderRow.id && editingCell.field === field);\n const isAggregation =\n (renderRow.kind === 'group' || renderRow.kind === 'footer') && Boolean(renderRow.aggregates?.[field]);\n const params =\n renderRow.kind === 'leaf' && renderRow.row\n ? buildCellParams(renderRow.id, field, renderRow.row, renderRow.node)\n : null;\n const editable = params ? isCellEditableFn(params) : false;\n const customClass =\n params && col.cellClassName\n ? typeof col.cellClassName === 'function'\n ? col.cellClassName(params)\n : col.cellClassName\n : undefined;\n const isCheckbox = field === CHECKBOX_FIELD;\n const isDetailToggle = field === DETAIL_PANEL_TOGGLE_FIELD;\n return (\n <div\n key={field}\n role=\"gridcell\"\n data-mgh-field={field}\n data-mgh-colindex={layout.columns.indexOf(lc)}\n tabIndex={isFocused ? 0 : -1}\n aria-selected={renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : undefined}\n className={cx(\n 'mgh-grid-cell',\n `mgh-grid-cell--align-${col.align ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-cell'),\n isFocused && !isEditing && 'mgh-grid-cell--focused',\n isEditing && 'mgh-grid-cell--editing',\n editable && !isEditing && 'mgh-grid-cell--editable',\n col.type === 'boolean' && 'mgh-grid-cell--boolean',\n col.type === 'actions' && 'mgh-grid-cell--actions',\n isCheckbox && 'mgh-grid-cell--checkbox',\n isDetailToggle && 'mgh-grid-cell--detail-toggle',\n isAggregation && 'mgh-grid-cell--aggregation',\n customClass\n )}\n style={cellStyle(lc)}\n onMouseDown={() => {\n if (renderRow.kind === 'leaf' || renderRow.kind === 'group') {\n if (!isFocused) setFocusedCell({ id: renderRow.id, field });\n }\n }}\n onClick={(event) => {\n if (params && onCellClick) onCellClick(params, event, getDetails());\n }}\n onDoubleClick={(event) => {\n if (params) {\n onCellDoubleClick?.(params, event, getDetails());\n if (editable && !isEditing) {\n event.stopPropagation();\n startCellEditMode(renderRow.id, field);\n }\n }\n }}\n >\n {renderCellContent(lc, renderRow)}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: rows */\n\n const rowIsClickable = Boolean(onRowClick || onRowDoubleClick || !disableRowSelectionOnClick);\n\n const renderRowElement = (\n renderRow: RenderRow<R>,\n options: { height?: number; index: number; isFirst: boolean; isLast: boolean; isAuto: boolean }\n ) => {\n const isSelected = renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : false;\n const customClass =\n renderRow.kind === 'leaf' && renderRow.row && getRowClassName\n ? getRowClassName({\n ...buildRowParams(renderRow.id, renderRow.row),\n indexRelativeToCurrentPage: options.index,\n isFirstVisible: options.isFirst,\n isLastVisible: options.isLast,\n rowNode: renderRow.node,\n })\n : undefined;\n return (\n <div\n role=\"row\"\n aria-rowindex={options.index + 2}\n aria-selected={renderRow.kind === 'leaf' ? isSelected : undefined}\n data-mgh-row-id={String(renderRow.id)}\n data-mgh-row-index={options.index}\n className={cx(\n 'mgh-grid-row',\n isSelected && 'mgh-grid-row--selected',\n rowIsClickable && renderRow.kind === 'leaf' && 'mgh-grid-row--clickable',\n renderRow.kind === 'group' && 'mgh-grid-row--group',\n renderRow.kind === 'pinnedRow' && 'mgh-grid-row--pinned',\n renderRow.kind === 'footer' && 'mgh-grid-row--footer',\n options.isAuto && 'mgh-grid-row--auto-height',\n customClass\n )}\n style={{\n width: layout.totalWidth,\n height: options.isAuto ? undefined : options.height,\n minHeight: options.isAuto ? rowHeight : undefined,\n }}\n onClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n if (!disableRowSelectionOnClick) handleRowSelectionClick(renderRow, event);\n onRowClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n } else if (renderRow.kind === 'group' && renderRow.group) {\n setRowChildrenExpansion(renderRow.group.id, !isGroupExpanded(renderRow.group));\n }\n }}\n onDoubleClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n onRowDoubleClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n }\n }}\n >\n {layout.columns.map((lc) => renderCell(lc, renderRow, options.isAuto))}\n <div className=\"mgh-grid-row-filler\" />\n </div>\n );\n };\n\n const toRenderRow = (dr: DisplayRow<R>): RenderRow<R> => ({\n id: dr.id,\n kind: dr.type,\n row: dr.row,\n node: dr.node,\n depth: dr.depth,\n group: dr.group,\n aggregates: dr.type === 'group' && dr.group ? getGroupAggregates(dr.group) : undefined,\n });\n\n const renderBodyRows = () => {\n const { start, end } = virtualRange;\n const items: React.ReactNode[] = [];\n for (let i = start; i < end; i += 1) {\n const dr = pagedRows[i];\n const renderRow = toRenderRow(dr);\n const detailHeight = heights.detailHeights[i];\n const isExpanded =\n dr.type === 'leaf' && Boolean(dr.row) && Boolean(getDetailPanelContent) && expandedDetailPanels.has(dr.id);\n const detailContent = isExpanded && dr.row ? getDetailPanelContent?.(buildRowParams(dr.id, dr.row)) : null;\n const detailAuto =\n isExpanded && dr.row && getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row }) === 'auto'\n : false;\n const rowAuto =\n !virtual &&\n (getRowHeight && dr.type === 'leaf' && dr.row\n ? getRowHeight({ id: dr.id, model: dr.row, densityFactor }) === 'auto'\n : false);\n items.push(\n <div\n key={String(dr.id)}\n className=\"mgh-grid-row-block\"\n style={virtual ? { top: heights.offsets[i], width: layout.totalWidth } : { width: layout.totalWidth }}\n >\n {renderRowElement(renderRow, {\n height: heights.rowHeights[i],\n index: i,\n isFirst: i === 0,\n isLast: i === pagedRows.length - 1,\n isAuto: rowAuto,\n })}\n {isExpanded && detailContent !== null && detailContent !== undefined && detailContent !== false && (\n <div\n className=\"mgh-grid-detail-panel\"\n style={{\n height: detailAuto ? undefined : detailHeight || undefined,\n width: viewportWidth || undefined,\n }}\n onClick={(event) => event.stopPropagation()}\n >\n {detailContent}\n </div>\n )}\n </div>\n );\n }\n return items;\n };\n\n const renderPinnedRows = (list: R[] | undefined, position: 'top' | 'bottom') => {\n const items: React.ReactNode[] = [];\n (list ?? []).forEach((row, index) => {\n const id = getRowIdFromRow(row, getRowId);\n const renderRow: RenderRow<R> = {\n id,\n kind: 'pinnedRow',\n row,\n node: { type: 'pinnedRow', id, depth: 0, parent: null, position },\n depth: 0,\n };\n items.push(\n <React.Fragment key={String(id)}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: index,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n });\n if (position === 'bottom' && footerAggregates) {\n const renderRow: RenderRow<R> = {\n id: AGGREGATION_FOOTER_ID,\n kind: 'footer',\n row: null,\n node: { type: 'footer', id: AGGREGATION_FOOTER_ID, depth: 0, parent: null },\n depth: 0,\n aggregates: footerAggregates,\n };\n items.push(\n <React.Fragment key={AGGREGATION_FOOTER_ID}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: 0,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n }\n return items;\n };\n\n /* ------------------------------------------------------------------ rendering: header */\n\n const renderHeaderCell = (lc: ColumnLayout, index: number) => {\n const { col } = lc;\n const field = col.field;\n const sortIndex = sortModel.findIndex((item) => item.field === field && item.sort);\n const sortItem = sortIndex !== -1 ? sortModel[sortIndex] : undefined;\n const sortable =\n (col.sortable !== false && !disableColumnSorting && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && col.sortable !== false);\n const showMenu =\n (!disableColumnMenu && !col.disableColumnMenu && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnMenu);\n const resizable =\n (!disableColumnResize && col.resizable !== false && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnResize);\n const draggable = canReorder(col);\n const isDragging = drag?.field === field;\n const isDropTarget = drag && drag.overField === field && drag.field !== field;\n const menuOpen = columnMenu?.field === field;\n const headerParams = { field, colDef: col as MGHGridColDef<R>, api: apiObject };\n const customClass = col.headerClassName\n ? typeof col.headerClassName === 'function'\n ? col.headerClassName(headerParams)\n : col.headerClassName\n : undefined;\n\n let content: React.ReactNode;\n if (field === CHECKBOX_FIELD) {\n content = disableMultipleRowSelection ? null : (\n <Checkbox\n checked={allCandidatesSelected}\n indeterminate={someCandidatesSelected}\n disabled={selectionCandidates.length === 0}\n label={\n allCandidatesSelected\n ? localeText.checkboxSelectionUnselectAllRows\n : localeText.checkboxSelectionSelectAllRows\n }\n onChange={toggleAllCandidates}\n onClick={(event) => event.stopPropagation()}\n />\n );\n } else if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n content = null;\n } else {\n content = col.renderHeader ? (\n col.renderHeader(headerParams)\n ) : (\n <span className=\"mgh-grid-header-title\">{col.headerName ?? field}</span>\n );\n }\n\n return (\n <div\n key={field}\n role=\"columnheader\"\n aria-colindex={index + 1}\n aria-sort={sortItem ? (sortItem.sort === 'asc' ? 'ascending' : 'descending') : sortable ? 'none' : undefined}\n data-mgh-field={field}\n title={col.description}\n tabIndex={-1}\n draggable={draggable}\n className={cx(\n 'mgh-grid-header-cell',\n `mgh-grid-header-cell--align-${col.headerAlign ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-header-cell'),\n sortable && 'mgh-grid-header-cell--sortable',\n field === CHECKBOX_FIELD && 'mgh-grid-header-cell--checkbox',\n field === DETAIL_PANEL_TOGGLE_FIELD && 'mgh-grid-header-cell--detail-toggle',\n index === layout.columns.length - 1 && 'mgh-grid-header-cell--last',\n isDragging && 'mgh-grid-header-cell--dragging',\n isDropTarget && drag?.side === 'left' && 'mgh-grid-header-cell--drop-left',\n isDropTarget && drag?.side === 'right' && 'mgh-grid-header-cell--drop-right',\n menuOpen && 'mgh-grid-header-cell--menu-open',\n customClass\n )}\n style={cellStyle(lc)}\n onClick={(event) => {\n if (!sortable || resizingField) return;\n sortColumn(field, undefined, event.shiftKey);\n }}\n onDragStart={(event) => {\n if (!draggable) return;\n event.dataTransfer.effectAllowed = 'move';\n try {\n event.dataTransfer.setData('text/plain', field);\n } catch {\n /* ignore */\n }\n setDrag({ field, overField: null, side: 'left' });\n }}\n onDragOver={(event) => {\n if (!drag || drag.field === field) return;\n const sourceLc = layout.columns.find((c) => c.col.field === drag.field);\n if (!sourceLc || sourceLc.pinned !== lc.pinned || !canReorder(col)) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = 'move';\n const rect = event.currentTarget.getBoundingClientRect();\n const side = event.clientX < rect.left + rect.width / 2 ? 'left' : 'right';\n if (drag.overField !== field || drag.side !== side) setDrag({ ...drag, overField: field, side });\n }}\n onDragLeave={() => {\n if (drag && drag.overField === field) setDrag({ ...drag, overField: null });\n }}\n onDrop={(event) => handleDrop(lc, event)}\n onDragEnd={() => setDrag(null)}\n >\n <div className=\"mgh-grid-header-title-container\">\n {content}\n {sortable && (\n <span\n className={cx('mgh-grid-sort-icon', sortItem && 'mgh-grid-sort-icon--active')}\n aria-hidden=\"true\"\n >\n {sortItem?.sort === 'desc' ? <ArrowDownwardIcon size={18} /> : <ArrowUpwardIcon size={18} />}\n {sortItem && sortModel.filter((s) => s.sort).length > 1 && (\n <span className=\"mgh-grid-sort-index\">{sortIndex + 1}</span>\n )}\n </span>\n )}\n </div>\n {showMenu && (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-header-menu-btn', menuOpen && 'mgh-grid-header-menu-btn--open')}\n label={localeText.columnMenuLabel}\n aria-haspopup=\"menu\"\n aria-expanded={menuOpen}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setColumnMenu((prev) =>\n prev?.field === field ? null : { field, anchorEl: event.currentTarget }\n );\n }}\n onMouseDown={(event) => event.stopPropagation()}\n >\n <MoreVertIcon />\n </IconButton>\n )}\n {resizable && (\n <div\n className={cx('mgh-grid-resize-handle', resizingField === field && 'mgh-grid-resize-handle--active')}\n role=\"separator\"\n aria-orientation=\"vertical\"\n onPointerDown={(event) => handleResizeStart(lc, event)}\n onClick={(event) => event.stopPropagation()}\n onDoubleClick={(event) => {\n event.stopPropagation();\n autosizeColumns({ columns: [field] });\n }}\n draggable={false}\n onDragStart={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n />\n )}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: slots */\n\n const ToolbarSlot = slots.toolbar === null ? null : (slots.toolbar ?? MGHGridToolbar);\n const FooterSlot = slots.footer === null ? null : (slots.footer ?? MGHGridFooter);\n const NoRowsOverlaySlot = slots.noRowsOverlay ?? MGHGridNoRowsOverlay;\n const LoadingOverlaySlot = slots.loadingOverlay ?? MGHGridLoadingOverlay;\n const mergedToolbarProps = { ...toolbarProps, ...slotProps.toolbar };\n const noRowsProps = { text: noRowsText, ...slotProps.noRowsOverlay };\n const loadingProps = { ...slotProps.loadingOverlay };\n\n const showNoRows = !loading && pagedRows.length === 0;\n const menuColumn = columnMenu ? getColumn(columnMenu.field) : undefined;\n\n const cardStyles: React.CSSProperties = {\n height: 'auto',\n flexGrow: 1,\n ...sanitizeStyle(cardSx),\n ...sanitizeStyle(cardStyle),\n ...(themeVars as any),\n };\n const boxStyles: React.CSSProperties = { flexGrow: 1, ...sanitizeStyle(boxSx), ...sanitizeStyle(boxStyle) };\n const rootStyles: React.CSSProperties = {\n ...sanitizeStyle(sx),\n ...sanitizeStyle(style),\n ['--mgh-grid-header-height' as any]: `${headerHeight}px`,\n ['--mgh-grid-row-height' as any]: `${rowHeight}px`,\n };\n\n // Nested selectors from sx/style props become a <style> block scoped to this grid instance.\n const scopedCss = React.useMemo(() => {\n const css: string[] = [];\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, sx, css);\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, style, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardSx, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardStyle, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxSx, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxStyle, css);\n return css.join('\\n');\n }, [gridId, sx, style, cardSx, cardStyle, boxSx, boxStyle]);\n\n const smDown = viewportWidth > 0 && viewportWidth < 600;\n\n const grid = (\n <div\n ref={rootRef}\n id={gridId}\n data-mgh-grid-id={gridId}\n role=\"grid\"\n aria-rowcount={rowCount + 1}\n aria-colcount={layout.columns.length}\n aria-multiselectable={checkboxSelection && !disableMultipleRowSelection ? true : undefined}\n aria-busy={loading || undefined}\n className={cx(\n 'mgh-grid',\n autoHeight && 'mgh-grid--auto-height',\n !layout.hasPinning && 'mgh-grid--no-pinned-shadow',\n className\n )}\n style={rootStyles}\n onKeyDown={handleKeyDown}\n >\n {showToolbar && ToolbarSlot && (\n <div ref={toolbarRef}>\n <ToolbarSlot {...mergedToolbarProps} />\n </div>\n )}\n <div className=\"mgh-grid-main\">\n <div ref={scrollerRef} className=\"mgh-grid-scroller\" onScroll={handleScroll} tabIndex={-1}>\n <div className=\"mgh-grid-columns\" role=\"rowgroup\" style={{ width: layout.totalWidth }}>\n <div className=\"mgh-grid-header-row\" role=\"row\" aria-rowindex={1} style={{ height: headerHeight }}>\n {layout.columns.map((lc, index) => renderHeaderCell(lc, index))}\n <div className=\"mgh-grid-header-filler\" />\n </div>\n </div>\n {pinnedRows?.top && pinnedRows.top.length > 0 && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--top\"\n role=\"rowgroup\"\n style={{ top: headerHeight, width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows.top, 'top')}\n </div>\n )}\n <div\n className={cx('mgh-grid-body', virtual ? 'mgh-grid-body--virtual' : 'mgh-grid-body--flow')}\n role=\"rowgroup\"\n style={\n virtual\n ? { height: heights.total, width: layout.totalWidth }\n : { width: layout.totalWidth, minHeight: showNoRows || loading ? 120 : undefined }\n }\n >\n {renderBodyRows()}\n </div>\n {((pinnedRows?.bottom && pinnedRows.bottom.length > 0) || footerAggregates) && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--bottom\"\n role=\"rowgroup\"\n style={{ width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows?.bottom, 'bottom')}\n </div>\n )}\n </div>\n {loading && (\n <div className=\"mgh-grid-overlay mgh-grid-overlay--loading\" style={{ top: headerHeight }}>\n <LoadingOverlaySlot {...loadingProps} />\n </div>\n )}\n {showNoRows && (\n <div className=\"mgh-grid-overlay\" style={{ top: headerHeight }}>\n <NoRowsOverlaySlot {...noRowsProps} />\n </div>\n )}\n </div>\n {!hideFooter && FooterSlot && <FooterSlot {...slotProps.footer} />}\n\n <Popover\n open={preferencePanel.open}\n anchorEl={preferencePanel.anchorEl}\n onClose={hidePreferences}\n themeMode={themeMode}\n placement=\"bottom-start\"\n autoFocus\n >\n {preferencePanel.openedPanelValue === 'columns' ? <MGHGridColumnsPanel /> : <MGHGridFilterPanel />}\n </Popover>\n\n {menuColumn && columnMenu && (\n <MGHGridColumnMenu\n column={menuColumn}\n anchorEl={columnMenu.anchorEl}\n open\n onClose={() => setColumnMenu(null)}\n themeMode={themeMode}\n panelAnchorEl={toolbarRef.current}\n />\n )}\n </div>\n );\n\n return (\n <MGHGridContext.Provider value={contextValue}>\n <div\n className={cx('mgh-grid-card', disableCard && 'mgh-grid-card--plain', cardClassName)}\n data-mgh-theme={themeMode}\n data-mgh-grid-card={gridId}\n style={cardStyles}\n >\n {scopedCss && <style data-mgh-grid-sx={gridId}>{scopedCss}</style>}\n {!disableCard && (header !== undefined || renderHeaderCenterContent || renderHeaderEndContent) && (\n <div className=\"mgh-grid-card-header\">\n {header !== undefined && <h3 className=\"mgh-grid-card-title\">{header}</h3>}\n {renderHeaderCenterContent && (\n <div className=\"mgh-grid-card-header-center\">{renderHeaderCenterContent}</div>\n )}\n <div className=\"mgh-grid-card-header-end\" style={{ gap: smDown ? 8 : 16 }}>\n {renderHeaderEndContent}\n </div>\n </div>\n )}\n <div className={cx('mgh-grid-box', boxClassName)} data-mgh-grid-box={gridId} style={boxStyles}>\n {grid}\n </div>\n </div>\n </MGHGridContext.Provider>\n );\n}\n\nMGHGrid.displayName = 'MGHGrid';\n"],"names":["useResponsive","query","start","end","theme","useTheme","mediaUp","useMediaQuery","breakpoints","up","mediaDown","down","mediaBetween","between","mediaOnly","only","CustomNoRowsOverlay","text","useSettingsContext","themeMode","palette","mode","StyledGridOverlay","styled","display","alignItems","justifyContent","height","fill","fillOpacity","React","createElement","Box","component","alt","src","sx","width","maxWidth","mb","canUseLocalStorage","window","localStorage","readLocalStorage","key","value","getItem","JSON","parse","writeLocalStorage","setItem","stringify","MGHDataGrid","header","rows","columns","onRowClick","onRowDoubleClick","pagination","pageSize","slots","slotProps","toolbarProps","initialState","pageSizeOptions","cardSx","flexGrow","boxSx","columnVisibilityModel","onColumnVisibilityModelChange","columnVisibilityStorageKey","columnOrderStorageKey","disableDensitySelector","disableRowSelectionOnClick","disableColumnFilter","disableColumnMenu","disableColumnSelector","checkboxSelectionVisibleOnly","renderHeaderEndContent","renderHeaderCenterContent","noRowsText","checkboxSelection","onRowSelectionModelChange","rowSelectionModel","getRowClassName","getDetailPanelContent","getDetailPanelHeight","loading","isRowSelectable","getRowHeight","showToolbar","hideFooterRowCount","onColumnOrderChange","defaultGroupingExpansionDepth","pinnedRows","keepNonExistentRowsSelected","smDown","persistedColumnVisibilityModel","useMemo","undefined","persistedOrderedFields","normalizeOrderedFields","orderedFields","length","columnFields","Set","map","column","field","filter","has","resolvedColumnVisibilityModel","handleColumnVisibilityModelChange","useCallback","model","details","handleColumnOrderChange","params","event","api","getAllColumns","mergedInitialState","density","paginationModel","filterModel","items","quickFilterExcludeHiddenColumns","Card","pr","CardHeader","title","gap","flexWrap","flexDirection","DataGridPremium","noRowsOverlay","toolbar","MGHGridToolbar","cursor","disableRowSelectionExcludeModel","showColumnsButton","showFilterButton","showExportButton","showQuickFilter","renderOtherButtons","renderDateRange","customMenuItem","showCsvOption","Toolbar","style","Tooltip","ColumnsPanelTrigger","render","ToolbarButton","GridViewColumnIcon","fontSize","FilterPanelTrigger","props","state","color","Badge","badgeContent","filterCount","variant","GridFilterListIcon","CustomGridToolbarExport","DataGridQuickFilter","csvOptions","allColumns","excelOptions","printOptions","other","GridToolbarExportContainer","el","GridCsvExportMenuItem","options","GridExcelExportMenuItem","GridPrintExportMenuItem","StyledQuickFilter","QuickFilter","StyledToolbarButton","ownerState","gridArea","zIndex","opacity","expanded","pointerEvents","transition","transitions","create","StyledTextField","TextField","overflowX","QuickFilterTrigger","triggerProps","enterDelay","GridSearchIcon","QuickFilterControl","ref","controlProps","inputRef","placeholder","size","input","startAdornment","InputAdornment","position","endAdornment","QuickFilterClear","edge","material","marginRight","GridCloseIcon","ConfirmDialog","content","action","open","onClose","Dialog","fullWidth","DialogTitle","pb","DialogContent","typography","DialogActions","Button","onClick","ExportingDialog","Fragment","p","textAlign","Typography","CircularProgress","Iconify","forwardRef","icon","Icon","StyledLabel","lightMode","filledVariant","outlinedVariant","softVariant","defaultStyle","common","white","grey","backgroundColor","primary","border","secondary","alpha","colorStyle","contrastText","main","minWidth","lineHeight","borderRadius","whiteSpace","textTransform","padding","spacing","pxToRem","fontWeight","fontWeightBold","duration","shorter","Label","children","startIcon","endIcon","iconStyles","objectFit","pl","mr","ml","GROUPING_COLUMN_FIELD","CHECKBOX_FIELD","DETAIL_PANEL_TOGGLE_FIELD","AGGREGATION_FOOTER_ID","INTERNAL_FIELDS","DENSITY_FACTORS","compact","standard","comfortable","DEFAULT_ROW_HEIGHT","DEFAULT_HEADER_HEIGHT","DEFAULT_COLUMN_MIN_WIDTH","isInternalField","isNil","isEmptyValue","Array","isArray","clamp","min","max","Math","cx","classNames","Boolean","join","uniqueId","counter","prefix","getRowIdFromRow","row","getRowId","id","normalizeSelectionModel","allIds","type","ids","forEach","add","toDate","Date","Number","isNaN","getTime","dayjs","isDayjs","isValid","d","parsed","formatDate","withTime","date","format","startOfUnit","startOf","valueOf","isValueOptionObject","option","getOptionValue","col","getOptionLabel","label","String","resolveValueOptions","valueOptions","getCellValue","raw","valueGetter","defaultFormatValue","match","find","isFinite","getFormattedValue","valueFormatter","formattedValueToString","formatted","collator","Intl","Collator","numeric","sensitivity","nilFirst","v1","v2","n1","n2","numberComparator","nil","stringComparator","s1","s2","compare","stringOrNumberComparator","p1","p2","dateComparator","d1","d2","booleanComparator","getDefaultComparator","lower","toLowerCase","hasValue","item","stringFilterOperators","inputType","getApplyFilterFn","needle","indexOf","s","lastIndexOf","requiresFilterValue","set","numberOperator","filterValue","cell","n","numberFilterOperators","a","b","v","dateOperator","filterDate","filterTime","cellDate","getDateFilterOperators","booleanFilterOperators","expected","singleSelectFilterOperators","getColumnFilterOperators","filterOperators","getDefaultFilterOperators","normalizeColumn","isNumber","isBoolean","isActions","headerName","align","headerAlign","sortable","filterable","hideable","resizable","pinnable","groupable","aggregable","editable","disableExport","internalColumn","disableReorder","CHECKBOX_COLUMN_DEF","DETAIL_PANEL_TOGGLE_COLUMN_DEF","UNITLESS_PROPERTIES","isSelectorKey","test","serializeDeclarations","block","Object","keys","property","kebab","replace","m","toKebabCase","formatCssValue","buildScopedCss","scope","out","charAt","inner","declarations","push","selector","scopeSelector","split","part","trim","numericValues","values","BUILT_IN_AGGREGATION_FUNCTIONS","sum","columnTypes","apply","nums","reduce","acc","avg","defined","every","dates","slice","sort","sorted","DEFAULT_LOCALE_TEXT","noRowsLabel","loadingLabel","toolbarColumns","toolbarFilters","toolbarExport","toolbarDensity","toolbarQuickFilterPlaceholder","toolbarQuickFilterLabel","toolbarExportCSV","toolbarExportExcel","toolbarExportPrint","densityCompact","densityStandard","densityComfortable","columnsPanelSearchPlaceholder","columnsPanelShowAll","columnsPanelHideAll","columnsPanelReset","filterPanelAddFilter","filterPanelRemoveAll","filterPanelDeleteIcon","filterPanelColumns","filterPanelOperator","filterPanelValue","filterPanelInputPlaceholder","filterPanelLogicOperator","filterPanelOperatorAnd","filterPanelOperatorOr","columnMenuSortAsc","columnMenuSortDesc","columnMenuUnsort","columnMenuFilter","columnMenuHideColumn","columnMenuManageColumns","columnMenuPinLeft","columnMenuPinRight","columnMenuUnpin","columnMenuGroup","name","columnMenuUngroup","columnMenuAggregation","aggregationMenuItemHeader","aggregationFunctionLabelNone","aggregationFunctionLabelSum","aggregationFunctionLabelAvg","aggregationFunctionLabelMin","aggregationFunctionLabelMax","aggregationFunctionLabelSize","footerRowSelected","count","toLocaleString","footerTotalRows","footerPaginationRowsPerPage","footerPaginationDisplayedRows","from","to","footerPaginationFirstPage","footerPaginationPreviousPage","footerPaginationNextPage","footerPaginationLastPage","checkboxSelectionHeaderName","checkboxSelectionSelectAllRows","checkboxSelectionUnselectAllRows","checkboxSelectionSelectRow","checkboxSelectionUnselectRow","booleanCellTrueLabel","booleanCellFalseLabel","detailPanelToggle","expandDetailPanel","collapseDetailPanel","groupingColumnHeaderName","groupColumn","unGroupColumn","actionsCellMore","columnHeaderSortIconLabel","columnMenuLabel","clearSearch","measureContext","measureText","font","document","canvas","getContext","downloadBlob","blob","fileName","url","URL","createObjectURL","anchor","href","download","body","appendChild","click","setTimeout","removeChild","revokeObjectURL","MGH_GRID_STYLE_ID","MGH_GRID_CSS","injected","useInsertion","useInsertionEffect","useLayoutEffect","useEffect","useMGHGridStyles","injectStyles","getElementById","setAttribute","textContent","head","MGHGridContext","createContext","displayName","useMGHGridContext","ctx","useContext","Error","useMGHGridApiContext","useMGHGridLocaleText","localeText","useMGHGridApiRef","useRef","useLatestRef","current","useControlledState","controlled","defaultValue","onChange","isControlled","internal","setInternal","useState","valueRef","controlledRef","onChangeRef","next","resolved","is","idCounter","buildExportTable","resolveExportColumns","all","fields","byField","Map","c","f","get","getVisibleColumns","getRowsToExport","getSortedRowIds","getRow","headers","sanitizeFileName","fallback","extension","base","endsWith","defaultFileBase","escapeCsvCell","delimiter","getDataAsCsv","includeHeaders","table","lines","h","cells","useRawValues","UTF8_BOM","fromCharCode","CRC_TABLE","Uint32Array","k","textEncoder","TextEncoder","encodeUtf8","encode","utf8","unescape","encodeURIComponent","Uint8Array","i","charCodeAt","concatBytes","chunks","total","offset","zipStore","entries","localChunks","centralChunks","entry","nameBytes","crc","bytes","crc32","data","local","lv","DataView","buffer","setUint32","setUint16","central","cv","centralDirectory","eocd","ev","concat","INVALID_XML_CHARS","RegExp","escapeXml","stripInvalidXml","columnLetter","index","letters","rem","floor","XML_HEADER","buildSheetXml","columnWidths","rowsXml","rowIndex","inlineString","xmlCells","UTC","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","lastCol","lastRow","cols","w","STYLES_XML","CONTENT_TYPES_XML","ROOT_RELS_XML","WORKBOOK_RELS_XML","buildWorkbookXml","sheetName","buildCoreXml","now","toISOString","APP_XML","buildXlsx","widths","explicit","columnsStyles","r","len","cleaned","sanitizeSheetName","escapeHtml","keyToString","buildGroupTree","groupingFields","columnsByField","emptyLabel","build","depth","parentId","path","buckets","getGroupingValue","groupingValueGetter","keyStr","node","parent","groupingField","groupingKey","groupingLabel","childGroups","leaves","descendants","nodes","collectTreeLeaves","roots","root","aggregateRows","aggregationModel","functions","result","fnName","fn","createIcon","className","rest","viewBox","focusable","ViewColumnIcon","FilterListIcon","SearchIcon","CloseIcon","DownloadIcon","ArrowUpwardIcon","ArrowDownwardIcon","MoreVertIcon","CheckIcon","ExpandMoreIcon","ChevronRightIcon","ChevronLeftIcon","FirstPageIcon","LastPageIcon","PushPinIcon","DeleteIcon","AddIcon","DensitySmallIcon","DensityMediumIcon","DensityLargeIcon","DragIndicatorIcon","PrintIcon","TableChartIcon","DescriptionIcon","VisibilityOffIcon","FunctionsIcon","WorkspacesIcon","EmptyBoxIcon","active","IconButton","TextInput","Select","Field","htmlFor","Checkbox","indeterminate","forwardedRef","innerRef","setRef","Spinner","role","Popover","anchorEl","placement","autoFocus","ignoreOutsideClickOn","setPosition","top","left","ready","update","vw","innerWidth","vh","innerHeight","offsetWidth","offsetHeight","isConnected","getBoundingClientRect","right","bottom","prev","addEventListener","observer","ResizeObserver","observe","removeEventListener","disconnect","handlePointerDown","target","contains","some","closest","handleKeyDown","querySelector","focus","stop","stopPropagation","createPortal","tabIndex","visibility","onDoubleClick","onMouseDown","onKeyDown","Menu","first","querySelectorAll","preventDefault","currentIndex","activeElement","MenuItem","selected","disabled","hideMenu","MenuDivider","MenuSection","MGHGridColumnsButton","isOpen","preferencePanel","openedPanelValue","hidePreferences","showPreferences","currentTarget","MGHGridFiltersButton","MGHGridDensitySelector","setAnchor","o","setDensity","MGHGridExportMenuItem","MGHGridExportMenu","showExcelOption","showPrintOption","rootProps","customItems","Children","child","isValidElement","cloneElement","resolvedPrintOptions","exportDataAsCsv","exportDataAsExcel","exportDataAsPrint","MGHGridQuickFilter","debounceMs","alwaysExpanded","externalValue","quickFilterValues","setText","setExpanded","timer","delay","quickFilterDebounceMs","lastExternal","clearTimeout","commit","setQuickFilterValues","clear","isExpanded","expand","handleChange","onBlur","blur","showDensitySelector","quickFilterPlaceholder","showColumns","showFilters","showDensity","MGHGridPagination","page","rowCount","pageCount","setPageSize","setPage","MGHGridFooter","selectedCount","showSelected","hideFooterSelectedRowCount","showPagination","hideFooterPagination","showRowCount","MGHGridColumnsPanel","visibleColumns","visibleFields","search","setSearch","filtered","setAll","visible","setColumnVisibilityModel","checked","setColumnVisibility","useDebouncedValue","onCommit","setLocal","TextValueInput","MultiValueInput","joined","multiple","selectedOptions","FilterValueInput","operator","InputComponent","Component","applyValue","createFilterItem","MGHGridFilterPanel","filterableColumns","logicOperator","targetField","seeded","upsertFilterItem","updateItem","patch","canAddMore","disableMultipleColumnsFiltering","paddingTop","operators","op","showLogic","deleteFilterItem","setFilterLogicOperator","nextColumn","nextOperators","keepOperator","nextOperator","nextIsMulti","currentIsMulti","addItem","setFilterModel","MGHGridColumnMenu","panelAnchorEl","isGroupingColumn","sortItem","sortModel","pinned","isColumnPinned","isGrouped","rowGroupingModel","aggregation","canSort","disableColumnSorting","canFilter","canHide","canPin","disableColumnPinning","canGroup","disableRowGrouping","aggregationFunctions","availableAggregationFunctions","canAggregate","disableAggregation","anchorForPanel","sortColumn","showFilterPanel","transform","pinColumn","unpinColumn","removeRowGroupingCriteria","addRowGroupingCriteria","setAggregationModel","MGHGridNoRowsOverlay","imageSrc","MGHGridLoadingOverlay","MGHGridActionsCellItem","showInMenu","ActionsCell","actions","moreLabel","inline","inMenu","EMPTY_ARRAY","EMPTY_OBJECT","EMPTY_MAP","DEFAULT_SORTING_ORDER","DEFAULT_PAGE_SIZE_OPTIONS","DEFAULT_FILTER_MODEL","sanitizeStyle","toDateInputValue","pad","padStart","MGHGrid","columnsProp","disableCard","cardClassName","boxClassName","cardStyle","boxStyle","themeVars","localeTextProp","rowHeight","rowHeightProp","columnHeaderHeight","autoHeight","disableVirtualization","densityProp","onDensityChange","paginationModelProp","onPaginationModelChange","hideFooter","sortModelProp","onSortModelChange","sortingOrder","disableMultipleColumnsSorting","filterModelProp","onFilterModelChange","columnVisibilityModelProp","columnWidthStorageKey","pinnedColumnsStorageKey","onColumnWidthChange","disableColumnResize","disableColumnReorder","pinnedColumns","pinnedColumnsProp","onPinnedColumnsChange","disableMultipleRowSelection","rowSelectionModelProp","onCellClick","onCellDoubleClick","detailPanelExpandedRowIds","detailPanelExpandedRowIdsProp","onDetailPanelExpandedRowIdsChange","rowGroupingModelProp","onRowGroupingModelChange","groupingColDef","isGroupExpandedByDefault","aggregationModelProp","onAggregationModelChange","aggregationFunctionsProp","aggregationPosition","processRowUpdate","onProcessRowUpdateError","onCellEditStop","isCellEditable","apiRef","onStateChange","gridId","reactUseId","useId","useStableId","rootRef","scrollerRef","toolbarRef","forceUpdate","setTick","t","useForceUpdate","latest","getDetails","apiObject","L","apiImpl","rowsById","getRowModels","getAllRowIds","rowEntries","e","getRowNode","nodesById","getSortedRows","sortedLeaves","getVisibleRows","pagedRows","dr","getRowIndexRelativeToVisibleRows","findIndex","updateRows","updates","existing","setRowOverride","orderedUserColumns","visibleUserColumns","getColumn","getColumnIndex","useVisibleColumns","getColumnVisibilityModel","isVisible","setColumnWidth","setColumnIndex","targetIndex","autosizeColumns","side","getPinnedColumns","setPinnedColumns","getSortModel","setSortModel","direction","allowMultipleSorting","getFilterModel","upsertFilterItems","targetColumnField","hideFilterPanel","panel","getSelectedRows","selectedIds","getRowSelectionModel","setRowSelectionModel","normalized","setSelectedIds","selectRow","isSelected","resetSelection","selectRows","isRowSelected","isRowSelectableFn","nextPage","setPaginationModel","nextPageSize","csv","bom","utf8WithBom","Blob","async","headerHtml","bodyHtml","html","pageStyle","iframe","cleanup","parentNode","onload","win","contentWindow","onafterprint","print","doc","contentDocument","write","close","srcdoc","toggleDetailPanel","setExpandedDetailPanels","getExpandedDetailPanels","expandedDetailPanels","getRowGroupingModel","setRowGroupingModel","groupingIndex","splice","setRowChildrenExpansion","getRowGroupChildren","groupId","group","groupsById","getAggregationModel","startCellEditMode","stopCellEditMode","ignoreModifications","getCellMode","editing","editingCell","setEditCellValue","setEditValue","getCellParams","buildCellParams","setCellFocus","pendingFocusRef","setFocusedCell","scrollToIndexes","scroll","scroller","scrollLeft","scrollTop","getScrollPosition","rootElementRef","persisted","order","sorting","rowGrouping","controlledExpandedDetail","detailPanel","expandedRowIds","controlledSelection","setOrderedFields","setColumnWidths","dims","dimensions","groupExpansion","setGroupExpansion","setEditingCell","editValue","focusedCell","setPreferencePanel","columnMenu","setColumnMenu","resizingField","setResizingField","drag","setDrag","setScrollTop","scrollRaf","lastClickedIdRef","overrideState","setOverrideState","rowOverrides","viewportWidth","viewportHeight","enabled","setSize","clientWidth","clientHeight","useElementSize","densityFactor","round","headerHeight","userColumns","groupingActive","groupingColumn","single","seen","isColumnVisible","layout","leftFields","rightFields","visibleByField","center","ordered","computeWidths","available","overrides","Infinity","override","flex","pool","fixedTotal","remainingSpace","remainingFlex","changed","share","fixed","idx","hasPinning","x","leftOffset","isLeft","isRight","isLastLeft","isFirstRight","rightOffset","totalWidth","leftCount","rightCount","allDisplayColumnsByField","activeFilters","quickFilterColumns","filteredEntries","logicAnd","quickAnd","quickFilterLogicOperator","apiRefLocal","quickFns","lowered","getApplyQuickFilterFn","custom","results","compareEntries","sorters","dir","comparator","sortComparator","sortEntries","aggregationActive","isGroupExpanded","leafIds","processed","displayRows","tree","groupingSort","sortGroupTree","compareGroups","sortLeaves","sortLevel","flattenGroupTree","visit","groupNode","toGroupNode","l","childVisible","leaf","leafNode","totalDisplayRows","ceil","footerAggregates","rowsForFooter","groupAggregatesCache","getGroupAggregates","cached","heights","rowHeights","detailHeights","offsets","hasAuto","dh","virtual","virtualRange","overscan","viewTop","viewBottom","lo","hi","mid","handleScroll","requestAnimationFrame","cancelAnimationFrame","selectionCandidates","selectedCandidateCount","allCandidatesSelected","someCandidatesSelected","updateSelection","updater","selectionModelsEqual","equal","delete","lastId","toggleAllCandidates","allowMultiple","persistOrder","persistWidths","targets","lc","computed","getComputedStyle","fontFamily","cellFont","headerFont","sample","isCellEditableFn","colDef","rowNode","reason","valueParser","parseEditValue","currentValue","applyRowUpdate","newRow","oldRow","Promise","resolve","then","rowId","catch","error","console","valueSetter","previousGroupingKey","formattedValue","hasFocus","cellMode","isEditable","buildRowParams","preventScroll","visibleTop","visibleBottom","scrollIntoView","colIndex","leftPinnedWidth","rightPinnedWidth","visibleLeft","visibleRight","moveFocus","rowDelta","colDelta","absolute","canReorder","resizeRef","totalRowCount","clamped","oldIndex","moveItem","list","unshift","nextItems","withId","random","toString","contextValue","renderCellContent","renderRow","kind","selectable","hideCount","hideDescendantCount","paddingLeft","agg","aggregates","sampleRow","cancel","renderEditCell","onValueChange","renderEditor","renderCell","getActions","cellStyle","pinnedClasses","rowIsClickable","renderRowElement","customClass","indexRelativeToCurrentPage","isFirstVisible","isFirst","isLastVisible","isLast","isAuto","minHeight","handleRowSelectionClick","allSelected","shiftKey","ctrlKey","metaKey","isFocused","isEditing","isAggregation","cellClassName","isCheckbox","isDetailToggle","toRenderRow","renderPinnedRows","renderHeaderCell","sortIndex","showMenu","draggable","isDragging","isDropTarget","overField","menuOpen","headerParams","headerClassName","renderHeader","description","onDragStart","dataTransfer","effectAllowed","setData","onDragOver","sourceLc","dropEffect","rect","clientX","onDragLeave","onDrop","handleDrop","targetLc","without","onDragEnd","onPointerDown","handleResizeStart","startX","startWidth","lastWidth","onMove","onUp","ToolbarSlot","FooterSlot","footer","NoRowsOverlaySlot","LoadingOverlaySlot","loadingOverlay","mergedToolbarProps","noRowsProps","loadingProps","showNoRows","menuColumn","cardStyles","boxStyles","rootStyles","scopedCss","css","grid","tagName","pageRows","onScroll","renderBodyRows","detailHeight","detailContent","detailAuto","rowAuto","Provider"],"mappings":"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"}
1
+ {"version":3,"file":"index.esm.js","sources":["../src/hooks/useResponsive.ts","../src/components/CustomNoRowsOverlay/CustomNoRowsOverlay.tsx","../src/components/MGHDataGrid/MGHDataGrid.tsx","../src/components/CustomGridToolbarExport/CustomGridToolbarExport.tsx","../src/components/Confirm-Dialog/confirm-dialog.tsx","../src/components/Exporting/Exporting-Dialog.tsx","../src/components/iconify/iconify.tsx","../src/components/Label/styles.ts","../src/components/Label/Label.tsx","../src/components/MGHGrid/utils.ts","../src/components/MGHGrid/MGHGrid.styles.ts","../src/components/MGHGrid/context.tsx","../src/components/MGHGrid/hooks.ts","../src/components/MGHGrid/export.ts","../src/components/MGHGrid/print.ts","../src/components/MGHGrid/grouping.ts","../src/components/MGHGrid/icons.tsx","../src/components/MGHGrid/components/primitives.tsx","../src/components/MGHGrid/components/Toolbar.tsx","../src/components/MGHGrid/components/Footer.tsx","../src/components/MGHGrid/components/ColumnsPanel.tsx","../src/components/MGHGrid/components/FilterPanel.tsx","../src/components/MGHGrid/components/ColumnMenu.tsx","../src/components/MGHGrid/components/Overlays.tsx","../src/components/MGHGrid/components/ActionsCell.tsx","../src/components/MGHGrid/MGHGrid.tsx","../src/components/MGHDateRangePicker/MGHDateRangePicker.styles.ts","../src/components/MGHDateRangePicker/icons.tsx","../src/components/MGHDateRangePicker/utils.ts","../src/components/MGHDateRangePicker/MGHDateRangeCalendar.tsx","../src/components/MGHDateRangePicker/MGHDateRangePicker.tsx"],"sourcesContent":["import useMediaQuery from '@mui/material/useMediaQuery';\nimport { useTheme, Breakpoint } from '@mui/material/styles';\n\n// ----------------------------------------------------------------------\n\ntype ReturnType = boolean;\n\nexport type Query = 'up' | 'down' | 'between' | 'only';\n\nexport type Value = Breakpoint | number;\n\nexport function useResponsive(query: Query, start?: Value, end?: Value): ReturnType {\n const theme = useTheme();\n\n const mediaUp = useMediaQuery(theme.breakpoints.up(start as Value));\n\n const mediaDown = useMediaQuery(theme.breakpoints.down(start as Value));\n\n const mediaBetween = useMediaQuery(theme.breakpoints.between(start as Value, end as Value));\n\n const mediaOnly = useMediaQuery(theme.breakpoints.only(start as Breakpoint));\n\n if (query === 'up') {\n return mediaUp;\n }\n\n if (query === 'down') {\n return mediaDown;\n }\n\n if (query === 'between') {\n return mediaBetween;\n }\n\n return mediaOnly;\n}\n\n// ----------------------------------------------------------------------\n\ntype BreakpointOrNull = Breakpoint | null;\n\nexport function useWidth() {\n const theme = useTheme();\n\n const keys = [...theme.breakpoints.keys].reverse();\n\n return (\n keys.reduce((output: BreakpointOrNull, key: Breakpoint) => {\n const matches = useMediaQuery(theme.breakpoints.up(key));\n\n return !output && matches ? key : output;\n }, null) || 'xs'\n );\n}\n","import styled from '@emotion/styled';\n\nimport { Box } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n// import { NoRowsOverlayPropsOverrides } from '@mui/x-data-grid-premium';\n\nimport React from 'react';\n// import { NoRowsOverlayPropsOverrides } from './CustomNoRowsOverlay.types';\n\n/// ---------------------------------------------------------------------------------------\n\ndeclare module '@mui/x-data-grid-premium' {\n export interface NoRowsOverlayPropsOverrides {\n text: string;\n useSettingsContext?: () => { themeMode?: string };\n }\n}\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomNoRowsOverlay({ text, useSettingsContext }: NoRowsOverlayPropsOverrides) {\n const theme = useTheme();\n const themeMode = useSettingsContext?.()?.themeMode ?? theme.palette.mode ?? 'light';\n\n const StyledGridOverlay = styled('div')(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n height: '100%',\n '& .ant-empty-img-1': {\n fill: themeMode === 'light' ? '#aeb8c2' : '#262626',\n },\n '& .ant-empty-img-2': {\n fill: themeMode === 'light' ? '#f5f5f7' : '#595959',\n },\n '& .ant-empty-img-3': {\n fill: themeMode === 'light' ? '#dce0e6' : '#434343',\n },\n '& .ant-empty-img-4': {\n fill: themeMode === 'light' ? '#fff' : '#1c1c1c',\n },\n '& .ant-empty-img-5': {\n fillOpacity: themeMode === 'light' ? '0.8' : '0.08',\n fill: themeMode === 'light' ? '#f5f5f5' : '#fff',\n },\n }));\n return (\n <StyledGridOverlay>\n <Box\n component=\"img\"\n alt=\"empty content\"\n src=\"/assets/icons/empty/ic_content.svg\"\n sx={{ width: 50, maxWidth: 160 }}\n />\n <Box sx={{ mb: 0 }}>{text}</Box>\n </StyledGridOverlay>\n );\n}\n","import React, { JSX } from 'react';\nimport dayjs from 'dayjs';\n\nimport { DateRange } from '@mui/x-date-pickers-pro';\n// `GridInitialStatePremium` itself only lives under an internal (non-exported) subpath; the\n// package re-exports it under this name from its public entry point instead.\nimport { GridInitialState as GridInitialStatePremium } from '@mui/x-data-grid-premium';\nimport { Box, Card, Theme, Badge, styled, SxProps, Tooltip, TextField, CardHeader, InputAdornment } from '@mui/material';\nimport {\n Toolbar,\n GridColDef,\n QuickFilter,\n GridRowParams,\n ToolbarButton,\n GridCloseIcon,\n GridSearchIcon,\n DataGridPremium,\n GridToolbarProps,\n QuickFilterClear,\n GridEventListener,\n GridSlotsComponent,\n FilterPanelTrigger,\n GridViewColumnIcon,\n GridFilterListIcon,\n QuickFilterControl,\n QuickFilterTrigger,\n GridCallbackDetails,\n ColumnsPanelTrigger,\n GridRowHeightParams,\n GridCsvExportOptions,\n GridRowSelectionModel,\n GridCsvExportMenuItem,\n ToolbarPropsOverrides,\n GridRowClassNameParams,\n GridExcelExportOptions,\n GridPrintExportOptions,\n GridExcelExportMenuItem,\n GridPrintExportMenuItem,\n GridSlotsComponentsProps,\n GridExportDisplayOptions,\n GridRowHeightReturnValue,\n GridColumnVisibilityModel,\n GridToolbarExportContainer,\n GridPinnedRowsProp,\n} from '@mui/x-data-grid-premium';\nimport { useResponsive } from '../../hooks/useResponsive';\nimport CustomNoRowsOverlay from '../CustomNoRowsOverlay/CustomNoRowsOverlay';\n\ninterface CustomToolbarProps {\n dateValues: React.SetStateAction<DateRange<dayjs.Dayjs>>;\n setDateValues: React.Dispatch<React.SetStateAction<DateRange<dayjs.Dayjs>>>;\n renderDateRange?: React.ReactNode;\n customMenuItem?: JSX.Element[];\n currentParentFolderKey?: number | null;\n types?: any;\n typeKey?: number;\n setTypeKey?: React.Dispatch<React.SetStateAction<number>>;\n userData?: unknown;\n exporting?: boolean;\n setExporting?: React.Dispatch<React.SetStateAction<boolean>>;\n}\n\ninterface MGHDataGridProps {\n rows: any[];\n columns: GridColDef[];\n onRowClick?: GridEventListener<'rowClick'>;\n onRowDoubleClick?: GridEventListener<'rowDoubleClick'>;\n header: string;\n pagination?: boolean;\n pageSize?: number;\n pageSizeOptions?: number[];\n slots?: Partial<GridSlotsComponent>;\n slotProps?: GridSlotsComponentsProps & {\n toolbar?: Partial<GridToolbarProps & ToolbarPropsOverrides & CustomToolbarProps>;\n };\n toolbarProps?: any;\n initialState?: GridInitialStatePremium;\n sx?: SxProps<Theme>;\n cardSx?: SxProps<Theme>;\n boxSx?: SxProps<Theme>;\n columnVisibilityModel?: GridColumnVisibilityModel;\n onColumnVisibilityModelChange?: (model: GridColumnVisibilityModel, details: GridCallbackDetails) => void;\n columnVisibilityStorageKey?: string;\n columnOrderStorageKey?: string;\n disableDensitySelector?: boolean;\n disableRowSelectionOnClick?: boolean;\n disableColumnFilter?: boolean;\n disableColumnMenu?: boolean;\n disableColumnSelector?: boolean;\n renderHeaderEndContent?: JSX.Element;\n renderHeaderCenterContent?: JSX.Element;\n noRowsText?: string;\n checkboxSelection?: boolean;\n checkboxSelectionVisibleOnly?: boolean;\n onRowSelectionModelChange?:\n | ((rowSelectionModel: GridRowSelectionModel, details: GridCallbackDetails<any>) => void)\n | undefined;\n rowSelectionModel?: GridRowSelectionModel | undefined;\n getRowClassName?: ((params: GridRowClassNameParams<any>) => string) | undefined;\n getDetailPanelContent?: (params: GridRowParams<any>) => React.ReactNode;\n getDetailPanelHeight?: () => number;\n loading?: boolean;\n isRowSelectable?: (params: GridRowParams<any>) => boolean;\n getRowHeight?: ((params: GridRowHeightParams) => GridRowHeightReturnValue) | undefined;\n showToolbar?: boolean;\n hideFooterRowCount?: boolean;\n onColumnOrderChange?: GridEventListener<'columnOrderChange'> | undefined;\n defaultGroupingExpansionDepth?: number;\n pinnedRows?: GridPinnedRowsProp;\n keepNonExistentRowsSelected?: boolean;\n}\n\nconst canUseLocalStorage = () => typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';\n\nconst readLocalStorage = <T,>(key: string): T | null => {\n if (!canUseLocalStorage()) {\n return null;\n }\n try {\n const value = window.localStorage.getItem(key);\n return value ? (JSON.parse(value) as T) : null;\n } catch {\n return null;\n }\n};\n\nconst writeLocalStorage = (key: string, value: unknown) => {\n if (!canUseLocalStorage()) {\n return;\n }\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n return;\n }\n};\n\nconst normalizeOrderedFields = (orderedFields: string[] | null, columns: GridColDef[]) => {\n if (!orderedFields || orderedFields.length === 0) {\n return undefined;\n }\n const columnFields = new Set(columns.map((column) => column.field));\n return orderedFields.filter((field) => columnFields.has(field));\n};\n\nexport default function MGHDataGrid({\n header,\n rows,\n columns,\n onRowClick,\n onRowDoubleClick,\n pagination = true,\n pageSize = 25,\n slots = {},\n slotProps = {},\n toolbarProps = {},\n initialState = {},\n pageSizeOptions = [10, 25, 50, 100],\n sx = {},\n cardSx = { flexGrow: 1 },\n boxSx = { flexGrow: 1 },\n columnVisibilityModel,\n onColumnVisibilityModelChange,\n columnVisibilityStorageKey,\n columnOrderStorageKey,\n disableDensitySelector = false,\n disableRowSelectionOnClick = true,\n disableColumnFilter = false,\n disableColumnMenu = false,\n disableColumnSelector = false,\n checkboxSelectionVisibleOnly = false,\n renderHeaderEndContent,\n renderHeaderCenterContent,\n noRowsText = 'No data found within selected parameters.',\n checkboxSelection = false,\n onRowSelectionModelChange = undefined,\n rowSelectionModel = undefined,\n getRowClassName = undefined,\n getDetailPanelContent,\n getDetailPanelHeight,\n loading = false,\n isRowSelectable = undefined,\n getRowHeight,\n showToolbar = true,\n hideFooterRowCount = false,\n onColumnOrderChange = undefined,\n defaultGroupingExpansionDepth = undefined,\n pinnedRows = undefined,\n keepNonExistentRowsSelected = true,\n}: MGHDataGridProps) {\n const smDown = useResponsive('down', 'sm');\n const persistedColumnVisibilityModel = React.useMemo(() => {\n if (!columnVisibilityStorageKey) {\n return undefined;\n }\n return readLocalStorage<GridColumnVisibilityModel>(columnVisibilityStorageKey) ?? undefined;\n }, [columnVisibilityStorageKey]);\n\n const persistedOrderedFields = React.useMemo(() => {\n if (!columnOrderStorageKey) {\n return undefined;\n }\n const storedOrder = readLocalStorage<string[]>(columnOrderStorageKey);\n return normalizeOrderedFields(storedOrder, columns);\n }, [columnOrderStorageKey, columns]);\n\n const resolvedColumnVisibilityModel =\n columnVisibilityModel !== undefined ? columnVisibilityModel : persistedColumnVisibilityModel;\n\n const handleColumnVisibilityModelChange = React.useCallback(\n (model: GridColumnVisibilityModel, details: GridCallbackDetails) => {\n if (columnVisibilityStorageKey) {\n writeLocalStorage(columnVisibilityStorageKey, model);\n }\n onColumnVisibilityModelChange?.(model, details);\n },\n [columnVisibilityStorageKey, onColumnVisibilityModelChange]\n );\n\n const handleColumnOrderChange = React.useCallback<GridEventListener<'columnOrderChange'>>(\n (params, event, details) => {\n if (columnOrderStorageKey) {\n const orderedFields = details.api.getAllColumns().map((column) => column.field);\n writeLocalStorage(columnOrderStorageKey, orderedFields);\n }\n onColumnOrderChange?.(params, event, details);\n },\n [columnOrderStorageKey, onColumnOrderChange]\n );\n\n const mergedInitialState: GridInitialStatePremium = {\n density: 'compact',\n pagination: { paginationModel: { pageSize } },\n filter: {\n filterModel: {\n items: [],\n quickFilterExcludeHiddenColumns: false,\n },\n },\n ...initialState,\n columns: {\n ...initialState?.columns,\n columnVisibilityModel: resolvedColumnVisibilityModel ?? initialState?.columns?.columnVisibilityModel,\n orderedFields: persistedOrderedFields ?? initialState?.columns?.orderedFields,\n },\n };\n\n return (\n <Card sx={{ height: 'auto', ...cardSx }}>\n <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', pr: 1 }}>\n <CardHeader title={header} sx={{ mb: 2 }} />\n {renderHeaderCenterContent}\n <Box\n sx={{\n display: 'flex',\n gap: smDown ? 1 : 2,\n alignItems: 'center',\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n }}\n >\n {renderHeaderEndContent}\n </Box>\n </Box>\n <Box component=\"div\" sx={{ display: 'flex', flexDirection: 'column', flexGrow: 1, ...boxSx }}>\n <DataGridPremium\n loading={loading}\n onRowClick={onRowClick}\n onRowDoubleClick={onRowDoubleClick}\n rows={rows}\n columns={columns}\n pagination={pagination}\n disableDensitySelector={disableDensitySelector}\n disableRowSelectionOnClick={disableRowSelectionOnClick}\n disableColumnFilter={disableColumnFilter}\n disableColumnMenu={disableColumnMenu}\n disableColumnSelector={disableColumnSelector}\n slots={{ noRowsOverlay: CustomNoRowsOverlay, toolbar: MGHGridToolbar, ...slots }}\n slotProps={{ noRowsOverlay: { text: noRowsText }, toolbar: toolbarProps, ...slotProps }}\n initialState={mergedInitialState}\n pageSizeOptions={pageSizeOptions}\n sx={{\n '& .MuiDataGrid-row:hover': {\n cursor: onRowClick || onRowDoubleClick ? 'pointer' : 'default',\n },\n ...sx,\n }}\n \n onColumnVisibilityModelChange={handleColumnVisibilityModelChange}\n checkboxSelection={checkboxSelection}\n onRowSelectionModelChange={onRowSelectionModelChange}\n rowSelectionModel={rowSelectionModel}\n isRowSelectable={isRowSelectable}\n getRowClassName={getRowClassName}\n getDetailPanelContent={getDetailPanelContent}\n getDetailPanelHeight={getDetailPanelHeight}\n checkboxSelectionVisibleOnly={checkboxSelectionVisibleOnly}\n disableRowSelectionExcludeModel\n showToolbar={showToolbar}\n hideFooterRowCount={hideFooterRowCount}\n getRowHeight={getRowHeight}\n onColumnOrderChange={handleColumnOrderChange}\n defaultGroupingExpansionDepth={defaultGroupingExpansionDepth}\n pinnedRows={pinnedRows}\n keepNonExistentRowsSelected={keepNonExistentRowsSelected}\n />\n </Box>\n </Card>\n );\n}\n\ninterface MGHGridToolbarProps {\n showColumnsButton?: boolean;\n showFilterButton?: boolean;\n showExportButton?: boolean;\n showQuickFilter?: boolean;\n renderOtherButtons?: JSX.Element;\n renderDateRange?: JSX.Element;\n customMenuItem?: JSX.Element[];\n showCsvOption?: boolean;\n}\nexport function MGHGridToolbar({\n showColumnsButton = true,\n showFilterButton = true,\n showExportButton = true,\n showQuickFilter = true,\n renderOtherButtons,\n renderDateRange,\n customMenuItem,\n showCsvOption = true,\n}: MGHGridToolbarProps) {\n return (\n <Toolbar style={{ display: 'flex', justifyContent: 'space-between' }}>\n <div>\n {showColumnsButton && (\n <Tooltip title=\"Columns\">\n <ColumnsPanelTrigger render={<ToolbarButton />}>\n <GridViewColumnIcon fontSize=\"small\" />\n </ColumnsPanelTrigger>\n </Tooltip>\n )}\n {showFilterButton && (\n <Tooltip title=\"Filters\">\n <FilterPanelTrigger\n render={(props, state) => (\n <ToolbarButton {...props} color=\"default\">\n <Badge badgeContent={state.filterCount} color=\"primary\" variant=\"dot\">\n <GridFilterListIcon fontSize=\"small\" />\n </Badge>\n </ToolbarButton>\n )}\n />\n </Tooltip>\n )}\n {showExportButton && (\n <CustomGridToolbarExport customMenuItem={customMenuItem} showCsvOption={showCsvOption} />\n )}\n </div>\n\n {renderDateRange}\n\n <div>\n {renderOtherButtons}\n {showQuickFilter && <DataGridQuickFilter />}\n </div>\n </Toolbar>\n );\n}\n\ninterface ExportContainerProps {\n csvOptions?: GridCsvExportOptions & GridExportDisplayOptions;\n excelOptions?: GridExcelExportOptions & GridExportDisplayOptions;\n printOptions?: GridPrintExportOptions & GridExportDisplayOptions;\n customMenuItem?: JSX.Element[] | undefined;\n showCsvOption?: boolean;\n}\nexport const CustomGridToolbarExport = ({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n customMenuItem,\n showCsvOption = true,\n ...other\n}: ExportContainerProps) => (\n <GridToolbarExportContainer {...other}>\n {customMenuItem?.map((el) => el)}\n {showCsvOption && <GridCsvExportMenuItem options={csvOptions} />}\n <GridExcelExportMenuItem options={excelOptions} />\n <GridPrintExportMenuItem options={printOptions} />\n </GridToolbarExportContainer>\n);\n\nexport function DataGridQuickFilter() {\n type OwnerState = {\n expanded: boolean;\n };\n\n const StyledQuickFilter = styled(QuickFilter)({\n display: 'grid',\n alignItems: 'center',\n });\n\n const StyledToolbarButton = styled(ToolbarButton)<{ ownerState: OwnerState }>(({ theme, ownerState }) => ({\n gridArea: '1 / 1',\n width: 'min-content',\n height: 'min-content',\n zIndex: 1,\n opacity: ownerState.expanded ? 0 : 1,\n pointerEvents: ownerState.expanded ? 'none' : 'auto',\n transition: theme.transitions.create(['opacity']),\n }));\n\n const StyledTextField = styled(TextField)<{\n ownerState: OwnerState;\n }>(({ theme, ownerState }) => ({\n gridArea: '1 / 1',\n overflowX: 'clip',\n width: ownerState.expanded ? 260 : 'var(--trigger-width)',\n opacity: ownerState.expanded ? 1 : 0,\n transition: theme.transitions.create(['width', 'opacity']),\n }));\n\n return (\n <StyledQuickFilter>\n <QuickFilterTrigger\n render={(triggerProps, state) => (\n <Tooltip title=\"Search\" enterDelay={0}>\n <StyledToolbarButton\n {...triggerProps}\n ownerState={{ expanded: state.expanded }}\n color=\"default\"\n aria-disabled={state.expanded}\n >\n <GridSearchIcon fontSize=\"small\" />\n </StyledToolbarButton>\n </Tooltip>\n )}\n />\n <QuickFilterControl\n render={({ ref, ...controlProps }, state) => (\n <StyledTextField\n {...controlProps}\n ownerState={{ expanded: state.expanded }}\n inputRef={ref}\n aria-label=\"Search\"\n placeholder=\"Search...\"\n size=\"small\"\n slotProps={{\n input: {\n startAdornment: (\n <InputAdornment position=\"start\">\n <GridSearchIcon fontSize=\"small\" />\n </InputAdornment>\n ),\n endAdornment: state.value ? (\n <InputAdornment position=\"end\">\n <QuickFilterClear\n edge=\"end\"\n size=\"small\"\n aria-label=\"Clear search\"\n material={{ sx: { marginRight: -0.75 } }}\n >\n <GridCloseIcon fontSize=\"small\" />\n </QuickFilterClear>\n </InputAdornment>\n ) : null,\n ...controlProps.slotProps?.input,\n },\n ...controlProps.slotProps,\n }}\n />\n )}\n />\n </StyledQuickFilter>\n );\n}\n","import {\n GridToolbarExportContainer,\n GridCsvExportMenuItem,\n GridExcelExportMenuItem,\n GridPrintExportMenuItem,\n} from '@mui/x-data-grid-premium';\nimport React from 'react';\nimport { ExportContainerProps } from './CustomGridToolbarExport.types';\n\n/// ---------------------------------------------------------------------------------------\n\nexport default function CustomGridToolbarExport({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n // color,\n customMenuItem,\n ...other\n}: ExportContainerProps) {\n return (\n <GridToolbarExportContainer\n {...other}\n // color={color}\n >\n {customMenuItem}\n <GridCsvExportMenuItem options={csvOptions} />\n <GridExcelExportMenuItem options={excelOptions} />\n <GridPrintExportMenuItem options={printOptions} />\n </GridToolbarExportContainer>\n );\n}\n","import Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\n\nimport { ConfirmDialogProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nexport default function ConfirmDialog({ title, content, action, open, onClose, ...other }: ConfirmDialogProps) {\n return (\n <Dialog fullWidth maxWidth=\"xs\" open={open} onClose={onClose} {...other}>\n <DialogTitle sx={{ pb: 2 }}>{title}</DialogTitle>\n\n {content && <DialogContent sx={{ typography: 'body2' }}> {content} </DialogContent>}\n\n <DialogActions>\n <Button onClick={onClose}>Cancel</Button>\n {action}\n </DialogActions>\n </Dialog>\n );\n}\n","import { JSX } from 'react';\n\nimport { Dialog, Typography, DialogContent, CircularProgress } from '@mui/material';\nimport React from 'react';\n\n/// ---------------------------------------------------------------------------------------\n\ninterface ExportingProps {\n open: boolean;\n text?: JSX.Element | string;\n}\nexport default function ExportingDialog({\n open,\n text = (\n <>\n Your export is currently being built. Some larger exports can take a couple of minutes to complete. <br />\n <br />\n Please do not close your browser or refresh the page.\n </>\n ),\n}: ExportingProps) {\n return (\n <Dialog open={open} fullWidth sx={{ p: 4 }}>\n <DialogContent sx={{ p: 4, textAlign: 'center' }}>\n <Typography variant=\"subtitle1\" sx={{ mb: 3 }}>\n {text}\n </Typography>\n <CircularProgress />\n </DialogContent>\n </Dialog>\n );\n}\n","import { forwardRef } from 'react';\nimport { Icon } from '@iconify/react';\n\nimport { IconifyProps } from './types';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\ninterface Props {\n icon: IconifyProps;\n width?: number;\n height?: number;\n sx?: any;\n}\n\nconst Iconify = forwardRef<SVGElement, Props>(({ icon, width = 20, sx, ...other }, ref) => (\n <Icon icon={icon} style={{ width: 20, height: width ?? 20, ...sx }} />\n));\n\nexport default Iconify;\n","import type { ComponentProps, ComponentType } from 'react';\nimport Box from '@mui/material/Box';\nimport { alpha, styled, useTheme } from '@mui/material/styles';\nimport { LabelColor, LabelVariant } from './types';\n\n// ----------------------------------------------------------------------\n\ninterface StyledLabelOwnerState {\n color: LabelColor;\n variant: LabelVariant;\n}\n\n// Explicitly annotated so TS doesn't need to synthesize (and re-print) an anonymous type that\n// references @mui/system's install path — under pnpm that path is store-relative and triggers\n// TS2742 (\"inferred type cannot be named without a reference to ...\") during declaration emit.\nexport const StyledLabel = styled(Box)(({\n // theme,\n ownerState,\n}: {\n // theme: Theme;\n ownerState: StyledLabelOwnerState;\n}) => {\n const theme = useTheme();\n\n const lightMode = theme.palette.mode === 'light';\n\n const filledVariant = ownerState.variant === 'filled';\n\n const outlinedVariant = ownerState.variant === 'outlined';\n\n const softVariant = ownerState.variant === 'soft';\n\n const defaultStyle = {\n ...(ownerState.color === 'default' && {\n // FILLED\n ...(filledVariant && {\n color: lightMode ? theme.palette.common.white : theme.palette.grey[800],\n backgroundColor: theme.palette.text.primary,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette.text.primary,\n border: `2px solid ${theme.palette.text.primary}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette.text.secondary,\n backgroundColor: alpha(theme.palette.grey[500], 0.16),\n }),\n }),\n };\n\n const colorStyle = {\n ...(ownerState.color !== 'default' && {\n // FILLED\n ...(filledVariant && {\n color: theme.palette[ownerState.color].contrastText,\n backgroundColor: theme.palette[ownerState.color].main,\n }),\n // OUTLINED\n ...(outlinedVariant && {\n backgroundColor: 'transparent',\n color: theme.palette[ownerState.color].main,\n border: `2px solid ${theme.palette[ownerState.color].main}`,\n }),\n // SOFT\n ...(softVariant && {\n color: theme.palette[ownerState.color][lightMode ? 'dark' : 'light'],\n backgroundColor: alpha(theme.palette[ownerState.color].main, 0.16),\n }),\n }),\n };\n\n return {\n height: 24,\n minWidth: 24,\n lineHeight: 0,\n borderRadius: 6,\n cursor: 'default',\n alignItems: 'center',\n whiteSpace: 'nowrap',\n display: 'inline-flex',\n justifyContent: 'center',\n textTransform: 'capitalize',\n padding: theme.spacing(0, 0.75),\n fontSize: theme.typography.pxToRem(12),\n fontWeight: theme.typography.fontWeightBold,\n transition: theme.transitions.create('all', {\n duration: theme.transitions.duration.shorter,\n }),\n ...defaultStyle,\n ...colorStyle,\n };\n}) as ComponentType<ComponentProps<typeof Box> & { ownerState: StyledLabelOwnerState }>;\n","import { forwardRef } from 'react';\n\nimport Box from '@mui/material/Box';\nimport { LabelProps } from './types';\nimport { StyledLabel } from './styles';\nimport React from 'react';\n\n// ----------------------------------------------------------------------\n\nconst Label = forwardRef<HTMLSpanElement, LabelProps>(\n ({ children, color = 'default', variant = 'soft', startIcon, endIcon, sx, ...other }, ref) => {\n // const theme = useTheme();\n\n const iconStyles = {\n width: 16,\n height: 16,\n '& svg, img': { width: 1, height: 1, objectFit: 'cover' },\n };\n\n return (\n <StyledLabel\n ref={ref}\n // component=\"span\"\n ownerState={{ color, variant }}\n sx={{\n ...(startIcon && { pl: 0.75 }),\n ...(endIcon && { pr: 0.75 }),\n ...sx,\n }}\n // theme={theme}\n {...other}\n >\n {startIcon && <Box sx={{ mr: 0.75, ...iconStyles }}> {startIcon} </Box>}\n\n {children}\n\n {endIcon && <Box sx={{ ml: 0.75, ...iconStyles }}> {endIcon} </Box>}\n </StyledLabel>\n );\n }\n);\n\nexport default Label;\n","import dayjs from 'dayjs';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridColType,\n MGHGridComparatorFn,\n MGHGridFilterItem,\n MGHGridFilterOperator,\n MGHGridLocaleText,\n MGHGridRowId,\n MGHGridRowSelectionModel,\n MGHGridRowSelectionModelInput,\n MGHGridValidRowModel,\n MGHGridValueOption,\n MGHGridValueOptionObject,\n} from './MGHGrid.types';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants\n * ----------------------------------------------------------------------------------------------- */\n\nexport const GROUPING_COLUMN_FIELD = '__row_group_by_columns_group__';\nexport const CHECKBOX_FIELD = '__check__';\nexport const DETAIL_PANEL_TOGGLE_FIELD = '__detail_panel_toggle__';\nexport const AGGREGATION_FOOTER_ID = '__aggregation_footer__';\nexport const INTERNAL_FIELDS = new Set<string>([CHECKBOX_FIELD, DETAIL_PANEL_TOGGLE_FIELD]);\n\nexport const DENSITY_FACTORS = { compact: 0.7, standard: 1, comfortable: 1.3 } as const;\nexport const DEFAULT_ROW_HEIGHT = 52;\nexport const DEFAULT_HEADER_HEIGHT = 56;\nexport const DEFAULT_COLUMN_WIDTH = 100;\nexport const DEFAULT_COLUMN_MIN_WIDTH = 50;\nexport const CHECKBOX_COLUMN_WIDTH = 50;\nexport const DETAIL_TOGGLE_COLUMN_WIDTH = 50;\nexport const GROUPING_COLUMN_WIDTH = 220;\n\nexport const isInternalField = (field: string) => INTERNAL_FIELDS.has(field) || field === GROUPING_COLUMN_FIELD;\n\n/* -------------------------------------------------------------------------------------------------\n * Generic helpers\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isNil = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isEmptyValue = (value: unknown) => isNil(value) || value === '' || (Array.isArray(value) && value.length === 0);\n\nexport const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nexport const cx = (...classNames: Array<string | false | null | undefined>) => classNames.filter(Boolean).join(' ');\n\nexport const arraysEqual = <T>(a: T[] | undefined, b: T[] | undefined) => {\n if (a === b) return true;\n if (!a || !b || a.length !== b.length) return false;\n for (let i = 0; i < a.length; i += 1) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n\nexport const moveItem = <T>(list: T[], from: number, to: number): T[] => {\n const next = list.slice();\n const [item] = next.splice(from, 1);\n next.splice(to, 0, item);\n return next;\n};\n\nexport const uniqueId = (() => {\n let counter = 0;\n return (prefix = 'mgh') => {\n counter += 1;\n return `${prefix}-${counter}`;\n };\n})();\n\n/* -------------------------------------------------------------------------------------------------\n * Local storage\n * ----------------------------------------------------------------------------------------------- */\n\nexport const canUseLocalStorage = () => typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';\n\nexport const readLocalStorage = <T>(key: string): T | null => {\n if (!canUseLocalStorage()) return null;\n try {\n const value = window.localStorage.getItem(key);\n return value ? (JSON.parse(value) as T) : null;\n } catch {\n return null;\n }\n};\n\nexport const writeLocalStorage = (key: string, value: unknown) => {\n if (!canUseLocalStorage()) return;\n try {\n window.localStorage.setItem(key, JSON.stringify(value));\n } catch {\n /* ignore quota / privacy errors */\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Rows\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getRowIdFromRow = <R extends MGHGridValidRowModel>(row: R, getRowId?: (row: R) => MGHGridRowId) =>\n getRowId ? getRowId(row) : (row.id as MGHGridRowId);\n\nexport const normalizeSelectionModel = (\n input: MGHGridRowSelectionModelInput | undefined,\n allIds?: MGHGridRowId[]\n): MGHGridRowSelectionModel => {\n if (!input) return { type: 'include', ids: new Set() };\n if (Array.isArray(input)) return { type: 'include', ids: new Set(input) };\n if (input instanceof Set) return { type: 'include', ids: new Set(input) };\n if (input.type === 'exclude' && allIds) {\n const ids = new Set<MGHGridRowId>();\n allIds.forEach((id) => {\n if (!input.ids.has(id)) ids.add(id);\n });\n return { type: 'include', ids };\n }\n return { type: 'include', ids: new Set(input.ids) };\n};\n\nexport const selectionModelsEqual = (a: MGHGridRowSelectionModel, b: MGHGridRowSelectionModel) => {\n if (a.ids.size !== b.ids.size) return false;\n let equal = true;\n a.ids.forEach((id) => {\n if (!b.ids.has(id)) equal = false;\n });\n return equal;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Dates\n * ----------------------------------------------------------------------------------------------- */\n\nexport const toDate = (value: unknown): Date | null => {\n if (isNil(value) || value === '') return null;\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;\n if (dayjs.isDayjs(value)) return value.isValid() ? value.toDate() : null;\n if (typeof value === 'number') {\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n if (typeof value === 'string') {\n const parsed = dayjs(value);\n return parsed.isValid() ? parsed.toDate() : null;\n }\n return null;\n};\n\nexport const formatDate = (value: unknown, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n return dayjs(date).format(withTime ? 'M/D/YYYY h:mm A' : 'M/D/YYYY');\n};\n\nconst startOfUnit = (date: Date, withTime: boolean) =>\n withTime ? dayjs(date).startOf('minute').valueOf() : dayjs(date).startOf('day').valueOf();\n\n/* -------------------------------------------------------------------------------------------------\n * Value options (singleSelect)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const isValueOptionObject = (option: MGHGridValueOption): option is MGHGridValueOptionObject =>\n typeof option === 'object' && option !== null;\n\nexport const getOptionValue = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionValue ? col.getOptionValue(option) : isValueOptionObject(option) ? option.value : option;\n\nexport const getOptionLabel = (col: MGHGridColDef, option: MGHGridValueOption) =>\n col.getOptionLabel ? col.getOptionLabel(option) : isValueOptionObject(option) ? option.label : String(option);\n\nexport const resolveValueOptions = (col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (!col.valueOptions) return [] as MGHGridValueOption[];\n return typeof col.valueOptions === 'function' ? col.valueOptions({ field: col.field, row, id }) : col.valueOptions;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Cell values\n * ----------------------------------------------------------------------------------------------- */\n\nexport const getCellValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n const raw = row ? row[col.field] : undefined;\n return col.valueGetter ? col.valueGetter(raw, row, col, api) : raw;\n};\n\nexport const getGroupingValue = (row: MGHGridValidRowModel, col: MGHGridColDef, api: MGHGridApi) => {\n if (col.groupingValueGetter) return col.groupingValueGetter(row[col.field], row, col, api);\n return getCellValue(row, col, api);\n};\n\nexport const defaultFormatValue = (value: any, col: MGHGridColDef, row?: MGHGridValidRowModel, id?: MGHGridRowId) => {\n if (isNil(value)) return '';\n switch (col.type) {\n case 'date':\n return formatDate(value, false);\n case 'dateTime':\n return formatDate(value, true);\n case 'boolean':\n return value ? 'Yes' : 'No';\n case 'singleSelect': {\n const options = resolveValueOptions(col, row, id);\n const match = options.find((option) => getOptionValue(col, option) === value);\n return match !== undefined ? getOptionLabel(col, match) : String(value);\n }\n case 'number':\n return typeof value === 'number' ? (Number.isFinite(value) ? String(value) : '') : String(value);\n default:\n if (value instanceof Date) return formatDate(value, true);\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n }\n};\n\nexport const getFormattedValue = (\n value: any,\n row: MGHGridValidRowModel,\n col: MGHGridColDef,\n api: MGHGridApi,\n id?: MGHGridRowId\n) => {\n if (col.valueFormatter) return col.valueFormatter(value, row, col, api);\n return defaultFormatValue(value, col, row, id);\n};\n\nexport const formattedValueToString = (formatted: any): string => {\n if (isNil(formatted)) return '';\n if (typeof formatted === 'string') return formatted;\n if (typeof formatted === 'number' || typeof formatted === 'boolean') return String(formatted);\n if (formatted instanceof Date) return formatDate(formatted, true);\n if (typeof formatted === 'object' && 'props' in formatted) return '';\n return String(formatted);\n};\n\nexport const parseEditValue = (raw: any, col: MGHGridColDef) => {\n switch (col.type) {\n case 'number': {\n if (raw === '' || isNil(raw)) return null;\n const n = Number(raw);\n return Number.isNaN(n) ? raw : n;\n }\n case 'boolean':\n return Boolean(raw);\n case 'date':\n case 'dateTime': {\n if (raw === '' || isNil(raw)) return null;\n const d = toDate(raw);\n return d ?? raw;\n }\n default:\n return raw;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Sorting\n * ----------------------------------------------------------------------------------------------- */\n\nconst collator = typeof Intl !== 'undefined' ? new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }) : null;\n\nconst nilFirst = (v1: any, v2: any): number | null => {\n const n1 = isNil(v1) || v1 === '';\n const n2 = isNil(v2) || v2 === '';\n if (n1 && n2) return 0;\n if (n1) return -1;\n if (n2) return 1;\n return null;\n};\n\nexport const numberComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(v1) - Number(v2);\n};\n\nexport const stringComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n const s1 = String(v1);\n const s2 = String(v2);\n if (collator) return collator.compare(s1, s2);\n return s1 < s2 ? -1 : s1 > s2 ? 1 : 0;\n};\n\nexport const stringOrNumberComparator: MGHGridComparatorFn = (v1, v2, p1, p2) => {\n if (typeof v1 === 'number' && typeof v2 === 'number') return numberComparator(v1, v2, p1, p2);\n return stringComparator(v1, v2, p1, p2);\n};\n\nexport const dateComparator: MGHGridComparatorFn = (v1, v2) => {\n const d1 = toDate(v1);\n const d2 = toDate(v2);\n const nil = nilFirst(d1, d2);\n if (nil !== null) return nil;\n return (d1 as Date).getTime() - (d2 as Date).getTime();\n};\n\nexport const booleanComparator: MGHGridComparatorFn = (v1, v2) => {\n const nil = nilFirst(v1, v2);\n if (nil !== null) return nil;\n return Number(Boolean(v1)) - Number(Boolean(v2));\n};\n\nexport const getDefaultComparator = (type: MGHGridColType | undefined): MGHGridComparatorFn => {\n switch (type) {\n case 'number':\n return numberComparator;\n case 'date':\n case 'dateTime':\n return dateComparator;\n case 'boolean':\n return booleanComparator;\n default:\n return stringOrNumberComparator;\n }\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Filter operators\n * ----------------------------------------------------------------------------------------------- */\n\nconst lower = (value: unknown) => (isNil(value) ? '' : String(value).toLowerCase());\n\nconst hasValue = (item: MGHGridFilterItem) => !isEmptyValue(item.value);\n\nexport const stringFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'contains',\n label: 'contains',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) !== -1;\n },\n },\n {\n value: 'doesNotContain',\n label: 'does not contain',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === -1;\n },\n },\n {\n value: 'equals',\n label: 'equals',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) === needle;\n },\n },\n {\n value: 'doesNotEqual',\n label: 'does not equal',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value) !== needle;\n },\n },\n {\n value: 'startsWith',\n label: 'starts with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => lower(value).indexOf(needle) === 0;\n },\n },\n {\n value: 'endsWith',\n label: 'ends with',\n inputType: 'text',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const needle = lower(item.value);\n return (value) => {\n const s = lower(value);\n return s.length >= needle.length && s.lastIndexOf(needle) === s.length - needle.length;\n };\n },\n },\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(lower));\n return (value) => set.has(lower(value));\n },\n },\n];\n\nconst numberOperator = (\n value: string,\n label: string,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: 'number',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterValue = Number(item.value);\n if (Number.isNaN(filterValue)) return null;\n return (cell) => {\n if (isNil(cell) || cell === '') return false;\n const n = Number(cell);\n return !Number.isNaN(n) && compare(n, filterValue);\n };\n },\n});\n\nexport const numberFilterOperators: MGHGridFilterOperator[] = [\n numberOperator('=', '=', (a, b) => a === b),\n numberOperator('!=', '!=', (a, b) => a !== b),\n numberOperator('>', '>', (a, b) => a > b),\n numberOperator('>=', '>=', (a, b) => a >= b),\n numberOperator('<', '<', (a, b) => a < b),\n numberOperator('<=', '<=', (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => isEmptyValue(value),\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => !isEmptyValue(value),\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map((v: any) => Number(v)));\n return (value) => !isNil(value) && set.has(Number(value));\n },\n },\n];\n\nconst dateOperator = (\n value: string,\n label: string,\n withTime: boolean,\n compare: (cell: number, filter: number) => boolean\n): MGHGridFilterOperator => ({\n value,\n label,\n inputType: withTime ? 'datetime-local' : 'date',\n getApplyFilterFn: (item) => {\n if (!hasValue(item)) return null;\n const filterDate = toDate(item.value);\n if (!filterDate) return null;\n const filterTime = startOfUnit(filterDate, withTime);\n return (cell) => {\n const cellDate = toDate(cell);\n if (!cellDate) return false;\n return compare(startOfUnit(cellDate, withTime), filterTime);\n };\n },\n});\n\nexport const getDateFilterOperators = (withTime: boolean): MGHGridFilterOperator[] => [\n dateOperator('is', 'is', withTime, (a, b) => a === b),\n dateOperator('not', 'is not', withTime, (a, b) => a !== b),\n dateOperator('after', 'is after', withTime, (a, b) => a > b),\n dateOperator('onOrAfter', 'is on or after', withTime, (a, b) => a >= b),\n dateOperator('before', 'is before', withTime, (a, b) => a < b),\n dateOperator('onOrBefore', 'is on or before', withTime, (a, b) => a <= b),\n {\n value: 'isEmpty',\n label: 'is empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) === null,\n },\n {\n value: 'isNotEmpty',\n label: 'is not empty',\n inputType: 'none',\n requiresFilterValue: false,\n getApplyFilterFn: () => (value) => toDate(value) !== null,\n },\n];\n\nexport const booleanFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'boolean',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '' || item.value === 'any') return null;\n const expected = item.value === true || item.value === 'true';\n return (value) => Boolean(value) === expected;\n },\n },\n];\n\nexport const singleSelectFilterOperators: MGHGridFilterOperator[] = [\n {\n value: 'is',\n label: 'is',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) === String(item.value);\n },\n },\n {\n value: 'not',\n label: 'is not',\n inputType: 'select',\n getApplyFilterFn: (item) => {\n if (isNil(item.value) || item.value === '') return null;\n return (value) => String(value) !== String(item.value);\n },\n },\n {\n value: 'isAnyOf',\n label: 'is any of',\n inputType: 'multiselect',\n getApplyFilterFn: (item) => {\n if (!Array.isArray(item.value) || item.value.length === 0) return null;\n const set = new Set(item.value.map(String));\n return (value) => set.has(String(value));\n },\n },\n];\n\nexport const getDefaultFilterOperators = (type: MGHGridColType | undefined): MGHGridFilterOperator[] => {\n switch (type) {\n case 'number':\n return numberFilterOperators;\n case 'date':\n return getDateFilterOperators(false);\n case 'dateTime':\n return getDateFilterOperators(true);\n case 'boolean':\n return booleanFilterOperators;\n case 'singleSelect':\n return singleSelectFilterOperators;\n case 'actions':\n return [];\n default:\n return stringFilterOperators;\n }\n};\n\nexport const getColumnFilterOperators = (col: MGHGridColDef) => col.filterOperators ?? getDefaultFilterOperators(col.type);\n\n/* -------------------------------------------------------------------------------------------------\n * Column normalisation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const normalizeColumn = <R extends MGHGridValidRowModel>(col: MGHGridColDef<R>): MGHGridColDef<R> => {\n const type = col.type ?? 'string';\n const isNumber = type === 'number';\n const isBoolean = type === 'boolean';\n const isActions = type === 'actions';\n return {\n ...col,\n type,\n headerName: col.headerName ?? col.field,\n width: col.width ?? (isActions ? 100 : isBoolean ? 100 : DEFAULT_COLUMN_WIDTH),\n minWidth: col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,\n align: col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n headerAlign: col.headerAlign ?? col.align ?? (isNumber ? 'right' : isBoolean || isActions ? 'center' : 'left'),\n sortable: isActions ? false : (col.sortable ?? true),\n filterable: isActions ? false : (col.filterable ?? true),\n hideable: col.hideable ?? true,\n resizable: col.resizable ?? true,\n pinnable: col.pinnable ?? true,\n groupable: isActions ? false : (col.groupable ?? true),\n aggregable: isActions ? false : (col.aggregable ?? true),\n editable: col.editable ?? false,\n disableColumnMenu: col.disableColumnMenu ?? isActions,\n disableExport: col.disableExport ?? isActions,\n };\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Internal (auto-generated) columns\n * ----------------------------------------------------------------------------------------------- */\n\nconst internalColumn = (field: string, width: number): MGHGridColDef =>\n normalizeColumn({\n field,\n headerName: '',\n width,\n minWidth: width,\n maxWidth: width,\n sortable: false,\n filterable: false,\n hideable: false,\n resizable: false,\n pinnable: false,\n groupable: false,\n aggregable: false,\n disableColumnMenu: true,\n disableExport: true,\n disableReorder: true,\n align: 'center',\n headerAlign: 'center',\n });\n\n/** Definition of the checkbox-selection column (equivalent of MUI's GRID_CHECKBOX_SELECTION_COL_DEF). */\nexport const CHECKBOX_COLUMN_DEF: MGHGridColDef = internalColumn(CHECKBOX_FIELD, CHECKBOX_COLUMN_WIDTH);\n/** Definition of the detail-panel toggle column (equivalent of MUI's GRID_DETAIL_PANEL_TOGGLE_COL_DEF). */\nexport const DETAIL_PANEL_TOGGLE_COLUMN_DEF: MGHGridColDef = internalColumn(\n DETAIL_PANEL_TOGGLE_FIELD,\n DETAIL_TOGGLE_COLUMN_WIDTH\n);\n\n/* -------------------------------------------------------------------------------------------------\n * sx -> scoped CSS\n * ----------------------------------------------------------------------------------------------- */\n\nconst UNITLESS_PROPERTIES = new Set([\n 'animationIterationCount',\n 'borderImageOutset',\n 'borderImageSlice',\n 'borderImageWidth',\n 'boxFlex',\n 'boxFlexGroup',\n 'boxOrdinalGroup',\n 'columnCount',\n 'columns',\n 'flex',\n 'flexGrow',\n 'flexPositive',\n 'flexShrink',\n 'flexNegative',\n 'flexOrder',\n 'gridArea',\n 'gridRow',\n 'gridRowEnd',\n 'gridRowSpan',\n 'gridRowStart',\n 'gridColumn',\n 'gridColumnEnd',\n 'gridColumnSpan',\n 'gridColumnStart',\n 'fontWeight',\n 'lineClamp',\n 'lineHeight',\n 'opacity',\n 'order',\n 'orphans',\n 'tabSize',\n 'widows',\n 'zIndex',\n 'zoom',\n 'fillOpacity',\n 'floodOpacity',\n 'stopOpacity',\n 'strokeDasharray',\n 'strokeDashoffset',\n 'strokeMiterlimit',\n 'strokeOpacity',\n 'strokeWidth',\n]);\n\n/** Keys that are CSS selectors / at-rules rather than CSS properties. */\nexport const isSelectorKey = (key: string) => /[&.:#>\\[\\s*~+,@]/.test(key);\n\nconst toKebabCase = (property: string) => {\n if (property.indexOf('--') === 0) return property;\n const kebab = property.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n return kebab.indexOf('ms-') === 0 ? `-${kebab}` : kebab;\n};\n\nconst formatCssValue = (property: string, value: string | number) =>\n typeof value === 'number' && value !== 0 && !UNITLESS_PROPERTIES.has(property) && property.indexOf('--') !== 0\n ? `${value}px`\n : String(value);\n\nconst serializeDeclarations = (block: Record<string, unknown>) =>\n Object.keys(block)\n .filter((key) => {\n const value = block[key];\n return !isSelectorKey(key) && (typeof value === 'string' || typeof value === 'number');\n })\n .map((key) => `${toKebabCase(key)}:${formatCssValue(key, block[key] as string | number)}`)\n .join(';');\n\nconst scopeSelector = (scope: string, selector: string) =>\n selector\n .split(',')\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => (part.indexOf('&') !== -1 ? part.replace(/&/g, scope) : `${scope} ${part}`))\n .join(',');\n\n/**\n * Compiles the nested-selector part of an `sx`-like object into CSS scoped under `scope`.\n * Top-level plain properties are ignored here (they are applied as inline styles instead).\n */\nexport const buildScopedCss = (scope: string, sx: Record<string, unknown> | undefined, out: string[] = []): string[] => {\n if (!sx) return out;\n Object.keys(sx).forEach((key) => {\n const value = sx[key];\n if (!value || typeof value !== 'object') return;\n const block = value as Record<string, unknown>;\n if (key.charAt(0) === '@') {\n const inner: string[] = [];\n const declarations = serializeDeclarations(block);\n if (declarations) inner.push(`${scope}{${declarations}}`);\n buildScopedCss(scope, block, inner);\n if (inner.length) out.push(`${key}{${inner.join('')}}`);\n return;\n }\n const selector = scopeSelector(scope, key);\n const declarations = serializeDeclarations(block);\n if (declarations) out.push(`${selector}{${declarations}}`);\n buildScopedCss(selector, block, out);\n });\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nconst numericValues = (values: any[]) =>\n values.map((v) => (typeof v === 'number' ? v : Number(v))).filter((n) => !Number.isNaN(n) && n !== null);\n\nexport const BUILT_IN_AGGREGATION_FUNCTIONS: Record<string, MGHGridAggregationFunction> = {\n sum: {\n label: 'sum',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0);\n },\n },\n avg: {\n label: 'avg',\n columnTypes: ['number'],\n apply: ({ values }) => {\n const nums = numericValues(values.filter((v) => !isNil(v) && v !== ''));\n if (nums.length === 0) return null;\n return nums.reduce((acc, n) => acc + n, 0) / nums.length;\n },\n },\n min: {\n label: 'min',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.min(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.min(...dates.map((d) => (d as Date).getTime())));\n }\n return defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any))[0];\n },\n },\n max: {\n label: 'max',\n columnTypes: ['number', 'date', 'dateTime'],\n apply: ({ values }) => {\n const defined = values.filter((v) => !isNil(v) && v !== '');\n if (defined.length === 0) return null;\n if (defined.every((v) => typeof v === 'number')) return Math.max(...(defined as number[]));\n const dates = defined.map(toDate);\n if (dates.every((d) => d !== null)) {\n return new Date(Math.max(...dates.map((d) => (d as Date).getTime())));\n }\n const sorted = defined.slice().sort((a, b) => stringComparator(a, b, null as any, null as any));\n return sorted[sorted.length - 1];\n },\n },\n size: {\n label: 'size',\n apply: ({ values }) => values.length,\n },\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Locale\n * ----------------------------------------------------------------------------------------------- */\n\nexport const DEFAULT_LOCALE_TEXT: MGHGridLocaleText = {\n noRowsLabel: 'No rows',\n loadingLabel: 'Loading…',\n toolbarColumns: 'Columns',\n toolbarFilters: 'Filters',\n toolbarExport: 'Export',\n toolbarDensity: 'Density',\n toolbarQuickFilterPlaceholder: 'Search...',\n toolbarQuickFilterLabel: 'Search',\n toolbarExportCSV: 'Download as CSV',\n toolbarExportExcel: 'Download as Excel',\n toolbarExportPrint: 'Print',\n densityCompact: 'Compact',\n densityStandard: 'Standard',\n densityComfortable: 'Comfortable',\n columnsPanelSearchPlaceholder: 'Search',\n columnsPanelShowAll: 'Show all',\n columnsPanelHideAll: 'Hide all',\n columnsPanelReset: 'Reset',\n filterPanelAddFilter: 'Add filter',\n filterPanelRemoveAll: 'Remove all',\n filterPanelDeleteIcon: 'Delete',\n filterPanelColumns: 'Columns',\n filterPanelOperator: 'Operator',\n filterPanelValue: 'Value',\n filterPanelInputPlaceholder: 'Filter value',\n filterPanelLogicOperator: 'Logic operator',\n filterPanelOperatorAnd: 'And',\n filterPanelOperatorOr: 'Or',\n columnMenuSortAsc: 'Sort by ASC',\n columnMenuSortDesc: 'Sort by DESC',\n columnMenuUnsort: 'Unsort',\n columnMenuFilter: 'Filter',\n columnMenuHideColumn: 'Hide column',\n columnMenuManageColumns: 'Manage columns',\n columnMenuPinLeft: 'Pin to left',\n columnMenuPinRight: 'Pin to right',\n columnMenuUnpin: 'Unpin',\n columnMenuGroup: (name) => `Group by ${name}`,\n columnMenuUngroup: (name) => `Stop grouping by ${name}`,\n columnMenuAggregation: 'Aggregation',\n aggregationMenuItemHeader: 'Aggregation',\n aggregationFunctionLabelNone: 'none',\n aggregationFunctionLabelSum: 'sum',\n aggregationFunctionLabelAvg: 'avg',\n aggregationFunctionLabelMin: 'min',\n aggregationFunctionLabelMax: 'max',\n aggregationFunctionLabelSize: 'size',\n footerRowSelected: (count) => (count === 1 ? '1 row selected' : `${count.toLocaleString()} rows selected`),\n footerTotalRows: 'Total Rows:',\n footerPaginationRowsPerPage: 'Rows per page:',\n footerPaginationDisplayedRows: (from, to, count) => `${from}–${to} of ${count.toLocaleString()}`,\n footerPaginationFirstPage: 'First page',\n footerPaginationPreviousPage: 'Previous page',\n footerPaginationNextPage: 'Next page',\n footerPaginationLastPage: 'Last page',\n checkboxSelectionHeaderName: 'Checkbox selection',\n checkboxSelectionSelectAllRows: 'Select all rows',\n checkboxSelectionUnselectAllRows: 'Unselect all rows',\n checkboxSelectionSelectRow: 'Select row',\n checkboxSelectionUnselectRow: 'Unselect row',\n booleanCellTrueLabel: 'yes',\n booleanCellFalseLabel: 'no',\n detailPanelToggle: 'Detail panel toggle',\n expandDetailPanel: 'Expand',\n collapseDetailPanel: 'Collapse',\n groupingColumnHeaderName: 'Group',\n groupColumn: (name) => `Group by ${name}`,\n unGroupColumn: (name) => `Stop grouping by ${name}`,\n actionsCellMore: 'more',\n columnHeaderSortIconLabel: 'Sort',\n columnMenuLabel: 'Menu',\n clearSearch: 'Clear search',\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Text measurement (used for autosize)\n * ----------------------------------------------------------------------------------------------- */\n\nlet measureContext: CanvasRenderingContext2D | null | undefined;\n\nexport const measureText = (text: string, font: string) => {\n if (typeof document === 'undefined') return text.length * 8;\n if (measureContext === undefined) {\n const canvas = document.createElement('canvas');\n measureContext = canvas.getContext('2d');\n }\n if (!measureContext) return text.length * 8;\n measureContext.font = font;\n return measureContext.measureText(text).width;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Downloads\n * ----------------------------------------------------------------------------------------------- */\n\nexport const downloadBlob = (blob: Blob, fileName: string) => {\n if (typeof document === 'undefined') return;\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = fileName;\n anchor.style.display = 'none';\n document.body.appendChild(anchor);\n anchor.click();\n window.setTimeout(() => {\n document.body.removeChild(anchor);\n URL.revokeObjectURL(url);\n }, 0);\n};\n","import React from 'react';\n\nexport const MGH_GRID_STYLE_ID = 'mgh-grid-styles';\n\n/**\n * Stylesheet for MGHGrid. It is injected once into <head> the first time a grid mounts,\n * so consumers do not need a CSS loader. All colours are CSS variables so the look can be\n * customised globally (by redefining `--mgh-grid-*` on `.mgh-grid-card`) or per instance\n * through the `themeVars` prop.\n */\nexport const MGH_GRID_CSS = `\n.mgh-grid-card {\n --mgh-grid-font-family: inherit;\n --mgh-grid-font-size: 14px;\n --mgh-grid-radius: 16px;\n --mgh-grid-inner-radius: 4px;\n --mgh-grid-paper: #ffffff;\n --mgh-grid-bg: #ffffff;\n --mgh-grid-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-fg-secondary: rgba(0, 0, 0, 0.6);\n --mgh-grid-fg-disabled: rgba(0, 0, 0, 0.38);\n --mgh-grid-border: rgba(224, 224, 224, 1);\n --mgh-grid-header-bg: #ffffff;\n --mgh-grid-header-fg: rgba(0, 0, 0, 0.87);\n --mgh-grid-hover: rgba(0, 0, 0, 0.04);\n --mgh-grid-hover-strong: rgba(0, 0, 0, 0.08);\n --mgh-grid-selected: rgba(25, 118, 210, 0.08);\n --mgh-grid-selected-hover: rgba(25, 118, 210, 0.12);\n --mgh-grid-primary: #1976d2;\n --mgh-grid-primary-contrast: #ffffff;\n --mgh-grid-focus: #1976d2;\n --mgh-grid-shadow: 0 0 2px rgba(145, 158, 171, 0.2), 0 12px 24px -4px rgba(145, 158, 171, 0.12);\n --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n --mgh-grid-overlay: rgba(255, 255, 255, 0.6);\n --mgh-grid-input-bg: transparent;\n --mgh-grid-input-border: rgba(0, 0, 0, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.12);\n --mgh-grid-group-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-footer-bg: rgba(0, 0, 0, 0.02);\n --mgh-grid-badge: #1976d2;\n --mgh-grid-scrollbar: rgba(0, 0, 0, 0.3);\n\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n background: var(--mgh-grid-paper);\n color: var(--mgh-grid-fg);\n border-radius: var(--mgh-grid-radius);\n box-shadow: var(--mgh-grid-shadow);\n font-family: var(--mgh-grid-font-family);\n font-size: var(--mgh-grid-font-size);\n line-height: 1.5;\n overflow: hidden;\n box-sizing: border-box;\n}\n.mgh-grid-card[data-mgh-theme=\"dark\"] {\n --mgh-grid-paper: #212b36;\n --mgh-grid-bg: #212b36;\n --mgh-grid-fg: #ffffff;\n --mgh-grid-fg-secondary: rgba(255, 255, 255, 0.7);\n --mgh-grid-fg-disabled: rgba(255, 255, 255, 0.5);\n --mgh-grid-border: rgba(81, 81, 81, 1);\n --mgh-grid-header-bg: #212b36;\n --mgh-grid-header-fg: #ffffff;\n --mgh-grid-hover: rgba(255, 255, 255, 0.08);\n --mgh-grid-hover-strong: rgba(255, 255, 255, 0.16);\n --mgh-grid-selected: rgba(144, 202, 249, 0.16);\n --mgh-grid-selected-hover: rgba(144, 202, 249, 0.24);\n --mgh-grid-primary: #90caf9;\n --mgh-grid-primary-contrast: rgba(0, 0, 0, 0.87);\n --mgh-grid-focus: #90caf9;\n --mgh-grid-shadow: 0 0 2px rgba(0, 0, 0, 0.2), 0 12px 24px -4px rgba(0, 0, 0, 0.12);\n --mgh-grid-overlay: rgba(33, 43, 54, 0.6);\n --mgh-grid-input-border: rgba(255, 255, 255, 0.23);\n --mgh-grid-pinned-shadow: rgba(0, 0, 0, 0.5);\n --mgh-grid-group-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-footer-bg: rgba(255, 255, 255, 0.03);\n --mgh-grid-badge: #90caf9;\n --mgh-grid-scrollbar: rgba(255, 255, 255, 0.3);\n}\n/* Only our own elements get the border-box reset. A blanket descendant reset would leak into\n consumer content rendered through slots (e.g. MUI TextField inputs rely on content-box). */\n[class*=\"mgh-grid\"], [class*=\"mgh-grid\"]::before, [class*=\"mgh-grid\"]::after { box-sizing: border-box; }\n.mgh-grid-card--plain { box-shadow: none; border-radius: 0; background: transparent; }\n\n/* ---- card header ---- */\n/* Title stays on its row; only the end-content group wraps internally (like the legacy MUI card). */\n.mgh-grid-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 16px 16px 16px 0; flex-wrap: nowrap; }\n.mgh-grid-card-title { flex: 0 0 auto; padding: 8px 24px; margin: 0; font-size: 1.125rem; font-weight: 700; line-height: 1.5556; }\n/* Children are auto-sized so space-between leaves equal gaps title|center|end (like the legacy MUI card).\n Only the end group shrinks (and wraps internally); the centre content keeps its natural width. */\n.mgh-grid-card-header-center { flex: 0 0 auto; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 16px; flex-wrap: wrap; }\n.mgh-grid-card-header-end { flex: 0 1 auto; min-width: 0; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; justify-content: flex-end; }\n.mgh-grid-card-header-end:first-child { margin-left: auto; }\n@media (max-width: 599.95px) {\n .mgh-grid-card-header { flex-wrap: wrap; }\n .mgh-grid-card-header-end { gap: 8px; }\n}\n\n/* ---- box + root ---- */\n.mgh-grid-box { display: flex; flex-direction: column; flex-grow: 1; min-height: 0; min-width: 0; }\n.mgh-grid {\n position: relative;\n display: flex;\n flex-direction: column;\n flex: 1 1 auto;\n min-height: 0;\n min-width: 0;\n border: 1px solid var(--mgh-grid-border);\n border-radius: var(--mgh-grid-inner-radius);\n background: var(--mgh-grid-bg);\n color: var(--mgh-grid-fg);\n outline: none;\n}\n.mgh-grid--auto-height { flex: 0 0 auto; }\n\n/* ---- toolbar ---- */\n.mgh-grid-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 45px; padding: 4px 8px; border-bottom: 1px solid var(--mgh-grid-border); flex-wrap: wrap; }\n.mgh-grid-toolbar-group { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }\n.mgh-grid-toolbar-center { display: flex; align-items: center; flex: 1 1 auto; justify-content: center; }\n\n/* ---- buttons ---- */\n.mgh-grid-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 0; margin: 0; background: transparent; color: var(--mgh-grid-fg-secondary); font: inherit; font-size: 0.8125rem; font-weight: 500; line-height: 1.75; letter-spacing: .02em; padding: 4px 8px; border-radius: 4px; cursor: pointer; user-select: none; transition: background-color .15s, color .15s; text-transform: none; white-space: nowrap; }\n.mgh-grid-btn:hover { background: var(--mgh-grid-hover); color: var(--mgh-grid-fg); }\n.mgh-grid-btn:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 1px; }\n.mgh-grid-btn:disabled { color: var(--mgh-grid-fg-disabled); cursor: default; background: transparent; }\n.mgh-grid-btn--icon { padding: 6px; border-radius: 50%; width: 32px; height: 32px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small { width: 26px; height: 26px; padding: 3px; }\n.mgh-grid-btn--icon.mgh-grid-btn--small .mgh-grid-icon { width: 18px; height: 18px; }\n.mgh-grid-btn--primary { color: var(--mgh-grid-primary); }\n.mgh-grid-btn--primary:hover { background: var(--mgh-grid-selected); color: var(--mgh-grid-primary); }\n.mgh-grid-btn--contained { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); }\n.mgh-grid-btn--contained:hover { background: var(--mgh-grid-primary); color: var(--mgh-grid-primary-contrast); filter: brightness(0.92); }\n.mgh-grid-btn--active { color: var(--mgh-grid-primary); }\n\n/* ---- badge ---- */\n.mgh-grid-badge { position: relative; display: inline-flex; }\n.mgh-grid-badge-dot { position: absolute; top: 0; right: 0; min-width: 8px; height: 8px; border-radius: 4px; background: var(--mgh-grid-badge); transform: translate(50%, -50%); }\n.mgh-grid-badge-count { position: absolute; top: 0; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--mgh-grid-badge); color: var(--mgh-grid-primary-contrast); font-size: 10px; font-weight: 600; line-height: 16px; text-align: center; transform: translate(50%, -50%); }\n\n/* ---- inputs ---- */\n.mgh-grid-input, .mgh-grid-select { font: inherit; font-size: 0.875rem; color: var(--mgh-grid-fg); background: var(--mgh-grid-input-bg); border: 1px solid var(--mgh-grid-input-border); border-radius: 6px; padding: 6px 10px; height: 36px; min-width: 0; outline: none; transition: border-color .15s, box-shadow .15s; }\n.mgh-grid-input:hover, .mgh-grid-select:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-input:focus, .mgh-grid-select:focus { border-color: var(--mgh-grid-focus); box-shadow: 0 0 0 1px var(--mgh-grid-focus); }\n.mgh-grid-input::placeholder { color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-input--small, .mgh-grid-select--small { height: 32px; padding: 4px 8px; font-size: 0.8125rem; }\n.mgh-grid-select { appearance: none; -webkit-appearance: none; padding-right: 28px; background-image: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23888'><path d='M7 10l5 5 5-5z'/></svg>\"); background-repeat: no-repeat; background-position: right 6px center; background-size: 18px; cursor: pointer; }\n.mgh-grid-select option { color: initial; background: initial; }\n.mgh-grid-card[data-mgh-theme=\"dark\"] .mgh-grid-select option, .mgh-grid-popover[data-mgh-theme=\"dark\"] .mgh-grid-select option { color: #fff; background: #212b36; }\n.mgh-grid-select[multiple] { height: auto; min-height: 36px; background-image: none; padding-right: 10px; }\n.mgh-grid-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n.mgh-grid-field-label { font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-input-adorned { position: relative; display: flex; align-items: center; }\n.mgh-grid-input-adorned .mgh-grid-input { width: 100%; padding-left: 34px; }\n.mgh-grid-input-adorned--clearable .mgh-grid-input { padding-right: 34px; }\n.mgh-grid-input-adornment { position: absolute; left: 10px; display: inline-flex; color: var(--mgh-grid-fg-secondary); pointer-events: none; }\n.mgh-grid-input-adornment--end { left: auto; right: 4px; pointer-events: auto; }\n\n/* ---- checkbox ---- */\n.mgh-grid-checkbox { appearance: none; -webkit-appearance: none; width: 18px; height: 18px; margin: 0; border: 2px solid var(--mgh-grid-fg-secondary); border-radius: 3px; background: transparent; cursor: pointer; display: inline-grid; place-content: center; position: relative; flex: 0 0 auto; transition: background-color .12s, border-color .12s; }\n.mgh-grid-checkbox:hover { border-color: var(--mgh-grid-fg); }\n.mgh-grid-checkbox:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: 2px; }\n.mgh-grid-checkbox:checked, .mgh-grid-checkbox:indeterminate { background: var(--mgh-grid-primary); border-color: var(--mgh-grid-primary); }\n.mgh-grid-checkbox:checked::after { content: \"\"; width: 5px; height: 10px; border: solid var(--mgh-grid-primary-contrast); border-width: 0 2px 2px 0; transform: translateY(-1px) rotate(45deg); }\n.mgh-grid-checkbox:indeterminate::after { content: \"\"; width: 10px; height: 2px; background: var(--mgh-grid-primary-contrast); }\n.mgh-grid-checkbox:disabled { opacity: 0.4; cursor: default; }\n.mgh-grid-checkbox-label { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; font-size: 0.875rem; padding: 6px 4px; border-radius: 4px; }\n.mgh-grid-checkbox-label:hover { background: var(--mgh-grid-hover); }\n\n/* ---- quick filter ---- */\n.mgh-grid-quick-filter { display: grid; align-items: center; }\n.mgh-grid-quick-filter-trigger { grid-area: 1 / 1; z-index: 1; transition: opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-trigger { opacity: 0; pointer-events: none; }\n.mgh-grid-quick-filter-control { grid-area: 1 / 1; width: 32px; opacity: 0; overflow: hidden; transition: width .2s, opacity .2s; }\n.mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 260px; opacity: 1; }\n@media (max-width: 599.95px) { .mgh-grid-quick-filter--expanded .mgh-grid-quick-filter-control { width: 180px; } }\n\n/* ---- main / scroller ---- */\n.mgh-grid-main { position: relative; display: flex; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: hidden; }\n.mgh-grid--auto-height .mgh-grid-main { flex: 0 0 auto; }\n.mgh-grid-scroller { position: relative; flex: 1 1 auto; min-height: 0; min-width: 0; overflow: auto; outline: none; scrollbar-width: thin; }\n.mgh-grid--auto-height .mgh-grid-scroller { overflow-y: hidden; }\n.mgh-grid-scroller::-webkit-scrollbar { width: 10px; height: 10px; }\n.mgh-grid-scroller::-webkit-scrollbar-thumb { background: var(--mgh-grid-scrollbar); border-radius: 5px; border: 2px solid transparent; background-clip: content-box; }\n\n/* ---- column headers ---- */\n.mgh-grid-columns { position: sticky; top: 0; z-index: 3; background: var(--mgh-grid-header-bg); border-bottom: 1px solid var(--mgh-grid-border); min-width: 100%; width: max-content; }\n.mgh-grid-header-row { display: flex; min-width: 100%; }\n.mgh-grid-header-cell { position: relative; display: flex; align-items: center; flex: 0 0 auto; height: var(--mgh-grid-header-height); padding: 0 10px; font-weight: 600; font-size: 0.875rem; color: var(--mgh-grid-header-fg); background: var(--mgh-grid-header-bg); white-space: nowrap; overflow: hidden; user-select: none; outline: none; }\n.mgh-grid-header-cell--sortable { cursor: pointer; }\n.mgh-grid-header-cell:focus-visible { outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; }\n.mgh-grid-header-cell--align-center { justify-content: center; }\n.mgh-grid-header-cell--align-right { justify-content: flex-end; }\n.mgh-grid-header-cell--align-right .mgh-grid-header-title-container { flex-direction: row-reverse; }\n.mgh-grid-header-title-container { display: flex; align-items: center; gap: 2px; min-width: 0; flex: 1 1 auto; overflow: hidden; }\n.mgh-grid-header-cell--align-center .mgh-grid-header-title-container { flex: 0 1 auto; }\n.mgh-grid-header-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.mgh-grid-sort-icon { display: inline-flex; align-items: center; color: var(--mgh-grid-fg-secondary); opacity: 0; transition: opacity .15s; flex: 0 0 auto; }\n.mgh-grid-header-cell:hover .mgh-grid-sort-icon, .mgh-grid-sort-icon--active { opacity: 1; }\n.mgh-grid-sort-index { font-size: 10px; margin-left: -2px; color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-header-menu-btn { position: absolute; right: 2px; opacity: 0; transition: opacity .15s; background: var(--mgh-grid-header-bg); }\n.mgh-grid-header-cell--align-right .mgh-grid-header-menu-btn { right: auto; left: 2px; }\n.mgh-grid-header-cell:hover .mgh-grid-header-menu-btn, .mgh-grid-header-menu-btn--open, .mgh-grid-header-cell:focus-within .mgh-grid-header-menu-btn { opacity: 1; }\n.mgh-grid-header-cell--menu-open { background: var(--mgh-grid-hover); }\n.mgh-grid-resize-handle { position: absolute; top: 0; right: -4px; width: 9px; height: 100%; cursor: col-resize; z-index: 2; display: flex; justify-content: center; touch-action: none; }\n.mgh-grid-resize-handle::after { content: \"\"; width: 1px; height: 60%; margin-top: 20%; background: var(--mgh-grid-border); transition: background .15s, width .15s; }\n.mgh-grid-resize-handle:hover::after, .mgh-grid-resize-handle--active::after { background: var(--mgh-grid-primary); width: 2px; }\n.mgh-grid-header-cell--last .mgh-grid-resize-handle { right: 0; }\n.mgh-grid-header-cell--dragging { opacity: 0.5; }\n.mgh-grid-header-cell--drop-left::before, .mgh-grid-header-cell--drop-right::before { content: \"\"; position: absolute; top: 4px; bottom: 4px; width: 2px; background: var(--mgh-grid-primary); z-index: 3; }\n.mgh-grid-header-cell--drop-left::before { left: 0; }\n.mgh-grid-header-cell--drop-right::before { right: 0; }\n.mgh-grid-header-filler { flex: 1 1 auto; background: var(--mgh-grid-header-bg); }\n\n/* ---- pinned cells ---- */\n.mgh-grid-cell--pinned-left, .mgh-grid-header-cell--pinned-left { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-cell--pinned-right, .mgh-grid-header-cell--pinned-right { position: sticky; z-index: 2; background-color: var(--mgh-grid-bg); }\n.mgh-grid-header-cell--pinned-left, .mgh-grid-header-cell--pinned-right { z-index: 4; background-color: var(--mgh-grid-header-bg); }\n.mgh-grid-cell--pinned-left-last, .mgh-grid-header-cell--pinned-left-last { box-shadow: 2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-cell--pinned-right-first, .mgh-grid-header-cell--pinned-right-first { box-shadow: -2px 0 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid--no-pinned-shadow .mgh-grid-cell--pinned-left-last, .mgh-grid--no-pinned-shadow .mgh-grid-header-cell--pinned-left-last { box-shadow: none; }\n\n/* ---- body & rows ---- */\n.mgh-grid-body { position: relative; min-width: 100%; width: max-content; }\n.mgh-grid-body--flow { display: flex; flex-direction: column; }\n.mgh-grid-row-block { min-width: 100%; }\n.mgh-grid-body--virtual .mgh-grid-row-block { position: absolute; left: 0; }\n.mgh-grid-row { display: flex; min-width: 100%; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); position: relative; }\n.mgh-grid-row--auto-height { align-items: stretch; }\n.mgh-grid-row:hover { background: var(--mgh-grid-hover); }\n.mgh-grid-row--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-row--selected:hover { background: var(--mgh-grid-selected-hover); }\n.mgh-grid-row--clickable { cursor: pointer; }\n.mgh-grid-row--group { background: var(--mgh-grid-group-bg); }\n.mgh-grid-row--pinned { background: var(--mgh-grid-bg); }\n.mgh-grid-row--footer { background: var(--mgh-grid-footer-bg); font-weight: 600; }\n.mgh-grid-row:hover .mgh-grid-cell--pinned-left, .mgh-grid-row:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-hover), var(--mgh-grid-hover)); }\n.mgh-grid-row--selected .mgh-grid-cell--pinned-left, .mgh-grid-row--selected .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected), var(--mgh-grid-selected)); }\n.mgh-grid-row--selected:hover .mgh-grid-cell--pinned-left, .mgh-grid-row--selected:hover .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-selected-hover), var(--mgh-grid-selected-hover)); }\n.mgh-grid-row--group .mgh-grid-cell--pinned-left, .mgh-grid-row--group .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-group-bg), var(--mgh-grid-group-bg)); }\n.mgh-grid-row--footer .mgh-grid-cell--pinned-left, .mgh-grid-row--footer .mgh-grid-cell--pinned-right { background-image: linear-gradient(var(--mgh-grid-footer-bg), var(--mgh-grid-footer-bg)); }\n.mgh-grid-row-filler { flex: 1 1 auto; }\n\n.mgh-grid-cell { display: flex; align-items: center; flex: 0 0 auto; padding: 0 10px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 0.875rem; outline: none; min-height: 100%; }\n.mgh-grid-cell > .mgh-grid-cell-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }\n.mgh-grid-row--auto-height .mgh-grid-cell { white-space: normal; align-items: flex-start; padding-top: 8px; padding-bottom: 8px; }\n.mgh-grid-row--auto-height .mgh-grid-cell > .mgh-grid-cell-text { white-space: normal; word-break: break-word; }\n.mgh-grid-cell--align-center { justify-content: center; }\n.mgh-grid-cell--align-right { justify-content: flex-end; }\n.mgh-grid-cell--focused { outline: 1px solid var(--mgh-grid-focus); outline-offset: -1px; }\n.mgh-grid-cell--editable { cursor: text; }\n.mgh-grid-cell--editing { padding: 0 4px; outline: 2px solid var(--mgh-grid-focus); outline-offset: -2px; background: var(--mgh-grid-bg); }\n.mgh-grid-cell--editing .mgh-grid-input, .mgh-grid-cell--editing .mgh-grid-select { width: 100%; height: calc(100% - 6px); border: 0; box-shadow: none; padding: 0 6px; background: transparent; }\n.mgh-grid-cell--checkbox, .mgh-grid-header-cell--checkbox, .mgh-grid-cell--detail-toggle, .mgh-grid-header-cell--detail-toggle { justify-content: center; padding: 0; }\n.mgh-grid-cell--boolean .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); }\n.mgh-grid-cell--actions { gap: 2px; justify-content: center; }\n.mgh-grid-cell--aggregation { flex-direction: column; align-items: stretch; justify-content: center; line-height: 1.2; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-right { align-items: flex-end; }\n.mgh-grid-cell--aggregation.mgh-grid-cell--align-center { align-items: center; }\n.mgh-grid-aggregation-label { font-size: 0.65rem; font-weight: 500; text-transform: uppercase; color: var(--mgh-grid-fg-secondary); letter-spacing: .04em; }\n.mgh-grid-group-cell { display: flex; align-items: center; gap: 4px; min-width: 0; }\n.mgh-grid-group-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }\n.mgh-grid-group-count { color: var(--mgh-grid-fg-secondary); margin-left: 2px; }\n.mgh-grid-group-toggle { flex: 0 0 auto; }\n.mgh-grid-group-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-group-toggle--expanded .mgh-grid-icon { transform: rotate(90deg); }\n.mgh-grid-detail-toggle .mgh-grid-icon { transition: transform .15s; }\n.mgh-grid-detail-toggle--expanded .mgh-grid-icon { transform: rotate(180deg); }\n\n/* ---- pinned rows ---- */\n.mgh-grid-pinned-rows { position: sticky; z-index: 2; min-width: 100%; width: max-content; background: var(--mgh-grid-bg); }\n.mgh-grid-pinned-rows--top { box-shadow: 0 2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom { bottom: 0; box-shadow: 0 -2px 4px -2px var(--mgh-grid-pinned-shadow); }\n.mgh-grid-pinned-rows--bottom .mgh-grid-row { border-bottom: 0; border-top: 1px solid var(--mgh-grid-border); }\n\n/* ---- detail panel ---- */\n.mgh-grid-detail-panel { position: sticky; left: 0; overflow: auto; border-bottom: 1px solid var(--mgh-grid-border); background: var(--mgh-grid-bg); z-index: 1; }\n\n/* ---- overlays ---- */\n.mgh-grid-overlay { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 8px; z-index: 5; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; pointer-events: none; }\n.mgh-grid-overlay--loading { background: var(--mgh-grid-overlay); pointer-events: auto; }\n.mgh-grid-no-rows { display: flex; align-items: center; justify-content: center; gap: 8px; height: 100%; text-align: center; padding: 16px; }\n.mgh-grid-no-rows img, .mgh-grid-no-rows .mgh-grid-icon { width: 50px; height: 50px; color: var(--mgh-grid-fg-disabled); }\n.mgh-grid-spinner { width: 36px; height: 36px; border-radius: 50%; border: 3px solid var(--mgh-grid-selected); border-top-color: var(--mgh-grid-primary); animation: mgh-grid-spin .8s linear infinite; }\n@keyframes mgh-grid-spin { to { transform: rotate(360deg); } }\n\n/* ---- footer ---- */\n.mgh-grid-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 52px; padding: 0 8px 0 16px; border-top: 1px solid var(--mgh-grid-border); font-size: 0.875rem; color: var(--mgh-grid-fg-secondary); flex-wrap: wrap; }\n.mgh-grid-footer-left { display: flex; align-items: center; gap: 16px; }\n.mgh-grid-pagination { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }\n.mgh-grid-pagination-select { height: 32px; padding: 2px 24px 2px 8px; font-size: 0.875rem; border-color: transparent; }\n.mgh-grid-pagination-select:hover { border-color: transparent; background-color: var(--mgh-grid-hover); }\n.mgh-grid-pagination-actions { display: inline-flex; align-items: center; }\n\n/* ---- popover / menu / panels ---- */\n.mgh-grid-popover {\n --mgh-grid-font-family: inherit; --mgh-grid-font-size: 14px; --mgh-grid-paper: #ffffff; --mgh-grid-bg: #fff; --mgh-grid-fg: rgba(0,0,0,.87); --mgh-grid-fg-secondary: rgba(0,0,0,.6); --mgh-grid-fg-disabled: rgba(0,0,0,.38); --mgh-grid-border: rgba(224,224,224,1); --mgh-grid-hover: rgba(0,0,0,.04); --mgh-grid-selected: rgba(25,118,210,.08); --mgh-grid-primary: #1976d2; --mgh-grid-primary-contrast: #fff; --mgh-grid-focus: #1976d2; --mgh-grid-input-bg: transparent; --mgh-grid-input-border: rgba(0,0,0,.23); --mgh-grid-popover-shadow: 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12);\n position: fixed; z-index: 1300; background: var(--mgh-grid-paper); color: var(--mgh-grid-fg); border-radius: 8px; box-shadow: var(--mgh-grid-popover-shadow); font-family: var(--mgh-grid-font-family); font-size: var(--mgh-grid-font-size); line-height: 1.5; outline: none; max-height: calc(100vh - 16px); overflow: auto; animation: mgh-grid-pop .12s ease-out;\n}\n.mgh-grid-popover[data-mgh-theme=\"dark\"] { --mgh-grid-paper: #212b36; --mgh-grid-bg: #212b36; --mgh-grid-fg: #fff; --mgh-grid-fg-secondary: rgba(255,255,255,.7); --mgh-grid-fg-disabled: rgba(255,255,255,.5); --mgh-grid-border: rgba(81,81,81,1); --mgh-grid-hover: rgba(255,255,255,.08); --mgh-grid-selected: rgba(144,202,249,.16); --mgh-grid-primary: #90caf9; --mgh-grid-primary-contrast: rgba(0,0,0,.87); --mgh-grid-focus: #90caf9; --mgh-grid-input-border: rgba(255,255,255,.23); }\n@keyframes mgh-grid-pop { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: scale(1); } }\n.mgh-grid-menu { list-style: none; margin: 0; padding: 6px 0; min-width: 180px; }\n.mgh-grid-menu-item { display: flex; align-items: center; gap: 12px; padding: 6px 16px; min-height: 36px; font-size: 0.875rem; cursor: pointer; white-space: nowrap; color: var(--mgh-grid-fg); background: transparent; border: 0; width: 100%; text-align: left; font-family: inherit; outline: none; }\n.mgh-grid-menu-item:hover, .mgh-grid-menu-item:focus-visible { background: var(--mgh-grid-hover); }\n.mgh-grid-menu-item--disabled { color: var(--mgh-grid-fg-disabled); cursor: default; pointer-events: none; }\n.mgh-grid-menu-item--selected { background: var(--mgh-grid-selected); }\n.mgh-grid-menu-item .mgh-grid-icon { color: var(--mgh-grid-fg-secondary); flex: 0 0 auto; }\n.mgh-grid-menu-divider { height: 1px; margin: 6px 0; background: var(--mgh-grid-border); border: 0; }\n.mgh-grid-menu-header { padding: 6px 16px 2px; font-size: 0.75rem; color: var(--mgh-grid-fg-secondary); text-transform: uppercase; letter-spacing: .04em; }\n.mgh-grid-menu-section { padding: 4px 16px 8px; display: flex; flex-direction: column; gap: 4px; }\n.mgh-grid-panel { display: flex; flex-direction: column; min-width: 300px; max-width: min(640px, calc(100vw - 16px)); }\n.mgh-grid-panel-header { padding: 12px 12px 4px; }\n.mgh-grid-panel-content { padding: 4px 12px; overflow: auto; max-height: 360px; }\n.mgh-grid-panel-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; }\n.mgh-grid-columns-list { display: flex; flex-direction: column; }\n.mgh-grid-filter-row { display: grid; grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); gap: 8px; align-items: end; margin-bottom: 8px; }\n.mgh-grid-filter-row--first { grid-template-columns: 32px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row--with-logic { grid-template-columns: 32px 80px minmax(120px, 1fr) minmax(120px, 1fr) minmax(140px, 1.3fr); }\n.mgh-grid-filter-row .mgh-grid-btn--icon { margin-bottom: 4px; }\n.mgh-grid-filter-empty { padding: 8px 4px; color: var(--mgh-grid-fg-secondary); font-size: 0.875rem; }\n@media (max-width: 599.95px) { .mgh-grid-filter-row, .mgh-grid-filter-row--with-logic { grid-template-columns: 1fr; } }\n\n/* ---- misc ---- */\n.mgh-grid-tooltip-anchor { display: inline-flex; }\n.mgh-grid-visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); border: 0; }\n@media print { .mgh-grid-toolbar, .mgh-grid-footer { display: none !important; } }\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_GRID_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_GRID_STYLE_ID;\n style.setAttribute('data-mgh-grid', 'true');\n style.textContent = MGH_GRID_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHGrid stylesheet once per document. Safe on the server (no-op). */\nexport const useMGHGridStyles = () => {\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import React from 'react';\nimport {\n MGHGridAggregationFunction,\n MGHGridApi,\n MGHGridColDef,\n MGHGridLocaleText,\n MGHGridState,\n MGHGridThemeMode,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\n\nexport interface MGHGridRootProps {\n header?: React.ReactNode;\n pagination: boolean;\n pageSizeOptions: number[];\n hideFooterPagination: boolean;\n hideFooterRowCount: boolean;\n hideFooterSelectedRowCount: boolean;\n disableColumnFilter: boolean;\n disableColumnSelector: boolean;\n disableDensitySelector: boolean;\n disableColumnPinning: boolean;\n disableColumnSorting: boolean;\n disableMultipleColumnsSorting: boolean;\n disableMultipleColumnsFiltering: boolean;\n disableRowGrouping: boolean;\n disableAggregation: boolean;\n checkboxSelection: boolean;\n aggregationFunctions: Record<string, MGHGridAggregationFunction>;\n quickFilterDebounceMs: number;\n}\n\nexport interface MGHGridContextValue {\n api: MGHGridApi;\n state: MGHGridState;\n localeText: MGHGridLocaleText;\n themeMode: MGHGridThemeMode;\n rootProps: MGHGridRootProps;\n /** All user columns (ordered, including hidden). */\n columns: MGHGridColDef[];\n /** Visible user columns. */\n visibleColumns: MGHGridColDef[];\n}\n\nexport const MGHGridContext = React.createContext<MGHGridContextValue | null>(null);\nMGHGridContext.displayName = 'MGHGridContext';\n\nexport const useMGHGridContext = () => {\n const ctx = React.useContext(MGHGridContext);\n if (!ctx) {\n throw new Error('MGHGrid: this component must be rendered inside an <MGHGrid /> (e.g. through a slot).');\n }\n return ctx;\n};\n\n/** Access the grid API from custom toolbars, menu items, cells, etc. */\nexport const useMGHGridApiContext = <R extends MGHGridValidRowModel = any>() => useMGHGridContext().api as MGHGridApi<R>;\n\nexport const useMGHGridLocaleText = () => useMGHGridContext().localeText;\n\n/** Creates a ref to hold the grid API; pass it to `<MGHGrid apiRef={apiRef} />`. */\nexport const useMGHGridApiRef = <R extends MGHGridValidRowModel = any>() =>\n React.useRef<MGHGridApi<R> | null>(null) as React.MutableRefObject<MGHGridApi<R> | null>;\n","import React from 'react';\n\n/** Keeps a ref always pointing at the latest value (assigned during render). */\nexport function useLatestRef<T>(value: T) {\n const ref = React.useRef(value);\n ref.current = value;\n return ref;\n}\n\n/** Returns a stable function that always calls the latest `fn`. */\nexport function useEventCallback<T extends (...args: any[]) => any>(fn: T): T {\n const ref = useLatestRef(fn);\n return React.useCallback(((...args: any[]) => ref.current(...args)) as T, []);\n}\n\n/**\n * Controlled / uncontrolled state helper. When `controlled` is defined the internal state is\n * ignored and every change is reported through `onChange` only.\n */\nexport function useControlledState<T>(\n controlled: T | undefined,\n defaultValue: T,\n onChange?: (value: T) => void\n): [T, (next: T | ((prev: T) => T)) => void] {\n const isControlled = controlled !== undefined;\n const [internal, setInternal] = React.useState<T>(defaultValue);\n const value = isControlled ? (controlled as T) : internal;\n const valueRef = useLatestRef(value);\n const controlledRef = useLatestRef(isControlled);\n const onChangeRef = useLatestRef(onChange);\n\n const setValue = React.useCallback((next: T | ((prev: T) => T)) => {\n const resolved = typeof next === 'function' ? (next as (prev: T) => T)(valueRef.current) : next;\n if (Object.is(resolved, valueRef.current)) return;\n valueRef.current = resolved;\n if (!controlledRef.current) setInternal(resolved);\n onChangeRef.current?.(resolved);\n }, []);\n\n return [value, setValue];\n}\n\nexport interface ElementSize {\n width: number;\n height: number;\n}\n\n/** Observes the client size of an element. */\nexport function useElementSize<T extends HTMLElement>(ref: React.RefObject<T | null>, enabled = true): ElementSize {\n const [size, setSize] = React.useState<ElementSize>({ width: 0, height: 0 });\n\n React.useLayoutEffect(() => {\n const el = ref.current;\n if (!el || !enabled) return undefined;\n const update = () => {\n const width = el.clientWidth;\n const height = el.clientHeight;\n setSize((prev) => (prev.width === width && prev.height === height ? prev : { width, height }));\n };\n update();\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', update);\n return () => window.removeEventListener('resize', update);\n }\n const observer = new ResizeObserver(update);\n observer.observe(el);\n return () => observer.disconnect();\n }, [ref, enabled]);\n\n return size;\n}\n\n/** `window.matchMedia` as a hook. Always false on the server. */\nexport function useMediaQuery(query: string) {\n const getMatch = () =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function' ? window.matchMedia(query).matches : false;\n const [matches, setMatches] = React.useState(getMatch);\n\n React.useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return undefined;\n const media = window.matchMedia(query);\n const listener = () => setMatches(media.matches);\n listener();\n if (media.addEventListener) {\n media.addEventListener('change', listener);\n return () => media.removeEventListener('change', listener);\n }\n media.addListener(listener);\n return () => media.removeListener(listener);\n }, [query]);\n\n return matches;\n}\n\n/** Debounced version of a callback. The returned function is stable. */\nexport function useDebouncedCallback<T extends (...args: any[]) => void>(fn: T, delay: number) {\n const fnRef = useLatestRef(fn);\n const timerRef = React.useRef<number | null>(null);\n\n React.useEffect(\n () => () => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n },\n []\n );\n\n return React.useCallback(\n (...args: Parameters<T>) => {\n if (timerRef.current !== null) window.clearTimeout(timerRef.current);\n timerRef.current = window.setTimeout(() => {\n timerRef.current = null;\n fnRef.current(...args);\n }, delay);\n },\n [delay]\n );\n}\n\nexport function useForceUpdate() {\n const [, setTick] = React.useState(0);\n return React.useCallback(() => setTick((t) => t + 1), []);\n}\n\nlet idCounter = 0;\n/** Stable unique id per component instance (React.useId fallback for older Reacts). */\nexport function useStableId(prefix: string) {\n const reactUseId = (React as any).useId as undefined | (() => string);\n if (reactUseId) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const id = reactUseId();\n return `${prefix}-${id.replace(/:/g, '')}`;\n }\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const ref = React.useRef<string | null>(null);\n if (ref.current === null) {\n idCounter += 1;\n ref.current = `${prefix}-${idCounter}`;\n }\n return ref.current;\n}\n","import {\n MGHGridApi,\n MGHGridColDef,\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridExportOptions,\n MGHGridPrintExportOptions,\n MGHGridRowId,\n} from './MGHGrid.types';\nimport {\n downloadBlob,\n formattedValueToString,\n getCellValue,\n getFormattedValue,\n isInternalField,\n isNil,\n toDate,\n} from './utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Shared: resolve the columns & rows to export\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ExportCell {\n raw: any;\n formatted: string;\n col: MGHGridColDef;\n}\n\nexport interface ExportTable {\n columns: MGHGridColDef[];\n headers: string[];\n rows: ExportCell[][];\n}\n\nexport const resolveExportColumns = (api: MGHGridApi, options: MGHGridExportOptions): MGHGridColDef[] => {\n const all = api.getAllColumns();\n let columns: MGHGridColDef[];\n if (options.fields) {\n const byField = new Map<string, MGHGridColDef>();\n all.forEach((c) => byField.set(c.field, c));\n columns = options.fields.map((f) => byField.get(f)).filter(Boolean) as MGHGridColDef[];\n } else if (options.allColumns) {\n columns = all;\n } else {\n columns = api.getVisibleColumns();\n }\n return columns.filter((c) => !c.disableExport && !isInternalField(c.field) && c.type !== 'actions');\n};\n\nexport const buildExportTable = (api: MGHGridApi, options: MGHGridExportOptions): ExportTable => {\n const columns = resolveExportColumns(api, options);\n const ids: MGHGridRowId[] = options.getRowsToExport ? options.getRowsToExport({ api }) : api.getSortedRowIds();\n const rows: ExportCell[][] = [];\n ids.forEach((id) => {\n const row = api.getRow(id);\n if (!row) return;\n rows.push(\n columns.map((col) => {\n const raw = getCellValue(row, col, api);\n const formatted = formattedValueToString(getFormattedValue(raw, row, col, api, id));\n return { raw, formatted, col };\n })\n );\n });\n return { columns, headers: columns.map((c) => c.headerName ?? c.field), rows };\n};\n\nconst sanitizeFileName = (name: string | undefined, fallback: string, extension: string) => {\n const base = (name && name.trim()) || fallback;\n return base.toLowerCase().endsWith(`.${extension}`) ? base : `${base}.${extension}`;\n};\n\nconst defaultFileBase = () => {\n const title = typeof document !== 'undefined' && document.title ? document.title.trim() : '';\n return (title || 'export').replace(/[\\\\/:*?\"<>|]+/g, '-');\n};\n\n/* -------------------------------------------------------------------------------------------------\n * CSV\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeCsvCell = (value: string, delimiter: string) => {\n let text = value;\n // Guard against formula injection when opening in spreadsheet software.\n if (/^[=+\\-@\\t\\r]/.test(text)) text = `'${text}`;\n if (text.indexOf('\"') !== -1 || text.indexOf(delimiter) !== -1 || /[\\r\\n]/.test(text)) {\n return `\"${text.replace(/\"/g, '\"\"')}\"`;\n }\n return text;\n};\n\nexport const getDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const delimiter = options.delimiter ?? ',';\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const lines: string[] = [];\n if (includeHeaders) {\n lines.push(table.headers.map((h) => escapeCsvCell(h, delimiter)).join(delimiter));\n }\n table.rows.forEach((cells) => {\n lines.push(\n cells\n .map((cell) => {\n const text = options.useRawValues ? (isNil(cell.raw) ? '' : String(cell.raw)) : cell.formatted;\n return escapeCsvCell(text, delimiter);\n })\n .join(delimiter)\n );\n });\n return lines.join('\\r\\n');\n};\n\nconst UTF8_BOM = String.fromCharCode(0xfeff);\n\nexport const exportDataAsCsv = (api: MGHGridApi, options: MGHGridCsvExportOptions = {}) => {\n const csv = getDataAsCsv(api, options);\n const bom = options.utf8WithBom ? UTF8_BOM : '';\n const blob = new Blob([bom + csv], { type: 'text/csv;charset=utf-8;' });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'csv'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * XLSX (minimal OOXML writer + store-only ZIP, no dependencies)\n * ----------------------------------------------------------------------------------------------- */\n\nconst CRC_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n += 1) {\n let c = n;\n for (let k = 0; k < 8; k += 1) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\nconst crc32 = (bytes: Uint8Array) => {\n let crc = 0xffffffff;\n for (let i = 0; i < bytes.length; i += 1) {\n crc = CRC_TABLE[(crc ^ bytes[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n};\n\nconst textEncoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null;\n\nconst encodeUtf8 = (text: string): Uint8Array => {\n if (textEncoder) return textEncoder.encode(text);\n // Fallback for very old environments.\n const utf8 = unescape(encodeURIComponent(text));\n const out = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i += 1) out[i] = utf8.charCodeAt(i);\n return out;\n};\n\ninterface ZipEntry {\n name: string;\n data: Uint8Array;\n}\n\nconst concatBytes = (chunks: Uint8Array[]) => {\n const total = chunks.reduce((acc, c) => acc + c.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n chunks.forEach((c) => {\n out.set(c, offset);\n offset += c.length;\n });\n return out;\n};\n\nconst zipStore = (entries: ZipEntry[]): Uint8Array => {\n const localChunks: Uint8Array[] = [];\n const centralChunks: Uint8Array[] = [];\n let offset = 0;\n // 1980-01-01 00:00 in DOS date/time format.\n const dosTime = 0;\n const dosDate = (1 << 5) | 1;\n\n entries.forEach((entry) => {\n const nameBytes = encodeUtf8(entry.name);\n const crc = crc32(entry.data);\n const size = entry.data.length;\n\n const local = new Uint8Array(30 + nameBytes.length);\n const lv = new DataView(local.buffer);\n lv.setUint32(0, 0x04034b50, true);\n lv.setUint16(4, 20, true);\n lv.setUint16(6, 0x0800, true); // UTF-8 names\n lv.setUint16(8, 0, true); // store\n lv.setUint16(10, dosTime, true);\n lv.setUint16(12, dosDate, true);\n lv.setUint32(14, crc, true);\n lv.setUint32(18, size, true);\n lv.setUint32(22, size, true);\n lv.setUint16(26, nameBytes.length, true);\n lv.setUint16(28, 0, true);\n local.set(nameBytes, 30);\n\n const central = new Uint8Array(46 + nameBytes.length);\n const cv = new DataView(central.buffer);\n cv.setUint32(0, 0x02014b50, true);\n cv.setUint16(4, 20, true);\n cv.setUint16(6, 20, true);\n cv.setUint16(8, 0x0800, true);\n cv.setUint16(10, 0, true);\n cv.setUint16(12, dosTime, true);\n cv.setUint16(14, dosDate, true);\n cv.setUint32(16, crc, true);\n cv.setUint32(20, size, true);\n cv.setUint32(24, size, true);\n cv.setUint16(28, nameBytes.length, true);\n cv.setUint16(30, 0, true);\n cv.setUint16(32, 0, true);\n cv.setUint16(34, 0, true);\n cv.setUint16(36, 0, true);\n cv.setUint32(38, 0, true);\n cv.setUint32(42, offset, true);\n central.set(nameBytes, 46);\n\n localChunks.push(local, entry.data);\n centralChunks.push(central);\n offset += local.length + size;\n });\n\n const centralDirectory = concatBytes(centralChunks);\n const eocd = new Uint8Array(22);\n const ev = new DataView(eocd.buffer);\n ev.setUint32(0, 0x06054b50, true);\n ev.setUint16(4, 0, true);\n ev.setUint16(6, 0, true);\n ev.setUint16(8, entries.length, true);\n ev.setUint16(10, entries.length, true);\n ev.setUint32(12, centralDirectory.length, true);\n ev.setUint32(16, offset, true);\n ev.setUint16(20, 0, true);\n\n return concatBytes(localChunks.concat([centralDirectory, eocd]));\n};\n\n// Characters that are illegal in XML 1.0 (built without literal control characters in source).\nconst INVALID_XML_CHARS = new RegExp(\n '[' +\n String.fromCharCode(0x00) +\n '-' +\n String.fromCharCode(0x08) +\n String.fromCharCode(0x0b) +\n String.fromCharCode(0x0c) +\n String.fromCharCode(0x0e) +\n '-' +\n String.fromCharCode(0x1f) +\n String.fromCharCode(0xfffe) +\n String.fromCharCode(0xffff) +\n ']',\n 'g'\n);\nconst stripInvalidXml = (text: string) => text.replace(INVALID_XML_CHARS, '');\n\nconst escapeXml = (text: string) =>\n stripInvalidXml(text)\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n\nconst columnLetter = (index: number) => {\n let n = index + 1;\n let letters = '';\n while (n > 0) {\n const rem = (n - 1) % 26;\n letters = String.fromCharCode(65 + rem) + letters;\n n = Math.floor((n - 1) / 26);\n }\n return letters;\n};\n\nconst sanitizeSheetName = (name: string | undefined) => {\n const cleaned = (name || 'Sheet1').replace(/[\\[\\]:*?/\\\\]/g, ' ').trim() || 'Sheet1';\n return cleaned.length > 31 ? cleaned.slice(0, 31) : cleaned;\n};\n\nconst XML_HEADER = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n';\n\nconst buildSheetXml = (table: ExportTable, includeHeaders: boolean, columnWidths: number[]) => {\n const rowsXml: string[] = [];\n let rowIndex = 1;\n\n const inlineString = (ref: string, text: string, style?: number) =>\n `<c r=\"${ref}\" t=\"inlineStr\"${style ? ` s=\"${style}\"` : ''}><is><t xml:space=\"preserve\">${escapeXml(\n text\n )}</t></is></c>`;\n\n if (includeHeaders) {\n const cells = table.headers.map((h, i) => inlineString(`${columnLetter(i)}${rowIndex}`, h, 1)).join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${cells}</row>`);\n rowIndex += 1;\n }\n\n table.rows.forEach((cells) => {\n const xmlCells = cells\n .map((cell, i) => {\n const ref = `${columnLetter(i)}${rowIndex}`;\n const type = cell.col.type;\n if (isNil(cell.raw) || cell.raw === '') return '';\n if (type === 'number' && typeof cell.raw === 'number' && Number.isFinite(cell.raw)) {\n return `<c r=\"${ref}\"><v>${cell.raw}</v></c>`;\n }\n if (type === 'boolean') {\n return `<c r=\"${ref}\" t=\"b\"><v>${cell.raw ? 1 : 0}</v></c>`;\n }\n if ((type === 'date' || type === 'dateTime') && toDate(cell.raw)) {\n // Excel serial date (days since 1899-12-30), written in local time with a date style.\n const d = toDate(cell.raw) as Date;\n const utc = Date.UTC(\n d.getFullYear(),\n d.getMonth(),\n d.getDate(),\n d.getHours(),\n d.getMinutes(),\n d.getSeconds()\n );\n const serial = utc / 86400000 + 25569;\n return `<c r=\"${ref}\" s=\"${type === 'dateTime' ? 3 : 2}\"><v>${serial}</v></c>`;\n }\n return inlineString(ref, cell.formatted);\n })\n .join('');\n rowsXml.push(`<row r=\"${rowIndex}\">${xmlCells}</row>`);\n rowIndex += 1;\n });\n\n const lastCol = columnLetter(Math.max(table.columns.length - 1, 0));\n const lastRow = Math.max(rowIndex - 1, 1);\n const cols = columnWidths.map((w, i) => `<col min=\"${i + 1}\" max=\"${i + 1}\" width=\"${w}\" customWidth=\"1\"/>`).join('');\n\n return (\n XML_HEADER +\n '<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<dimension ref=\"A1:${lastCol}${lastRow}\"/>` +\n '<sheetViews><sheetView workbookViewId=\"0\">' +\n (includeHeaders ? '<pane ySplit=\"1\" topLeftCell=\"A2\" activePane=\"bottomLeft\" state=\"frozen\"/>' : '') +\n '</sheetView></sheetViews>' +\n '<sheetFormatPr defaultRowHeight=\"15\"/>' +\n (cols ? `<cols>${cols}</cols>` : '') +\n `<sheetData>${rowsXml.join('')}</sheetData>` +\n (includeHeaders && table.rows.length > 0 ? `<autoFilter ref=\"A1:${lastCol}${lastRow}\"/>` : '') +\n '</worksheet>'\n );\n};\n\nconst STYLES_XML =\n XML_HEADER +\n '<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">' +\n '<numFmts count=\"2\"><numFmt numFmtId=\"164\" formatCode=\"m/d/yyyy\"/><numFmt numFmtId=\"165\" formatCode=\"m/d/yyyy h:mm AM/PM\"/></numFmts>' +\n '<fonts count=\"2\"><font><sz val=\"11\"/><name val=\"Calibri\"/></font><font><b/><sz val=\"11\"/><name val=\"Calibri\"/></font></fonts>' +\n '<fills count=\"2\"><fill><patternFill patternType=\"none\"/></fill><fill><patternFill patternType=\"gray125\"/></fill></fills>' +\n '<borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>' +\n '<cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>' +\n '<cellXfs count=\"4\">' +\n '<xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>' +\n '<xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>' +\n '<xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '<xf numFmtId=\"165\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>' +\n '</cellXfs>' +\n '<cellStyles count=\"1\"><cellStyle name=\"Normal\" xfId=\"0\" builtinId=\"0\"/></cellStyles>' +\n '</styleSheet>';\n\nconst CONTENT_TYPES_XML =\n XML_HEADER +\n '<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">' +\n '<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>' +\n '<Default Extension=\"xml\" ContentType=\"application/xml\"/>' +\n '<Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>' +\n '<Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>' +\n '<Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>' +\n '<Override PartName=\"/docProps/core.xml\" ContentType=\"application/vnd.openxmlformats-package.core-properties+xml\"/>' +\n '<Override PartName=\"/docProps/app.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.extended-properties+xml\"/>' +\n '</Types>';\n\nconst ROOT_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\" Target=\"docProps/core.xml\"/>' +\n '<Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\" Target=\"docProps/app.xml\"/>' +\n '</Relationships>';\n\nconst WORKBOOK_RELS_XML =\n XML_HEADER +\n '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">' +\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>' +\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>' +\n '</Relationships>';\n\nconst buildWorkbookXml = (sheetName: string) =>\n XML_HEADER +\n '<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" ' +\n 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">' +\n `<sheets><sheet name=\"${escapeXml(sheetName)}\" sheetId=\"1\" r:id=\"rId1\"/></sheets>` +\n '</workbook>';\n\nconst buildCoreXml = () => {\n const now = new Date().toISOString();\n return (\n XML_HEADER +\n '<cp:coreProperties xmlns:cp=\"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\" ' +\n 'xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:dcterms=\"http://purl.org/dc/terms/\" ' +\n 'xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n '<dc:creator>MGH Grid</dc:creator>' +\n `<dcterms:created xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:created>` +\n `<dcterms:modified xsi:type=\"dcterms:W3CDTF\">${now}</dcterms:modified>` +\n '</cp:coreProperties>'\n );\n};\n\nconst APP_XML =\n XML_HEADER +\n '<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" ' +\n 'xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">' +\n '<Application>MGH Grid</Application></Properties>';\n\nexport const buildXlsx = (api: MGHGridApi, options: MGHGridExcelExportOptions = {}): Uint8Array => {\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const widths = table.columns.map((col, i) => {\n const explicit = options.columnsStyles?.[col.field]?.width;\n if (explicit) return explicit;\n let max = table.headers[i].length;\n for (let r = 0; r < Math.min(table.rows.length, 500); r += 1) {\n const len = table.rows[r][i].formatted.length;\n if (len > max) max = len;\n }\n return Math.min(Math.max(max + 2, 8), 60);\n });\n const sheetName = sanitizeSheetName(options.sheetName);\n const entries: ZipEntry[] = [\n { name: '[Content_Types].xml', data: encodeUtf8(CONTENT_TYPES_XML) },\n { name: '_rels/.rels', data: encodeUtf8(ROOT_RELS_XML) },\n { name: 'docProps/core.xml', data: encodeUtf8(buildCoreXml()) },\n { name: 'docProps/app.xml', data: encodeUtf8(APP_XML) },\n { name: 'xl/workbook.xml', data: encodeUtf8(buildWorkbookXml(sheetName)) },\n { name: 'xl/_rels/workbook.xml.rels', data: encodeUtf8(WORKBOOK_RELS_XML) },\n { name: 'xl/styles.xml', data: encodeUtf8(STYLES_XML) },\n { name: 'xl/worksheets/sheet1.xml', data: encodeUtf8(buildSheetXml(table, includeHeaders, widths)) },\n ];\n return zipStore(entries);\n};\n\nexport const exportDataAsExcel = async (api: MGHGridApi, options: MGHGridExcelExportOptions = {}) => {\n const bytes = buildXlsx(api, options);\n const blob = new Blob([bytes as BlobPart], {\n type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n });\n downloadBlob(blob, sanitizeFileName(options.fileName, defaultFileBase(), 'xlsx'));\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Print\n * ----------------------------------------------------------------------------------------------- */\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/** Legacy value-based print (plain HTML table). The grid's `exportDataAsPrint` prints the live DOM instead. */\nexport const exportDataAsPrintTable = (api: MGHGridApi, options: MGHGridPrintExportOptions = {}) => {\n if (typeof document === 'undefined') return;\n const includeHeaders = options.includeHeaders ?? true;\n const table = buildExportTable(api, options);\n const title = options.title ?? options.fileName ?? document.title ?? '';\n\n const headerHtml = includeHeaders\n ? `<thead><tr>${table.headers\n .map((h, i) => `<th class=\"${table.columns[i].align ?? 'left'}\">${escapeHtml(h)}</th>`)\n .join('')}</tr></thead>`\n : '';\n const bodyHtml = `<tbody>${table.rows\n .map(\n (cells) =>\n `<tr>${cells\n .map((cell) => `<td class=\"${cell.col.align ?? 'left'}\">${escapeHtml(cell.formatted)}</td>`)\n .join('')}</tr>`\n )\n .join('')}</tbody>`;\n\n const html =\n '<!doctype html><html><head><meta charset=\"utf-8\" />' +\n `<title>${escapeHtml(title)}</title>` +\n '<style>' +\n 'body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif;font-size:12px;color:#111;margin:16px;}' +\n 'h1{font-size:16px;margin:0 0 12px;}' +\n 'table{border-collapse:collapse;width:100%;}' +\n 'th,td{border:1px solid #ccc;padding:4px 8px;text-align:left;vertical-align:top;}' +\n 'th{background:#f3f3f3;font-weight:600;}' +\n 'td.right,th.right{text-align:right;} td.center,th.center{text-align:center;}' +\n 'tr{page-break-inside:avoid;} thead{display:table-header-group;}' +\n (options.pageStyle ?? '') +\n '</style></head><body>' +\n (title ? `<h1>${escapeHtml(title)}</h1>` : '') +\n `<table>${headerHtml}${bodyHtml}</table>` +\n '</body></html>';\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.style.position = 'fixed';\n iframe.style.right = '0';\n iframe.style.bottom = '0';\n iframe.style.width = '0';\n iframe.style.height = '0';\n iframe.style.border = '0';\n iframe.style.opacity = '0';\n document.body.appendChild(iframe);\n\n const cleanup = () => {\n window.setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n }, 1000);\n };\n\n iframe.onload = () => {\n const win = iframe.contentWindow;\n if (!win) {\n cleanup();\n return;\n }\n try {\n win.focus();\n win.onafterprint = cleanup;\n win.print();\n } catch {\n cleanup();\n }\n };\n\n const doc = iframe.contentDocument || iframe.contentWindow?.document;\n if (doc) {\n doc.open();\n doc.write(html);\n doc.close();\n } else {\n iframe.srcdoc = html;\n }\n};\n","import { MGHGridPrintExportOptions } from './MGHGrid.types';\n\n/**\n * Prints the grid \"as seen on screen\": the live DOM of the grid card is cloned into a hidden iframe\n * together with the page's stylesheets, so anything rendered by `renderCell` (images, chips,\n * links, custom components) prints exactly as displayed. The grid itself must already be rendered\n * in print mode (all rows, no virtualization) when this is called.\n */\n\nconst PRINT_CSS = `\n@page { margin: 10mm; }\nhtml, body { margin: 0; padding: 0; background: #fff; }\n.mgh-grid-print-title { margin: 0 0 12px; font: 600 16px/1.4 -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif; }\n.mgh-grid-card { box-shadow: none !important; border-radius: 0 !important; height: auto !important; max-height: none !important; overflow: visible !important; background: transparent !important; }\n.mgh-grid-box { height: auto !important; max-height: none !important; flex: none !important; }\n.mgh-grid { height: auto !important; max-height: none !important; border-radius: 0 !important; }\n.mgh-grid-main, .mgh-grid-scroller { overflow: visible !important; height: auto !important; max-height: none !important; }\n.mgh-grid-columns, .mgh-grid-pinned-rows, .mgh-grid-detail-panel { position: static !important; box-shadow: none !important; }\n.mgh-grid-header-cell, .mgh-grid-cell { position: static !important; box-shadow: none !important; background-image: none !important; }\n.mgh-grid-detail-panel { width: auto !important; }\n.mgh-grid-body { min-height: 0 !important; }\n.mgh-grid-row, .mgh-grid-row-block, .mgh-grid-detail-panel { break-inside: avoid; page-break-inside: avoid; }\n.mgh-grid-columns { break-after: avoid; page-break-after: avoid; }\n.mgh-grid-header-menu-btn, .mgh-grid-resize-handle, .mgh-grid-overlay, .mgh-grid-sort-icon:not(.mgh-grid-sort-icon--active) { display: none !important; }\n.mgh-grid-popover { display: none !important; }\n`;\n\nconst collectStyles = (doc: Document) => {\n const styles: string[] = [];\n const links: string[] = [];\n Array.from(doc.styleSheets).forEach((sheet) => {\n try {\n const rules = Array.from(sheet.cssRules)\n .map((rule) => rule.cssText)\n .join('\\n');\n if (rules) styles.push(rules);\n } catch {\n // Cross-origin stylesheet: reference it instead of inlining.\n if (sheet.href) links.push(sheet.href);\n }\n });\n return { styles, links };\n};\n\nconst escapeHtml = (text: string) =>\n text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n\n/** Copies live form-control state (cloneNode does not copy `checked` / `value`). */\nconst syncFormState = (source: HTMLElement, target: HTMLElement) => {\n const sourceInputs = Array.from(source.querySelectorAll('input, select, textarea'));\n const targetInputs = Array.from(target.querySelectorAll('input, select, textarea'));\n sourceInputs.forEach((el, i) => {\n const t = targetInputs[i];\n if (!t || t.tagName !== el.tagName) return;\n // Tag-name checks instead of `instanceof`: the elements may belong to different documents.\n if (el.tagName === 'INPUT') {\n const src = el as HTMLInputElement;\n const dst = t as HTMLInputElement;\n if (src.type === 'checkbox' || src.type === 'radio') {\n dst.checked = src.checked;\n if (src.checked) dst.setAttribute('checked', '');\n dst.indeterminate = src.indeterminate;\n } else {\n dst.value = src.value;\n dst.setAttribute('value', src.value);\n }\n } else if (el.tagName === 'SELECT') {\n (t as HTMLSelectElement).value = (el as HTMLSelectElement).value;\n } else if (el.tagName === 'TEXTAREA') {\n (t as HTMLTextAreaElement).value = (el as HTMLTextAreaElement).value;\n t.textContent = (el as HTMLTextAreaElement).value;\n }\n });\n // Canvases lose their bitmap when cloned: replace them with images.\n const sourceCanvases = Array.from(source.querySelectorAll('canvas'));\n const targetCanvases = Array.from(target.querySelectorAll('canvas'));\n sourceCanvases.forEach((canvas, i) => {\n const t = targetCanvases[i];\n if (!t) return;\n try {\n const img = t.ownerDocument.createElement('img');\n img.src = canvas.toDataURL();\n img.width = canvas.width;\n img.height = canvas.height;\n img.style.cssText = t.style.cssText;\n t.replaceWith(img);\n } catch {\n /* tainted canvas – leave as is */\n }\n });\n};\n\nconst waitForImages = (doc: Document, timeoutMs: number) =>\n new Promise<void>((resolve) => {\n const images = Array.from(doc.images).filter((img) => !img.complete);\n if (images.length === 0) {\n resolve();\n return;\n }\n let remaining = images.length;\n let done = false;\n const finish = () => {\n if (done) return;\n done = true;\n resolve();\n };\n const timer = window.setTimeout(finish, timeoutMs);\n images.forEach((img) => {\n const onSettled = () => {\n remaining -= 1;\n if (remaining <= 0) {\n window.clearTimeout(timer);\n finish();\n }\n };\n img.addEventListener('load', onSettled, { once: true });\n img.addEventListener('error', onSettled, { once: true });\n });\n });\n\nexport interface PrintGridParams {\n /** The `.mgh-grid-card` element (already rendered in print mode). */\n cardElement: HTMLElement;\n options: MGHGridPrintExportOptions;\n /** Called once the print dialog has been handed off (or failed) so the grid can leave print mode. */\n onDone: () => void;\n}\n\nexport const printGridElement = (params: PrintGridParams) => {\n let done = false;\n const onDone = () => {\n if (done) return;\n done = true;\n params.onDone();\n };\n try {\n printGridElementUnsafe({ ...params, onDone });\n } catch (error) {\n console.error('MGHGrid: print failed', error);\n onDone();\n }\n};\n\nconst printGridElementUnsafe = ({ cardElement, options, onDone }: PrintGridParams) => {\n if (typeof document === 'undefined') {\n onDone();\n return;\n }\n const hideToolbar = options.hideToolbar ?? true;\n const hideFooter = options.hideFooter ?? false;\n const includeHeaders = options.includeHeaders ?? true;\n const copyStyles = options.copyStyles ?? true;\n\n const clone = cardElement.cloneNode(true) as HTMLElement;\n syncFormState(cardElement, clone);\n clone.querySelectorAll('.mgh-grid-card-header').forEach((el) => el.remove());\n if (hideToolbar) clone.querySelectorAll('.mgh-grid-toolbar').forEach((el) => el.remove());\n if (hideFooter) clone.querySelectorAll('.mgh-grid-footer').forEach((el) => el.remove());\n if (!includeHeaders) clone.querySelectorAll('.mgh-grid-columns').forEach((el) => el.remove());\n clone.classList.add('mgh-grid-card--plain');\n // Remove ids to avoid duplicates and drop inline sizing coming from cardStyle/boxStyle.\n clone.querySelectorAll('[id]').forEach((el) => el.removeAttribute('id'));\n clone.style.height = 'auto';\n clone.style.flexGrow = '0';\n\n const title = options.title ?? '';\n const { styles, links } = copyStyles ? collectStyles(document) : { styles: [], links: [] };\n\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n iframe.setAttribute('data-mgh-grid-print', 'true');\n iframe.style.cssText = 'position:fixed;right:0;bottom:0;width:0;height:0;border:0;opacity:0;pointer-events:none;';\n document.body.appendChild(iframe);\n\n let finished = false;\n const finish = () => {\n if (finished) return;\n finished = true;\n window.setTimeout(() => {\n if (iframe.parentNode) iframe.parentNode.removeChild(iframe);\n }, 500);\n onDone();\n };\n\n const win = iframe.contentWindow;\n const doc = iframe.contentDocument || win?.document;\n if (!win || !doc) {\n finish();\n return;\n }\n\n doc.open();\n doc.write(\n `<!doctype html><html><head><meta charset=\"utf-8\" /><title>${escapeHtml(title || document.title || 'Print')}</title>` +\n links.map((href) => `<link rel=\"stylesheet\" href=\"${escapeHtml(href)}\" />`).join('') +\n `</head><body></body></html>`\n );\n doc.close();\n\n styles.forEach((css) => {\n const style = doc.createElement('style');\n style.textContent = css;\n doc.head.appendChild(style);\n });\n const printStyle = doc.createElement('style');\n printStyle.textContent = PRINT_CSS + (options.pageStyle ?? '');\n doc.head.appendChild(printStyle);\n\n if (title) {\n const h1 = doc.createElement('h1');\n h1.className = 'mgh-grid-print-title';\n h1.textContent = title;\n doc.body.appendChild(h1);\n }\n doc.body.appendChild(doc.adoptNode(clone));\n\n const run = async () => {\n try {\n await waitForImages(doc, 4000);\n if (options.onBeforePrint) await options.onBeforePrint(doc);\n win.onafterprint = finish;\n win.focus();\n win.print();\n // Most browsers block on print(); if afterprint never fires, still restore the grid.\n window.setTimeout(finish, 1000);\n } catch {\n finish();\n }\n };\n void run();\n};\n","import {\n MGHGridAggregationFunction,\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridColDef,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridRowId,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport { formattedValueToString, getCellValue, getFormattedValue, getGroupingValue, isNil } from './utils';\n\nexport interface RowEntry<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n row: R;\n}\n\n/** Internal tree node used while grouping. */\nexport interface GroupTreeNode<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n depth: number;\n parent: MGHGridRowId | null;\n groupingField: string;\n groupingKey: any;\n groupingLabel: string;\n childGroups: GroupTreeNode<R>[];\n /** Direct leaf children (only populated at the deepest level). */\n leaves: RowEntry<R>[];\n /** Every descendant leaf, in display order after sorting. */\n descendants: RowEntry<R>[];\n}\n\nexport interface DisplayRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n type: 'leaf' | 'group';\n row: R | null;\n node: MGHGridLeafNode | MGHGridGroupNode;\n depth: number;\n group?: GroupTreeNode<R>;\n}\n\nexport const GROUP_ID_PREFIX = 'auto-generated-row-';\n\nconst keyToString = (key: any) => (isNil(key) ? '' : key instanceof Date ? String(key.getTime()) : String(key));\n\nexport const buildGroupTree = <R extends MGHGridValidRowModel>(\n entries: RowEntry<R>[],\n groupingFields: string[],\n columnsByField: Map<string, MGHGridColDef<R>>,\n api: MGHGridApi<R>,\n emptyLabel = '(empty)'\n): GroupTreeNode<R>[] => {\n const build = (items: RowEntry<R>[], depth: number, parentId: MGHGridRowId | null, path: string): GroupTreeNode<R>[] => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return [];\n const buckets = new Map<string, GroupTreeNode<R>>();\n items.forEach((entry) => {\n const key = getGroupingValue(entry.row, col, api);\n const keyStr = keyToString(key);\n let node = buckets.get(keyStr);\n if (!node) {\n const label = formattedValueToString(getFormattedValue(key, entry.row, col, api, entry.id)) || emptyLabel;\n const id = `${GROUP_ID_PREFIX}${path}${field}/${keyStr}`;\n node = {\n id,\n depth,\n parent: parentId,\n groupingField: field,\n groupingKey: key,\n groupingLabel: label,\n childGroups: [],\n leaves: [],\n descendants: [],\n };\n buckets.set(keyStr, node);\n }\n node.leaves.push(entry);\n });\n const nodes: GroupTreeNode<R>[] = [];\n buckets.forEach((node) => {\n if (depth < groupingFields.length - 1) {\n node.childGroups = build(\n node.leaves,\n depth + 1,\n node.id,\n `${path}${field}/${keyToString(node.groupingKey)}|`\n );\n node.descendants = node.leaves;\n node.leaves = [];\n } else {\n node.descendants = node.leaves;\n }\n nodes.push(node);\n });\n return nodes;\n };\n return build(entries, 0, null, '');\n};\n\nexport type GroupComparator<R extends MGHGridValidRowModel = any> = (a: GroupTreeNode<R>, b: GroupTreeNode<R>) => number;\n\n/** Sorts groups (with the given comparator) and leaves (with the given sorter), recursively. */\nexport const sortGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n compareGroups: ((depth: number) => GroupComparator<R> | null) | null,\n sortLeaves: (leaves: RowEntry<R>[]) => RowEntry<R>[]\n): GroupTreeNode<R>[] => {\n const sortLevel = (nodes: GroupTreeNode<R>[], depth: number): GroupTreeNode<R>[] => {\n const comparator = compareGroups ? compareGroups(depth) : null;\n const sorted = comparator\n ? nodes\n .map((node, index) => ({ node, index }))\n .sort((a, b) => comparator(a.node, b.node) || a.index - b.index)\n .map((item) => item.node)\n : nodes;\n sorted.forEach((node) => {\n if (node.childGroups.length > 0) {\n node.childGroups = sortLevel(node.childGroups, depth + 1);\n const descendants: RowEntry<R>[] = [];\n node.childGroups.forEach((child) => child.descendants.forEach((d) => descendants.push(d)));\n node.descendants = descendants;\n } else {\n node.leaves = sortLeaves(node.leaves);\n node.descendants = node.leaves;\n }\n });\n return sorted;\n };\n return sortLevel(roots, 0);\n};\n\nexport const collectTreeLeaves = <R extends MGHGridValidRowModel>(roots: GroupTreeNode<R>[]): RowEntry<R>[] => {\n const out: RowEntry<R>[] = [];\n roots.forEach((root) => root.descendants.forEach((d) => out.push(d)));\n return out;\n};\n\nexport const toGroupNode = <R extends MGHGridValidRowModel>(\n node: GroupTreeNode<R>,\n isExpanded: boolean\n): MGHGridGroupNode => ({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: node.childGroups.length > 0 ? node.childGroups.map((c) => c.id) : node.leaves.map((l) => l.id),\n leafIds: node.descendants.map((d) => d.id),\n isExpanded,\n});\n\n/** Flattens the tree into display rows, honouring expansion state. Also fills `nodesById` with every node. */\nexport const flattenGroupTree = <R extends MGHGridValidRowModel>(\n roots: GroupTreeNode<R>[],\n isExpanded: (node: GroupTreeNode<R>) => boolean,\n nodesById: Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>,\n groupsById: Map<MGHGridRowId, GroupTreeNode<R>>\n): DisplayRow<R>[] => {\n const out: DisplayRow<R>[] = [];\n const visit = (nodes: GroupTreeNode<R>[], visible: boolean) => {\n nodes.forEach((node) => {\n const expanded = isExpanded(node);\n const groupNode = toGroupNode(node, expanded);\n nodesById.set(node.id, groupNode);\n groupsById.set(node.id, node);\n if (visible)\n out.push({ id: node.id, type: 'group', row: null, node: groupNode, depth: node.depth, group: node });\n const childVisible = visible && expanded;\n if (node.childGroups.length > 0) {\n visit(node.childGroups, childVisible);\n } else {\n node.leaves.forEach((leaf) => {\n const leafNode: MGHGridLeafNode = { type: 'leaf', id: leaf.id, depth: node.depth + 1, parent: node.id };\n nodesById.set(leaf.id, leafNode);\n if (childVisible)\n out.push({ id: leaf.id, type: 'leaf', row: leaf.row, node: leafNode, depth: node.depth + 1 });\n });\n }\n });\n };\n visit(roots, true);\n return out;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Aggregation\n * ----------------------------------------------------------------------------------------------- */\n\nexport const aggregateRows = <R extends MGHGridValidRowModel>(\n rows: R[],\n aggregationModel: MGHGridAggregationModel,\n columnsByField: Map<string, MGHGridColDef<R>>,\n functions: Record<string, MGHGridAggregationFunction>,\n api: MGHGridApi<R>\n): Record<string, { value: any; fn: string }> => {\n const result: Record<string, { value: any; fn: string }> = {};\n Object.keys(aggregationModel).forEach((field) => {\n const fnName = aggregationModel[field];\n const fn = functions[fnName];\n const col = columnsByField.get(field);\n if (!fn || !col || col.aggregable === false) return;\n const values = rows.map((row) => getCellValue(row, col, api));\n result[field] = { value: fn.apply({ values, field }), fn: fnName };\n });\n return result;\n};\n","import React from 'react';\n\n/* Small inline SVG icon set (Material Design icon paths, Apache-2.0). No external dependencies. */\n\nexport interface MGHGridIconProps extends React.SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nconst createIcon = (path: React.ReactNode, displayName: string) => {\n const Icon = React.forwardRef<SVGSVGElement, MGHGridIconProps>(({ size = 20, className, style, ...rest }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"currentColor\"\n focusable=\"false\"\n aria-hidden=\"true\"\n className={['mgh-grid-icon', className].filter(Boolean).join(' ')}\n style={style}\n {...rest}\n >\n {path}\n </svg>\n ));\n Icon.displayName = displayName;\n return Icon;\n};\n\nexport const ViewColumnIcon = createIcon(\n <path d=\"M14.67 5v14H9.33V5h5.34zm1 14H21V5h-5.33v14zm-7.34 0V5H3v14h5.33z\" />,\n 'ViewColumnIcon'\n);\nexport const FilterListIcon = createIcon(<path d=\"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z\" />, 'FilterListIcon');\nexport const SearchIcon = createIcon(\n <path d=\"M15.5 14h-.79l-.28-.27A6.471 6.471 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z\" />,\n 'SearchIcon'\n);\nexport const CloseIcon = createIcon(\n <path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />,\n 'CloseIcon'\n);\nexport const DownloadIcon = createIcon(\n <path d=\"M19 12v7H5v-7H3v7c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zm-6 .67 2.59-2.58L17 11.5l-5 5-5-5 1.41-1.41L11 12.67V3h2z\" />,\n 'DownloadIcon'\n);\nexport const ArrowUpwardIcon = createIcon(\n <path d=\"m4 12 1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z\" />,\n 'ArrowUpwardIcon'\n);\nexport const ArrowDownwardIcon = createIcon(\n <path d=\"m20 12-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z\" />,\n 'ArrowDownwardIcon'\n);\nexport const MoreVertIcon = createIcon(\n <path d=\"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'MoreVertIcon'\n);\nexport const CheckIcon = createIcon(<path d=\"M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\" />, 'CheckIcon');\nexport const ExpandMoreIcon = createIcon(<path d=\"M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z\" />, 'ExpandMoreIcon');\nexport const ChevronRightIcon = createIcon(<path d=\"M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\" />, 'ChevronRightIcon');\nexport const ChevronLeftIcon = createIcon(<path d=\"M15.41 7.41 14 6l-6 6 6 6 1.41-1.41L10.83 12z\" />, 'ChevronLeftIcon');\nexport const FirstPageIcon = createIcon(\n <path d=\"M18.41 16.59 13.82 12l4.59-4.59L17 6l-6 6 6 6zM6 6h2v12H6z\" />,\n 'FirstPageIcon'\n);\nexport const LastPageIcon = createIcon(\n <path d=\"M5.59 7.41 10.18 12l-4.59 4.59L7 18l6-6-6-6zM16 6h2v12h-2z\" />,\n 'LastPageIcon'\n);\nexport const PushPinIcon = createIcon(\n <path d=\"M16 9V4h1c.55 0 1-.45 1-1s-.45-1-1-1H7c-.55 0-1 .45-1 1s.45 1 1 1h1v5c0 1.66-1.34 3-3 3v2h5.97v7l1 1 1-1v-7H19v-2c-1.66 0-3-1.34-3-3z\" />,\n 'PushPinIcon'\n);\nexport const DeleteIcon = createIcon(\n <path d=\"M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z\" />,\n 'DeleteIcon'\n);\nexport const AddIcon = createIcon(<path d=\"M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\" />, 'AddIcon');\nexport const DensitySmallIcon = createIcon(\n <path d=\"M3 2h18v2H3zm0 18h18v2H3zm0-6h18v2H3zm0-6h18v2H3z\" />,\n 'DensitySmallIcon'\n);\nexport const DensityMediumIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3zm0-8h18v2H3z\" />, 'DensityMediumIcon');\nexport const DensityLargeIcon = createIcon(<path d=\"M3 3h18v2H3zm0 16h18v2H3z\" />, 'DensityLargeIcon');\nexport const DragIndicatorIcon = createIcon(\n <path d=\"M11 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm-2-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0-6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm6 4c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\" />,\n 'DragIndicatorIcon'\n);\nexport const PrintIcon = createIcon(\n <path d=\"M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z\" />,\n 'PrintIcon'\n);\nexport const TableChartIcon = createIcon(\n <path d=\"M10 10.02h5V21h-5zM17 21h3c1.1 0 2-.9 2-2v-9h-5v11zm3-18H5c-1.1 0-2 .9-2 2v3h19V5c0-1.1-.9-2-2-2zM3 19c0 1.1.9 2 2 2h3V10H3v9z\" />,\n 'TableChartIcon'\n);\nexport const DescriptionIcon = createIcon(\n <path d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z\" />,\n 'DescriptionIcon'\n);\nexport const VisibilityOffIcon = createIcon(\n <path d=\"M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46A11.804 11.804 0 0 0 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78 3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z\" />,\n 'VisibilityOffIcon'\n);\nexport const FunctionsIcon = createIcon(<path d=\"M18 4H6v2l6.5 6L6 18v2h12v-3h-7l5-5-5-5h7z\" />, 'FunctionsIcon');\nexport const WorkspacesIcon = createIcon(\n <path d=\"M6 13c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6-10C9.8 3 8 4.8 8 7s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm6 10c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4z\" />,\n 'WorkspacesIcon'\n);\nexport const EmptyBoxIcon = createIcon(\n <>\n <path\n d=\"M20 6h-2.18c.11-.31.18-.65.18-1a2.996 2.996 0 0 0-5.5-1.65l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2z\"\n opacity=\".25\"\n />\n <path d=\"M4 8h16v11H4z\" opacity=\".15\" />\n </>,\n 'EmptyBoxIcon'\n);\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { clamp, cx } from '../utils';\n\n/* -------------------------------------------------------------------------------------------------\n * Button / IconButton\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: 'text' | 'primary' | 'contained';\n size?: 'small' | 'medium';\n startIcon?: React.ReactNode;\n endIcon?: React.ReactNode;\n active?: boolean;\n}\n\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n { variant = 'text', size = 'medium', startIcon, endIcon, active, className, children, type = 'button', ...rest },\n ref\n ) => (\n <button\n ref={ref}\n type={type}\n className={cx(\n 'mgh-grid-btn',\n variant === 'primary' && 'mgh-grid-btn--primary',\n variant === 'contained' && 'mgh-grid-btn--contained',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {startIcon}\n {children}\n {endIcon}\n </button>\n )\n);\nButton.displayName = 'MGHGridButton';\n\nexport interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n size?: 'small' | 'medium';\n active?: boolean;\n /** Tooltip (native title) and aria-label. */\n label?: string;\n}\n\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(\n ({ size = 'medium', active, label, className, children, type = 'button', ...rest }, ref) => (\n <button\n ref={ref}\n type={type}\n title={label}\n aria-label={label}\n className={cx(\n 'mgh-grid-btn mgh-grid-btn--icon',\n size === 'small' && 'mgh-grid-btn--small',\n active && 'mgh-grid-btn--active',\n className\n )}\n {...rest}\n >\n {children}\n </button>\n )\n);\nIconButton.displayName = 'MGHGridIconButton';\n\n/* -------------------------------------------------------------------------------------------------\n * Badge\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface BadgeProps {\n count?: number;\n variant?: 'dot' | 'count';\n children: React.ReactNode;\n}\n\nexport const Badge = ({ count = 0, variant = 'dot', children }: BadgeProps) => (\n <span className=\"mgh-grid-badge\">\n {children}\n {count > 0 &&\n (variant === 'dot' ? (\n <span className=\"mgh-grid-badge-dot\" />\n ) : (\n <span className=\"mgh-grid-badge-count\">{count > 99 ? '99+' : count}</span>\n ))}\n </span>\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Inputs\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const TextInput = React.forwardRef<HTMLInputElement, TextInputProps>(\n ({ size = 'medium', className, ...rest }, ref) => (\n <input\n ref={ref}\n className={cx('mgh-grid-input', size === 'small' && 'mgh-grid-input--small', className)}\n {...rest}\n />\n )\n);\nTextInput.displayName = 'MGHGridTextInput';\n\nexport interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, 'size'> {\n size?: 'small' | 'medium';\n}\n\nexport const Select = React.forwardRef<HTMLSelectElement, SelectProps>(({ size = 'medium', className, ...rest }, ref) => (\n <select ref={ref} className={cx('mgh-grid-select', size === 'small' && 'mgh-grid-select--small', className)} {...rest} />\n));\nSelect.displayName = 'MGHGridSelect';\n\nexport interface FieldProps {\n label?: React.ReactNode;\n children: React.ReactNode;\n className?: string;\n htmlFor?: string;\n}\n\nexport const Field = ({ label, children, className, htmlFor }: FieldProps) => (\n <div className={cx('mgh-grid-field', className)}>\n {label && (\n <label className=\"mgh-grid-field-label\" htmlFor={htmlFor}>\n {label}\n </label>\n )}\n {children}\n </div>\n);\n\nexport interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n indeterminate?: boolean;\n label?: string;\n}\n\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n ({ indeterminate = false, label, className, ...rest }, forwardedRef) => {\n const innerRef = React.useRef<HTMLInputElement | null>(null);\n const setRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n innerRef.current = node;\n if (typeof forwardedRef === 'function') forwardedRef(node);\n else if (forwardedRef) (forwardedRef as React.MutableRefObject<HTMLInputElement | null>).current = node;\n },\n [forwardedRef]\n );\n React.useEffect(() => {\n if (innerRef.current) innerRef.current.indeterminate = indeterminate;\n }, [indeterminate]);\n return (\n <input\n ref={setRef}\n type=\"checkbox\"\n title={label}\n aria-label={label}\n className={cx('mgh-grid-checkbox', className)}\n {...rest}\n />\n );\n }\n);\nCheckbox.displayName = 'MGHGridCheckbox';\n\n/* -------------------------------------------------------------------------------------------------\n * Spinner\n * ----------------------------------------------------------------------------------------------- */\n\nexport const Spinner = ({ className }: { className?: string }) => (\n <div className={cx('mgh-grid-spinner', className)} role=\"progressbar\" aria-label=\"Loading\" />\n);\n\n/* -------------------------------------------------------------------------------------------------\n * Popover (portal, anchored)\n * ----------------------------------------------------------------------------------------------- */\n\nexport type PopoverPlacement = 'bottom-start' | 'bottom-end' | 'bottom' | 'right-start';\n\nexport interface PopoverProps {\n open: boolean;\n anchorEl: HTMLElement | null | undefined;\n onClose: (reason: 'backdrop' | 'escape') => void;\n children: React.ReactNode;\n placement?: PopoverPlacement;\n themeMode?: MGHGridThemeMode;\n className?: string;\n style?: React.CSSProperties;\n offset?: number;\n role?: string;\n autoFocus?: boolean;\n /** Additional elements considered \"inside\" for outside-click detection. */\n ignoreOutsideClickOn?: Array<React.RefObject<HTMLElement | null>>;\n}\n\nexport function Popover({\n open,\n anchorEl,\n onClose,\n children,\n placement = 'bottom-start',\n themeMode = 'light',\n className,\n style,\n offset = 4,\n role = 'dialog',\n autoFocus = false,\n ignoreOutsideClickOn,\n}: PopoverProps) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const [position, setPosition] = React.useState<{ top: number; left: number; ready: boolean }>({\n top: 0,\n left: 0,\n ready: false,\n });\n\n const update = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n let top: number;\n let left: number;\n if (anchorEl && anchorEl.isConnected) {\n const a = anchorEl.getBoundingClientRect();\n if (placement === 'right-start') {\n top = a.top;\n left = a.right + offset;\n if (left + w > vw - 8) left = a.left - offset - w;\n } else {\n top = a.bottom + offset;\n if (top + h > vh - 8 && a.top - offset - h >= 8) top = a.top - offset - h;\n left =\n placement === 'bottom-end'\n ? a.right - w\n : placement === 'bottom'\n ? a.left + a.width / 2 - w / 2\n : a.left;\n }\n } else {\n top = vh / 2 - h / 2;\n left = vw / 2 - w / 2;\n }\n top = clamp(top, 8, Math.max(8, vh - h - 8));\n left = clamp(left, 8, Math.max(8, vw - w - 8));\n setPosition((prev) => (prev.ready && prev.top === top && prev.left === left ? prev : { top, left, ready: true }));\n }, [anchorEl, placement, offset]);\n\n React.useLayoutEffect(() => {\n if (!open) {\n setPosition((prev) => (prev.ready ? { ...prev, ready: false } : prev));\n return undefined;\n }\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n let observer: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined' && ref.current) {\n observer = new ResizeObserver(() => update());\n observer.observe(ref.current);\n }\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n observer?.disconnect();\n };\n }, [open, update]);\n\n React.useEffect(() => {\n if (!open) return undefined;\n const handlePointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (ref.current?.contains(target)) return;\n if (anchorEl?.contains(target)) return;\n if (ignoreOutsideClickOn?.some((r) => r.current?.contains(target))) return;\n // Clicks inside other popovers (nested menus) should not close this one.\n if ((target as HTMLElement).closest?.('.mgh-grid-popover')) return;\n onClose('backdrop');\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose('escape');\n };\n document.addEventListener('mousedown', handlePointerDown, true);\n document.addEventListener('touchstart', handlePointerDown, true);\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown, true);\n document.removeEventListener('touchstart', handlePointerDown, true);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [open, onClose, anchorEl, ignoreOutsideClickOn]);\n\n React.useEffect(() => {\n if (open && autoFocus && ref.current) {\n const focusable = ref.current.querySelector<HTMLElement>(\n 'input, select, textarea, button, [tabindex]:not([tabindex=\"-1\"])'\n );\n (focusable ?? ref.current).focus();\n }\n }, [open, autoFocus]);\n\n if (!open || typeof document === 'undefined') return null;\n\n const stop = (event: React.SyntheticEvent) => event.stopPropagation();\n\n return createPortal(\n <div\n ref={ref}\n role={role}\n tabIndex={-1}\n className={cx('mgh-grid-popover', className)}\n data-mgh-theme={themeMode}\n style={{\n top: position.top,\n left: position.left,\n visibility: position.ready ? 'visible' : 'hidden',\n ...style,\n }}\n onClick={stop}\n onDoubleClick={stop}\n onMouseDown={stop}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n onClose('escape');\n return;\n }\n event.stopPropagation();\n }}\n >\n {children}\n </div>,\n document.body\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {\n children: React.ReactNode;\n}\n\nexport const Menu = ({ children, className, onKeyDown, ...rest }: MenuProps) => {\n const ref = React.useRef<HTMLUListElement | null>(null);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLUListElement>) => {\n onKeyDown?.(event);\n if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp' && event.key !== 'Home' && event.key !== 'End') return;\n const items = Array.from(\n ref.current?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])') ?? []\n );\n if (items.length === 0) return;\n event.preventDefault();\n const currentIndex = items.indexOf(document.activeElement as HTMLElement);\n let next = 0;\n if (event.key === 'ArrowDown') next = currentIndex < 0 ? 0 : (currentIndex + 1) % items.length;\n else if (event.key === 'ArrowUp')\n next = currentIndex < 0 ? items.length - 1 : (currentIndex - 1 + items.length) % items.length;\n else if (event.key === 'Home') next = 0;\n else next = items.length - 1;\n items[next].focus();\n };\n\n React.useEffect(() => {\n const first = ref.current?.querySelector<HTMLElement>('[role=\"menuitem\"]:not([aria-disabled=\"true\"])');\n first?.focus();\n }, []);\n\n return (\n <ul ref={ref} role=\"menu\" className={cx('mgh-grid-menu', className)} onKeyDown={handleKeyDown} {...rest}>\n {children}\n </ul>\n );\n};\n\nexport interface MenuItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {\n icon?: React.ReactNode;\n selected?: boolean;\n /** Injected by menus that should close after the click. */\n hideMenu?: () => void;\n}\n\nexport const MenuItem = React.forwardRef<HTMLButtonElement, MenuItemProps>(\n ({ icon, selected, disabled, className, children, onClick, hideMenu, ...rest }, ref) => (\n <li role=\"none\">\n <button\n ref={ref}\n type=\"button\"\n role=\"menuitem\"\n aria-disabled={disabled || undefined}\n disabled={disabled}\n tabIndex={-1}\n className={cx(\n 'mgh-grid-menu-item',\n disabled && 'mgh-grid-menu-item--disabled',\n selected && 'mgh-grid-menu-item--selected',\n className\n )}\n onClick={(event) => {\n if (disabled) return;\n onClick?.(event);\n hideMenu?.();\n }}\n {...rest}\n >\n {icon}\n <span>{children}</span>\n </button>\n </li>\n )\n);\nMenuItem.displayName = 'MGHGridMenuItem';\n\nexport const MenuDivider = () => <li role=\"separator\" className=\"mgh-grid-menu-divider\" />;\n\nexport const MenuHeader = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-header\">\n {children}\n </li>\n);\n\nexport const MenuSection = ({ children }: { children: React.ReactNode }) => (\n <li role=\"presentation\" className=\"mgh-grid-menu-section\">\n {children}\n </li>\n);\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport {\n MGHGridCsvExportOptions,\n MGHGridExcelExportOptions,\n MGHGridPrintExportOptions,\n MGHGridToolbarProps,\n} from '../MGHGrid.types';\nimport {\n CloseIcon,\n DensityLargeIcon,\n DensityMediumIcon,\n DensitySmallIcon,\n DescriptionIcon,\n DownloadIcon,\n FilterListIcon,\n PrintIcon,\n SearchIcon,\n TableChartIcon,\n ViewColumnIcon,\n} from '../icons';\nimport { cx } from '../utils';\nimport { Badge, IconButton, Menu, MenuItem, MenuItemProps, Popover, TextInput } from './primitives';\n\n/* -------------------------------------------------------------------------------------------------\n * Buttons\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridColumnsButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'columns';\n return (\n <IconButton\n label={localeText.toolbarColumns}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('columns', event.currentTarget))}\n >\n <ViewColumnIcon />\n </IconButton>\n );\n}\n\nexport function MGHGridFiltersButton() {\n const { api, state, localeText } = useMGHGridContext();\n const isOpen = state.preferencePanel.open && state.preferencePanel.openedPanelValue === 'filters';\n return (\n <IconButton\n label={localeText.toolbarFilters}\n active={isOpen}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n onClick={(event) => (isOpen ? api.hidePreferences() : api.showPreferences('filters', event.currentTarget))}\n >\n <Badge count={state.filterCount} variant=\"dot\">\n <FilterListIcon />\n </Badge>\n </IconButton>\n );\n}\n\nexport function MGHGridDensitySelector() {\n const { api, state, localeText, themeMode } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const options = [\n { value: 'compact', label: localeText.densityCompact, icon: <DensitySmallIcon /> },\n { value: 'standard', label: localeText.densityStandard, icon: <DensityMediumIcon /> },\n { value: 'comfortable', label: localeText.densityComfortable, icon: <DensityLargeIcon /> },\n ] as const;\n const current = options.find((o) => o.value === state.density) ?? options[1];\n return (\n <>\n <IconButton\n label={localeText.toolbarDensity}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n {current.icon}\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n role=\"menu\"\n >\n <Menu>\n {options.map((option) => (\n <MenuItem\n key={option.value}\n icon={option.icon}\n selected={option.value === state.density}\n onClick={() => api.setDensity(option.value)}\n hideMenu={() => setAnchor(null)}\n >\n {option.label}\n </MenuItem>\n ))}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Export menu\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridExportMenuItemProps extends MenuItemProps {\n /** Injected by MGHGridExportMenu; call it to close the menu after your action. */\n hideMenu?: () => void;\n}\n\n/** Menu item for custom export actions. Drop-in for MUI's GridExportMenuItemProps pattern. */\nexport const MGHGridExportMenuItem = MenuItem as React.ForwardRefExoticComponent<\n MGHGridExportMenuItemProps & React.RefAttributes<HTMLButtonElement>\n>;\n\nexport interface MGHGridExportMenuProps {\n csvOptions?: MGHGridCsvExportOptions;\n excelOptions?: MGHGridExcelExportOptions;\n printOptions?: MGHGridPrintExportOptions;\n showCsvOption?: boolean;\n showExcelOption?: boolean;\n showPrintOption?: boolean;\n customMenuItem?: React.ReactNode;\n}\n\nexport function MGHGridExportMenu({\n csvOptions = { allColumns: true },\n excelOptions = { allColumns: true },\n printOptions,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n customMenuItem,\n}: MGHGridExportMenuProps) {\n const { api, localeText, themeMode, rootProps } = useMGHGridContext();\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const hideMenu = () => setAnchor(null);\n\n const customItems = React.Children.map(customMenuItem, (child) =>\n React.isValidElement(child) ? React.cloneElement(child as React.ReactElement<any>, { hideMenu }) : child\n );\n\n const resolvedPrintOptions: MGHGridPrintExportOptions = {\n title: typeof rootProps.header === 'string' ? rootProps.header : undefined,\n ...printOptions,\n };\n\n return (\n <>\n <IconButton\n label={localeText.toolbarExport}\n active={Boolean(anchor)}\n aria-haspopup=\"menu\"\n onClick={(event) => setAnchor((prev) => (prev ? null : event.currentTarget))}\n >\n <DownloadIcon />\n </IconButton>\n <Popover open={Boolean(anchor)} anchorEl={anchor} onClose={hideMenu} themeMode={themeMode} role=\"menu\">\n <Menu>\n {customItems}\n {showCsvOption && (\n <MenuItem\n icon={<DescriptionIcon />}\n onClick={() => api.exportDataAsCsv(csvOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportCSV}\n </MenuItem>\n )}\n {showExcelOption && (\n <MenuItem\n icon={<TableChartIcon />}\n onClick={() => {\n void api.exportDataAsExcel(excelOptions);\n }}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportExcel}\n </MenuItem>\n )}\n {showPrintOption && (\n <MenuItem\n icon={<PrintIcon />}\n onClick={() => api.exportDataAsPrint(resolvedPrintOptions)}\n hideMenu={hideMenu}\n >\n {localeText.toolbarExportPrint}\n </MenuItem>\n )}\n </Menu>\n </Popover>\n </>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Quick filter\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface MGHGridQuickFilterProps {\n placeholder?: string;\n debounceMs?: number;\n /** Always show the expanded input. */\n alwaysExpanded?: boolean;\n}\n\nexport function MGHGridQuickFilter({ placeholder, debounceMs, alwaysExpanded = false }: MGHGridQuickFilterProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const externalValue = (state.quickFilterValues ?? []).join(' ');\n const [text, setText] = React.useState(externalValue);\n const [expanded, setExpanded] = React.useState(alwaysExpanded || externalValue !== '');\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const timer = React.useRef<number | null>(null);\n const delay = debounceMs ?? rootProps.quickFilterDebounceMs;\n\n // Sync when the model is changed from outside (e.g. api.setQuickFilterValues).\n const lastExternal = React.useRef(externalValue);\n React.useEffect(() => {\n if (externalValue !== lastExternal.current) {\n lastExternal.current = externalValue;\n setText(externalValue);\n if (externalValue !== '') setExpanded(true);\n }\n }, [externalValue]);\n\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n\n const commit = (value: string) => {\n const values = value.split(/\\s+/).filter((v) => v !== '');\n lastExternal.current = values.join(' ');\n api.setQuickFilterValues(values);\n };\n\n const handleChange = (value: string) => {\n setText(value);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => commit(value), delay);\n };\n\n const clear = () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n setText('');\n commit('');\n inputRef.current?.focus();\n };\n\n const expand = () => {\n setExpanded(true);\n window.setTimeout(() => inputRef.current?.focus(), 0);\n };\n\n const isExpanded = alwaysExpanded || expanded;\n\n return (\n <div className={cx('mgh-grid-quick-filter', isExpanded && 'mgh-grid-quick-filter--expanded')}>\n <IconButton\n className=\"mgh-grid-quick-filter-trigger\"\n label={localeText.toolbarQuickFilterLabel}\n aria-disabled={isExpanded}\n tabIndex={isExpanded ? -1 : 0}\n onClick={expand}\n >\n <SearchIcon />\n </IconButton>\n <div\n className={cx(\n 'mgh-grid-quick-filter-control mgh-grid-input-adorned',\n text && 'mgh-grid-input-adorned--clearable'\n )}\n >\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n ref={inputRef}\n size=\"small\"\n type=\"search\"\n value={text}\n tabIndex={isExpanded ? 0 : -1}\n placeholder={placeholder ?? localeText.toolbarQuickFilterPlaceholder}\n aria-label={localeText.toolbarQuickFilterLabel}\n onChange={(event) => handleChange(event.target.value)}\n onBlur={() => {\n if (!alwaysExpanded && text.trim() === '') setExpanded(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n if (text) clear();\n else if (!alwaysExpanded) {\n setExpanded(false);\n inputRef.current?.blur();\n }\n }\n if (event.key === 'Enter') {\n if (timer.current !== null) window.clearTimeout(timer.current);\n commit(text);\n }\n }}\n />\n {text && (\n <span className=\"mgh-grid-input-adornment mgh-grid-input-adornment--end\">\n <IconButton size=\"small\" label={localeText.clearSearch} onClick={clear} tabIndex={-1}>\n <CloseIcon />\n </IconButton>\n </span>\n )}\n </div>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Default toolbar\n * ----------------------------------------------------------------------------------------------- */\n\nexport function MGHGridToolbar({\n showColumnsButton = true,\n showFilterButton = true,\n showExportButton = true,\n showQuickFilter = true,\n showDensitySelector = false,\n showCsvOption = true,\n showExcelOption = true,\n showPrintOption = true,\n csvOptions,\n excelOptions,\n printOptions,\n renderOtherButtons,\n renderDateRange,\n customMenuItem,\n quickFilterPlaceholder,\n quickFilterDebounceMs,\n}: MGHGridToolbarProps) {\n const { rootProps } = useMGHGridContext();\n const showColumns = showColumnsButton && !rootProps.disableColumnSelector;\n const showFilters = showFilterButton && !rootProps.disableColumnFilter;\n const showDensity = showDensitySelector && !rootProps.disableDensitySelector;\n\n return (\n <div className=\"mgh-grid-toolbar\" role=\"toolbar\">\n <div className=\"mgh-grid-toolbar-group\">\n {showColumns && <MGHGridColumnsButton />}\n {showFilters && <MGHGridFiltersButton />}\n {showDensity && <MGHGridDensitySelector />}\n {showExportButton && (\n <MGHGridExportMenu\n csvOptions={csvOptions}\n excelOptions={excelOptions}\n printOptions={printOptions}\n showCsvOption={showCsvOption}\n showExcelOption={showExcelOption}\n showPrintOption={showPrintOption}\n customMenuItem={customMenuItem}\n />\n )}\n </div>\n {renderDateRange && <div className=\"mgh-grid-toolbar-center\">{renderDateRange}</div>}\n <div className=\"mgh-grid-toolbar-group\">\n {renderOtherButtons}\n {showQuickFilter && (\n <MGHGridQuickFilter placeholder={quickFilterPlaceholder} debounceMs={quickFilterDebounceMs} />\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { ChevronLeftIcon, ChevronRightIcon, FirstPageIcon, LastPageIcon } from '../icons';\nimport { IconButton, Select } from './primitives';\n\nexport function MGHGridPagination() {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const { page, pageSize } = state.paginationModel;\n const count = state.rowCount;\n const pageCount = state.pageCount;\n const from = count === 0 ? 0 : page * pageSize + 1;\n const to = Math.min(count, (page + 1) * pageSize);\n const options =\n rootProps.pageSizeOptions.indexOf(pageSize) === -1\n ? rootProps.pageSizeOptions.concat([pageSize]).sort((a, b) => a - b)\n : rootProps.pageSizeOptions;\n\n return (\n <div className=\"mgh-grid-pagination\" role=\"navigation\" aria-label=\"Pagination\">\n <span>{localeText.footerPaginationRowsPerPage}</span>\n <Select\n className=\"mgh-grid-pagination-select\"\n value={pageSize}\n aria-label={localeText.footerPaginationRowsPerPage}\n onChange={(event) => api.setPageSize(Number(event.target.value))}\n >\n {options.map((option) => (\n <option key={option} value={option}>\n {option}\n </option>\n ))}\n </Select>\n <span>{localeText.footerPaginationDisplayedRows(from, to, count)}</span>\n <div className=\"mgh-grid-pagination-actions\">\n <IconButton label={localeText.footerPaginationFirstPage} disabled={page <= 0} onClick={() => api.setPage(0)}>\n <FirstPageIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationPreviousPage}\n disabled={page <= 0}\n onClick={() => api.setPage(page - 1)}\n >\n <ChevronLeftIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationNextPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(page + 1)}\n >\n <ChevronRightIcon />\n </IconButton>\n <IconButton\n label={localeText.footerPaginationLastPage}\n disabled={page >= pageCount - 1}\n onClick={() => api.setPage(Math.max(pageCount - 1, 0))}\n >\n <LastPageIcon />\n </IconButton>\n </div>\n </div>\n );\n}\n\nexport function MGHGridFooter() {\n const { state, localeText, rootProps } = useMGHGridContext();\n const selectedCount = state.rowSelectionModel.ids.size;\n const showSelected = selectedCount > 0 && !rootProps.hideFooterSelectedRowCount;\n const showPagination = rootProps.pagination && !rootProps.hideFooterPagination;\n const showRowCount = !showPagination && !rootProps.hideFooterRowCount;\n\n return (\n <div className=\"mgh-grid-footer\">\n <div className=\"mgh-grid-footer-left\">\n {showSelected && <span>{localeText.footerRowSelected(selectedCount)}</span>}\n </div>\n {showRowCount && (\n <span>\n {localeText.footerTotalRows} {state.rowCount.toLocaleString()}\n </span>\n )}\n {showPagination && <MGHGridPagination />}\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { SearchIcon } from '../icons';\nimport { Button, Checkbox, TextInput } from './primitives';\n\nexport function MGHGridColumnsPanel() {\n const { api, state, localeText, columns, visibleColumns } = useMGHGridContext();\n const visibleFields = React.useMemo(() => new Set(visibleColumns.map((col) => col.field)), [visibleColumns]);\n const [search, setSearch] = React.useState('');\n const model = state.columnVisibilityModel;\n\n const hideable = columns.filter((col) => col.hideable !== false);\n const needle = search.trim().toLowerCase();\n const filtered = needle\n ? hideable.filter((col) => (col.headerName ?? col.field).toLowerCase().indexOf(needle) !== -1)\n : hideable;\n\n const setAll = (visible: boolean) => {\n const next = { ...model };\n hideable.forEach((col) => {\n next[col.field] = visible;\n });\n api.setColumnVisibilityModel(next);\n };\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarColumns}>\n <div className=\"mgh-grid-panel-header\">\n <div className=\"mgh-grid-input-adorned\">\n <span className=\"mgh-grid-input-adornment\">\n <SearchIcon size={18} />\n </span>\n <TextInput\n autoFocus\n size=\"small\"\n value={search}\n placeholder={localeText.columnsPanelSearchPlaceholder}\n aria-label={localeText.columnsPanelSearchPlaceholder}\n onChange={(event) => setSearch(event.target.value)}\n />\n </div>\n </div>\n <div className=\"mgh-grid-panel-content\">\n <div className=\"mgh-grid-columns-list\">\n {filtered.map((col) => {\n const visible = visibleFields.has(col.field);\n return (\n <label key={col.field} className=\"mgh-grid-checkbox-label\">\n <Checkbox checked={visible} onChange={() => api.setColumnVisibility(col.field, !visible)} />\n <span>{col.headerName ?? col.field}</span>\n </label>\n );\n })}\n {filtered.length === 0 && <div className=\"mgh-grid-filter-empty\">No columns</div>}\n </div>\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(true)}>\n {localeText.columnsPanelShowAll}\n </Button>\n <Button variant=\"primary\" size=\"small\" onClick={() => setAll(false)}>\n {localeText.columnsPanelHideAll}\n </Button>\n <Button size=\"small\" onClick={() => api.setColumnVisibilityModel({})}>\n {localeText.columnsPanelReset}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridFilterItem, MGHGridFilterOperator } from '../MGHGrid.types';\nimport { AddIcon, DeleteIcon } from '../icons';\nimport { getColumnFilterOperators, getOptionLabel, getOptionValue, resolveValueOptions, uniqueId } from '../utils';\nimport { Button, Field, IconButton, Select, TextInput } from './primitives';\n\ninterface FilterValueInputProps {\n item: MGHGridFilterItem;\n column: MGHGridColDef;\n operator: MGHGridFilterOperator | undefined;\n onChange: (value: any) => void;\n placeholder: string;\n}\n\nconst useDebouncedValue = (value: any, onCommit: (value: any) => void, delay = 250) => {\n const [local, setLocal] = React.useState(value ?? '');\n const timer = React.useRef<number | null>(null);\n React.useEffect(() => {\n setLocal(value ?? '');\n }, [value]);\n const update = (next: any) => {\n setLocal(next);\n if (timer.current !== null) window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => onCommit(next), delay);\n };\n React.useEffect(\n () => () => {\n if (timer.current !== null) window.clearTimeout(timer.current);\n },\n []\n );\n return [local, update] as const;\n};\n\nfunction TextValueInput({ item, onChange, placeholder, type }: FilterValueInputProps & { type: string }) {\n const [local, update] = useDebouncedValue(item.value, onChange);\n return (\n <TextInput\n size=\"small\"\n type={type}\n value={local}\n placeholder={placeholder}\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction MultiValueInput({ item, column, onChange, placeholder }: FilterValueInputProps) {\n const joined = Array.isArray(item.value) ? item.value.join(', ') : (item.value ?? '');\n const [local, update] = useDebouncedValue(joined, (text: string) =>\n onChange(\n String(text)\n .split(',')\n .map((v) => v.trim())\n .filter((v) => v !== '')\n )\n );\n if (column.type === 'singleSelect') {\n const options = resolveValueOptions(column);\n const selected: string[] = Array.isArray(item.value) ? item.value.map(String) : [];\n return (\n <Select\n multiple\n size=\"small\"\n value={selected}\n aria-label={placeholder}\n onChange={(event) => {\n const values = Array.from(event.target.selectedOptions).map((option) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === option.value);\n return match !== undefined ? getOptionValue(column, match) : option.value;\n });\n onChange(values);\n }}\n >\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n return (\n <TextInput\n size=\"small\"\n value={local}\n placeholder=\"Comma separated values\"\n aria-label={placeholder}\n onChange={(event) => update(event.target.value)}\n />\n );\n}\n\nfunction FilterValueInput(props: FilterValueInputProps) {\n const { item, column, operator, onChange, placeholder } = props;\n const { api } = useMGHGridContext();\n const inputType = operator?.inputType ?? 'text';\n\n if (operator?.InputComponent) {\n const Component = operator.InputComponent;\n return <Component item={item} column={column} applyValue={(next) => onChange(next.value)} api={api} />;\n }\n\n switch (inputType) {\n case 'none':\n return <div />;\n case 'boolean':\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => onChange(event.target.value === '' ? undefined : event.target.value)}\n >\n <option value=\"\">any</option>\n <option value=\"true\">yes</option>\n <option value=\"false\">no</option>\n </Select>\n );\n case 'select': {\n const options = resolveValueOptions(column);\n return (\n <Select\n size=\"small\"\n value={item.value === undefined || item.value === null ? '' : String(item.value)}\n aria-label={placeholder}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(column, o)) === event.target.value);\n onChange(\n event.target.value === ''\n ? undefined\n : match !== undefined\n ? getOptionValue(column, match)\n : event.target.value\n );\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(column, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(column, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'multiselect':\n return <MultiValueInput {...props} />;\n case 'number':\n return <TextValueInput {...props} type=\"number\" />;\n case 'date':\n return <TextValueInput {...props} type=\"date\" />;\n case 'datetime-local':\n return <TextValueInput {...props} type=\"datetime-local\" />;\n default:\n return <TextValueInput {...props} type=\"text\" />;\n }\n}\n\nconst createFilterItem = (column: MGHGridColDef | undefined): MGHGridFilterItem => ({\n id: uniqueId('filter'),\n field: column?.field ?? '',\n operator: column ? (getColumnFilterOperators(column)[0]?.value ?? 'contains') : 'contains',\n value: undefined,\n});\n\nexport function MGHGridFilterPanel() {\n const { api, state, localeText, columns, rootProps } = useMGHGridContext();\n const filterableColumns = React.useMemo(() => columns.filter((col) => col.filterable !== false), [columns]);\n const byField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n filterableColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [filterableColumns]);\n\n const items = state.filterModel.items;\n const logicOperator = state.filterModel.logicOperator ?? 'and';\n const targetField = state.preferencePanel.targetField;\n\n // Ensure at least one (possibly empty) item is displayed when the panel opens, like MUI does.\n const seeded = React.useRef(false);\n React.useEffect(() => {\n if (seeded.current) return;\n seeded.current = true;\n if (targetField && byField.has(targetField)) {\n const existing = items.find((item) => item.field === targetField);\n if (!existing) api.upsertFilterItem(createFilterItem(byField.get(targetField)));\n } else if (items.length === 0 && filterableColumns.length > 0) {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n }\n }, [api, byField, filterableColumns, items, targetField]);\n\n const updateItem = (item: MGHGridFilterItem, patch: Partial<MGHGridFilterItem>) => {\n api.upsertFilterItem({ ...item, ...patch });\n };\n\n const addItem = () => {\n api.upsertFilterItem(createFilterItem(filterableColumns[0]));\n };\n\n const canAddMore = !rootProps.disableMultipleColumnsFiltering || items.length === 0;\n\n return (\n <div className=\"mgh-grid-panel\" role=\"group\" aria-label={localeText.toolbarFilters}>\n <div className=\"mgh-grid-panel-content\" style={{ paddingTop: 12 }}>\n {items.length === 0 && <div className=\"mgh-grid-filter-empty\">No filters</div>}\n {items.map((item, index) => {\n const column = byField.get(item.field) ?? filterableColumns[0];\n const operators = column ? getColumnFilterOperators(column) : [];\n const operator = operators.find((op) => op.value === item.operator) ?? operators[0];\n const showLogic = items.length > 1;\n return (\n <div\n key={String(item.id ?? index)}\n className={\n showLogic ? 'mgh-grid-filter-row mgh-grid-filter-row--with-logic' : 'mgh-grid-filter-row'\n }\n >\n <IconButton\n size=\"small\"\n label={localeText.filterPanelDeleteIcon}\n onClick={() => api.deleteFilterItem(item)}\n >\n <DeleteIcon />\n </IconButton>\n {showLogic && (\n <Field label={index === 1 ? localeText.filterPanelLogicOperator : ' '}>\n {index === 0 ? (\n <div style={{ height: 32 }} />\n ) : (\n <Select\n size=\"small\"\n value={logicOperator}\n disabled={index > 1}\n aria-label={localeText.filterPanelLogicOperator}\n onChange={(event) =>\n api.setFilterLogicOperator(event.target.value as 'and' | 'or')\n }\n >\n <option value=\"and\">{localeText.filterPanelOperatorAnd}</option>\n <option value=\"or\">{localeText.filterPanelOperatorOr}</option>\n </Select>\n )}\n </Field>\n )}\n <Field label={localeText.filterPanelColumns}>\n <Select\n size=\"small\"\n value={column?.field ?? ''}\n aria-label={localeText.filterPanelColumns}\n onChange={(event) => {\n const nextColumn = byField.get(event.target.value);\n const nextOperators = nextColumn ? getColumnFilterOperators(nextColumn) : [];\n const keepOperator = nextOperators.some((op) => op.value === item.operator);\n updateItem(item, {\n field: event.target.value,\n operator: keepOperator ? item.operator : (nextOperators[0]?.value ?? 'contains'),\n value: undefined,\n });\n }}\n >\n {filterableColumns.map((col) => (\n <option key={col.field} value={col.field}>\n {col.headerName ?? col.field}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelOperator}>\n <Select\n size=\"small\"\n value={operator?.value ?? ''}\n aria-label={localeText.filterPanelOperator}\n onChange={(event) => {\n const nextOperator = operators.find((op) => op.value === event.target.value);\n const nextIsMulti = nextOperator?.inputType === 'multiselect';\n const currentIsMulti = operator?.inputType === 'multiselect';\n updateItem(item, {\n operator: event.target.value,\n value: nextIsMulti !== currentIsMulti ? undefined : item.value,\n });\n }}\n >\n {operators.map((op) => (\n <option key={op.value} value={op.value}>\n {op.label ?? op.value}\n </option>\n ))}\n </Select>\n </Field>\n <Field label={localeText.filterPanelValue}>\n {column ? (\n <FilterValueInput\n item={item}\n column={column}\n operator={operator}\n placeholder={localeText.filterPanelInputPlaceholder}\n onChange={(value) => updateItem(item, { value })}\n />\n ) : (\n <div />\n )}\n </Field>\n </div>\n );\n })}\n </div>\n <div className=\"mgh-grid-panel-footer\">\n <Button\n variant=\"primary\"\n size=\"small\"\n startIcon={<AddIcon size={18} />}\n onClick={addItem}\n disabled={!canAddMore}\n >\n {localeText.filterPanelAddFilter}\n </Button>\n <Button\n size=\"small\"\n startIcon={<DeleteIcon size={18} />}\n disabled={items.length === 0}\n onClick={() => api.setFilterModel({ ...state.filterModel, items: [] })}\n >\n {localeText.filterPanelRemoveAll}\n </Button>\n </div>\n </div>\n );\n}\n","import React from 'react';\nimport { useMGHGridContext } from '../context';\nimport { MGHGridColDef, MGHGridThemeMode } from '../MGHGrid.types';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n FilterListIcon,\n FunctionsIcon,\n PushPinIcon,\n ViewColumnIcon,\n VisibilityOffIcon,\n WorkspacesIcon,\n} from '../icons';\nimport { GROUPING_COLUMN_FIELD } from '../utils';\nimport { Menu, MenuDivider, MenuItem, MenuSection, Popover, Select } from './primitives';\n\nexport interface MGHGridColumnMenuProps {\n column: MGHGridColDef;\n anchorEl: HTMLElement | null;\n open: boolean;\n onClose: () => void;\n themeMode: MGHGridThemeMode;\n /** Anchor for panels opened from the menu (usually the toolbar button or the header cell). */\n panelAnchorEl?: HTMLElement | null;\n}\n\nexport function MGHGridColumnMenu({ column, anchorEl, open, onClose, themeMode, panelAnchorEl }: MGHGridColumnMenuProps) {\n const { api, state, localeText, rootProps } = useMGHGridContext();\n const field = column.field;\n const isGroupingColumn = field === GROUPING_COLUMN_FIELD;\n const sortItem = state.sortModel.find((item) => item.field === field);\n const pinned = api.isColumnPinned(field);\n const isGrouped = state.rowGroupingModel.indexOf(field) !== -1;\n const aggregation = state.aggregationModel[field];\n\n const canSort = column.sortable !== false && !rootProps.disableColumnSorting;\n const canFilter = column.filterable !== false && !rootProps.disableColumnFilter && !isGroupingColumn;\n const canHide = column.hideable !== false;\n const canPin = column.pinnable !== false && !rootProps.disableColumnPinning;\n const canGroup = column.groupable !== false && !rootProps.disableRowGrouping && !isGroupingColumn;\n const aggregationFunctions = Object.keys(rootProps.aggregationFunctions).filter((name) => {\n const fn = rootProps.aggregationFunctions[name];\n if (column.availableAggregationFunctions && column.availableAggregationFunctions.indexOf(name) === -1) return false;\n if (fn.columnTypes && column.type && fn.columnTypes.indexOf(column.type) === -1) return false;\n return true;\n });\n const canAggregate =\n column.aggregable !== false && !rootProps.disableAggregation && !isGroupingColumn && aggregationFunctions.length > 0;\n\n const anchorForPanel = panelAnchorEl ?? anchorEl;\n const name = column.headerName ?? column.field;\n\n return (\n <Popover open={open} anchorEl={anchorEl} onClose={onClose} themeMode={themeMode} placement=\"bottom-end\" role=\"menu\">\n <Menu aria-label={localeText.columnMenuLabel}>\n {canSort && (\n <>\n <MenuItem\n icon={<ArrowUpwardIcon />}\n selected={sortItem?.sort === 'asc'}\n onClick={() => api.sortColumn(field, 'asc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortAsc}\n </MenuItem>\n <MenuItem\n icon={<ArrowDownwardIcon />}\n selected={sortItem?.sort === 'desc'}\n onClick={() => api.sortColumn(field, 'desc')}\n hideMenu={onClose}\n >\n {localeText.columnMenuSortDesc}\n </MenuItem>\n {sortItem && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.sortColumn(field, null)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnsort}\n </MenuItem>\n )}\n </>\n )}\n {canFilter && (\n <>\n {canSort && <MenuDivider />}\n <MenuItem\n icon={<FilterListIcon />}\n onClick={() => api.showFilterPanel(field, anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuFilter}\n </MenuItem>\n </>\n )}\n {(canHide || !rootProps.disableColumnSelector) && (\n <>\n {(canSort || canFilter) && <MenuDivider />}\n {canHide && (\n <MenuItem\n icon={<VisibilityOffIcon />}\n onClick={() => api.setColumnVisibility(field, false)}\n hideMenu={onClose}\n >\n {localeText.columnMenuHideColumn}\n </MenuItem>\n )}\n {!rootProps.disableColumnSelector && (\n <MenuItem\n icon={<ViewColumnIcon />}\n onClick={() => api.showPreferences('columns', anchorForPanel)}\n hideMenu={onClose}\n >\n {localeText.columnMenuManageColumns}\n </MenuItem>\n )}\n </>\n )}\n {canPin && (\n <>\n <MenuDivider />\n {pinned !== 'left' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(30deg)' }} />}\n onClick={() => api.pinColumn(field, 'left')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinLeft}\n </MenuItem>\n )}\n {pinned !== 'right' && (\n <MenuItem\n icon={<PushPinIcon style={{ transform: 'rotate(-30deg)' }} />}\n onClick={() => api.pinColumn(field, 'right')}\n hideMenu={onClose}\n >\n {localeText.columnMenuPinRight}\n </MenuItem>\n )}\n {pinned && (\n <MenuItem\n icon={<span style={{ width: 20 }} />}\n onClick={() => api.unpinColumn(field)}\n hideMenu={onClose}\n >\n {localeText.columnMenuUnpin}\n </MenuItem>\n )}\n </>\n )}\n {canGroup && (\n <>\n <MenuDivider />\n <MenuItem\n icon={<WorkspacesIcon />}\n onClick={() =>\n isGrouped ? api.removeRowGroupingCriteria(field) : api.addRowGroupingCriteria(field)\n }\n hideMenu={onClose}\n >\n {isGrouped ? localeText.columnMenuUngroup(name) : localeText.columnMenuGroup(name)}\n </MenuItem>\n </>\n )}\n {canAggregate && (\n <>\n <MenuDivider />\n <MenuSection>\n <label\n className=\"mgh-grid-field-label\"\n style={{ display: 'flex', alignItems: 'center', gap: 6 }}\n >\n <FunctionsIcon size={16} /> {localeText.columnMenuAggregation}\n </label>\n <Select\n size=\"small\"\n value={aggregation ?? ''}\n aria-label={localeText.columnMenuAggregation}\n onChange={(event) => {\n const next = { ...state.aggregationModel };\n if (event.target.value === '') delete next[field];\n else next[field] = event.target.value;\n api.setAggregationModel(next);\n }}\n >\n <option value=\"\">{localeText.aggregationFunctionLabelNone}</option>\n {aggregationFunctions.map((fnName) => (\n <option key={fnName} value={fnName}>\n {rootProps.aggregationFunctions[fnName].label ?? fnName}\n </option>\n ))}\n </Select>\n </MenuSection>\n </>\n )}\n </Menu>\n </Popover>\n );\n}\n","import React from 'react';\nimport { MGHGridLoadingOverlayProps, MGHGridNoRowsOverlayProps } from '../MGHGrid.types';\nimport { EmptyBoxIcon } from '../icons';\nimport { Spinner } from './primitives';\n\n/** Default \"no rows\" overlay. Mirrors the legacy CustomNoRowsOverlay but has no MUI dependency. */\nexport function MGHGridNoRowsOverlay({ text = 'No rows', imageSrc }: MGHGridNoRowsOverlayProps) {\n return (\n <div className=\"mgh-grid-no-rows\" role=\"status\">\n {imageSrc ? <img alt=\"\" src={imageSrc} /> : <EmptyBoxIcon size={50} />}\n <div>{text}</div>\n </div>\n );\n}\n\nexport function MGHGridLoadingOverlay({ text }: MGHGridLoadingOverlayProps) {\n return (\n <>\n <Spinner />\n {text && <div>{text}</div>}\n </>\n );\n}\n","import React from 'react';\nimport { MGHGridThemeMode } from '../MGHGrid.types';\nimport { MoreVertIcon } from '../icons';\nimport { IconButton, Menu, MenuItem, Popover } from './primitives';\n\nexport interface MGHGridActionsCellItemProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {\n icon?: React.ReactElement;\n label: string;\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n /** Render the action inside the \"more\" menu instead of inline. */\n showInMenu?: boolean;\n disabled?: boolean;\n}\n\n/** Drop-in replacement for MUI's GridActionsCellItem. Use it from `colDef.getActions`. */\nexport function MGHGridActionsCellItem({\n icon,\n label,\n onClick,\n showInMenu,\n disabled,\n className,\n ...rest\n}: MGHGridActionsCellItemProps) {\n return (\n <IconButton\n size=\"small\"\n label={label}\n disabled={disabled}\n className={className}\n onClick={(event) => {\n event.stopPropagation();\n onClick?.(event);\n }}\n {...rest}\n >\n {icon}\n </IconButton>\n );\n}\nMGHGridActionsCellItem.displayName = 'MGHGridActionsCellItem';\n\ninterface ActionsCellProps {\n actions: React.ReactElement[];\n themeMode: MGHGridThemeMode;\n moreLabel: string;\n}\n\nexport function ActionsCell({ actions, themeMode, moreLabel }: ActionsCellProps) {\n const [anchor, setAnchor] = React.useState<HTMLElement | null>(null);\n const inline: React.ReactElement[] = [];\n const inMenu: React.ReactElement[] = [];\n actions.forEach((action) => {\n if (!React.isValidElement(action)) return;\n if ((action.props as MGHGridActionsCellItemProps)?.showInMenu) inMenu.push(action);\n else inline.push(action);\n });\n\n return (\n <>\n {inline.map((action, index) => (\n <React.Fragment key={action.key ?? index}>{action}</React.Fragment>\n ))}\n {inMenu.length > 0 && (\n <>\n <IconButton\n size=\"small\"\n label={moreLabel}\n active={Boolean(anchor)}\n onClick={(event) => {\n event.stopPropagation();\n setAnchor((prev) => (prev ? null : event.currentTarget));\n }}\n >\n <MoreVertIcon />\n </IconButton>\n <Popover\n open={Boolean(anchor)}\n anchorEl={anchor}\n onClose={() => setAnchor(null)}\n themeMode={themeMode}\n placement=\"bottom-end\"\n role=\"menu\"\n >\n <Menu>\n {inMenu.map((action, index) => {\n const props = action.props as MGHGridActionsCellItemProps;\n return (\n <MenuItem\n key={action.key ?? index}\n icon={props.icon}\n disabled={props.disabled}\n onClick={(event) => {\n props.onClick?.(event);\n setAnchor(null);\n }}\n >\n {props.label}\n </MenuItem>\n );\n })}\n </Menu>\n </Popover>\n </>\n )}\n </>\n );\n}\n","import React from 'react';\nimport {\n MGHGridAggregationModel,\n MGHGridApi,\n MGHGridApplyFilterFn,\n MGHGridCallbackDetails,\n MGHGridCellParams,\n MGHGridColDef,\n MGHGridColumnVisibilityModel,\n MGHGridDensity,\n MGHGridFilterItem,\n MGHGridFilterModel,\n MGHGridGroupNode,\n MGHGridLeafNode,\n MGHGridLocaleText,\n MGHGridPaginationModel,\n MGHGridPinnedColumns,\n MGHGridPinnedSide,\n MGHGridPreferencePanelState,\n MGHGridPrintExportOptions,\n MGHGridProps,\n MGHGridRowGroupingModel,\n MGHGridRowId,\n MGHGridRowNode,\n MGHGridRowParams,\n MGHGridRowSelectionModel,\n MGHGridSortDirection,\n MGHGridSortModel,\n MGHGridState,\n MGHGridSxProps,\n MGHGridValidRowModel,\n} from './MGHGrid.types';\nimport {\n AGGREGATION_FOOTER_ID,\n BUILT_IN_AGGREGATION_FUNCTIONS,\n CHECKBOX_COLUMN_DEF,\n CHECKBOX_FIELD,\n DEFAULT_COLUMN_MIN_WIDTH,\n DEFAULT_HEADER_HEIGHT,\n DEFAULT_LOCALE_TEXT,\n DEFAULT_ROW_HEIGHT,\n DENSITY_FACTORS,\n DETAIL_PANEL_TOGGLE_COLUMN_DEF,\n DETAIL_PANEL_TOGGLE_FIELD,\n GROUPING_COLUMN_FIELD,\n GROUPING_COLUMN_WIDTH,\n clamp,\n cx,\n defaultFormatValue,\n formattedValueToString,\n getCellValue,\n getColumnFilterOperators,\n getDefaultComparator,\n getFormattedValue,\n getOptionLabel,\n getOptionValue,\n getRowIdFromRow,\n buildScopedCss,\n isInternalField,\n isNil,\n isSelectorKey,\n measureText,\n moveItem,\n normalizeColumn,\n normalizeSelectionModel,\n parseEditValue,\n readLocalStorage,\n resolveValueOptions,\n selectionModelsEqual,\n toDate,\n writeLocalStorage,\n} from './utils';\nimport { useMGHGridStyles } from './MGHGrid.styles';\nimport { MGHGridContext, MGHGridContextValue, MGHGridRootProps } from './context';\nimport { useControlledState, useElementSize, useForceUpdate, useLatestRef, useStableId } from './hooks';\nimport { exportDataAsCsv, exportDataAsExcel, getDataAsCsv } from './export';\nimport { printGridElement } from './print';\nimport {\n DisplayRow,\n GroupTreeNode,\n RowEntry,\n aggregateRows,\n buildGroupTree,\n collectTreeLeaves,\n flattenGroupTree,\n sortGroupTree,\n} from './grouping';\nimport {\n ArrowDownwardIcon,\n ArrowUpwardIcon,\n CheckIcon,\n ChevronRightIcon,\n CloseIcon,\n ExpandMoreIcon,\n MoreVertIcon,\n} from './icons';\nimport { Checkbox, IconButton, Popover, Select, TextInput } from './components/primitives';\nimport { MGHGridToolbar } from './components/Toolbar';\nimport { MGHGridFooter } from './components/Footer';\nimport { MGHGridColumnsPanel } from './components/ColumnsPanel';\nimport { MGHGridFilterPanel } from './components/FilterPanel';\nimport { MGHGridColumnMenu } from './components/ColumnMenu';\nimport { MGHGridLoadingOverlay, MGHGridNoRowsOverlay } from './components/Overlays';\nimport { ActionsCell } from './components/ActionsCell';\n\n/* -------------------------------------------------------------------------------------------------\n * Constants & helpers\n * ----------------------------------------------------------------------------------------------- */\n\nconst EMPTY_ARRAY: any[] = [];\nconst EMPTY_OBJECT: Record<string, any> = {};\nconst EMPTY_MAP = new Map<any, any>();\nconst DEFAULT_SORTING_ORDER: MGHGridSortDirection[] = ['asc', 'desc', null];\nconst DEFAULT_PAGE_SIZE_OPTIONS = [10, 25, 50, 100];\nconst DEFAULT_FILTER_MODEL: MGHGridFilterModel = { items: [], quickFilterExcludeHiddenColumns: false };\nconst OVERSCAN_ROWS = 6;\nconst DEFAULT_DETAIL_PANEL_HEIGHT = 500;\n\ninterface ColumnLayout {\n col: MGHGridColDef;\n width: number;\n pinned: MGHGridPinnedSide | null;\n /** Sticky offset (left or right) for pinned columns. */\n offset: number;\n /** X position from the start of the row. */\n x: number;\n isLastLeft: boolean;\n isFirstRight: boolean;\n}\n\ntype RenderRowKind = 'leaf' | 'group' | 'pinnedRow' | 'footer';\n\ninterface RenderRow<R extends MGHGridValidRowModel = any> {\n id: MGHGridRowId;\n kind: RenderRowKind;\n row: R | null;\n node: MGHGridRowNode;\n depth: number;\n group?: GroupTreeNode<R>;\n aggregates?: Record<string, { value: any; fn: string }>;\n}\n\ninterface CellCoords {\n id: MGHGridRowId;\n field: string;\n}\n\n/** Keeps only the inline-applicable part of an sx-like object (nested selectors are compiled to CSS). */\nconst sanitizeStyle = (style: MGHGridSxProps | undefined): React.CSSProperties | undefined => {\n if (!style) return undefined;\n const out: Record<string, any> = {};\n Object.keys(style).forEach((key) => {\n if (isSelectorKey(key)) return;\n const value = (style as any)[key];\n if (typeof value !== 'string' && typeof value !== 'number') return;\n out[key] = value;\n });\n return out;\n};\n\nconst computeWidths = (cols: MGHGridColDef[], available: number, overrides: Record<string, number>) => {\n const result: Array<number | null> = cols.map((col) => {\n const min = col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const max = col.maxWidth ?? Infinity;\n const override = overrides[col.field];\n if (override) return clamp(override, min, max);\n if (col.flex && col.flex > 0) return null;\n return clamp(col.width ?? 100, min, max);\n });\n const pool: number[] = [];\n let fixedTotal = 0;\n result.forEach((w, i) => {\n if (w === null) pool.push(i);\n else fixedTotal += w;\n });\n if (pool.length > 0) {\n let remainingSpace = Math.max(0, available - fixedTotal);\n let remainingFlex = pool.reduce((acc, i) => acc + (cols[i].flex as number), 0);\n let active = pool.slice();\n let changed = true;\n while (changed && active.length > 0) {\n changed = false;\n for (let k = 0; k < active.length; k += 1) {\n const i = active[k];\n const col = cols[i];\n const min = col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH;\n const max = col.maxWidth ?? Infinity;\n const share = remainingFlex > 0 ? (remainingSpace * (col.flex as number)) / remainingFlex : 0;\n if (share < min || share > max) {\n const fixed = share < min ? min : max;\n result[i] = fixed;\n remainingSpace = Math.max(0, remainingSpace - fixed);\n remainingFlex -= col.flex as number;\n active = active.filter((idx) => idx !== i);\n changed = true;\n break;\n }\n }\n }\n active.forEach((i) => {\n const col = cols[i];\n result[i] =\n remainingFlex > 0\n ? Math.floor((remainingSpace * (col.flex as number)) / remainingFlex)\n : (col.minWidth ?? 50);\n });\n }\n return result as number[];\n};\n\nconst toDateInputValue = (value: any, withTime: boolean) => {\n const date = toDate(value);\n if (!date) return '';\n const pad = (n: number) => String(n).padStart(2, '0');\n const base = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n return withTime ? `${base}T${pad(date.getHours())}:${pad(date.getMinutes())}` : base;\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Component\n * ----------------------------------------------------------------------------------------------- */\n\nexport default function MGHGrid<R extends MGHGridValidRowModel = any>(props: MGHGridProps<R>) {\n const {\n rows,\n columns: columnsProp,\n getRowId,\n loading = false,\n header,\n renderHeaderEndContent,\n renderHeaderCenterContent,\n disableCard = false,\n className,\n cardClassName,\n boxClassName,\n cardStyle,\n cardSx,\n boxStyle,\n boxSx,\n style,\n sx,\n themeMode = 'light',\n themeVars,\n showToolbar = true,\n toolbarProps,\n slots = EMPTY_OBJECT,\n slotProps = EMPTY_OBJECT,\n noRowsText = 'No data found within selected parameters.',\n localeText: localeTextProp,\n rowHeight: rowHeightProp = DEFAULT_ROW_HEIGHT,\n columnHeaderHeight = DEFAULT_HEADER_HEIGHT,\n getRowHeight,\n autoHeight = false,\n disableVirtualization = false,\n density: densityProp,\n onDensityChange,\n disableDensitySelector = false,\n pagination = true,\n pageSize = 25,\n pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,\n paginationModel: paginationModelProp,\n onPaginationModelChange,\n hideFooter = false,\n hideFooterPagination = false,\n hideFooterRowCount = false,\n hideFooterSelectedRowCount = false,\n sortModel: sortModelProp,\n onSortModelChange,\n sortingOrder = DEFAULT_SORTING_ORDER,\n disableMultipleColumnsSorting = false,\n disableColumnSorting = false,\n filterModel: filterModelProp,\n onFilterModelChange,\n disableColumnFilter = false,\n disableMultipleColumnsFiltering = false,\n quickFilterDebounceMs = 150,\n columnVisibilityModel: columnVisibilityModelProp,\n onColumnVisibilityModelChange,\n columnVisibilityStorageKey,\n columnOrderStorageKey,\n columnWidthStorageKey,\n pinnedColumnsStorageKey,\n onColumnOrderChange,\n onColumnWidthChange,\n disableColumnMenu = false,\n disableColumnSelector = false,\n disableColumnResize = false,\n disableColumnReorder = false,\n disableColumnPinning = false,\n pinnedColumns: pinnedColumnsProp,\n onPinnedColumnsChange,\n checkboxSelection = false,\n checkboxSelectionVisibleOnly = false,\n disableRowSelectionOnClick = true,\n disableMultipleRowSelection = false,\n rowSelectionModel: rowSelectionModelProp,\n onRowSelectionModelChange,\n isRowSelectable,\n keepNonExistentRowsSelected = true,\n getRowClassName,\n onRowClick,\n onRowDoubleClick,\n onCellClick,\n onCellDoubleClick,\n pinnedRows,\n getDetailPanelContent,\n getDetailPanelHeight,\n detailPanelExpandedRowIds: detailPanelExpandedRowIdsProp,\n onDetailPanelExpandedRowIdsChange,\n rowGroupingModel: rowGroupingModelProp,\n onRowGroupingModelChange,\n defaultGroupingExpansionDepth = 0,\n groupingColDef,\n disableRowGrouping = false,\n isGroupExpandedByDefault,\n aggregationModel: aggregationModelProp,\n onAggregationModelChange,\n aggregationFunctions: aggregationFunctionsProp,\n disableAggregation = false,\n aggregationPosition = 'both',\n processRowUpdate,\n onProcessRowUpdateError,\n onCellEditStop,\n isCellEditable,\n initialState,\n apiRef,\n onStateChange,\n } = props;\n\n useMGHGridStyles();\n\n const gridId = useStableId('mgh-grid');\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const cardRef = React.useRef<HTMLDivElement | null>(null);\n const scrollerRef = React.useRef<HTMLDivElement | null>(null);\n const toolbarRef = React.useRef<HTMLDivElement | null>(null);\n const forceUpdate = useForceUpdate();\n\n const localeText = React.useMemo<MGHGridLocaleText>(\n () => ({ ...DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n\n /* ------------------------------------------------------------------ latest ref + api shell */\n\n const latest = React.useRef<any>({});\n const getDetails = React.useCallback((): MGHGridCallbackDetails => ({ api: latest.current.api }), []);\n\n const apiObject = React.useMemo<MGHGridApi<R>>(() => {\n const L = () => latest.current;\n const apiImpl: MGHGridApi<R> = {\n getRow: (id) => L().rowsById.get(id) ?? null,\n getRowModels: () => new Map(L().rowsById),\n getAllRowIds: () => L().rowEntries.map((e: RowEntry<R>) => e.id),\n getRowNode: (id) => L().nodesById.get(id) ?? null,\n getSortedRows: () => L().sortedLeaves.map((e: RowEntry<R>) => e.row),\n getSortedRowIds: () => L().sortedLeaves.map((e: RowEntry<R>) => e.id),\n getVisibleRows: () =>\n L()\n .pagedRows.filter((dr: DisplayRow<R>) => dr.type === 'leaf' && dr.row)\n .map((dr: DisplayRow<R>) => ({ id: dr.id, model: dr.row as R })),\n getRowIndexRelativeToVisibleRows: (id) => L().pagedRows.findIndex((dr: DisplayRow<R>) => dr.id === id),\n updateRows: (updates) => {\n updates.forEach((update) => {\n const id = getRowIdFromRow(update as R, L().getRowId);\n const existing = L().rowsById.get(id);\n if (existing) L().setRowOverride(id, { ...existing, ...update });\n });\n },\n\n getAllColumns: () => L().orderedUserColumns,\n getVisibleColumns: () => L().visibleUserColumns,\n getColumn: (field) => L().getColumn(field),\n getColumnIndex: (field, useVisibleColumns = true) =>\n (useVisibleColumns ? L().visibleUserColumns : L().orderedUserColumns).findIndex(\n (c: MGHGridColDef) => c.field === field\n ),\n getColumnVisibilityModel: () => L().columnVisibilityModel,\n setColumnVisibility: (field, isVisible) =>\n L().setColumnVisibilityModel({ ...L().columnVisibilityModel, [field]: isVisible }),\n setColumnVisibilityModel: (model) => L().setColumnVisibilityModel(model),\n setColumnWidth: (field, width) => L().setColumnWidth(field, width),\n setColumnIndex: (field, targetIndex) => L().setColumnIndex(field, targetIndex),\n autosizeColumns: (options) => L().autosizeColumns(options),\n pinColumn: (field, side) => L().pinColumn(field, side),\n unpinColumn: (field) => L().unpinColumn(field),\n isColumnPinned: (field) => L().isColumnPinned(field),\n getPinnedColumns: () => L().pinnedColumns,\n setPinnedColumns: (model) => L().setPinnedColumns(model),\n\n getSortModel: () => L().sortModel,\n setSortModel: (model) => L().setSortModel(model),\n sortColumn: (field, direction, allowMultipleSorting) => L().sortColumn(field, direction, allowMultipleSorting),\n\n getFilterModel: () => L().filterModel,\n setFilterModel: (model) => L().setFilterModel(model),\n upsertFilterItem: (item) => L().upsertFilterItems([item]),\n upsertFilterItems: (items) => L().upsertFilterItems(items),\n deleteFilterItem: (item) => L().deleteFilterItem(item),\n setFilterLogicOperator: (operator) => L().setFilterModel({ ...L().filterModel, logicOperator: operator }),\n setQuickFilterValues: (values) => L().setFilterModel({ ...L().filterModel, quickFilterValues: values }),\n showFilterPanel: (targetColumnField, anchorEl) => L().showPreferences('filters', anchorEl, targetColumnField),\n hideFilterPanel: () => L().hidePreferences(),\n showPreferences: (panel, anchorEl, targetField) => L().showPreferences(panel, anchorEl, targetField),\n hidePreferences: () => L().hidePreferences(),\n\n getSelectedRows: () => {\n const map = new Map<MGHGridRowId, R>();\n L().selectedIds.forEach((id: MGHGridRowId) => {\n const row = L().rowsById.get(id);\n if (row) map.set(id, row);\n });\n return map;\n },\n getRowSelectionModel: () => ({ type: 'include', ids: L().selectedIds }),\n setRowSelectionModel: (model) => {\n const normalized = normalizeSelectionModel(\n model,\n L().rowEntries.map((e: RowEntry<R>) => e.id)\n );\n L().setSelectedIds(normalized.ids);\n },\n selectRow: (id, isSelected = true, resetSelection = false) => L().selectRows([id], isSelected, resetSelection),\n selectRows: (ids, isSelected = true, resetSelection = false) => L().selectRows(ids, isSelected, resetSelection),\n isRowSelected: (id) => L().selectedIds.has(id),\n isRowSelectable: (id) => L().isRowSelectableFn(id, L().rowsById.get(id)),\n\n setPage: (nextPage) => L().setPaginationModel({ ...L().paginationModel, page: Math.max(0, nextPage) }),\n setPageSize: (nextPageSize) => L().setPaginationModel({ page: 0, pageSize: Math.max(1, nextPageSize) }),\n setPaginationModel: (model) => L().setPaginationModel(model),\n\n setDensity: (value) => L().setDensity(value),\n\n getDataAsCsv: (options) => getDataAsCsv(apiImpl, options),\n exportDataAsCsv: (options) => exportDataAsCsv(apiImpl, options),\n exportDataAsExcel: (options) => exportDataAsExcel(apiImpl, options),\n exportDataAsPrint: (options) => L().startPrint(options),\n\n toggleDetailPanel: (id) => L().toggleDetailPanel(id),\n setExpandedDetailPanels: (ids) => L().setExpandedDetailPanels(new Set(ids)),\n getExpandedDetailPanels: () => Array.from(L().expandedDetailPanels as Set<MGHGridRowId>),\n\n getRowGroupingModel: () => L().rowGroupingModel,\n setRowGroupingModel: (model) => L().setRowGroupingModel(model),\n addRowGroupingCriteria: (field, groupingIndex) => {\n const current: string[] = L().rowGroupingModel.filter((f: string) => f !== field);\n if (groupingIndex === undefined) current.push(field);\n else current.splice(clamp(groupingIndex, 0, current.length), 0, field);\n L().setRowGroupingModel(current);\n },\n removeRowGroupingCriteria: (field) =>\n L().setRowGroupingModel(L().rowGroupingModel.filter((f: string) => f !== field)),\n setRowChildrenExpansion: (id, isExpanded) => L().setRowChildrenExpansion(id, isExpanded),\n getRowGroupChildren: ({ groupId }) => {\n const group = L().groupsById.get(groupId) as GroupTreeNode<R> | undefined;\n return group ? group.descendants.map((d) => d.id) : [];\n },\n\n getAggregationModel: () => L().aggregationModel,\n setAggregationModel: (model) => L().setAggregationModel(model),\n\n startCellEditMode: ({ id, field }) => L().startCellEditMode(id, field),\n stopCellEditMode: ({ id, field, ignoreModifications }) =>\n L().stopCellEditMode(id, field, ignoreModifications, 'api'),\n getCellMode: (id, field) => {\n const editing = L().editingCell as CellCoords | null;\n return editing && editing.id === id && editing.field === field ? 'edit' : 'view';\n },\n setEditCellValue: ({ id, field, value }) => {\n const editing = L().editingCell as CellCoords | null;\n if (editing && editing.id === id && editing.field === field) L().setEditValue(value);\n },\n\n getCellValue: (id, field) => {\n const row = L().rowsById.get(id);\n const col = L().getColumn(field);\n return row && col ? getCellValue(row, col, apiImpl) : undefined;\n },\n getCellParams: (id, field) => {\n const row = L().rowsById.get(id);\n return L().buildCellParams(\n id,\n field,\n row,\n L().nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null }\n );\n },\n setCellFocus: (id, field) => {\n pendingFocusRef.current = true;\n L().setFocusedCell({ id, field });\n },\n\n scrollToIndexes: (params) => L().scrollToIndexes(params),\n scroll: ({ left, top }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return;\n if (left !== undefined) scroller.scrollLeft = left;\n if (top !== undefined) scroller.scrollTop = top;\n },\n getScrollPosition: () => ({\n left: scrollerRef.current?.scrollLeft ?? 0,\n top: scrollerRef.current?.scrollTop ?? 0,\n }),\n\n get state() {\n return L().state as MGHGridState;\n },\n forceUpdate: () => L().forceUpdate(),\n rootElementRef: rootRef,\n };\n return apiImpl;\n }, []);\n if (!latest.current.api) latest.current.api = apiObject;\n\n /* ------------------------------------------------------------------ persisted state */\n\n const persisted = React.useMemo(\n () => ({\n visibility: columnVisibilityStorageKey\n ? readLocalStorage<MGHGridColumnVisibilityModel>(columnVisibilityStorageKey)\n : null,\n order: columnOrderStorageKey ? readLocalStorage<string[]>(columnOrderStorageKey) : null,\n widths: columnWidthStorageKey ? readLocalStorage<Record<string, number>>(columnWidthStorageKey) : null,\n pinned: pinnedColumnsStorageKey ? readLocalStorage<MGHGridPinnedColumns>(pinnedColumnsStorageKey) : null,\n }),\n [columnVisibilityStorageKey, columnOrderStorageKey, columnWidthStorageKey, pinnedColumnsStorageKey]\n );\n\n /* ------------------------------------------------------------------ models */\n\n const [sortModel, setSortModel] = useControlledState<MGHGridSortModel>(\n sortModelProp,\n initialState?.sorting?.sortModel ?? EMPTY_ARRAY,\n (model) => onSortModelChange?.(model, getDetails())\n );\n\n const [filterModel, setFilterModel] = useControlledState<MGHGridFilterModel>(\n filterModelProp,\n initialState?.filter?.filterModel ?? DEFAULT_FILTER_MODEL,\n (model) => onFilterModelChange?.(model, getDetails())\n );\n\n const [paginationModel, setPaginationModel] = useControlledState<MGHGridPaginationModel>(\n paginationModelProp,\n {\n page: initialState?.pagination?.paginationModel?.page ?? 0,\n pageSize: initialState?.pagination?.paginationModel?.pageSize ?? pageSize,\n },\n (model) => onPaginationModelChange?.(model, getDetails())\n );\n\n const [columnVisibilityModel, setColumnVisibilityModel] = useControlledState<MGHGridColumnVisibilityModel>(\n columnVisibilityModelProp,\n persisted.visibility ?? initialState?.columns?.columnVisibilityModel ?? EMPTY_OBJECT,\n (model) => {\n if (columnVisibilityStorageKey) writeLocalStorage(columnVisibilityStorageKey, model);\n onColumnVisibilityModelChange?.(model, getDetails());\n }\n );\n\n const [density, setDensity] = useControlledState<MGHGridDensity>(\n densityProp,\n initialState?.density ?? 'compact',\n (value) => onDensityChange?.(value, getDetails())\n );\n\n const [pinnedColumns, setPinnedColumns] = useControlledState<MGHGridPinnedColumns>(\n pinnedColumnsProp,\n persisted.pinned ?? initialState?.pinnedColumns ?? EMPTY_OBJECT,\n (model) => {\n if (pinnedColumnsStorageKey) writeLocalStorage(pinnedColumnsStorageKey, model);\n onPinnedColumnsChange?.(model, getDetails());\n }\n );\n\n const [rowGroupingModel, setRowGroupingModel] = useControlledState<MGHGridRowGroupingModel>(\n rowGroupingModelProp,\n initialState?.rowGrouping?.model ?? EMPTY_ARRAY,\n (model) => onRowGroupingModelChange?.(model, getDetails())\n );\n\n const [aggregationModel, setAggregationModel] = useControlledState<MGHGridAggregationModel>(\n aggregationModelProp,\n initialState?.aggregation?.model ?? EMPTY_OBJECT,\n (model) => onAggregationModelChange?.(model, getDetails())\n );\n\n const controlledExpandedDetail = React.useMemo(\n () => (detailPanelExpandedRowIdsProp ? new Set<MGHGridRowId>(detailPanelExpandedRowIdsProp) : undefined),\n [detailPanelExpandedRowIdsProp]\n );\n const [expandedDetailPanels, setExpandedDetailPanels] = useControlledState<Set<MGHGridRowId>>(\n controlledExpandedDetail,\n React.useMemo(() => new Set<MGHGridRowId>(initialState?.detailPanel?.expandedRowIds ?? []), []),\n (ids) => onDetailPanelExpandedRowIdsChange?.(Array.from(ids), getDetails())\n );\n\n const controlledSelection = React.useMemo(\n () => (rowSelectionModelProp !== undefined ? normalizeSelectionModel(rowSelectionModelProp).ids : undefined),\n [rowSelectionModelProp]\n );\n const [selectedIds, setSelectedIds] = useControlledState<Set<MGHGridRowId>>(\n controlledSelection,\n React.useMemo(() => new Set<MGHGridRowId>(), []),\n (ids) => onRowSelectionModelChange?.({ type: 'include', ids }, getDetails())\n );\n\n /* ------------------------------------------------------------------ internal state */\n\n const [orderedFields, setOrderedFields] = React.useState<string[] | null>(\n () => persisted.order ?? initialState?.columns?.orderedFields ?? null\n );\n const [columnWidths, setColumnWidths] = React.useState<Record<string, number>>(() => {\n if (persisted.widths) return persisted.widths;\n const dims = initialState?.columns?.dimensions;\n if (!dims) return {};\n const out: Record<string, number> = {};\n Object.keys(dims).forEach((field) => {\n if (dims[field].width) out[field] = dims[field].width as number;\n });\n return out;\n });\n const [groupExpansion, setGroupExpansion] = React.useState<Map<MGHGridRowId, boolean>>(() => new Map());\n const [editingCell, setEditingCell] = React.useState<CellCoords | null>(null);\n const [editValue, setEditValue] = React.useState<any>(undefined);\n const [focusedCell, setFocusedCell] = React.useState<CellCoords | null>(null);\n const pendingFocusRef = React.useRef(false);\n const [preferencePanel, setPreferencePanel] = React.useState<\n MGHGridPreferencePanelState & { anchorEl: HTMLElement | null }\n >({\n open: false,\n anchorEl: null,\n });\n const [columnMenu, setColumnMenu] = React.useState<{ field: string; anchorEl: HTMLElement } | null>(null);\n const [resizingField, setResizingField] = React.useState<string | null>(null);\n // While set, the grid renders every row (no pagination / virtualization) so the DOM can be printed.\n const [printState, setPrintState] = React.useState<MGHGridPrintExportOptions | null>(null);\n const printing = printState !== null;\n const [drag, setDrag] = React.useState<{ field: string; overField: string | null; side: 'left' | 'right' } | null>(null);\n const [scrollTop, setScrollTop] = React.useState(0);\n const scrollRaf = React.useRef(0);\n const lastClickedIdRef = React.useRef<MGHGridRowId | null>(null);\n\n // Row updates (editing / api.updateRows) are kept until the `rows` prop identity changes.\n const [overrideState, setOverrideState] = React.useState<{ rows: R[]; map: Map<MGHGridRowId, R> }>(() => ({\n rows,\n map: new Map(),\n }));\n const rowOverrides: Map<MGHGridRowId, R> = overrideState.rows === rows ? overrideState.map : EMPTY_MAP;\n const setRowOverride = React.useCallback(\n (id: MGHGridRowId, row: R) => {\n setOverrideState((prev) => {\n const map = new Map(prev.rows === rows ? prev.map : []);\n map.set(id, row);\n return { rows, map };\n });\n },\n [rows]\n );\n\n /* ------------------------------------------------------------------ sizes */\n\n const { width: viewportWidth, height: viewportHeight } = useElementSize(scrollerRef);\n const densityFactor = DENSITY_FACTORS[density] ?? 1;\n const rowHeight = Math.round(rowHeightProp * densityFactor);\n const headerHeight = Math.round(columnHeaderHeight * densityFactor);\n\n /* ------------------------------------------------------------------ rows */\n\n const rowEntries = React.useMemo<RowEntry<R>[]>(() => {\n const out: RowEntry<R>[] = [];\n rows.forEach((raw) => {\n const id = getRowIdFromRow(raw, getRowId);\n if (id === undefined || id === null) return;\n out.push({ id, row: rowOverrides.get(id) ?? raw });\n });\n return out;\n }, [rows, getRowId, rowOverrides]);\n\n const rowsById = React.useMemo(() => {\n const map = new Map<MGHGridRowId, R>();\n rowEntries.forEach((entry) => map.set(entry.id, entry.row));\n (pinnedRows?.top ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n (pinnedRows?.bottom ?? []).forEach((row) => map.set(getRowIdFromRow(row, getRowId), row));\n return map;\n }, [rowEntries, pinnedRows, getRowId]);\n\n /* ------------------------------------------------------------------ columns */\n\n const userColumns = React.useMemo(() => columnsProp.map((col) => normalizeColumn(col)), [columnsProp]);\n\n const columnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef<R>>();\n userColumns.forEach((col) => map.set(col.field, col));\n return map;\n }, [userColumns]);\n\n const groupingFields = React.useMemo(\n () => (disableRowGrouping ? [] : rowGroupingModel.filter((field) => columnsByField.has(field))),\n [rowGroupingModel, columnsByField, disableRowGrouping]\n );\n const groupingActive = groupingFields.length > 0;\n\n const groupingColumn = React.useMemo<MGHGridColDef<R> | null>(() => {\n if (!groupingActive) return null;\n const single = groupingFields.length === 1 ? columnsByField.get(groupingFields[0]) : undefined;\n return normalizeColumn<R>({\n field: GROUPING_COLUMN_FIELD,\n headerName: single ? (single.headerName ?? single.field) : localeText.groupingColumnHeaderName,\n width: GROUPING_COLUMN_WIDTH,\n minWidth: 120,\n sortable: true,\n filterable: false,\n hideable: false,\n groupable: false,\n aggregable: false,\n editable: false,\n disableExport: true,\n disableReorder: true,\n ...(groupingColDef as any),\n });\n }, [groupingActive, groupingFields, columnsByField, localeText.groupingColumnHeaderName, groupingColDef]);\n\n const orderedUserColumns = React.useMemo(() => {\n if (!orderedFields || orderedFields.length === 0) return userColumns;\n const seen = new Set<string>();\n const out: MGHGridColDef<R>[] = [];\n orderedFields.forEach((field) => {\n const col = columnsByField.get(field);\n if (col && !seen.has(field)) {\n seen.add(field);\n out.push(col);\n }\n });\n userColumns.forEach((col) => {\n if (!seen.has(col.field)) out.push(col);\n });\n return out;\n }, [orderedFields, userColumns, columnsByField]);\n\n const isColumnVisible = React.useCallback(\n (field: string) => {\n const value = columnVisibilityModel[field];\n if (value === false) return false;\n if (value === undefined && groupingFields.indexOf(field) !== -1) return false;\n return true;\n },\n [columnVisibilityModel, groupingFields]\n );\n\n const visibleUserColumns = React.useMemo(() => {\n if (printState) {\n let cols = orderedUserColumns.filter((col) => isColumnVisible(col.field));\n if (printState.fields) {\n const wanted = new Set(printState.fields);\n cols = orderedUserColumns.filter((col) => wanted.has(col.field));\n } else if (printState.allColumns) {\n cols = orderedUserColumns;\n }\n return cols.filter((col) => !col.disableExport);\n }\n return orderedUserColumns.filter((col) => isColumnVisible(col.field));\n }, [orderedUserColumns, isColumnVisible, printState]);\n\n const layout = React.useMemo(() => {\n const internal: MGHGridColDef[] = [];\n if (checkboxSelection) internal.push(CHECKBOX_COLUMN_DEF);\n if (getDetailPanelContent) internal.push(DETAIL_PANEL_TOGGLE_COLUMN_DEF);\n const leftFields = disableColumnPinning ? [] : (pinnedColumns.left ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const rightFields = disableColumnPinning\n ? []\n : (pinnedColumns.right ?? []).filter((f) => f !== GROUPING_COLUMN_FIELD);\n const visibleByField = new Map<string, MGHGridColDef>();\n visibleUserColumns.forEach((col) => visibleByField.set(col.field, col));\n const left: MGHGridColDef[] = internal.slice();\n if (groupingColumn) left.push(groupingColumn);\n leftFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col) left.push(col);\n });\n const right: MGHGridColDef[] = [];\n rightFields.forEach((f) => {\n const col = visibleByField.get(f);\n if (col && leftFields.indexOf(f) === -1) right.push(col);\n });\n const center = visibleUserColumns.filter(\n (col) => leftFields.indexOf(col.field) === -1 && rightFields.indexOf(col.field) === -1\n );\n const ordered = left.concat(center, right);\n const widths = computeWidths(ordered, viewportWidth, columnWidths);\n const hasPinning = left.length > internal.length + (groupingColumn ? 1 : 0) || right.length > 0;\n const columns: ColumnLayout[] = [];\n let x = 0;\n let leftOffset = 0;\n ordered.forEach((col, i) => {\n const width = widths[i];\n const isLeft = i < left.length;\n const isRight = i >= left.length + center.length;\n columns.push({\n col,\n width,\n pinned: isLeft ? 'left' : isRight ? 'right' : null,\n offset: isLeft ? leftOffset : 0,\n x,\n isLastLeft: isLeft && i === left.length - 1,\n isFirstRight: isRight && i === left.length + center.length,\n });\n if (isLeft) leftOffset += width;\n x += width;\n });\n let rightOffset = 0;\n for (let i = columns.length - 1; i >= 0; i -= 1) {\n if (columns[i].pinned !== 'right') break;\n columns[i].offset = rightOffset;\n rightOffset += columns[i].width;\n }\n return { columns, totalWidth: x, hasPinning, leftCount: left.length, rightCount: right.length };\n }, [\n checkboxSelection,\n getDetailPanelContent,\n pinnedColumns,\n disableColumnPinning,\n visibleUserColumns,\n groupingColumn,\n viewportWidth,\n columnWidths,\n ]);\n\n const allDisplayColumnsByField = React.useMemo(() => {\n const map = new Map<string, MGHGridColDef>();\n layout.columns.forEach((c) => map.set(c.col.field, c.col));\n if (groupingColumn) map.set(GROUPING_COLUMN_FIELD, groupingColumn);\n return map;\n }, [layout.columns, groupingColumn]);\n\n const getColumn = React.useCallback(\n (field: string): MGHGridColDef<R> | undefined =>\n columnsByField.get(field) ?? (allDisplayColumnsByField.get(field) as any),\n [columnsByField, allDisplayColumnsByField]\n );\n\n /* ------------------------------------------------------------------ filtering */\n\n const activeFilters = React.useMemo(() => {\n const out: Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }> = [];\n filterModel.items.forEach((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.filterable === false) return;\n const operator = getColumnFilterOperators(col).find((op) => op.value === item.operator);\n if (!operator) return;\n const fn = operator.getApplyFilterFn(item, col);\n if (fn) out.push({ col, fn });\n });\n return out;\n }, [filterModel.items, columnsByField]);\n\n const quickFilterValues = React.useMemo(\n () => (filterModel.quickFilterValues ?? []).map((v) => String(v).trim()).filter((v) => v !== ''),\n [filterModel.quickFilterValues]\n );\n\n const quickFilterColumns = React.useMemo(() => {\n const base = filterModel.quickFilterExcludeHiddenColumns ? visibleUserColumns : orderedUserColumns;\n return base.filter((col) => col.filterable !== false && col.type !== 'actions');\n }, [filterModel.quickFilterExcludeHiddenColumns, visibleUserColumns, orderedUserColumns]);\n\n const filteredEntries = React.useMemo(() => {\n if (activeFilters.length === 0 && quickFilterValues.length === 0) return rowEntries;\n const logicAnd = (filterModel.logicOperator ?? 'and') === 'and';\n const quickAnd = (filterModel.quickFilterLogicOperator ?? 'and') === 'and';\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const quickFns = quickFilterValues.map((needle) => {\n const lowered = needle.toLowerCase();\n const perColumn = quickFilterColumns.map((col) => {\n if (col.getApplyQuickFilterFn) {\n const custom = col.getApplyQuickFilterFn(needle, col, apiRefLocal);\n return custom ? { col, fn: custom } : null;\n }\n const fn: MGHGridApplyFilterFn<R> = (value, row) => {\n if (isNil(value)) return false;\n const formatted = formattedValueToString(getFormattedValue(value, row, col, apiRefLocal)).toLowerCase();\n if (formatted.indexOf(lowered) !== -1) return true;\n const raw = typeof value === 'object' ? '' : String(value).toLowerCase();\n return raw.indexOf(lowered) !== -1;\n };\n return { col, fn };\n });\n const active = perColumn.filter(Boolean) as Array<{ col: MGHGridColDef<R>; fn: MGHGridApplyFilterFn<R> }>;\n return (row: R) => active.some(({ col, fn }) => fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal));\n });\n return rowEntries.filter(({ row }) => {\n if (activeFilters.length > 0) {\n const results = activeFilters.map(({ col, fn }) =>\n fn(getCellValue(row, col, apiRefLocal), row, col, apiRefLocal)\n );\n const pass = logicAnd ? results.every(Boolean) : results.some(Boolean);\n if (!pass) return false;\n }\n if (quickFns.length > 0) {\n const results = quickFns.map((fn) => fn(row));\n return quickAnd ? results.every(Boolean) : results.some(Boolean);\n }\n return true;\n });\n }, [\n rowEntries,\n activeFilters,\n quickFilterValues,\n quickFilterColumns,\n filterModel.logicOperator,\n filterModel.quickFilterLogicOperator,\n ]);\n\n /* ------------------------------------------------------------------ sorting */\n\n const compareEntries = React.useMemo(() => {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sorters = sortModel\n .filter((item) => item.sort && item.field !== GROUPING_COLUMN_FIELD)\n .map((item) => {\n const col = columnsByField.get(item.field);\n if (!col || col.sortable === false) return null;\n return {\n col,\n dir: item.sort === 'desc' ? -1 : 1,\n comparator: col.sortComparator ?? getDefaultComparator(col.type),\n };\n })\n .filter(Boolean) as Array<{ col: MGHGridColDef<R>; dir: number; comparator: any }>;\n if (sorters.length === 0) return null;\n return (a: RowEntry<R>, b: RowEntry<R>) => {\n for (let i = 0; i < sorters.length; i += 1) {\n const { col, dir, comparator } = sorters[i];\n const v1 = getCellValue(a.row, col, apiRefLocal);\n const v2 = getCellValue(b.row, col, apiRefLocal);\n const result = comparator(\n v1,\n v2,\n { id: a.id, field: col.field, value: v1, row: a.row, api: apiRefLocal },\n { id: b.id, field: col.field, value: v2, row: b.row, api: apiRefLocal }\n );\n if (result !== 0) return result * dir;\n }\n return 0;\n };\n }, [sortModel, columnsByField]);\n\n const sortEntries = React.useCallback(\n (entries: RowEntry<R>[]) => {\n if (!compareEntries) return entries;\n return entries\n .map((entry, index) => ({ entry, index }))\n .sort((a, b) => compareEntries(a.entry, b.entry) || a.index - b.index)\n .map((item) => item.entry);\n },\n [compareEntries]\n );\n\n /* ------------------------------------------------------------------ grouping + display rows */\n\n const aggregationFunctions = React.useMemo(\n () => ({ ...BUILT_IN_AGGREGATION_FUNCTIONS, ...aggregationFunctionsProp }),\n [aggregationFunctionsProp]\n );\n const aggregationActive = !disableAggregation && Object.keys(aggregationModel).length > 0;\n\n const isGroupExpanded = React.useCallback(\n (node: GroupTreeNode<R>) => {\n const override = groupExpansion.get(node.id);\n if (override !== undefined) return override;\n if (isGroupExpandedByDefault) {\n return isGroupExpandedByDefault({\n type: 'group',\n id: node.id,\n depth: node.depth,\n parent: node.parent,\n groupingField: node.groupingField,\n groupingKey: node.groupingKey,\n groupingLabel: node.groupingLabel,\n children: [],\n leafIds: [],\n isExpanded: false,\n });\n }\n return defaultGroupingExpansionDepth === -1 || node.depth < defaultGroupingExpansionDepth;\n },\n [groupExpansion, isGroupExpandedByDefault, defaultGroupingExpansionDepth]\n );\n\n const processed = React.useMemo(() => {\n const nodesById = new Map<MGHGridRowId, MGHGridLeafNode | MGHGridGroupNode>();\n const groupsById = new Map<MGHGridRowId, GroupTreeNode<R>>();\n if (!groupingActive) {\n const sorted = sortEntries(filteredEntries);\n const displayRows: DisplayRow<R>[] = sorted.map((entry) => {\n const node: MGHGridLeafNode = { type: 'leaf', id: entry.id, depth: 0, parent: null };\n nodesById.set(entry.id, node);\n return { id: entry.id, type: 'leaf', row: entry.row, node, depth: 0 };\n });\n return { displayRows, sortedLeaves: sorted, nodesById, groupsById, tree: [] as GroupTreeNode<R>[] };\n }\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n let tree = buildGroupTree(filteredEntries, groupingFields, columnsByField, apiRefLocal);\n const groupingSort = sortModel.find((item) => item.field === GROUPING_COLUMN_FIELD && item.sort);\n const compareGroups = (depth: number) => {\n const field = groupingFields[depth];\n const col = columnsByField.get(field);\n if (!col) return null;\n const sortItem = groupingSort ?? sortModel.find((item) => item.field === field && item.sort);\n if (!sortItem) return null;\n const comparator = col.sortComparator ?? getDefaultComparator(col.type);\n const dir = sortItem.sort === 'desc' ? -1 : 1;\n return (a: GroupTreeNode<R>, b: GroupTreeNode<R>) =>\n comparator(\n a.groupingKey,\n b.groupingKey,\n { id: a.id, field, value: a.groupingKey, row: a.descendants[0]?.row, api: apiRefLocal },\n { id: b.id, field, value: b.groupingKey, row: b.descendants[0]?.row, api: apiRefLocal }\n ) * dir;\n };\n tree = sortGroupTree(tree, compareGroups, sortEntries);\n const displayRows = flattenGroupTree(tree, isGroupExpanded, nodesById, groupsById);\n return { displayRows, sortedLeaves: collectTreeLeaves(tree), nodesById, groupsById, tree };\n }, [groupingActive, filteredEntries, sortEntries, groupingFields, columnsByField, sortModel, isGroupExpanded]);\n\n const { displayRows, sortedLeaves, nodesById, groupsById } = processed;\n\n /* ------------------------------------------------------------------ pagination */\n\n const totalDisplayRows = displayRows.length;\n const paginate = pagination && !printing;\n const pageCount = pagination ? Math.max(1, Math.ceil(totalDisplayRows / Math.max(paginationModel.pageSize, 1))) : 1;\n const page = pagination ? clamp(paginationModel.page, 0, pageCount - 1) : 0;\n\n React.useEffect(() => {\n if (pagination && paginationModel.page !== page) {\n setPaginationModel({ ...paginationModel, page });\n }\n }, [pagination, paginationModel, page, setPaginationModel]);\n\n const pagedRows = React.useMemo(\n () =>\n paginate\n ? displayRows.slice(page * paginationModel.pageSize, (page + 1) * paginationModel.pageSize)\n : displayRows,\n [displayRows, paginate, page, paginationModel.pageSize]\n );\n\n /* ------------------------------------------------------------------ aggregation values */\n\n const footerAggregates = React.useMemo(() => {\n if (!aggregationActive || aggregationPosition === 'inline') return null;\n const rowsForFooter = sortedLeaves.map((entry) => entry.row);\n return aggregateRows(rowsForFooter, aggregationModel, columnsByField, aggregationFunctions, latest.current.api);\n }, [aggregationActive, aggregationPosition, sortedLeaves, aggregationModel, columnsByField, aggregationFunctions]);\n\n const groupAggregatesCache = React.useMemo(\n () => new Map<MGHGridRowId, Record<string, { value: any; fn: string }>>(),\n [pagedRows, aggregationModel, aggregationFunctions]\n );\n const getGroupAggregates = (group: GroupTreeNode<R>) => {\n if (!aggregationActive || aggregationPosition === 'footer') return undefined;\n let cached = groupAggregatesCache.get(group.id);\n if (!cached) {\n cached = aggregateRows(\n group.descendants.map((d) => d.row),\n aggregationModel,\n columnsByField,\n aggregationFunctions,\n latest.current.api\n );\n groupAggregatesCache.set(group.id, cached);\n }\n return cached;\n };\n\n /* ------------------------------------------------------------------ row heights + virtualization */\n\n const heights = React.useMemo(() => {\n const rowHeights: number[] = [];\n const detailHeights: number[] = [];\n const offsets: number[] = [];\n let total = 0;\n let hasAuto = autoHeight || disableVirtualization || printing;\n pagedRows.forEach((dr) => {\n let h = rowHeight;\n if (getRowHeight && dr.type === 'leaf' && dr.row) {\n const result = getRowHeight({ id: dr.id, model: dr.row, densityFactor });\n if (result === 'auto') hasAuto = true;\n else if (typeof result === 'number' && result > 0) h = result;\n }\n let d = 0;\n if (dr.type === 'leaf' && getDetailPanelContent && expandedDetailPanels.has(dr.id) && dr.row) {\n const dh = getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row })\n : DEFAULT_DETAIL_PANEL_HEIGHT;\n if (dh === 'auto') hasAuto = true;\n else d = dh;\n }\n rowHeights.push(h);\n detailHeights.push(d);\n offsets.push(total);\n total += h + d;\n });\n return { rowHeights, detailHeights, offsets, total, hasAuto };\n }, [\n pagedRows,\n rowHeight,\n getRowHeight,\n densityFactor,\n getDetailPanelContent,\n getDetailPanelHeight,\n expandedDetailPanels,\n autoHeight,\n disableVirtualization,\n printing,\n ]);\n\n const virtual = !heights.hasAuto;\n\n /* ------------------------------------------------------------------ print */\n\n const startPrint = (options: MGHGridPrintExportOptions = {}) => {\n if (printState) return;\n const resolved: MGHGridPrintExportOptions = {\n title: typeof header === 'string' ? header : undefined,\n ...options,\n };\n if (!cardRef.current || typeof window === 'undefined') return;\n setPrintState(resolved);\n };\n\n React.useEffect(() => {\n if (!printState) return undefined;\n // The un-virtualized rows are already committed when this effect runs; a short timeout lets the\n // browser lay them out first. (A timeout rather than rAF so it also fires in hidden/background tabs.)\n const timer = window.setTimeout(() => {\n if (!cardRef.current) return;\n printGridElement({\n cardElement: cardRef.current,\n options: printState,\n onDone: () => setPrintState(null),\n });\n }, 50);\n return () => window.clearTimeout(timer);\n }, [printState]);\n\n const virtualRange = React.useMemo(() => {\n const count = pagedRows.length;\n if (!virtual || count === 0) return { start: 0, end: count };\n const overscan = OVERSCAN_ROWS * rowHeight;\n const viewTop = Math.max(0, scrollTop - headerHeight - overscan);\n const viewBottom = scrollTop + Math.max(viewportHeight, rowHeight) + overscan;\n const { offsets } = heights;\n let lo = 0;\n let hi = count - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid] + heights.rowHeights[mid] + heights.detailHeights[mid] < viewTop) lo = mid + 1;\n else hi = mid;\n }\n const start = lo;\n let end = start;\n while (end < count && offsets[end] < viewBottom) end += 1;\n return { start, end };\n }, [virtual, pagedRows.length, scrollTop, viewportHeight, rowHeight, headerHeight, heights]);\n\n const handleScroll = React.useCallback(() => {\n if (!latest.current.virtual) return;\n if (scrollRaf.current) return;\n scrollRaf.current = window.requestAnimationFrame(() => {\n scrollRaf.current = 0;\n if (scrollerRef.current) setScrollTop(scrollerRef.current.scrollTop);\n });\n }, []);\n\n React.useEffect(\n () => () => {\n if (scrollRaf.current) window.cancelAnimationFrame(scrollRaf.current);\n },\n []\n );\n\n /* ------------------------------------------------------------------ selection */\n\n const isRowSelectableFn = React.useCallback(\n (id: MGHGridRowId, row: R | null | undefined) => {\n if (!row) return false;\n if (!isRowSelectable) return true;\n return isRowSelectable({ id, row, columns: orderedUserColumns, api: latest.current.api });\n },\n [isRowSelectable, orderedUserColumns]\n );\n\n const selectionCandidates = React.useMemo(() => {\n const source: RowEntry<R>[] = checkboxSelectionVisibleOnly\n ? (pagedRows\n .filter((dr) => dr.type === 'leaf' && dr.row)\n .map((dr) => ({ id: dr.id, row: dr.row as R })) as RowEntry<R>[])\n : sortedLeaves;\n return source.filter((entry) => isRowSelectableFn(entry.id, entry.row)).map((entry) => entry.id);\n }, [checkboxSelectionVisibleOnly, pagedRows, sortedLeaves, isRowSelectableFn]);\n\n const selectedCandidateCount = React.useMemo(\n () => selectionCandidates.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0),\n [selectionCandidates, selectedIds]\n );\n const allCandidatesSelected = selectionCandidates.length > 0 && selectedCandidateCount === selectionCandidates.length;\n const someCandidatesSelected = selectedCandidateCount > 0 && !allCandidatesSelected;\n\n const updateSelection = React.useCallback(\n (updater: (prev: Set<MGHGridRowId>) => Set<MGHGridRowId>) => {\n setSelectedIds((prev) => {\n const next = updater(prev);\n return selectionModelsEqual({ type: 'include', ids: prev }, { type: 'include', ids: next }) ? prev : next;\n });\n },\n [setSelectedIds]\n );\n\n const selectRows = React.useCallback(\n (ids: MGHGridRowId[], isSelected = true, resetSelection = false) => {\n updateSelection((prev) => {\n const next = resetSelection ? new Set<MGHGridRowId>() : new Set(prev);\n ids.forEach((id) => {\n if (isSelected) {\n if (isRowSelectableFn(id, rowsById.get(id))) next.add(id);\n } else next.delete(id);\n });\n if (disableMultipleRowSelection && next.size > 1) {\n const lastId = ids[ids.length - 1];\n return new Set<MGHGridRowId>(isSelected && next.has(lastId) ? [lastId] : []);\n }\n return next;\n });\n },\n [updateSelection, isRowSelectableFn, rowsById, disableMultipleRowSelection]\n );\n\n React.useEffect(() => {\n if (keepNonExistentRowsSelected || selectedIds.size === 0) return;\n let changed = false;\n const next = new Set<MGHGridRowId>();\n selectedIds.forEach((id) => {\n if (rowsById.has(id)) next.add(id);\n else changed = true;\n });\n if (changed) setSelectedIds(next);\n }, [rowsById, keepNonExistentRowsSelected, selectedIds, setSelectedIds]);\n\n const toggleAllCandidates = () => {\n if (allCandidatesSelected) selectRows(selectionCandidates, false);\n else selectRows(selectionCandidates, true);\n };\n\n const handleRowSelectionClick = (renderRow: RenderRow<R>, event: React.MouseEvent) => {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const allSelected = leafIds.every((id) => selectedIds.has(id));\n selectRows(leafIds, !allSelected, false);\n return;\n }\n if (renderRow.kind !== 'leaf') return;\n const id = renderRow.id;\n if (!isRowSelectableFn(id, renderRow.row)) return;\n const multiple = !disableMultipleRowSelection;\n if (event.shiftKey && multiple && lastClickedIdRef.current !== null) {\n const ids = pagedRows.filter((dr) => dr.type === 'leaf').map((dr) => dr.id);\n const from = ids.indexOf(lastClickedIdRef.current);\n const to = ids.indexOf(id);\n if (from !== -1 && to !== -1) {\n const [a, b] = from < to ? [from, to] : [to, from];\n selectRows(ids.slice(a, b + 1), true, !checkboxSelection && !event.ctrlKey && !event.metaKey);\n return;\n }\n }\n lastClickedIdRef.current = id;\n const isSelected = selectedIds.has(id);\n const resetSelection = !checkboxSelection && !event.ctrlKey && !event.metaKey;\n if (resetSelection) {\n if (isSelected && selectedIds.size === 1) selectRows([id], false, true);\n else selectRows([id], true, true);\n } else {\n selectRows([id], !isSelected, false);\n }\n };\n\n /* ------------------------------------------------------------------ sorting helpers */\n\n const sortColumn = (field: string, direction?: MGHGridSortDirection, allowMultiple = false) => {\n const col = getColumn(field);\n if (!col || col.sortable === false || disableColumnSorting) return;\n const current = sortModel.find((item) => item.field === field);\n let next: MGHGridSortDirection;\n if (direction === undefined) {\n const order = col.sortingOrder ?? sortingOrder;\n const index = order.indexOf(current?.sort ?? null);\n next = order[(index + 1) % order.length];\n } else {\n next = direction;\n }\n let model: MGHGridSortModel;\n if (allowMultiple && !disableMultipleColumnsSorting) {\n model = sortModel.filter((item) => item.field !== field);\n if (next)\n model = current\n ? sortModel.map((item) => (item.field === field ? { field, sort: next } : item))\n : model.concat([{ field, sort: next }]);\n } else {\n model = next ? [{ field, sort: next }] : [];\n }\n setSortModel(model);\n };\n\n /* ------------------------------------------------------------------ column helpers */\n\n const persistOrder = (fields: string[]) => {\n if (columnOrderStorageKey) writeLocalStorage(columnOrderStorageKey, fields);\n };\n\n const persistWidths = (widths: Record<string, number>) => {\n if (columnWidthStorageKey) writeLocalStorage(columnWidthStorageKey, widths);\n };\n\n const setColumnIndex = (field: string, targetIndex: number, event: React.DragEvent | null = null) => {\n const fields = orderedUserColumns.map((c) => c.field);\n const oldIndex = fields.indexOf(field);\n if (oldIndex === -1) return;\n const next = moveItem(fields, oldIndex, clamp(targetIndex, 0, fields.length - 1));\n setOrderedFields(next);\n persistOrder(next);\n const col = columnsByField.get(field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex, oldIndex }, event, getDetails());\n };\n\n const setColumnWidth = (field: string, width: number) => {\n const col = getColumn(field);\n if (!col) return;\n const clamped = clamp(width, col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n setColumnWidths((prev) => {\n const next = { ...prev, [field]: clamped };\n persistWidths(next);\n return next;\n });\n onColumnWidthChange?.({ colDef: col, width: clamped }, getDetails());\n };\n\n const autosizeColumns = (options: { columns?: string[]; includeHeaders?: boolean; expand?: boolean } = {}) => {\n const includeHeaders = options.includeHeaders ?? true;\n const targets = layout.columns.filter(\n (lc) => !isInternalField(lc.col.field) && (!options.columns || options.columns.indexOf(lc.col.field) !== -1)\n );\n if (targets.length === 0) return;\n const root = rootRef.current;\n const computed = root && typeof window !== 'undefined' ? window.getComputedStyle(root) : null;\n const fontFamily = computed?.fontFamily || 'sans-serif';\n const cellFont = `400 14px ${fontFamily}`;\n const headerFont = `600 14px ${fontFamily}`;\n const sample = sortedLeaves.slice(0, 500);\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const next = { ...columnWidths };\n targets.forEach(({ col }) => {\n let max = includeHeaders ? measureText(col.headerName ?? col.field, headerFont) + 64 : 0;\n sample.forEach((entry) => {\n const value = getCellValue(entry.row, col, apiRefLocal);\n const text = formattedValueToString(getFormattedValue(value, entry.row, col, apiRefLocal, entry.id));\n const w = measureText(text, cellFont) + 24;\n if (w > max) max = w;\n });\n next[col.field] = clamp(Math.ceil(max), col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH, col.maxWidth ?? Infinity);\n });\n setColumnWidths(next);\n persistWidths(next);\n };\n\n const pinColumn = (field: string, side: MGHGridPinnedSide) => {\n if (disableColumnPinning) return;\n const left = (pinnedColumns.left ?? []).filter((f) => f !== field);\n const right = (pinnedColumns.right ?? []).filter((f) => f !== field);\n if (side === 'left') left.push(field);\n else right.unshift(field);\n setPinnedColumns({ left, right });\n };\n\n const unpinColumn = (field: string) => {\n setPinnedColumns({\n left: (pinnedColumns.left ?? []).filter((f) => f !== field),\n right: (pinnedColumns.right ?? []).filter((f) => f !== field),\n });\n };\n\n const isColumnPinned = (field: string): MGHGridPinnedSide | false => {\n if (disableColumnPinning) return false;\n if ((pinnedColumns.left ?? []).indexOf(field) !== -1) return 'left';\n if ((pinnedColumns.right ?? []).indexOf(field) !== -1) return 'right';\n return false;\n };\n\n /* ------------------------------------------------------------------ filter helpers */\n\n const upsertFilterItems = (items: MGHGridFilterItem[]) => {\n let nextItems = filterModel.items.slice();\n items.forEach((item) => {\n const withId =\n item.id === undefined ? { ...item, id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}` } : item;\n const index = nextItems.findIndex((existing) => existing.id !== undefined && existing.id === withId.id);\n if (index === -1) nextItems.push(withId);\n else nextItems[index] = withId;\n });\n if (disableMultipleColumnsFiltering && nextItems.length > 1) nextItems = nextItems.slice(-1);\n setFilterModel({ ...filterModel, items: nextItems });\n };\n\n const deleteFilterItem = (item: MGHGridFilterItem) => {\n setFilterModel({\n ...filterModel,\n items: filterModel.items.filter((existing) =>\n item.id !== undefined ? existing.id !== item.id : existing !== item\n ),\n });\n };\n\n const showPreferences = (panel: 'columns' | 'filters', anchorEl?: HTMLElement | null, targetField?: string) => {\n setColumnMenu(null);\n setPreferencePanel({\n open: true,\n openedPanelValue: panel,\n targetField,\n anchorEl: anchorEl ?? toolbarRef.current ?? rootRef.current,\n });\n };\n\n const hidePreferences = React.useCallback(() => {\n setPreferencePanel((prev) => (prev.open ? { open: false, anchorEl: null } : prev));\n }, []);\n\n /* ------------------------------------------------------------------ editing */\n\n const isCellEditableFn = (params: MGHGridCellParams<R>) => {\n if (!params.colDef.editable) return false;\n if (params.rowNode.type !== 'leaf') return false;\n return isCellEditable ? isCellEditable(params) : true;\n };\n\n const startCellEditMode = (id: MGHGridRowId, field: string) => {\n const row = rowsById.get(id);\n const col = getColumn(field);\n if (!row || !col) return;\n const params = buildCellParams(id, field, row, nodesById.get(id) ?? { type: 'leaf', id, depth: 0, parent: null });\n if (!isCellEditableFn(params)) return;\n setEditingCell({ id, field });\n setEditValue(params.value);\n setFocusedCell({ id, field });\n };\n\n const applyRowUpdate = (id: MGHGridRowId, newRow: R, oldRow: R) => {\n if (processRowUpdate) {\n Promise.resolve()\n .then(() => processRowUpdate(newRow, oldRow, { rowId: id }))\n .then((result) => setRowOverride(id, (result ?? newRow) as R))\n .catch((error) => {\n if (onProcessRowUpdateError) onProcessRowUpdateError(error);\n else console.error('MGHGrid: processRowUpdate failed', error);\n });\n } else {\n setRowOverride(id, newRow);\n }\n };\n\n const stopCellEditMode = (\n id: MGHGridRowId,\n field: string,\n ignoreModifications = false,\n reason: 'enterKeyDown' | 'escapeKeyDown' | 'cellFocusOut' | 'tabKeyDown' | 'api' = 'api'\n ) => {\n if (!editingCell || editingCell.id !== id || editingCell.field !== field) return;\n const row = rowsById.get(id);\n const col = getColumn(field);\n setEditingCell(null);\n if (!row || !col) return;\n if (!ignoreModifications) {\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const parsed = col.valueParser\n ? col.valueParser(editValue, row, col, apiRefLocal)\n : parseEditValue(editValue, col);\n const currentValue = getCellValue(row, col, apiRefLocal);\n if (!Object.is(parsed, currentValue)) {\n const newRow = col.valueSetter\n ? col.valueSetter(parsed, row, col, apiRefLocal)\n : ({ ...row, [field]: parsed } as R);\n applyRowUpdate(id, newRow, row);\n }\n }\n onCellEditStop?.({ id, field, row, reason }, getDetails());\n pendingFocusRef.current = true;\n setFocusedCell({ id, field });\n };\n\n /* ------------------------------------------------------------------ detail panel & grouping helpers */\n\n const toggleDetailPanel = (id: MGHGridRowId) => {\n setExpandedDetailPanels((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const setRowChildrenExpansion = (id: MGHGridRowId, isExpanded: boolean) => {\n setGroupExpansion((prev) => {\n const next = new Map(prev);\n next.set(id, isExpanded);\n return next;\n });\n };\n\n const groupingKey = groupingFields.join('|');\n const previousGroupingKey = React.useRef(groupingKey);\n React.useEffect(() => {\n if (previousGroupingKey.current === groupingKey) return;\n previousGroupingKey.current = groupingKey;\n setGroupExpansion(new Map());\n }, [groupingKey]);\n\n /* ------------------------------------------------------------------ cell params */\n\n const buildCellParams = (id: MGHGridRowId, field: string, row: R, node: MGHGridRowNode): MGHGridCellParams<R> => {\n const col = getColumn(field) as MGHGridColDef<R>;\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const value = getCellValue(row, col, apiRefLocal);\n const formattedValue = getFormattedValue(value, row, col, apiRefLocal, id);\n const hasFocus = Boolean(focusedCell && focusedCell.id === id && focusedCell.field === field);\n const cellMode = editingCell && editingCell.id === id && editingCell.field === field ? 'edit' : 'view';\n return {\n id,\n field,\n value,\n formattedValue,\n row,\n rowNode: node,\n colDef: col,\n api: apiRefLocal,\n hasFocus,\n tabIndex: hasFocus ? 0 : -1,\n cellMode,\n isEditable: Boolean(col.editable) && node.type === 'leaf',\n };\n };\n\n const buildRowParams = (id: MGHGridRowId, row: R): MGHGridRowParams<R> => ({\n id,\n row,\n columns: orderedUserColumns,\n api: latest.current.api,\n });\n\n /* ------------------------------------------------------------------ keyboard navigation */\n\n React.useEffect(() => {\n if (!pendingFocusRef.current || !focusedCell || !rootRef.current) return;\n pendingFocusRef.current = false;\n const selector = `[data-mgh-row-id=\"${String(focusedCell.id).replace(/\"/g, '\\\\\"')}\"] [data-mgh-field=\"${focusedCell.field.replace(/\"/g, '\\\\\"')}\"]`;\n const el = rootRef.current.querySelector<HTMLElement>(selector);\n if (el && document.activeElement !== el && !el.contains(document.activeElement)) el.focus({ preventScroll: true });\n }, [focusedCell, virtualRange.start, virtualRange.end]);\n\n const scrollToIndexes = (params: { rowIndex?: number; colIndex?: number }) => {\n const scroller = scrollerRef.current;\n if (!scroller) return false;\n if (params.rowIndex !== undefined && virtual) {\n const index = clamp(params.rowIndex, 0, Math.max(pagedRows.length - 1, 0));\n const top = heights.offsets[index] ?? 0;\n const bottom = top + (heights.rowHeights[index] ?? rowHeight);\n const visibleTop = scroller.scrollTop;\n const visibleBottom = scroller.scrollTop + scroller.clientHeight - headerHeight;\n if (top < visibleTop) scroller.scrollTop = top;\n else if (bottom > visibleBottom) scroller.scrollTop = bottom - (scroller.clientHeight - headerHeight);\n } else if (params.rowIndex !== undefined) {\n const el = scroller.querySelector(`[data-mgh-row-index=\"${params.rowIndex}\"]`) as HTMLElement | null | undefined;\n el?.scrollIntoView?.({ block: 'nearest' });\n }\n if (params.colIndex !== undefined) {\n const lc = layout.columns[clamp(params.colIndex, 0, layout.columns.length - 1)];\n if (lc && !lc.pinned) {\n const leftPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'left')\n .reduce((acc, c) => acc + c.width, 0);\n const rightPinnedWidth = layout.columns\n .filter((c) => c.pinned === 'right')\n .reduce((acc, c) => acc + c.width, 0);\n const visibleLeft = scroller.scrollLeft + leftPinnedWidth;\n const visibleRight = scroller.scrollLeft + scroller.clientWidth - rightPinnedWidth;\n if (lc.x < visibleLeft) scroller.scrollLeft = lc.x - leftPinnedWidth;\n else if (lc.x + lc.width > visibleRight)\n scroller.scrollLeft = lc.x + lc.width - scroller.clientWidth + rightPinnedWidth;\n }\n }\n return true;\n };\n\n const moveFocus = (\n rowDelta: number,\n colDelta: number,\n absolute?: { row?: 'first' | 'last'; col?: 'first' | 'last' }\n ) => {\n if (pagedRows.length === 0 || layout.columns.length === 0) return;\n let rowIndex = focusedCell ? pagedRows.findIndex((dr) => dr.id === focusedCell.id) : -1;\n let colIndex = focusedCell ? layout.columns.findIndex((lc) => lc.col.field === focusedCell.field) : -1;\n if (rowIndex === -1) rowIndex = 0;\n if (colIndex === -1) colIndex = 0;\n if (absolute?.row === 'first') rowIndex = 0;\n else if (absolute?.row === 'last') rowIndex = pagedRows.length - 1;\n else rowIndex = clamp(rowIndex + rowDelta, 0, pagedRows.length - 1);\n if (absolute?.col === 'first') colIndex = 0;\n else if (absolute?.col === 'last') colIndex = layout.columns.length - 1;\n else colIndex = clamp(colIndex + colDelta, 0, layout.columns.length - 1);\n const target = { id: pagedRows[rowIndex].id, field: layout.columns[colIndex].col.field };\n pendingFocusRef.current = true;\n setFocusedCell(target);\n scrollToIndexes({ rowIndex, colIndex });\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (editingCell) return;\n const target = event.target as HTMLElement;\n if (\n target &&\n (target.tagName === 'INPUT' ||\n target.tagName === 'SELECT' ||\n target.tagName === 'TEXTAREA' ||\n target.tagName === 'BUTTON')\n ) {\n return;\n }\n const pageRows = Math.max(1, Math.floor(Math.max(viewportHeight - headerHeight, rowHeight) / rowHeight));\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1, 0);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1, 0);\n break;\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(0, -1);\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(0, 1);\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(pageRows, 0);\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(-pageRows, 0);\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'first', col: 'first' } : { col: 'first' });\n break;\n case 'End':\n event.preventDefault();\n moveFocus(0, 0, event.ctrlKey || event.metaKey ? { row: 'last', col: 'last' } : { col: 'last' });\n break;\n case 'Enter':\n case 'F2':\n if (focusedCell) {\n const node = nodesById.get(focusedCell.id);\n if (node?.type === 'group' && focusedCell.field === GROUPING_COLUMN_FIELD) {\n const group = groupsById.get(focusedCell.id);\n if (group) setRowChildrenExpansion(group.id, !isGroupExpanded(group));\n } else {\n event.preventDefault();\n startCellEditMode(focusedCell.id, focusedCell.field);\n }\n }\n break;\n case ' ':\n if (focusedCell && (checkboxSelection || !disableRowSelectionOnClick)) {\n const dr = pagedRows.find((r) => r.id === focusedCell.id);\n if (dr && dr.type === 'leaf' && dr.row) {\n event.preventDefault();\n selectRows([dr.id], !selectedIds.has(dr.id), false);\n }\n }\n break;\n case 'Escape':\n if (preferencePanel.open) hidePreferences();\n if (columnMenu) setColumnMenu(null);\n break;\n default:\n if (\n (event.ctrlKey || event.metaKey) &&\n event.key.toLowerCase() === 'a' &&\n checkboxSelection &&\n !disableMultipleRowSelection\n ) {\n event.preventDefault();\n selectRows(selectionCandidates, true);\n }\n }\n };\n\n /* ------------------------------------------------------------------ drag & drop (reorder) */\n\n const canReorder = (col: MGHGridColDef) => !disableColumnReorder && !col.disableReorder && !isInternalField(col.field);\n\n const handleDrop = (targetLc: ColumnLayout, event: React.DragEvent) => {\n event.preventDefault();\n const current = drag;\n setDrag(null);\n if (!current || current.field === targetLc.col.field) return;\n const sourceLc = layout.columns.find((lc) => lc.col.field === current.field);\n if (!sourceLc || sourceLc.pinned !== targetLc.pinned || !canReorder(targetLc.col)) return;\n const side = current.side;\n if (sourceLc.pinned) {\n const key = sourceLc.pinned;\n const list = (pinnedColumns[key] ?? []).slice();\n const from = list.indexOf(current.field);\n let to = list.indexOf(targetLc.col.field);\n if (from === -1 || to === -1) return;\n list.splice(from, 1);\n to = list.indexOf(targetLc.col.field);\n list.splice(side === 'right' ? to + 1 : to, 0, current.field);\n setPinnedColumns({ ...pinnedColumns, [key]: list });\n return;\n }\n const fields = orderedUserColumns.map((c) => c.field);\n const from = fields.indexOf(current.field);\n const without = fields.filter((f) => f !== current.field);\n let to = without.indexOf(targetLc.col.field);\n if (side === 'right') to += 1;\n without.splice(to, 0, current.field);\n setOrderedFields(without);\n persistOrder(without);\n const col = columnsByField.get(current.field);\n if (col) onColumnOrderChange?.({ column: col, targetIndex: to, oldIndex: from }, event, getDetails());\n };\n\n /* ------------------------------------------------------------------ resize */\n\n const resizeRef = React.useRef<{\n field: string;\n startX: number;\n startWidth: number;\n lastWidth: number;\n min: number;\n max: number;\n } | null>(null);\n\n const handleResizeStart = (lc: ColumnLayout, event: React.PointerEvent) => {\n event.preventDefault();\n event.stopPropagation();\n resizeRef.current = {\n field: lc.col.field,\n startX: event.clientX,\n startWidth: lc.width,\n lastWidth: lc.width,\n min: lc.col.minWidth ?? DEFAULT_COLUMN_MIN_WIDTH,\n max: lc.col.maxWidth ?? Infinity,\n };\n setResizingField(lc.col.field);\n const onMove = (e: PointerEvent) => {\n const r = resizeRef.current;\n if (!r) return;\n const width = clamp(r.startWidth + (e.clientX - r.startX), r.min, r.max);\n r.lastWidth = width;\n setColumnWidths((prev) => (prev[r.field] === width ? prev : { ...prev, [r.field]: width }));\n };\n const onUp = () => {\n window.removeEventListener('pointermove', onMove);\n window.removeEventListener('pointerup', onUp);\n const r = resizeRef.current;\n resizeRef.current = null;\n setResizingField(null);\n if (!r) return;\n const next = { ...(latest.current.columnWidths as Record<string, number>), [r.field]: r.lastWidth };\n setColumnWidths(next);\n persistWidths(next);\n const col = latest.current.getColumn(r.field);\n if (col && r.lastWidth !== r.startWidth)\n onColumnWidthChange?.({ colDef: col, width: r.lastWidth }, getDetails());\n };\n window.addEventListener('pointermove', onMove);\n window.addEventListener('pointerup', onUp);\n };\n\n /* ------------------------------------------------------------------ state snapshot & API */\n\n const filterCount = activeFilters.length;\n const rowCount = groupingActive ? totalDisplayRows : filteredEntries.length;\n\n const state = React.useMemo<MGHGridState>(\n () => ({\n sortModel,\n filterModel,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n pageCount,\n rowCount,\n totalRowCount: rowEntries.length,\n columnVisibilityModel,\n orderedFields: orderedUserColumns.map((c) => c.field),\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n rowSelectionModel: { type: 'include', ids: selectedIds },\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel: {\n open: preferencePanel.open,\n openedPanelValue: preferencePanel.openedPanelValue,\n targetField: preferencePanel.targetField,\n },\n filterCount,\n quickFilterValues,\n }),\n [\n sortModel,\n filterModel,\n page,\n paginationModel.pageSize,\n pageCount,\n rowCount,\n rowEntries.length,\n columnVisibilityModel,\n orderedUserColumns,\n columnWidths,\n pinnedColumns,\n density,\n densityFactor,\n selectedIds,\n rowGroupingModel,\n aggregationModel,\n expandedDetailPanels,\n preferencePanel.open,\n preferencePanel.openedPanelValue,\n preferencePanel.targetField,\n filterCount,\n quickFilterValues,\n ]\n );\n\n latest.current = {\n api: apiObject,\n state,\n rowsById,\n rowEntries,\n nodesById,\n groupsById,\n sortedLeaves,\n pagedRows,\n getRowId,\n setRowOverride,\n orderedUserColumns,\n visibleUserColumns,\n getColumn,\n columnVisibilityModel,\n setColumnVisibilityModel,\n setColumnWidth,\n setColumnIndex,\n columnWidths,\n autosizeColumns,\n pinColumn,\n unpinColumn,\n isColumnPinned,\n pinnedColumns,\n setPinnedColumns,\n sortModel,\n setSortModel,\n sortColumn,\n filterModel,\n setFilterModel,\n upsertFilterItems,\n deleteFilterItem,\n showPreferences,\n hidePreferences,\n selectedIds,\n setSelectedIds,\n selectRows,\n isRowSelectableFn,\n paginationModel: { page, pageSize: paginationModel.pageSize },\n setPaginationModel,\n setDensity,\n toggleDetailPanel,\n expandedDetailPanels,\n setExpandedDetailPanels,\n rowGroupingModel,\n setRowGroupingModel,\n setRowChildrenExpansion,\n aggregationModel,\n setAggregationModel,\n startCellEditMode,\n stopCellEditMode,\n editingCell,\n setEditValue,\n buildCellParams,\n setFocusedCell,\n scrollToIndexes,\n forceUpdate,\n virtual,\n startPrint,\n };\n\n if (apiRef) apiRef.current = apiObject;\n\n React.useEffect(() => {\n onStateChange?.(state, { api: apiObject });\n }, [state, onStateChange, apiObject]);\n\n /* ------------------------------------------------------------------ context */\n\n const rootProps = React.useMemo<MGHGridRootProps>(\n () => ({\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n }),\n [\n header,\n pagination,\n pageSizeOptions,\n hideFooterPagination,\n hideFooterRowCount,\n hideFooterSelectedRowCount,\n disableColumnFilter,\n disableColumnSelector,\n disableDensitySelector,\n disableColumnPinning,\n disableColumnSorting,\n disableMultipleColumnsSorting,\n disableMultipleColumnsFiltering,\n disableRowGrouping,\n disableAggregation,\n checkboxSelection,\n aggregationFunctions,\n quickFilterDebounceMs,\n ]\n );\n\n const contextValue = React.useMemo<MGHGridContextValue>(\n () => ({\n api: apiObject,\n state,\n localeText,\n themeMode,\n rootProps,\n columns: orderedUserColumns,\n visibleColumns: visibleUserColumns,\n }),\n [apiObject, state, localeText, themeMode, rootProps, orderedUserColumns, visibleUserColumns]\n );\n\n /* ------------------------------------------------------------------ rendering: cells */\n\n const renderEditor = (params: MGHGridCellParams<R>) => {\n const col = params.colDef;\n const commit = (reason: 'enterKeyDown' | 'cellFocusOut' | 'tabKeyDown') =>\n stopCellEditMode(params.id, params.field, false, reason);\n const cancel = () => stopCellEditMode(params.id, params.field, true, 'escapeKeyDown');\n const keyHandler = (event: React.KeyboardEvent) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n event.stopPropagation();\n commit('enterKeyDown');\n } else if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n cancel();\n } else if (event.key === 'Tab') {\n commit('tabKeyDown');\n } else {\n event.stopPropagation();\n }\n };\n if (col.renderEditCell) {\n return col.renderEditCell({\n ...params,\n editValue,\n onValueChange: setEditValue,\n commit: () => commit('enterKeyDown'),\n cancel,\n });\n }\n const common = {\n autoFocus: true,\n onKeyDown: keyHandler,\n onBlur: () => commit('cellFocusOut'),\n onClick: (event: React.MouseEvent) => event.stopPropagation(),\n };\n switch (col.type) {\n case 'boolean':\n return (\n <Checkbox\n {...common}\n checked={Boolean(editValue)}\n onChange={(event) => setEditValue(event.target.checked)}\n />\n );\n case 'singleSelect': {\n const options = resolveValueOptions(col, params.row, params.id);\n return (\n <Select\n {...common}\n size=\"small\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => {\n const match = options.find((o) => String(getOptionValue(col, o)) === event.target.value);\n setEditValue(match !== undefined ? getOptionValue(col, match) : event.target.value);\n }}\n >\n <option value=\"\" />\n {options.map((option) => {\n const value = getOptionValue(col, option);\n return (\n <option key={String(value)} value={String(value)}>\n {getOptionLabel(col, option)}\n </option>\n );\n })}\n </Select>\n );\n }\n case 'number':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"number\"\n value={editValue === undefined || editValue === null ? '' : editValue}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n case 'date':\n case 'dateTime':\n return (\n <TextInput\n {...common}\n size=\"small\"\n type={col.type === 'date' ? 'date' : 'datetime-local'}\n value={\n typeof editValue === 'string' && /^\\d{4}-\\d{2}-\\d{2}/.test(editValue)\n ? editValue\n : toDateInputValue(editValue, col.type === 'dateTime')\n }\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n default:\n return (\n <TextInput\n {...common}\n size=\"small\"\n type=\"text\"\n value={editValue === undefined || editValue === null ? '' : String(editValue)}\n onChange={(event) => setEditValue(event.target.value)}\n />\n );\n }\n };\n\n const renderCellContent = (lc: ColumnLayout, renderRow: RenderRow<R>): React.ReactNode => {\n const { col } = lc;\n const field = col.field;\n\n if (field === CHECKBOX_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const leafIds = renderRow.group.descendants.map((d) => d.id);\n const selectedCount = leafIds.reduce<number>((acc, id) => acc + (selectedIds.has(id) ? 1 : 0), 0);\n return (\n <Checkbox\n checked={leafIds.length > 0 && selectedCount === leafIds.length}\n indeterminate={selectedCount > 0 && selectedCount < leafIds.length}\n label={localeText.checkboxSelectionSelectRow}\n onClick={(event) => event.stopPropagation()}\n onChange={() => selectRows(leafIds, selectedCount !== leafIds.length, false)}\n />\n );\n }\n if (renderRow.kind !== 'leaf') return null;\n const selectable = isRowSelectableFn(renderRow.id, renderRow.row);\n const checked = selectedIds.has(renderRow.id);\n return (\n <Checkbox\n checked={checked}\n disabled={!selectable}\n label={checked ? localeText.checkboxSelectionUnselectRow : localeText.checkboxSelectionSelectRow}\n tabIndex={-1}\n onClick={(event) => event.stopPropagation()}\n onChange={() => {\n lastClickedIdRef.current = renderRow.id;\n selectRows([renderRow.id], !checked, disableMultipleRowSelection);\n }}\n />\n );\n }\n\n if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n if (renderRow.kind !== 'leaf' || !renderRow.row) return null;\n const expanded = expandedDetailPanels.has(renderRow.id);\n const content = getDetailPanelContent?.(buildRowParams(renderRow.id, renderRow.row));\n if (content === null || content === undefined || content === false) return null;\n return (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-detail-toggle', expanded && 'mgh-grid-detail-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n toggleDetailPanel(renderRow.id);\n }}\n >\n <ExpandMoreIcon />\n </IconButton>\n );\n }\n\n if (field === GROUPING_COLUMN_FIELD) {\n if (renderRow.kind === 'group' && renderRow.group) {\n const group = renderRow.group;\n const expanded = isGroupExpanded(group);\n const hideCount = (groupingColDef as any)?.hideDescendantCount;\n return (\n <div className=\"mgh-grid-group-cell\" style={{ paddingLeft: renderRow.depth * 20 }}>\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-group-toggle', expanded && 'mgh-grid-group-toggle--expanded')}\n label={expanded ? localeText.collapseDetailPanel : localeText.expandDetailPanel}\n aria-expanded={expanded}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setRowChildrenExpansion(group.id, !expanded);\n }}\n >\n <ChevronRightIcon />\n </IconButton>\n <span className=\"mgh-grid-group-label\" title={group.groupingLabel}>\n {group.groupingLabel}\n </span>\n {!hideCount && <span className=\"mgh-grid-group-count\">({group.descendants.length})</span>}\n </div>\n );\n }\n return null;\n }\n\n if (renderRow.kind === 'group' || renderRow.kind === 'footer') {\n const agg = renderRow.aggregates?.[field];\n if (!agg || isNil(agg.value)) return null;\n const fn = aggregationFunctions[agg.fn];\n const apiRefLocal = latest.current.api as MGHGridApi<R>;\n const sampleRow = (renderRow.group?.descendants[0]?.row ?? latest.current.sortedLeaves[0]?.row ?? {}) as R;\n const formatted = fn?.valueFormatter\n ? fn.valueFormatter(agg.value)\n : col.valueFormatter\n ? col.valueFormatter(agg.value, sampleRow, col as MGHGridColDef<R>, apiRefLocal)\n : defaultFormatValue(agg.value, col);\n return (\n <>\n <span className=\"mgh-grid-aggregation-label\">{fn?.label ?? agg.fn}</span>\n <span className=\"mgh-grid-cell-text\">{formattedValueToString(formatted)}</span>\n </>\n );\n }\n\n if (!renderRow.row) return null;\n const params = buildCellParams(renderRow.id, field, renderRow.row, renderRow.node);\n\n if (params.cellMode === 'edit') return renderEditor(params);\n\n if (col.renderCell) return col.renderCell(params);\n\n if (col.type === 'actions') {\n const actions = col.getActions ? col.getActions(buildRowParams(renderRow.id, renderRow.row)) : [];\n return <ActionsCell actions={actions} themeMode={themeMode} moreLabel={localeText.actionsCellMore} />;\n }\n\n if (col.type === 'boolean') {\n if (isNil(params.value)) return null;\n return params.value ? (\n <CheckIcon aria-label={localeText.booleanCellTrueLabel} />\n ) : (\n <CloseIcon aria-label={localeText.booleanCellFalseLabel} />\n );\n }\n\n const formatted = params.formattedValue;\n if (formatted === null || formatted === undefined) return null;\n if (React.isValidElement(formatted)) return formatted;\n const text = formattedValueToString(formatted);\n return (\n <span className=\"mgh-grid-cell-text\" title={text.length > 20 ? text : undefined}>\n {text}\n </span>\n );\n };\n\n const cellStyle = (lc: ColumnLayout): React.CSSProperties => ({\n width: lc.width,\n minWidth: lc.width,\n maxWidth: lc.width,\n left: lc.pinned === 'left' ? lc.offset : undefined,\n right: lc.pinned === 'right' ? lc.offset : undefined,\n });\n\n const pinnedClasses = (lc: ColumnLayout, prefix: string) =>\n cx(\n lc.pinned === 'left' && `${prefix}--pinned-left`,\n lc.pinned === 'right' && `${prefix}--pinned-right`,\n lc.isLastLeft && layout.hasPinning && `${prefix}--pinned-left-last`,\n lc.isFirstRight && `${prefix}--pinned-right-first`\n );\n\n const renderCell = (lc: ColumnLayout, renderRow: RenderRow<R>, isAutoRow: boolean) => {\n const { col } = lc;\n const field = col.field;\n const isFocused = Boolean(focusedCell && focusedCell.id === renderRow.id && focusedCell.field === field);\n const isEditing = Boolean(editingCell && editingCell.id === renderRow.id && editingCell.field === field);\n const isAggregation =\n (renderRow.kind === 'group' || renderRow.kind === 'footer') && Boolean(renderRow.aggregates?.[field]);\n const params =\n renderRow.kind === 'leaf' && renderRow.row\n ? buildCellParams(renderRow.id, field, renderRow.row, renderRow.node)\n : null;\n const editable = params ? isCellEditableFn(params) : false;\n const customClass =\n params && col.cellClassName\n ? typeof col.cellClassName === 'function'\n ? col.cellClassName(params)\n : col.cellClassName\n : undefined;\n const isCheckbox = field === CHECKBOX_FIELD;\n const isDetailToggle = field === DETAIL_PANEL_TOGGLE_FIELD;\n return (\n <div\n key={field}\n role=\"gridcell\"\n data-mgh-field={field}\n data-mgh-colindex={layout.columns.indexOf(lc)}\n tabIndex={isFocused ? 0 : -1}\n aria-selected={renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : undefined}\n className={cx(\n 'mgh-grid-cell',\n `mgh-grid-cell--align-${col.align ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-cell'),\n isFocused && !isEditing && 'mgh-grid-cell--focused',\n isEditing && 'mgh-grid-cell--editing',\n editable && !isEditing && 'mgh-grid-cell--editable',\n col.type === 'boolean' && 'mgh-grid-cell--boolean',\n col.type === 'actions' && 'mgh-grid-cell--actions',\n isCheckbox && 'mgh-grid-cell--checkbox',\n isDetailToggle && 'mgh-grid-cell--detail-toggle',\n isAggregation && 'mgh-grid-cell--aggregation',\n customClass\n )}\n style={cellStyle(lc)}\n onMouseDown={() => {\n if (renderRow.kind === 'leaf' || renderRow.kind === 'group') {\n if (!isFocused) setFocusedCell({ id: renderRow.id, field });\n }\n }}\n onClick={(event) => {\n if (params && onCellClick) onCellClick(params, event, getDetails());\n }}\n onDoubleClick={(event) => {\n if (params) {\n onCellDoubleClick?.(params, event, getDetails());\n if (editable && !isEditing) {\n event.stopPropagation();\n startCellEditMode(renderRow.id, field);\n }\n }\n }}\n >\n {renderCellContent(lc, renderRow)}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: rows */\n\n const rowIsClickable = Boolean(onRowClick || onRowDoubleClick || !disableRowSelectionOnClick);\n\n const renderRowElement = (\n renderRow: RenderRow<R>,\n options: { height?: number; index: number; isFirst: boolean; isLast: boolean; isAuto: boolean }\n ) => {\n const isSelected = renderRow.kind === 'leaf' ? selectedIds.has(renderRow.id) : false;\n const customClass =\n renderRow.kind === 'leaf' && renderRow.row && getRowClassName\n ? getRowClassName({\n ...buildRowParams(renderRow.id, renderRow.row),\n indexRelativeToCurrentPage: options.index,\n isFirstVisible: options.isFirst,\n isLastVisible: options.isLast,\n rowNode: renderRow.node,\n })\n : undefined;\n return (\n <div\n role=\"row\"\n aria-rowindex={options.index + 2}\n aria-selected={renderRow.kind === 'leaf' ? isSelected : undefined}\n data-mgh-row-id={String(renderRow.id)}\n data-mgh-row-index={options.index}\n className={cx(\n 'mgh-grid-row',\n isSelected && 'mgh-grid-row--selected',\n rowIsClickable && renderRow.kind === 'leaf' && 'mgh-grid-row--clickable',\n renderRow.kind === 'group' && 'mgh-grid-row--group',\n renderRow.kind === 'pinnedRow' && 'mgh-grid-row--pinned',\n renderRow.kind === 'footer' && 'mgh-grid-row--footer',\n options.isAuto && 'mgh-grid-row--auto-height',\n customClass\n )}\n style={{\n width: layout.totalWidth,\n height: options.isAuto ? undefined : options.height,\n minHeight: options.isAuto ? rowHeight : undefined,\n }}\n onClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n if (!disableRowSelectionOnClick) handleRowSelectionClick(renderRow, event);\n onRowClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n } else if (renderRow.kind === 'group' && renderRow.group) {\n setRowChildrenExpansion(renderRow.group.id, !isGroupExpanded(renderRow.group));\n }\n }}\n onDoubleClick={(event) => {\n if (renderRow.kind === 'leaf' && renderRow.row) {\n onRowDoubleClick?.(buildRowParams(renderRow.id, renderRow.row), event, getDetails());\n }\n }}\n >\n {layout.columns.map((lc) => renderCell(lc, renderRow, options.isAuto))}\n <div className=\"mgh-grid-row-filler\" />\n </div>\n );\n };\n\n const toRenderRow = (dr: DisplayRow<R>): RenderRow<R> => ({\n id: dr.id,\n kind: dr.type,\n row: dr.row,\n node: dr.node,\n depth: dr.depth,\n group: dr.group,\n aggregates: dr.type === 'group' && dr.group ? getGroupAggregates(dr.group) : undefined,\n });\n\n const renderBodyRows = () => {\n const { start, end } = virtualRange;\n const items: React.ReactNode[] = [];\n for (let i = start; i < end; i += 1) {\n const dr = pagedRows[i];\n const renderRow = toRenderRow(dr);\n const detailHeight = heights.detailHeights[i];\n const isExpanded =\n dr.type === 'leaf' && Boolean(dr.row) && Boolean(getDetailPanelContent) && expandedDetailPanels.has(dr.id);\n const detailContent = isExpanded && dr.row ? getDetailPanelContent?.(buildRowParams(dr.id, dr.row)) : null;\n const detailAuto =\n isExpanded && dr.row && getDetailPanelHeight\n ? getDetailPanelHeight({ id: dr.id, row: dr.row }) === 'auto'\n : false;\n const rowAuto =\n !virtual &&\n (getRowHeight && dr.type === 'leaf' && dr.row\n ? getRowHeight({ id: dr.id, model: dr.row, densityFactor }) === 'auto'\n : false);\n items.push(\n <div\n key={String(dr.id)}\n className=\"mgh-grid-row-block\"\n style={virtual ? { top: heights.offsets[i], width: layout.totalWidth } : { width: layout.totalWidth }}\n >\n {renderRowElement(renderRow, {\n height: heights.rowHeights[i],\n index: i,\n isFirst: i === 0,\n isLast: i === pagedRows.length - 1,\n isAuto: rowAuto,\n })}\n {isExpanded && detailContent !== null && detailContent !== undefined && detailContent !== false && (\n <div\n className=\"mgh-grid-detail-panel\"\n style={{\n height: detailAuto ? undefined : detailHeight || undefined,\n width: viewportWidth || undefined,\n }}\n onClick={(event) => event.stopPropagation()}\n >\n {detailContent}\n </div>\n )}\n </div>\n );\n }\n return items;\n };\n\n const renderPinnedRows = (list: R[] | undefined, position: 'top' | 'bottom') => {\n const items: React.ReactNode[] = [];\n (list ?? []).forEach((row, index) => {\n const id = getRowIdFromRow(row, getRowId);\n const renderRow: RenderRow<R> = {\n id,\n kind: 'pinnedRow',\n row,\n node: { type: 'pinnedRow', id, depth: 0, parent: null, position },\n depth: 0,\n };\n items.push(\n <React.Fragment key={String(id)}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: index,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n });\n if (position === 'bottom' && footerAggregates) {\n const renderRow: RenderRow<R> = {\n id: AGGREGATION_FOOTER_ID,\n kind: 'footer',\n row: null,\n node: { type: 'footer', id: AGGREGATION_FOOTER_ID, depth: 0, parent: null },\n depth: 0,\n aggregates: footerAggregates,\n };\n items.push(\n <React.Fragment key={AGGREGATION_FOOTER_ID}>\n {renderRowElement(renderRow, {\n height: rowHeight,\n index: 0,\n isFirst: false,\n isLast: false,\n isAuto: false,\n })}\n </React.Fragment>\n );\n }\n return items;\n };\n\n /* ------------------------------------------------------------------ rendering: header */\n\n const renderHeaderCell = (lc: ColumnLayout, index: number) => {\n const { col } = lc;\n const field = col.field;\n const sortIndex = sortModel.findIndex((item) => item.field === field && item.sort);\n const sortItem = sortIndex !== -1 ? sortModel[sortIndex] : undefined;\n const sortable =\n (col.sortable !== false && !disableColumnSorting && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && col.sortable !== false);\n const showMenu =\n (!disableColumnMenu && !col.disableColumnMenu && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnMenu);\n const resizable =\n (!disableColumnResize && col.resizable !== false && !isInternalField(field)) ||\n (field === GROUPING_COLUMN_FIELD && !disableColumnResize);\n const draggable = canReorder(col);\n const isDragging = drag?.field === field;\n const isDropTarget = drag && drag.overField === field && drag.field !== field;\n const menuOpen = columnMenu?.field === field;\n const headerParams = { field, colDef: col as MGHGridColDef<R>, api: apiObject };\n const customClass = col.headerClassName\n ? typeof col.headerClassName === 'function'\n ? col.headerClassName(headerParams)\n : col.headerClassName\n : undefined;\n\n let content: React.ReactNode;\n if (field === CHECKBOX_FIELD) {\n content = disableMultipleRowSelection ? null : (\n <Checkbox\n checked={allCandidatesSelected}\n indeterminate={someCandidatesSelected}\n disabled={selectionCandidates.length === 0}\n label={\n allCandidatesSelected\n ? localeText.checkboxSelectionUnselectAllRows\n : localeText.checkboxSelectionSelectAllRows\n }\n onChange={toggleAllCandidates}\n onClick={(event) => event.stopPropagation()}\n />\n );\n } else if (field === DETAIL_PANEL_TOGGLE_FIELD) {\n content = null;\n } else {\n content = col.renderHeader ? (\n col.renderHeader(headerParams)\n ) : (\n <span className=\"mgh-grid-header-title\">{col.headerName ?? field}</span>\n );\n }\n\n return (\n <div\n key={field}\n role=\"columnheader\"\n aria-colindex={index + 1}\n aria-sort={sortItem ? (sortItem.sort === 'asc' ? 'ascending' : 'descending') : sortable ? 'none' : undefined}\n data-mgh-field={field}\n title={col.description}\n tabIndex={-1}\n draggable={draggable}\n className={cx(\n 'mgh-grid-header-cell',\n `mgh-grid-header-cell--align-${col.headerAlign ?? 'left'}`,\n pinnedClasses(lc, 'mgh-grid-header-cell'),\n sortable && 'mgh-grid-header-cell--sortable',\n field === CHECKBOX_FIELD && 'mgh-grid-header-cell--checkbox',\n field === DETAIL_PANEL_TOGGLE_FIELD && 'mgh-grid-header-cell--detail-toggle',\n index === layout.columns.length - 1 && 'mgh-grid-header-cell--last',\n isDragging && 'mgh-grid-header-cell--dragging',\n isDropTarget && drag?.side === 'left' && 'mgh-grid-header-cell--drop-left',\n isDropTarget && drag?.side === 'right' && 'mgh-grid-header-cell--drop-right',\n menuOpen && 'mgh-grid-header-cell--menu-open',\n customClass\n )}\n style={cellStyle(lc)}\n onClick={(event) => {\n if (!sortable || resizingField) return;\n sortColumn(field, undefined, event.shiftKey);\n }}\n onDragStart={(event) => {\n if (!draggable) return;\n event.dataTransfer.effectAllowed = 'move';\n try {\n event.dataTransfer.setData('text/plain', field);\n } catch {\n /* ignore */\n }\n setDrag({ field, overField: null, side: 'left' });\n }}\n onDragOver={(event) => {\n if (!drag || drag.field === field) return;\n const sourceLc = layout.columns.find((c) => c.col.field === drag.field);\n if (!sourceLc || sourceLc.pinned !== lc.pinned || !canReorder(col)) return;\n event.preventDefault();\n event.dataTransfer.dropEffect = 'move';\n const rect = event.currentTarget.getBoundingClientRect();\n const side = event.clientX < rect.left + rect.width / 2 ? 'left' : 'right';\n if (drag.overField !== field || drag.side !== side) setDrag({ ...drag, overField: field, side });\n }}\n onDragLeave={() => {\n if (drag && drag.overField === field) setDrag({ ...drag, overField: null });\n }}\n onDrop={(event) => handleDrop(lc, event)}\n onDragEnd={() => setDrag(null)}\n >\n <div className=\"mgh-grid-header-title-container\">\n {content}\n {sortable && (\n <span\n className={cx('mgh-grid-sort-icon', sortItem && 'mgh-grid-sort-icon--active')}\n aria-hidden=\"true\"\n >\n {sortItem?.sort === 'desc' ? <ArrowDownwardIcon size={18} /> : <ArrowUpwardIcon size={18} />}\n {sortItem && sortModel.filter((s) => s.sort).length > 1 && (\n <span className=\"mgh-grid-sort-index\">{sortIndex + 1}</span>\n )}\n </span>\n )}\n </div>\n {showMenu && (\n <IconButton\n size=\"small\"\n className={cx('mgh-grid-header-menu-btn', menuOpen && 'mgh-grid-header-menu-btn--open')}\n label={localeText.columnMenuLabel}\n aria-haspopup=\"menu\"\n aria-expanded={menuOpen}\n tabIndex={-1}\n onClick={(event) => {\n event.stopPropagation();\n setColumnMenu((prev) =>\n prev?.field === field ? null : { field, anchorEl: event.currentTarget }\n );\n }}\n onMouseDown={(event) => event.stopPropagation()}\n >\n <MoreVertIcon />\n </IconButton>\n )}\n {resizable && (\n <div\n className={cx('mgh-grid-resize-handle', resizingField === field && 'mgh-grid-resize-handle--active')}\n role=\"separator\"\n aria-orientation=\"vertical\"\n onPointerDown={(event) => handleResizeStart(lc, event)}\n onClick={(event) => event.stopPropagation()}\n onDoubleClick={(event) => {\n event.stopPropagation();\n autosizeColumns({ columns: [field] });\n }}\n draggable={false}\n onDragStart={(event) => {\n event.preventDefault();\n event.stopPropagation();\n }}\n />\n )}\n </div>\n );\n };\n\n /* ------------------------------------------------------------------ rendering: slots */\n\n const ToolbarSlot = slots.toolbar === null ? null : (slots.toolbar ?? MGHGridToolbar);\n const FooterSlot = slots.footer === null ? null : (slots.footer ?? MGHGridFooter);\n const NoRowsOverlaySlot = slots.noRowsOverlay ?? MGHGridNoRowsOverlay;\n const LoadingOverlaySlot = slots.loadingOverlay ?? MGHGridLoadingOverlay;\n const mergedToolbarProps = { ...toolbarProps, ...slotProps.toolbar };\n const noRowsProps = { text: noRowsText, ...slotProps.noRowsOverlay };\n const loadingProps = { ...slotProps.loadingOverlay };\n\n const showNoRows = !loading && pagedRows.length === 0;\n const menuColumn = columnMenu ? getColumn(columnMenu.field) : undefined;\n\n const cardStyles: React.CSSProperties = {\n height: 'auto',\n flexGrow: 1,\n ...sanitizeStyle(cardSx),\n ...sanitizeStyle(cardStyle),\n ...(themeVars as any),\n };\n const boxStyles: React.CSSProperties = { flexGrow: 1, ...sanitizeStyle(boxSx), ...sanitizeStyle(boxStyle) };\n const rootStyles: React.CSSProperties = {\n ...sanitizeStyle(sx),\n ...sanitizeStyle(style),\n ['--mgh-grid-header-height' as any]: `${headerHeight}px`,\n ['--mgh-grid-row-height' as any]: `${rowHeight}px`,\n };\n\n // Nested selectors from sx/style props become a <style> block scoped to this grid instance.\n const scopedCss = React.useMemo(() => {\n const css: string[] = [];\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, sx, css);\n buildScopedCss(`[data-mgh-grid-id=\"${gridId}\"]`, style, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardSx, css);\n buildScopedCss(`[data-mgh-grid-card=\"${gridId}\"]`, cardStyle, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxSx, css);\n buildScopedCss(`[data-mgh-grid-box=\"${gridId}\"]`, boxStyle, css);\n return css.join('\\n');\n }, [gridId, sx, style, cardSx, cardStyle, boxSx, boxStyle]);\n\n const smDown = viewportWidth > 0 && viewportWidth < 600;\n\n const grid = (\n <div\n ref={rootRef}\n id={gridId}\n data-mgh-grid-id={gridId}\n role=\"grid\"\n aria-rowcount={rowCount + 1}\n aria-colcount={layout.columns.length}\n aria-multiselectable={checkboxSelection && !disableMultipleRowSelection ? true : undefined}\n aria-busy={loading || undefined}\n className={cx(\n 'mgh-grid',\n (autoHeight || printing) && 'mgh-grid--auto-height',\n printing && 'mgh-grid--printing',\n !layout.hasPinning && 'mgh-grid--no-pinned-shadow',\n className\n )}\n style={rootStyles}\n onKeyDown={handleKeyDown}\n >\n {showToolbar && ToolbarSlot && (\n <div ref={toolbarRef}>\n <ToolbarSlot {...mergedToolbarProps} />\n </div>\n )}\n <div className=\"mgh-grid-main\">\n <div ref={scrollerRef} className=\"mgh-grid-scroller\" onScroll={handleScroll} tabIndex={-1}>\n <div className=\"mgh-grid-columns\" role=\"rowgroup\" style={{ width: layout.totalWidth }}>\n <div className=\"mgh-grid-header-row\" role=\"row\" aria-rowindex={1} style={{ height: headerHeight }}>\n {layout.columns.map((lc, index) => renderHeaderCell(lc, index))}\n <div className=\"mgh-grid-header-filler\" />\n </div>\n </div>\n {pinnedRows?.top && pinnedRows.top.length > 0 && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--top\"\n role=\"rowgroup\"\n style={{ top: headerHeight, width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows.top, 'top')}\n </div>\n )}\n <div\n className={cx('mgh-grid-body', virtual ? 'mgh-grid-body--virtual' : 'mgh-grid-body--flow')}\n role=\"rowgroup\"\n style={\n virtual\n ? { height: heights.total, width: layout.totalWidth }\n : { width: layout.totalWidth, minHeight: showNoRows || loading ? 120 : undefined }\n }\n >\n {renderBodyRows()}\n </div>\n {((pinnedRows?.bottom && pinnedRows.bottom.length > 0) || footerAggregates) && (\n <div\n className=\"mgh-grid-pinned-rows mgh-grid-pinned-rows--bottom\"\n role=\"rowgroup\"\n style={{ width: layout.totalWidth }}\n >\n {renderPinnedRows(pinnedRows?.bottom, 'bottom')}\n </div>\n )}\n </div>\n {loading && (\n <div className=\"mgh-grid-overlay mgh-grid-overlay--loading\" style={{ top: headerHeight }}>\n <LoadingOverlaySlot {...loadingProps} />\n </div>\n )}\n {showNoRows && (\n <div className=\"mgh-grid-overlay\" style={{ top: headerHeight }}>\n <NoRowsOverlaySlot {...noRowsProps} />\n </div>\n )}\n </div>\n {!hideFooter && FooterSlot && <FooterSlot {...slotProps.footer} />}\n\n <Popover\n open={preferencePanel.open}\n anchorEl={preferencePanel.anchorEl}\n onClose={hidePreferences}\n themeMode={themeMode}\n placement=\"bottom-start\"\n autoFocus\n >\n {preferencePanel.openedPanelValue === 'columns' ? <MGHGridColumnsPanel /> : <MGHGridFilterPanel />}\n </Popover>\n\n {menuColumn && columnMenu && (\n <MGHGridColumnMenu\n column={menuColumn}\n anchorEl={columnMenu.anchorEl}\n open\n onClose={() => setColumnMenu(null)}\n themeMode={themeMode}\n panelAnchorEl={toolbarRef.current}\n />\n )}\n </div>\n );\n\n return (\n <MGHGridContext.Provider value={contextValue}>\n <div\n ref={cardRef}\n className={cx('mgh-grid-card', disableCard && 'mgh-grid-card--plain', cardClassName)}\n data-mgh-theme={themeMode}\n data-mgh-grid-card={gridId}\n style={cardStyles}\n >\n {scopedCss && <style data-mgh-grid-sx={gridId}>{scopedCss}</style>}\n {!disableCard && (header !== undefined || renderHeaderCenterContent || renderHeaderEndContent) && (\n <div className=\"mgh-grid-card-header\">\n {header !== undefined && <h3 className=\"mgh-grid-card-title\">{header}</h3>}\n {renderHeaderCenterContent && (\n <div className=\"mgh-grid-card-header-center\">{renderHeaderCenterContent}</div>\n )}\n <div className=\"mgh-grid-card-header-end\" style={{ gap: smDown ? 8 : 16 }}>\n {renderHeaderEndContent}\n </div>\n </div>\n )}\n <div className={cx('mgh-grid-box', boxClassName)} data-mgh-grid-box={gridId} style={boxStyles}>\n {grid}\n </div>\n </div>\n </MGHGridContext.Provider>\n );\n}\n\nMGHGrid.displayName = 'MGHGrid';\n","import React from 'react';\n\nexport const MGH_DATE_RANGE_PICKER_STYLE_ID = 'mgh-drp-styles';\n\n/**\n * Stylesheet for MGHDateRangePicker. Injected once into <head> the first time a picker mounts.\n * Colours are CSS variables (`--mgh-drp-*`). When the picker is rendered inside an MGHGrid card\n * it inherits the grid palette (`--mgh-grid-*`) automatically.\n */\nexport const MGH_DATE_RANGE_PICKER_CSS = `\n.mgh-drp, .mgh-drp-popover, .mgh-drp-calendars {\n --mgh-drp-font-family: var(--mgh-grid-font-family, inherit);\n --mgh-drp-font-size: var(--mgh-grid-font-size, 14px);\n --mgh-drp-paper: var(--mgh-grid-paper, #ffffff);\n --mgh-drp-fg: var(--mgh-grid-fg, rgba(0, 0, 0, 0.87));\n --mgh-drp-fg-secondary: var(--mgh-grid-fg-secondary, rgba(0, 0, 0, 0.6));\n --mgh-drp-fg-disabled: var(--mgh-grid-fg-disabled, rgba(0, 0, 0, 0.38));\n --mgh-drp-border: var(--mgh-grid-border, rgba(224, 224, 224, 1));\n --mgh-drp-input-border: var(--mgh-grid-input-border, rgba(0, 0, 0, 0.23));\n --mgh-drp-hover: var(--mgh-grid-hover, rgba(0, 0, 0, 0.04));\n --mgh-drp-primary: var(--mgh-grid-primary, #1976d2);\n --mgh-drp-primary-contrast: var(--mgh-grid-primary-contrast, #ffffff);\n --mgh-drp-focus: var(--mgh-grid-focus, #1976d2);\n --mgh-drp-selected: var(--mgh-grid-selected, rgba(25, 118, 210, 0.12));\n --mgh-drp-preview: rgba(0, 0, 0, 0.06);\n --mgh-drp-error: #d32f2f;\n --mgh-drp-radius: 4px;\n --mgh-drp-popover-radius: 8px;\n --mgh-drp-popover-shadow: var(--mgh-grid-popover-shadow, 0 5px 5px -3px rgba(0,0,0,.2), 0 8px 10px 1px rgba(0,0,0,.14), 0 3px 14px 2px rgba(0,0,0,.12));\n --mgh-drp-day-size: 36px;\n --mgh-drp-day-margin: 2px;\n font-family: var(--mgh-drp-font-family);\n font-size: var(--mgh-drp-font-size);\n color: var(--mgh-drp-fg);\n line-height: 1.5;\n}\n/* Dark values also apply to a calendar nested inside a dark picker / popover, so the calendar's own\n defaults (declared above for standalone use) never reset the colours back to light. */\n.mgh-drp[data-mgh-theme=\"dark\"], .mgh-drp-popover[data-mgh-theme=\"dark\"], .mgh-drp-calendars[data-mgh-theme=\"dark\"],\n.mgh-drp[data-mgh-theme=\"dark\"] .mgh-drp-calendars, .mgh-drp-popover[data-mgh-theme=\"dark\"] .mgh-drp-calendars {\n --mgh-drp-paper: #212b36;\n --mgh-drp-fg: #ffffff;\n --mgh-drp-fg-secondary: rgba(255, 255, 255, 0.7);\n --mgh-drp-fg-disabled: rgba(255, 255, 255, 0.5);\n --mgh-drp-border: rgba(81, 81, 81, 1);\n --mgh-drp-input-border: rgba(255, 255, 255, 0.23);\n --mgh-drp-hover: rgba(255, 255, 255, 0.08);\n --mgh-drp-primary: #90caf9;\n --mgh-drp-primary-contrast: rgba(0, 0, 0, 0.87);\n --mgh-drp-focus: #90caf9;\n --mgh-drp-selected: rgba(144, 202, 249, 0.16);\n --mgh-drp-preview: rgba(255, 255, 255, 0.08);\n --mgh-drp-error: #f44336;\n}\n[class*=\"mgh-drp\"], [class*=\"mgh-drp\"]::before, [class*=\"mgh-drp\"]::after { box-sizing: border-box; }\n\n/* ---- root / multi-input layout ---- */\n.mgh-drp { display: inline-flex; flex-direction: column; vertical-align: top; min-width: 0; }\n.mgh-drp--full-width { display: flex; width: 100%; }\n.mgh-drp-fields { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }\n.mgh-drp-fields .mgh-drp-field { flex: 1 1 0; min-width: 0; }\n.mgh-drp-fields-separator { align-self: center; color: var(--mgh-drp-fg-secondary); padding: 0 2px; }\n\n/* ---- outlined text field (MUI TextField look-alike) ---- */\n.mgh-drp-field { position: relative; display: inline-flex; align-items: center; min-width: 0; width: 100%; border-radius: var(--mgh-drp-radius); color: var(--mgh-drp-fg); }\n.mgh-drp-field--medium { height: 56px; }\n.mgh-drp-field--small { height: 40px; }\n.mgh-drp-field:not(.mgh-drp-field--full-width) { width: 260px; }\n.mgh-drp-field--multi:not(.mgh-drp-field--full-width) { width: 170px; }\n.mgh-drp-field--full-width { width: 100%; }\n.mgh-drp-input { flex: 1 1 auto; min-width: 0; width: 100%; height: 100%; margin: 0; border: 0; outline: none; background: transparent; color: inherit; font: inherit; font-size: 1rem; letter-spacing: inherit; padding: 16.5px 14px; }\n.mgh-drp-field--small .mgh-drp-input { padding: 8.5px 14px; }\n.mgh-drp-field--adorned .mgh-drp-input { padding-right: 0; }\n.mgh-drp-input::placeholder { color: var(--mgh-drp-fg-disabled); opacity: 1; }\n.mgh-drp-input::-webkit-calendar-picker-indicator { display: none; }\n.mgh-drp-field--disabled .mgh-drp-input { color: var(--mgh-drp-fg-disabled); -webkit-text-fill-color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-field--disabled { cursor: default; }\n.mgh-drp-field--clickable .mgh-drp-input { cursor: pointer; }\n.mgh-drp-adornment { display: flex; align-items: center; gap: 0; margin-right: 6px; flex: 0 0 auto; color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-field--small .mgh-drp-adornment { margin-right: 4px; }\n\n/* notched outline */\n.mgh-drp-outline { position: absolute; inset: -5px 0 0 0; margin: 0; padding: 0 8px; pointer-events: none; border: 1px solid var(--mgh-drp-input-border); border-radius: inherit; min-width: 0; overflow: hidden; text-align: left; transition: border-color .15s; }\n.mgh-drp-outline legend { float: unset; width: auto; padding: 0; height: 11px; font-size: 0.75em; visibility: hidden; max-width: 0.01px; white-space: nowrap; transition: max-width 50ms cubic-bezier(0.0, 0, 0.2, 1) 0ms; overflow: hidden; display: block; line-height: 11px; }\n.mgh-drp-outline legend > span { padding-left: 5px; padding-right: 5px; display: inline-block; opacity: 0; visibility: visible; }\n.mgh-drp-field--shrink .mgh-drp-outline legend { max-width: 100%; transition: max-width 100ms cubic-bezier(0.0, 0, 0.2, 1) 50ms; }\n.mgh-drp-field--no-label .mgh-drp-outline legend { display: none; }\n.mgh-drp-field:hover:not(.mgh-drp-field--disabled) .mgh-drp-outline { border-color: var(--mgh-drp-fg); }\n.mgh-drp-field--focused .mgh-drp-outline, .mgh-drp-field--focused:hover .mgh-drp-outline { border-color: var(--mgh-drp-focus); border-width: 2px; }\n.mgh-drp-field--error .mgh-drp-outline, .mgh-drp-field--error:hover .mgh-drp-outline { border-color: var(--mgh-drp-error); }\n.mgh-drp-field--disabled .mgh-drp-outline { border-color: var(--mgh-drp-fg-disabled); }\n\n/* floating label */\n.mgh-drp-label { position: absolute; left: 0; top: 0; transform-origin: top left; transform: translate(14px, 16px) scale(1); color: var(--mgh-drp-fg-secondary); font-size: 1rem; line-height: 1.4375em; pointer-events: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: calc(100% - 24px); transition: color .15s, transform .15s cubic-bezier(0.0, 0, 0.2, 1), max-width .15s; z-index: 1; }\n.mgh-drp-field--small .mgh-drp-label { transform: translate(14px, 9px) scale(1); }\n.mgh-drp-field--shrink .mgh-drp-label, .mgh-drp-field--small.mgh-drp-field--shrink .mgh-drp-label { transform: translate(14px, -9px) scale(0.75); max-width: calc(133% - 32px); }\n.mgh-drp-field--focused .mgh-drp-label { color: var(--mgh-drp-focus); }\n.mgh-drp-field--error .mgh-drp-label { color: var(--mgh-drp-error); }\n.mgh-drp-field--disabled .mgh-drp-label { color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-label-asterisk { margin-left: 2px; }\n\n.mgh-drp-helper { margin: 3px 14px 0; font-size: 0.75rem; line-height: 1.66; color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-helper--error { color: var(--mgh-drp-error); }\n\n/* ---- buttons ---- */\n.mgh-drp-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; border: 0; margin: 0; background: transparent; color: var(--mgh-drp-fg-secondary); font: inherit; font-size: 0.8125rem; font-weight: 500; line-height: 1.75; letter-spacing: .02em; padding: 4px 8px; border-radius: 4px; cursor: pointer; user-select: none; transition: background-color .15s, color .15s; white-space: nowrap; text-transform: uppercase; }\n.mgh-drp-btn:hover { background: var(--mgh-drp-hover); color: var(--mgh-drp-fg); }\n.mgh-drp-btn:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: 1px; }\n.mgh-drp-btn:disabled { color: var(--mgh-drp-fg-disabled); cursor: default; background: transparent; }\n.mgh-drp-btn--primary { color: var(--mgh-drp-primary); }\n.mgh-drp-btn--primary:hover { background: var(--mgh-drp-selected); color: var(--mgh-drp-primary); }\n.mgh-drp-btn--icon { padding: 8px; border-radius: 50%; width: 40px; height: 40px; text-transform: none; }\n.mgh-drp-btn--icon.mgh-drp-btn--small { width: 32px; height: 32px; padding: 4px; }\n.mgh-drp-icon { flex: 0 0 auto; }\n\n/* ---- popover ---- */\n.mgh-drp-popover { position: fixed; z-index: 1300; display: flex; flex-direction: column; background: var(--mgh-drp-paper); color: var(--mgh-drp-fg); border-radius: var(--mgh-drp-popover-radius); box-shadow: var(--mgh-drp-popover-shadow); outline: none; max-height: calc(100vh - 16px); max-width: calc(100vw - 16px); overflow: auto; animation: mgh-drp-pop .12s ease-out; }\n@keyframes mgh-drp-pop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }\n.mgh-drp-layout { display: flex; flex-direction: row; align-items: stretch; }\n.mgh-drp-layout--with-toolbar { flex-direction: column; }\n.mgh-drp-layout-main { display: flex; flex-direction: row; align-items: stretch; }\n.mgh-drp-toolbar { padding: 16px 24px 0; }\n.mgh-drp-toolbar-title { font-size: 0.75rem; text-transform: uppercase; letter-spacing: .08em; color: var(--mgh-drp-fg-secondary); margin: 0 0 8px; }\n.mgh-drp-toolbar-range { display: flex; align-items: center; gap: 8px; font-size: 1.5rem; font-weight: 400; line-height: 1.334; }\n.mgh-drp-toolbar-range button { border: 0; background: transparent; padding: 0 2px; font: inherit; color: var(--mgh-drp-fg-secondary); cursor: pointer; border-radius: 4px; }\n.mgh-drp-toolbar-range button.mgh-drp-toolbar-range--active { color: var(--mgh-drp-fg); }\n.mgh-drp-toolbar-range button:hover { background: var(--mgh-drp-hover); }\n\n/* shortcuts (left column) */\n.mgh-drp-shortcuts { list-style: none; margin: 0; padding: 8px 0; min-width: 140px; max-height: 340px; overflow: auto; border-right: 1px solid var(--mgh-drp-border); display: flex; flex-direction: column; gap: 4px; padding-left: 8px; padding-right: 8px; }\n.mgh-drp-shortcut { display: inline-flex; align-items: center; height: 32px; padding: 0 12px; border-radius: 16px; border: 1px solid var(--mgh-drp-input-border); background: transparent; color: var(--mgh-drp-fg); font: inherit; font-size: 0.8125rem; cursor: pointer; white-space: nowrap; justify-content: flex-start; transition: background-color .15s; }\n.mgh-drp-shortcut:hover { background: var(--mgh-drp-hover); }\n.mgh-drp-shortcut:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: 1px; }\n.mgh-drp-shortcut:disabled { color: var(--mgh-drp-fg-disabled); cursor: default; }\n.mgh-drp-shortcut--selected { background: var(--mgh-drp-selected); border-color: var(--mgh-drp-primary); color: var(--mgh-drp-primary); }\n\n/* ---- calendars ---- */\n.mgh-drp-calendars { display: flex; flex-direction: row; align-items: flex-start; }\n.mgh-drp-calendar { display: flex; flex-direction: column; width: calc(7 * (var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin)) + 24px); padding: 0 12px 8px; }\n.mgh-drp-calendar + .mgh-drp-calendar { border-left: 1px solid var(--mgh-drp-border); }\n.mgh-drp-calendar-header { display: flex; align-items: center; justify-content: space-between; min-height: 40px; margin: 12px 0 8px; padding: 0 4px; }\n.mgh-drp-calendar-label { flex: 1 1 auto; text-align: center; font-size: 1rem; font-weight: 500; }\n.mgh-drp-calendar-header .mgh-drp-btn--icon { color: var(--mgh-drp-fg-secondary); }\n.mgh-drp-calendar-nav-spacer { width: 40px; height: 40px; flex: 0 0 auto; }\n.mgh-drp-weekdays, .mgh-drp-week { display: flex; justify-content: center; }\n.mgh-drp-weekday { width: var(--mgh-drp-day-size); height: 40px; margin: 0 var(--mgh-drp-day-margin); display: flex; align-items: center; justify-content: center; font-size: 0.75rem; color: var(--mgh-drp-fg-secondary); font-weight: 400; }\n.mgh-drp-weeks { display: flex; flex-direction: column; min-height: calc(6 * (var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin))); }\n.mgh-drp-week { margin: var(--mgh-drp-day-margin) 0; }\n\n/* day cell: the outer wrapper carries the range highlight, the inner button the day itself */\n.mgh-drp-day-wrap { position: relative; width: calc(var(--mgh-drp-day-size) + 2 * var(--mgh-drp-day-margin)); height: var(--mgh-drp-day-size); display: flex; align-items: center; justify-content: center; }\n.mgh-drp-day-wrap--in-range { background: var(--mgh-drp-selected); }\n.mgh-drp-day-wrap--range-start { border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--range-end { border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--preview { border-top: 1px dashed var(--mgh-drp-fg-secondary); border-bottom: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day-wrap--preview-start { border-left: 1px dashed var(--mgh-drp-fg-secondary); border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--preview-end { border-right: 1px dashed var(--mgh-drp-fg-secondary); border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--first-visible.mgh-drp-day-wrap--in-range:not(.mgh-drp-day-wrap--range-start) { border-top-left-radius: 50%; border-bottom-left-radius: 50%; }\n.mgh-drp-day-wrap--last-visible.mgh-drp-day-wrap--in-range:not(.mgh-drp-day-wrap--range-end) { border-top-right-radius: 50%; border-bottom-right-radius: 50%; }\n.mgh-drp-day-wrap--first-visible.mgh-drp-day-wrap--preview:not(.mgh-drp-day-wrap--preview-start) { border-top-left-radius: 50%; border-bottom-left-radius: 50%; border-left: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day-wrap--last-visible.mgh-drp-day-wrap--preview:not(.mgh-drp-day-wrap--preview-end) { border-top-right-radius: 50%; border-bottom-right-radius: 50%; border-right: 1px dashed var(--mgh-drp-fg-secondary); }\n.mgh-drp-day { width: var(--mgh-drp-day-size); height: var(--mgh-drp-day-size); border-radius: 50%; border: 0; margin: 0; padding: 0; background: transparent; color: var(--mgh-drp-fg); font: inherit; font-size: 0.75rem; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: background-color .15s, color .15s; position: relative; }\n.mgh-drp-day:hover { background: var(--mgh-drp-hover); }\n.mgh-drp-day:focus-visible { outline: 2px solid var(--mgh-drp-focus); outline-offset: -1px; }\n.mgh-drp-day--today:not(.mgh-drp-day--selected) { border: 1px solid var(--mgh-drp-fg-secondary); }\n.mgh-drp-day--outside { color: var(--mgh-drp-fg-secondary); opacity: .6; }\n.mgh-drp-day--hidden { visibility: hidden; pointer-events: none; }\n.mgh-drp-day--disabled, .mgh-drp-day--disabled:hover { color: var(--mgh-drp-fg-disabled); cursor: default; background: transparent; }\n.mgh-drp-day--selected, .mgh-drp-day--selected:hover { background: var(--mgh-drp-primary); color: var(--mgh-drp-primary-contrast); font-weight: 500; }\n.mgh-drp-day--selected:focus-visible { outline-offset: 2px; }\n.mgh-drp-calendar--read-only .mgh-drp-day, .mgh-drp-calendar--disabled .mgh-drp-day { cursor: default; }\n.mgh-drp-calendar--disabled .mgh-drp-day { color: var(--mgh-drp-fg-disabled); }\n.mgh-drp-calendar--disabled .mgh-drp-day--selected { opacity: .6; }\n\n/* ---- action bar ---- */\n.mgh-drp-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; padding: 8px; border-top: 1px solid var(--mgh-drp-border); }\n.mgh-drp-actions--spread { justify-content: space-between; }\n.mgh-drp-actions-group { display: flex; gap: 8px; }\n\n@media (max-width: 599.95px) {\n .mgh-drp-layout-main { flex-direction: column; }\n .mgh-drp-shortcuts { flex-direction: row; flex-wrap: wrap; border-right: 0; border-bottom: 1px solid var(--mgh-drp-border); max-height: none; }\n .mgh-drp-calendars { flex-direction: column; align-items: center; }\n .mgh-drp-calendar + .mgh-drp-calendar { border-left: 0; border-top: 1px solid var(--mgh-drp-border); }\n}\n`;\n\nlet injected = false;\n\nconst injectStyles = () => {\n if (injected || typeof document === 'undefined') return;\n if (document.getElementById(MGH_DATE_RANGE_PICKER_STYLE_ID)) {\n injected = true;\n return;\n }\n const style = document.createElement('style');\n style.id = MGH_DATE_RANGE_PICKER_STYLE_ID;\n style.setAttribute('data-mgh-drp', 'true');\n style.textContent = MGH_DATE_RANGE_PICKER_CSS;\n document.head.appendChild(style);\n injected = true;\n};\n\nconst useInsertion: typeof React.useLayoutEffect =\n (React as any).useInsertionEffect ?? (typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect);\n\n/** Injects the MGHDateRangePicker stylesheet once per document. Safe on the server (no-op). */\nexport const useMGHDateRangePickerStyles = () => {\n useInsertion(() => {\n injectStyles();\n }, []);\n};\n","import React from 'react';\n\n/* Inline SVG icons (Material Design icon paths, Apache-2.0). No external dependencies. */\n\nexport interface MGHDateRangeIconProps extends React.SVGProps<SVGSVGElement> {\n size?: number;\n}\n\nconst createIcon = (path: React.ReactNode, displayName: string) => {\n const Icon = React.forwardRef<SVGSVGElement, MGHDateRangeIconProps>(({ size = 24, className, style, ...rest }, ref) => (\n <svg\n ref={ref}\n viewBox=\"0 0 24 24\"\n width={size}\n height={size}\n fill=\"currentColor\"\n focusable=\"false\"\n aria-hidden=\"true\"\n className={['mgh-drp-icon', className].filter(Boolean).join(' ')}\n style={style}\n {...rest}\n >\n {path}\n </svg>\n ));\n Icon.displayName = displayName;\n return Icon;\n};\n\nexport const DateRangeIcon = createIcon(\n <path d=\"M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z\" />,\n 'DateRangeIcon'\n);\nexport const ChevronLeftIcon = createIcon(\n <path d=\"M15.41 16.59 10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z\" />,\n 'ChevronLeftIcon'\n);\nexport const ChevronRightIcon = createIcon(\n <path d=\"M8.59 16.59 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z\" />,\n 'ChevronRightIcon'\n);\nexport const CloseIcon = createIcon(\n <path d=\"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />,\n 'CloseIcon'\n);\n","import dayjs, { Dayjs } from 'dayjs';\nimport customParseFormat from 'dayjs/plugin/customParseFormat';\nimport type {\n MGHDateRange,\n MGHDateRangePosition,\n MGHDateRangeShortcut,\n MGHDateRangeValidationError,\n} from './MGHDateRangePicker.types';\n\ndayjs.extend(customParseFormat);\n\nexport const cx = (...classNames: Array<string | false | null | undefined>) => classNames.filter(Boolean).join(' ');\n\nexport const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\nexport const EMPTY_RANGE: MGHDateRange = [null, null];\n\n/** Coerces Dayjs / Date / ISO string / timestamp into a valid Dayjs (or null). */\nexport const toDayjs = (value: unknown): Dayjs | null => {\n if (value == null || value === '') return null;\n if (dayjs.isDayjs(value)) return value.isValid() ? value : null;\n if (value instanceof Date || typeof value === 'number' || typeof value === 'string') {\n const parsed = dayjs(value as Date | number | string);\n return parsed.isValid() ? parsed : null;\n }\n return null;\n};\n\nexport const isSameDay = (a: Dayjs | null | undefined, b: Dayjs | null | undefined) => !!a && !!b && a.isSame(b, 'day');\nexport const isBeforeDay = (a: Dayjs, b: Dayjs) => a.isBefore(b, 'day');\nexport const isAfterDay = (a: Dayjs, b: Dayjs) => a.isAfter(b, 'day');\nexport const isWithinRange = (day: Dayjs, start: Dayjs | null, end: Dayjs | null) =>\n !!start && !!end && !isBeforeDay(day, start) && !isAfterDay(day, end);\n\nexport const isRangeEqual = (a: MGHDateRange | undefined, b: MGHDateRange | undefined) => {\n if (a === b) return true;\n if (!a || !b) return false;\n const same = (x: Dayjs | null, y: Dayjs | null) => (x == null && y == null) || (!!x && !!y && x.isSame(y, 'day'));\n return same(a[0], b[0]) && same(a[1], b[1]);\n};\n\nexport const normalizeRange = (value: unknown): MGHDateRange => {\n if (!Array.isArray(value)) return EMPTY_RANGE;\n return [toDayjs(value[0]), toDayjs(value[1])];\n};\n\n/** Strict parse with the display format first, then a handful of forgiving fallbacks. */\nexport const parseDateText = (text: string, format: string): Dayjs | null => {\n const trimmed = text.trim();\n if (!trimmed) return null;\n const strict = dayjs(trimmed, format, true);\n if (strict.isValid()) return strict;\n const fallbacks = [\n format.replace(/MM/g, 'M').replace(/DD/g, 'D'),\n 'M/D/YYYY',\n 'M/D/YY',\n 'YYYY-MM-DD',\n 'MM-DD-YYYY',\n 'M-D-YYYY',\n ];\n for (const f of fallbacks) {\n const parsed = dayjs(trimmed, f, true);\n if (parsed.isValid()) return parsed;\n }\n return null;\n};\n\nexport const formatDate = (value: Dayjs | null, format: string) => (value && value.isValid() ? value.format(format) : '');\n\n/** Splits \"start – end\" text typed into the single-input field. */\nexport const splitRangeText = (text: string): [string, string] => {\n const parts = text.split(/\\s+[–—-]\\s+|\\s*–\\s*|\\s*—\\s*|\\s+to\\s+/i);\n if (parts.length >= 2) return [parts[0], parts.slice(1).join(' ')];\n return [text, ''];\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Validation (mirrors MUI's DateRangeValidationError semantics)\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface DateValidationOptions {\n minDate?: Dayjs | null;\n maxDate?: Dayjs | null;\n disablePast?: boolean;\n disableFuture?: boolean;\n shouldDisableDate?: (day: Dayjs, position: MGHDateRangePosition) => boolean;\n}\n\nexport const validateDay = (\n day: Dayjs | null,\n position: MGHDateRangePosition,\n options: DateValidationOptions,\n now: Dayjs = dayjs()\n): MGHDateRangeValidationError => {\n if (day == null) return null;\n if (!day.isValid()) return 'invalidDate';\n if (options.disablePast && isBeforeDay(day, now)) return 'disablePast';\n if (options.disableFuture && isAfterDay(day, now)) return 'disableFuture';\n if (options.minDate && isBeforeDay(day, options.minDate)) return 'minDate';\n if (options.maxDate && isAfterDay(day, options.maxDate)) return 'maxDate';\n if (options.shouldDisableDate?.(day, position)) return 'shouldDisableDate';\n return null;\n};\n\nexport const validateRange = (\n value: MGHDateRange,\n options: DateValidationOptions\n): [MGHDateRangeValidationError, MGHDateRangeValidationError] => {\n const now = dayjs();\n const startError = validateDay(value[0], 'start', options, now);\n const endError = validateDay(value[1], 'end', options, now);\n if (!startError && !endError && value[0] && value[1] && isAfterDay(value[0], value[1])) {\n return ['invalidRange', 'invalidRange'];\n }\n return [startError, endError];\n};\n\nexport const isDayDisabled = (day: Dayjs, position: MGHDateRangePosition, options: DateValidationOptions) =>\n validateDay(day, position, options) != null;\n\n/* -------------------------------------------------------------------------------------------------\n * Calendar grid\n * ----------------------------------------------------------------------------------------------- */\n\nexport interface CalendarWeek {\n key: string;\n days: Array<{ day: Dayjs; outsideMonth: boolean }>;\n}\n\n/**\n * Builds the weeks of `month`. Weeks start on the locale's first day of the week (Sunday for `en`).\n * Pass `fixedWeekNumber` (usually 6) to always render the same number of rows.\n */\nexport const getMonthWeeks = (month: Dayjs, fixedWeekNumber?: number): CalendarWeek[] => {\n const firstOfMonth = month.startOf('month');\n const start = firstOfMonth.startOf('week');\n const weeksInMonth = Math.ceil(firstOfMonth.endOf('month').diff(start, 'day') / 7 + 1 / 7);\n const weekCount = fixedWeekNumber && fixedWeekNumber > 0 ? fixedWeekNumber : Math.max(weeksInMonth, 1);\n const weeks: CalendarWeek[] = [];\n for (let w = 0; w < weekCount; w += 1) {\n const weekStart = start.add(w * 7, 'day');\n weeks.push({\n key: weekStart.format('YYYY-MM-DD'),\n days: Array.from({ length: 7 }, (_, d) => {\n const day = weekStart.add(d, 'day');\n return { day, outsideMonth: !day.isSame(firstOfMonth, 'month') };\n }),\n });\n }\n return weeks;\n};\n\nexport const getWeekDayLabels = (formatter: (day: Dayjs) => string) => {\n const start = dayjs().startOf('week');\n return Array.from({ length: 7 }, (_, i) => {\n const day = start.add(i, 'day');\n return { key: day.format('dd'), label: formatter(day), full: day.format('dddd') };\n });\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Shortcuts (same shape as MUI's PickersShortcuts items)\n * ----------------------------------------------------------------------------------------------- */\n\nexport const MGH_DATE_RANGE_DEFAULT_SHORTCUTS: MGHDateRangeShortcut[] = [\n {\n label: 'This Week',\n getValue: () => {\n const today = dayjs();\n return [today.startOf('week'), today.endOf('week')];\n },\n },\n {\n label: 'Last Week',\n getValue: () => {\n const prev = dayjs().subtract(7, 'day');\n return [prev.startOf('week'), prev.endOf('week')];\n },\n },\n {\n label: 'Last 7 Days',\n getValue: () => {\n const today = dayjs();\n return [today.subtract(7, 'day'), today];\n },\n },\n {\n label: 'Current Month',\n getValue: () => {\n const today = dayjs();\n return [today.startOf('month'), today.endOf('month')];\n },\n },\n {\n label: 'Next Month',\n getValue: () => {\n const next = dayjs().add(1, 'month');\n return [next.startOf('month'), next.endOf('month')];\n },\n },\n { label: 'Reset', getValue: () => [null, null] },\n];\n","import React from 'react';\nimport dayjs, { Dayjs } from 'dayjs';\nimport type { MGHDateRange, MGHDateRangeCalendarProps, MGHDateRangePosition } from './MGHDateRangePicker.types';\nimport { useMGHDateRangePickerStyles } from './MGHDateRangePicker.styles';\nimport { ChevronLeftIcon, ChevronRightIcon } from './icons';\nimport {\n EMPTY_RANGE,\n cx,\n getMonthWeeks,\n getWeekDayLabels,\n isAfterDay,\n isBeforeDay,\n isDayDisabled,\n isSameDay,\n isWithinRange,\n normalizeRange,\n} from './utils';\n\nconst defaultDayOfWeekFormatter = (day: Dayjs) => day.format('dd').charAt(0).toUpperCase();\n\n/**\n * Pure-React port of MUI X's `DateRangeCalendar`: one to three months side by side with range\n * highlighting, hover preview, keyboard navigation and min/max/disabled-day validation.\n */\nexport function MGHDateRangeCalendar({\n value: valueProp,\n defaultValue,\n onChange,\n rangePosition: rangePositionProp,\n onRangePositionChange,\n calendars = 2,\n referenceDate,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth = false,\n fixedWeekNumber,\n dayOfWeekFormatter = defaultDayOfWeekFormatter,\n disableHighlightToday = false,\n showRangePreview = true,\n autoFocus = false,\n onMonthChange,\n localeText,\n themeMode,\n className,\n style,\n}: MGHDateRangeCalendarProps) {\n useMGHDateRangePickerStyles();\n\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateRange>(() =>\n normalizeRange(defaultValue ?? EMPTY_RANGE)\n );\n const value = React.useMemo(\n () => (isControlled ? normalizeRange(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n const [start, end] = value;\n\n const [internalPosition, setInternalPosition] = React.useState<MGHDateRangePosition>('start');\n const rangePosition = rangePositionProp ?? internalPosition;\n const setRangePosition = React.useCallback(\n (position: MGHDateRangePosition) => {\n if (rangePositionProp === undefined) setInternalPosition(position);\n onRangePositionChange?.(position);\n },\n [rangePositionProp, onRangePositionChange]\n );\n\n const validation = React.useMemo(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate]\n );\n\n // Month displayed by the first calendar.\n const [currentMonth, setCurrentMonth] = React.useState<Dayjs>(() =>\n (start ?? end ?? referenceDate ?? dayjs()).startOf('month')\n );\n const visibleMonths = React.useMemo(\n () => Array.from({ length: calendars }, (_, i) => currentMonth.add(i, 'month')),\n [currentMonth, calendars]\n );\n const lastVisibleMonth = visibleMonths[visibleMonths.length - 1];\n\n const changeMonth = React.useCallback(\n (month: Dayjs) => {\n const next = month.startOf('month');\n setCurrentMonth((prev) => {\n if (prev.isSame(next, 'month')) return prev;\n onMonthChange?.(next);\n return next;\n });\n },\n [onMonthChange]\n );\n\n const ensureVisible = React.useCallback(\n (day: Dayjs) => {\n if (isBeforeDay(day, currentMonth.startOf('month'))) changeMonth(day);\n else if (isAfterDay(day, lastVisibleMonth.endOf('month'))) changeMonth(day.subtract(calendars - 1, 'month'));\n },\n [currentMonth, lastVisibleMonth, calendars, changeMonth]\n );\n\n // When a value arrives from outside (typed in the field / shortcut) scroll to it.\n const lastSeenRef = React.useRef<MGHDateRange>(value);\n React.useEffect(() => {\n const prev = lastSeenRef.current;\n lastSeenRef.current = value;\n const target = rangePosition === 'end' ? (end ?? start) : (start ?? end);\n if (!target) return;\n const changed = !isSameDay(prev[0], start) || !isSameDay(prev[1], end);\n if (changed) ensureVisible(target);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [start, end]);\n\n const canGoPrev = !minDate || currentMonth.isAfter(minDate, 'month');\n const canGoNext = !maxDate || lastVisibleMonth.isBefore(maxDate, 'month');\n\n /* ---- hover preview ---- */\n const [hoveredDay, setHoveredDay] = React.useState<Dayjs | null>(null);\n const preview = React.useMemo<MGHDateRange>(() => {\n if (!showRangePreview || !hoveredDay || disabled || readOnly) return EMPTY_RANGE;\n if (rangePosition === 'end' && start && !end) {\n return isBeforeDay(hoveredDay, start) ? EMPTY_RANGE : [start, hoveredDay];\n }\n if (rangePosition === 'start' && end && !start) {\n return isAfterDay(hoveredDay, end) ? EMPTY_RANGE : [hoveredDay, end];\n }\n return EMPTY_RANGE;\n }, [showRangePreview, hoveredDay, rangePosition, start, end, disabled, readOnly]);\n\n /* ---- selection (MUI semantics) ---- */\n const selectDay = React.useCallback(\n (day: Dayjs) => {\n if (disabled || readOnly) return;\n if (isDayDisabled(day, rangePosition, validation)) return;\n let next: MGHDateRange;\n let nextPosition: MGHDateRangePosition;\n if (rangePosition === 'start') {\n // Picking a start after the current end resets the end (MUI behaviour).\n next = [day, end && isAfterDay(day, end) ? null : end];\n nextPosition = 'end';\n } else if (start && isBeforeDay(day, start)) {\n // An \"end\" before the start becomes the new start; keep asking for the end.\n next = [day, null];\n nextPosition = 'end';\n } else {\n next = [start, day];\n nextPosition = 'start';\n }\n if (!isControlled) setInternalValue(next);\n onChange?.(next, day, rangePosition);\n setRangePosition(nextPosition);\n },\n [disabled, readOnly, rangePosition, validation, end, start, isControlled, onChange, setRangePosition]\n );\n\n /* ---- keyboard navigation (roving tabindex) ---- */\n const [focusedDay, setFocusedDay] = React.useState<Dayjs>(() => start ?? end ?? referenceDate ?? dayjs());\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const pendingFocusRef = React.useRef(autoFocus);\n\n const focusDay = React.useCallback((day: Dayjs) => {\n const key = day.format('YYYY-MM-DD');\n const el = rootRef.current?.querySelector<HTMLButtonElement>(`[data-day=\"${key}\"]`);\n el?.focus();\n }, []);\n\n React.useEffect(() => {\n if (!pendingFocusRef.current) return;\n pendingFocusRef.current = false;\n const target = focusedDay;\n ensureVisible(target);\n // Wait for a potential month change to render.\n const id = window.setTimeout(() => focusDay(target), 0);\n return () => window.clearTimeout(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const moveFocus = (day: Dayjs) => {\n setFocusedDay(day);\n ensureVisible(day);\n window.setTimeout(() => focusDay(day), 0);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLElement>, day: Dayjs) => {\n let next: Dayjs | null = null;\n switch (event.key) {\n case 'ArrowLeft':\n next = day.subtract(1, 'day');\n break;\n case 'ArrowRight':\n next = day.add(1, 'day');\n break;\n case 'ArrowUp':\n next = day.subtract(7, 'day');\n break;\n case 'ArrowDown':\n next = day.add(7, 'day');\n break;\n case 'Home':\n next = day.startOf('week');\n break;\n case 'End':\n next = day.endOf('week');\n break;\n case 'PageUp':\n next = event.shiftKey ? day.subtract(1, 'year') : day.subtract(1, 'month');\n break;\n case 'PageDown':\n next = event.shiftKey ? day.add(1, 'year') : day.add(1, 'month');\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n selectDay(day);\n return;\n default:\n return;\n }\n event.preventDefault();\n if (next) moveFocus(next);\n };\n\n const weekDays = React.useMemo(() => getWeekDayLabels(dayOfWeekFormatter), [dayOfWeekFormatter]);\n const today = dayjs();\n const previewStart = preview[0];\n const previewEnd = preview[1];\n const isRangeComplete = !!start && !!end;\n\n const renderMonth = (month: Dayjs, index: number) => {\n const weeks = getMonthWeeks(month, fixedWeekNumber);\n const isFirst = index === 0;\n const isLast = index === visibleMonths.length - 1;\n const focusedInMonth = focusedDay.isSame(month, 'month') ? focusedDay : null;\n const tabbableDay =\n focusedInMonth ??\n (start && start.isSame(month, 'month') ? start : null) ??\n (end && end.isSame(month, 'month') ? end : null) ??\n (isFirst && !visibleMonths.some((m) => focusedDay.isSame(m, 'month')) ? month.startOf('month') : null);\n\n return (\n <div\n key={month.format('YYYY-MM')}\n className=\"mgh-drp-calendar\"\n role=\"group\"\n aria-label={month.format('MMMM YYYY')}\n >\n <div className=\"mgh-drp-calendar-header\">\n {isFirst ? (\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.previousMonth ?? 'Previous month'}\n title={localeText?.previousMonth ?? 'Previous month'}\n disabled={disabled || !canGoPrev}\n onClick={() => changeMonth(currentMonth.subtract(1, 'month'))}\n >\n <ChevronLeftIcon />\n </button>\n ) : (\n <span className=\"mgh-drp-calendar-nav-spacer\" />\n )}\n <div className=\"mgh-drp-calendar-label\" aria-live=\"polite\">\n {month.format('MMMM YYYY')}\n </div>\n {isLast ? (\n <button\n type=\"button\"\n className=\"mgh-drp-btn mgh-drp-btn--icon\"\n aria-label={localeText?.nextMonth ?? 'Next month'}\n title={localeText?.nextMonth ?? 'Next month'}\n disabled={disabled || !canGoNext}\n onClick={() => changeMonth(currentMonth.add(1, 'month'))}\n >\n <ChevronRightIcon />\n </button>\n ) : (\n <span className=\"mgh-drp-calendar-nav-spacer\" />\n )}\n </div>\n <div className=\"mgh-drp-weekdays\" role=\"row\">\n {weekDays.map((wd) => (\n <span key={wd.key} className=\"mgh-drp-weekday\" role=\"columnheader\" aria-label={wd.full}>\n {wd.label}\n </span>\n ))}\n </div>\n <div className=\"mgh-drp-weeks\" role=\"grid\" aria-label={month.format('MMMM YYYY')}>\n {weeks.map((week) => (\n <div key={week.key} className=\"mgh-drp-week\" role=\"row\">\n {week.days.map(({ day, outsideMonth }, dayIndex) => {\n const hidden = outsideMonth && !showDaysOutsideCurrentMonth;\n const isStart = isSameDay(day, start);\n const isEnd = isSameDay(day, end);\n const selected = isStart || isEnd;\n const inRange = !hidden && isRangeComplete && isWithinRange(day, start, end);\n const inPreview =\n !hidden &&\n !!previewStart &&\n !!previewEnd &&\n isWithinRange(day, previewStart, previewEnd);\n const dayDisabled = disabled || isDayDisabled(day, rangePosition, validation);\n const isTabbable = !!tabbableDay && isSameDay(day, tabbableDay) && !hidden;\n const firstVisible = dayIndex === 0 || (!showDaysOutsideCurrentMonth && day.date() === 1);\n const lastVisible =\n dayIndex === 6 || (!showDaysOutsideCurrentMonth && day.date() === day.daysInMonth());\n return (\n <div\n key={day.format('YYYY-MM-DD')}\n role=\"gridcell\"\n aria-selected={selected || undefined}\n className={cx(\n 'mgh-drp-day-wrap',\n inRange && 'mgh-drp-day-wrap--in-range',\n inRange && isStart && 'mgh-drp-day-wrap--range-start',\n inRange && isEnd && 'mgh-drp-day-wrap--range-end',\n inPreview && 'mgh-drp-day-wrap--preview',\n inPreview && isSameDay(day, previewStart) && 'mgh-drp-day-wrap--preview-start',\n inPreview && isSameDay(day, previewEnd) && 'mgh-drp-day-wrap--preview-end',\n firstVisible && 'mgh-drp-day-wrap--first-visible',\n lastVisible && 'mgh-drp-day-wrap--last-visible'\n )}\n >\n <button\n type=\"button\"\n data-day={day.format('YYYY-MM-DD')}\n tabIndex={isTabbable ? 0 : -1}\n aria-label={day.format('dddd, MMMM D, YYYY')}\n aria-current={\n !disableHighlightToday && isSameDay(day, today) ? 'date' : undefined\n }\n aria-disabled={dayDisabled || undefined}\n disabled={hidden}\n className={cx(\n 'mgh-drp-day',\n hidden && 'mgh-drp-day--hidden',\n outsideMonth && !hidden && 'mgh-drp-day--outside',\n selected && 'mgh-drp-day--selected',\n !disableHighlightToday && isSameDay(day, today) && 'mgh-drp-day--today',\n dayDisabled && 'mgh-drp-day--disabled'\n )}\n onClick={() => selectDay(day)}\n onMouseEnter={() => setHoveredDay(day)}\n onMouseLeave={() =>\n setHoveredDay((prev) => (prev && isSameDay(prev, day) ? null : prev))\n }\n onFocus={() => setFocusedDay(day)}\n onKeyDown={(event) => handleKeyDown(event, day)}\n >\n {day.date()}\n </button>\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n };\n\n return (\n <div\n ref={rootRef}\n className={cx(\n 'mgh-drp-calendars',\n disabled && 'mgh-drp-calendar--disabled',\n readOnly && 'mgh-drp-calendar--read-only',\n className\n )}\n data-mgh-theme={themeMode}\n data-range-position={rangePosition}\n style={style}\n onMouseLeave={() => setHoveredDay(null)}\n >\n {visibleMonths.map(renderMonth)}\n </div>\n );\n}\n\nexport default MGHDateRangeCalendar;\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport dayjs from 'dayjs';\nimport type {\n MGHDateRange,\n MGHDateRangeChangeContext,\n MGHDateRangePickerLocaleText,\n MGHDateRangePickerProps,\n MGHDateRangePosition,\n MGHDateRangeShortcut,\n MGHDateRangeValidationError,\n} from './MGHDateRangePicker.types';\nimport { useMGHDateRangePickerStyles } from './MGHDateRangePicker.styles';\nimport { MGHDateRangeCalendar } from './MGHDateRangeCalendar';\nimport { CloseIcon, DateRangeIcon } from './icons';\nimport {\n EMPTY_RANGE,\n clamp,\n cx,\n formatDate,\n isRangeEqual,\n normalizeRange,\n parseDateText,\n splitRangeText,\n validateRange,\n} from './utils';\n\nexport const MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT: MGHDateRangePickerLocaleText = {\n start: 'Start',\n end: 'End',\n fieldSeparator: '–',\n openPicker: 'Choose date range',\n clear: 'Clear',\n today: 'Today',\n cancel: 'Cancel',\n accept: 'OK',\n previousMonth: 'Previous month',\n nextMonth: 'Next month',\n toolbarTitle: 'Select date range',\n};\n\nconst DEFAULT_FORMAT = 'MM/DD/YYYY';\n\n/* -------------------------------------------------------------------------------------------------\n * Anchored popover (portal)\n * ----------------------------------------------------------------------------------------------- */\n\ninterface PopoverProps {\n open: boolean;\n anchorEl: HTMLElement | null;\n placement: 'bottom-start' | 'bottom-end' | 'bottom';\n onDismiss: (reason: 'backdrop' | 'escape') => void;\n themeMode?: 'light' | 'dark';\n className?: string;\n style?: React.CSSProperties;\n labelledBy?: string;\n children: React.ReactNode;\n}\n\nfunction Popover({ open, anchorEl, placement, onDismiss, themeMode, className, style, labelledBy, children }: PopoverProps) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const [position, setPosition] = React.useState({ top: 0, left: 0, ready: false });\n\n const update = React.useCallback(() => {\n const el = ref.current;\n if (!el) return;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n let top: number;\n let left: number;\n if (anchorEl && anchorEl.isConnected) {\n const a = anchorEl.getBoundingClientRect();\n top = a.bottom + 4;\n if (top + h > vh - 8 && a.top - 4 - h >= 8) top = a.top - 4 - h;\n left = placement === 'bottom-end' ? a.right - w : placement === 'bottom' ? a.left + a.width / 2 - w / 2 : a.left;\n } else {\n top = vh / 2 - h / 2;\n left = vw / 2 - w / 2;\n }\n top = clamp(top, 8, Math.max(8, vh - h - 8));\n left = clamp(left, 8, Math.max(8, vw - w - 8));\n setPosition((prev) => (prev.ready && prev.top === top && prev.left === left ? prev : { top, left, ready: true }));\n }, [anchorEl, placement]);\n\n React.useLayoutEffect(() => {\n if (!open) {\n setPosition((prev) => (prev.ready ? { ...prev, ready: false } : prev));\n return undefined;\n }\n update();\n window.addEventListener('resize', update);\n window.addEventListener('scroll', update, true);\n let observer: ResizeObserver | null = null;\n if (typeof ResizeObserver !== 'undefined' && ref.current) {\n observer = new ResizeObserver(() => update());\n observer.observe(ref.current);\n }\n return () => {\n window.removeEventListener('resize', update);\n window.removeEventListener('scroll', update, true);\n observer?.disconnect();\n };\n }, [open, update]);\n\n React.useEffect(() => {\n if (!open) return undefined;\n const handlePointerDown = (event: MouseEvent | TouchEvent) => {\n const target = event.target as Node | null;\n if (!target) return;\n if (ref.current?.contains(target)) return;\n if (anchorEl?.contains(target)) return;\n onDismiss('backdrop');\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onDismiss('escape');\n };\n document.addEventListener('mousedown', handlePointerDown, true);\n document.addEventListener('touchstart', handlePointerDown, true);\n document.addEventListener('keydown', handleKeyDown);\n return () => {\n document.removeEventListener('mousedown', handlePointerDown, true);\n document.removeEventListener('touchstart', handlePointerDown, true);\n document.removeEventListener('keydown', handleKeyDown);\n };\n }, [open, onDismiss, anchorEl]);\n\n if (!open || typeof document === 'undefined') return null;\n\n return createPortal(\n <div\n ref={ref}\n role=\"dialog\"\n aria-modal=\"false\"\n aria-labelledby={labelledBy}\n tabIndex={-1}\n className={cx('mgh-drp-popover', className)}\n data-mgh-theme={themeMode}\n style={{ top: position.top, left: position.left, visibility: position.ready ? 'visible' : 'hidden', ...style }}\n onMouseDown={(event) => event.stopPropagation()}\n >\n {children}\n </div>,\n document.body\n );\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Outlined text field (MUI TextField look-alike, no dependency)\n * ----------------------------------------------------------------------------------------------- */\n\ninterface TextFieldProps {\n id: string;\n label?: React.ReactNode;\n value: string;\n placeholder?: string;\n size: 'small' | 'medium';\n fullWidth?: boolean;\n multi?: boolean;\n disabled?: boolean;\n readOnly?: boolean;\n required?: boolean;\n error?: boolean;\n focused?: boolean;\n clickable?: boolean;\n name?: string;\n autoFocus?: boolean;\n inputRef?: React.Ref<HTMLInputElement>;\n adornment?: React.ReactNode;\n ariaLabel?: string;\n onChange: (text: string) => void;\n onFocus: () => void;\n onBlur: () => void;\n onClick?: () => void;\n onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\nconst TextField = React.forwardRef<HTMLDivElement, TextFieldProps>(function TextField(\n {\n id,\n label,\n value,\n placeholder,\n size,\n fullWidth,\n multi,\n disabled,\n readOnly,\n required,\n error,\n focused,\n clickable,\n name,\n autoFocus,\n inputRef,\n adornment,\n ariaLabel,\n onChange,\n onFocus,\n onBlur,\n onClick,\n onKeyDown,\n },\n ref\n) {\n const hasLabel = label != null && label !== '';\n const shrink = focused || value !== '' || !hasLabel;\n return (\n <div\n ref={ref}\n className={cx(\n 'mgh-drp-field',\n `mgh-drp-field--${size}`,\n fullWidth && 'mgh-drp-field--full-width',\n multi && 'mgh-drp-field--multi',\n shrink && 'mgh-drp-field--shrink',\n focused && 'mgh-drp-field--focused',\n disabled && 'mgh-drp-field--disabled',\n error && 'mgh-drp-field--error',\n clickable && 'mgh-drp-field--clickable',\n !hasLabel && 'mgh-drp-field--no-label',\n !!adornment && 'mgh-drp-field--adorned'\n )}\n onClick={onClick}\n >\n {hasLabel && (\n <label className=\"mgh-drp-label\" htmlFor={id}>\n {label}\n {required && (\n <span className=\"mgh-drp-label-asterisk\" aria-hidden=\"true\">\n *\n </span>\n )}\n </label>\n )}\n <input\n id={id}\n ref={inputRef}\n name={name}\n className=\"mgh-drp-input\"\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"off\"\n spellCheck={false}\n value={value}\n placeholder={shrink ? placeholder : undefined}\n disabled={disabled}\n readOnly={readOnly}\n required={required}\n autoFocus={autoFocus}\n aria-label={ariaLabel}\n aria-invalid={error || undefined}\n onChange={(event) => onChange(event.target.value)}\n onFocus={onFocus}\n onBlur={onBlur}\n onKeyDown={onKeyDown}\n />\n {adornment && <div className=\"mgh-drp-adornment\">{adornment}</div>}\n <fieldset aria-hidden=\"true\" className=\"mgh-drp-outline\">\n <legend>\n <span>\n {hasLabel ? label : ''}\n {hasLabel && required ? ' *' : ''}\n </span>\n </legend>\n </fieldset>\n </div>\n );\n});\n\n/* -------------------------------------------------------------------------------------------------\n * MGHDateRangePicker\n * ----------------------------------------------------------------------------------------------- */\n\ntype FocusedInput = 'single' | 'start' | 'end' | null;\n\n/**\n * MUI-free port of MUI X Pro's `DateRangePicker` (desktop variant): an outlined text field with a\n * calendar button that opens a two-month range calendar, optional shortcuts and an action bar.\n * Values are dayjs `[start, end]` tuples so existing `DateRange<Dayjs>` state works unchanged.\n */\nexport const MGHDateRangePicker = React.forwardRef<HTMLDivElement, MGHDateRangePickerProps>(function MGHDateRangePicker(\n {\n value: valueProp,\n defaultValue,\n onChange,\n onAccept,\n onError,\n open: openProp,\n onOpen,\n onClose,\n rangePosition: rangePositionProp,\n onRangePositionChange,\n label,\n format = DEFAULT_FORMAT,\n fieldVariant = 'single',\n size = 'small',\n fullWidth = false,\n clearable = false,\n openOnClick,\n disableOpenPicker = false,\n closeOnSelect,\n shortcuts,\n actions = [],\n showToolbar = false,\n localeText: localeTextProp,\n calendars = 2,\n referenceDate,\n minDate,\n maxDate,\n disablePast,\n disableFuture,\n shouldDisableDate,\n disabled = false,\n readOnly = false,\n showDaysOutsideCurrentMonth,\n fixedWeekNumber,\n dayOfWeekFormatter,\n disableHighlightToday,\n showRangePreview,\n onMonthChange,\n name,\n id: idProp,\n placeholder: placeholderProp,\n required,\n error: errorProp,\n helperText,\n autoFocus,\n inputRef,\n themeMode,\n themeVars,\n className,\n style,\n popoverClassName,\n popoverStyle,\n placement = 'bottom-start',\n },\n ref\n) {\n useMGHDateRangePickerStyles();\n\n const localeText = React.useMemo(\n () => ({ ...MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT, ...localeTextProp }),\n [localeTextProp]\n );\n const datePlaceholder = localeText.datePlaceholder ?? format;\n const isMulti = fieldVariant === 'multi';\n const resolvedOpenOnClick = openOnClick ?? isMulti;\n const resolvedCloseOnSelect = closeOnSelect ?? !actions.includes('accept');\n\n const reactId = React.useId();\n const baseId = idProp ?? `mgh-drp-${reactId.replace(/:/g, '')}`;\n const startId = isMulti ? `${baseId}-start` : baseId;\n const endId = `${baseId}-end`;\n const dialogTitleId = `${baseId}-title`;\n\n /* ---- value ---- */\n const isControlled = valueProp !== undefined;\n const [internalValue, setInternalValue] = React.useState<MGHDateRange>(() =>\n normalizeRange(defaultValue ?? EMPTY_RANGE)\n );\n const value = React.useMemo(\n () => (isControlled ? normalizeRange(valueProp) : internalValue),\n [isControlled, valueProp, internalValue]\n );\n const [start, end] = value;\n\n const validation = React.useMemo(\n () => ({ minDate, maxDate, disablePast, disableFuture, shouldDisableDate }),\n [minDate, maxDate, disablePast, disableFuture, shouldDisableDate]\n );\n const validationError = React.useMemo(() => validateRange(value, validation), [value, validation]);\n const isValid = React.useCallback(\n (range: MGHDateRange) => validateRange(range, validation).every((e) => e == null),\n [validation]\n );\n\n const lastErrorRef = React.useRef<[MGHDateRangeValidationError, MGHDateRangeValidationError] | null>(null);\n React.useEffect(() => {\n const prev = lastErrorRef.current;\n if (prev && prev[0] === validationError[0] && prev[1] === validationError[1]) return;\n if (prev !== null || validationError[0] || validationError[1]) onError?.(validationError, value);\n lastErrorRef.current = validationError;\n }, [validationError, value, onError]);\n\n const setValue = React.useCallback(\n (next: MGHDateRange, shortcut?: MGHDateRangeShortcut) => {\n if (!isControlled) setInternalValue(next);\n const context: MGHDateRangeChangeContext = { validationError: validateRange(next, validation) };\n if (shortcut) context.shortcut = shortcut;\n onChange?.(next, context);\n },\n [isControlled, onChange, validation]\n );\n\n /* ---- range position ---- */\n const [internalPosition, setInternalPosition] = React.useState<MGHDateRangePosition>('start');\n const rangePosition = rangePositionProp ?? internalPosition;\n const setRangePosition = React.useCallback(\n (position: MGHDateRangePosition) => {\n if (rangePositionProp === undefined) setInternalPosition(position);\n onRangePositionChange?.(position);\n },\n [rangePositionProp, onRangePositionChange]\n );\n\n /* ---- open / close ---- */\n const isOpenControlled = openProp !== undefined;\n const [internalOpen, setInternalOpen] = React.useState(false);\n const open = isOpenControlled ? !!openProp : internalOpen;\n const valueAtOpenRef = React.useRef<MGHDateRange>(value);\n const lastAcceptedRef = React.useRef<MGHDateRange>(value);\n\n /** Fires `onAccept` only when the value differs from the last accepted one (MUI semantics). */\n const accept = React.useCallback(\n (next: MGHDateRange, force = false) => {\n if (!force && isRangeEqual(next, lastAcceptedRef.current)) return;\n lastAcceptedRef.current = next;\n onAccept?.(next);\n },\n [onAccept]\n );\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const toggleRef = React.useRef<HTMLButtonElement | null>(null);\n const restoreFocusRef = React.useRef<HTMLElement | null>(null);\n\n // Without an explicit `themeMode`, follow the closest `[data-mgh-theme]` ancestor (e.g. a dark MGHGrid card)\n // so the portaled popover matches the surface the field sits on.\n const [inheritedTheme, setInheritedTheme] = React.useState<'light' | 'dark' | undefined>(undefined);\n React.useEffect(() => {\n if (themeMode !== undefined) return;\n const attr = rootRef.current?.parentElement?.closest('[data-mgh-theme]')?.getAttribute('data-mgh-theme');\n setInheritedTheme(attr === 'dark' ? 'dark' : attr === 'light' ? 'light' : undefined);\n });\n const effectiveThemeMode = themeMode ?? inheritedTheme;\n\n const setRootRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n rootRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) (ref as React.MutableRefObject<HTMLDivElement | null>).current = node;\n },\n [ref]\n );\n\n const openPicker = React.useCallback(\n (position?: MGHDateRangePosition) => {\n if (disabled || readOnly || open) return;\n valueAtOpenRef.current = value;\n restoreFocusRef.current = (document.activeElement as HTMLElement | null) ?? null;\n setRangePosition(position ?? (start && !end ? 'end' : 'start'));\n if (!isOpenControlled) setInternalOpen(true);\n onOpen?.();\n },\n [disabled, readOnly, open, value, start, end, setRangePosition, isOpenControlled, onOpen]\n );\n\n const closePicker = React.useCallback(() => {\n if (!open) return;\n if (!isOpenControlled) setInternalOpen(false);\n onClose?.();\n const target = toggleRef.current ?? restoreFocusRef.current;\n window.setTimeout(() => target?.focus?.(), 0);\n }, [open, isOpenControlled, onClose]);\n\n const acceptAndClose = React.useCallback(\n (next: MGHDateRange) => {\n accept(next, true);\n closePicker();\n },\n [accept, closePicker]\n );\n\n const handleDismiss = React.useCallback(() => {\n // Clicking away / Escape keeps whatever was picked (MUI fires onAccept when the value changed).\n accept(value);\n closePicker();\n }, [value, accept, closePicker]);\n\n const handleCalendarChange = React.useCallback(\n (next: MGHDateRange, _day: dayjs.Dayjs, position: MGHDateRangePosition) => {\n setValue(next);\n if (position === 'end' && next[0] && next[1] && resolvedCloseOnSelect) acceptAndClose(next);\n },\n [setValue, resolvedCloseOnSelect, acceptAndClose]\n );\n\n const handleShortcut = (shortcut: MGHDateRangeShortcut) => {\n const next = normalizeRange(shortcut.getValue({ isValid }));\n setValue(next, shortcut);\n setRangePosition('start');\n acceptAndClose(next);\n };\n\n const handleAction = (action: 'clear' | 'today' | 'cancel' | 'accept') => {\n switch (action) {\n case 'clear': {\n setValue(EMPTY_RANGE);\n setRangePosition('start');\n acceptAndClose(EMPTY_RANGE);\n break;\n }\n case 'today': {\n const today = dayjs().startOf('day');\n const next: MGHDateRange = [today, today];\n setValue(next);\n setRangePosition('start');\n if (resolvedCloseOnSelect) acceptAndClose(next);\n break;\n }\n case 'cancel': {\n if (!isRangeEqual(value, valueAtOpenRef.current)) setValue(valueAtOpenRef.current);\n closePicker();\n break;\n }\n case 'accept':\n default:\n acceptAndClose(value);\n }\n };\n\n /* ---- text fields ---- */\n const [focusedInput, setFocusedInput] = React.useState<FocusedInput>(null);\n const formatSingle = React.useCallback(\n (range: MGHDateRange) => {\n const [s, e] = range;\n if (!s && !e) return '';\n return `${s ? formatDate(s, format) : datePlaceholder} ${localeText.fieldSeparator} ${e ? formatDate(e, format) : datePlaceholder}`;\n },\n [format, datePlaceholder, localeText.fieldSeparator]\n );\n\n const [singleText, setSingleText] = React.useState(() => formatSingle(value));\n const [startText, setStartText] = React.useState(() => formatDate(start, format));\n const [endText, setEndText] = React.useState(() => formatDate(end, format));\n const [inputInvalid, setInputInvalid] = React.useState<{ single: boolean; start: boolean; end: boolean }>({\n single: false,\n start: false,\n end: false,\n });\n\n // Keep the text in sync with the value unless the user is typing in that input.\n React.useEffect(() => {\n if (focusedInput !== 'single') {\n setSingleText(formatSingle(value));\n setInputInvalid((prev) => (prev.single ? { ...prev, single: false } : prev));\n }\n if (focusedInput !== 'start') {\n setStartText(formatDate(start, format));\n setInputInvalid((prev) => (prev.start ? { ...prev, start: false } : prev));\n }\n if (focusedInput !== 'end') {\n setEndText(formatDate(end, format));\n setInputInvalid((prev) => (prev.end ? { ...prev, end: false } : prev));\n }\n }, [value, start, end, focusedInput, format, formatSingle]);\n\n const parseSegment = (text: string): { date: dayjs.Dayjs | null; invalid: boolean } => {\n const trimmed = text.trim();\n if (!trimmed || trimmed.toUpperCase() === datePlaceholder.toUpperCase()) return { date: null, invalid: false };\n const parsed = parseDateText(trimmed, format);\n return { date: parsed, invalid: parsed == null };\n };\n\n const handleSingleChange = (text: string) => {\n setSingleText(text);\n const [s, e] = splitRangeText(text);\n const ps = parseSegment(s);\n const pe = parseSegment(e);\n const invalid = ps.invalid || pe.invalid;\n setInputInvalid((prev) => ({ ...prev, single: invalid }));\n if (invalid) return;\n const next: MGHDateRange = [ps.date, pe.date];\n if (!isRangeEqual(next, value)) setValue(next);\n };\n\n const handleSideChange = (side: 'start' | 'end', text: string) => {\n if (side === 'start') setStartText(text);\n else setEndText(text);\n const parsed = parseSegment(text);\n setInputInvalid((prev) => ({ ...prev, [side]: parsed.invalid }));\n if (parsed.invalid) return;\n const next: MGHDateRange = side === 'start' ? [parsed.date, end] : [start, parsed.date];\n if (!isRangeEqual(next, value)) setValue(next);\n };\n\n const handleBlur = (input: Exclude<FocusedInput, null>) => {\n setFocusedInput((prev) => (prev === input ? null : prev));\n // Re-format on blur unless the text could not be parsed (keep it so the user sees the error).\n if (input === 'single' && !inputInvalid.single) setSingleText(formatSingle(value));\n if (input === 'start' && !inputInvalid.start) setStartText(formatDate(start, format));\n if (input === 'end' && !inputInvalid.end) setEndText(formatDate(end, format));\n // Leaving the field commits a typed value (like pressing Enter).\n if (!open) accept(value);\n };\n\n const handleInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>, position: MGHDateRangePosition) => {\n if (event.key === 'ArrowDown' && !event.altKey) {\n event.preventDefault();\n openPicker(position);\n } else if (event.key === 'Enter') {\n event.preventDefault();\n if (!open) accept(value);\n }\n };\n\n const clear = (event: React.MouseEvent) => {\n event.stopPropagation();\n setValue(EMPTY_RANGE);\n setRangePosition('start');\n accept(EMPTY_RANGE);\n };\n\n const hasValue = !!start || !!end;\n const hasValidationError = validationError.some((e) => e != null);\n const showError = !!errorProp || hasValidationError || inputInvalid.single || inputInvalid.start || inputInvalid.end;\n\n const openButton = !disableOpenPicker && (\n <button\n ref={toggleRef}\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.openPicker}\n title={localeText.openPicker}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n disabled={disabled}\n onClick={(event) => {\n event.stopPropagation();\n if (open) handleDismiss();\n else openPicker();\n }}\n >\n <DateRangeIcon size={size === 'small' ? 20 : 24} />\n </button>\n );\n\n const clearButton = clearable && hasValue && !disabled && !readOnly && (\n <button\n type=\"button\"\n className={cx('mgh-drp-btn mgh-drp-btn--icon', size === 'small' && 'mgh-drp-btn--small')}\n aria-label={localeText.clear}\n title={localeText.clear}\n onClick={clear}\n >\n <CloseIcon size={size === 'small' ? 18 : 20} />\n </button>\n );\n\n const themeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...style }),\n [themeVars, style]\n );\n const popoverThemeStyle = React.useMemo(\n () => ({ ...(themeVars as React.CSSProperties | undefined), ...popoverStyle }),\n [themeVars, popoverStyle]\n );\n\n /* ---- shortcuts / actions / toolbar ---- */\n const shortcutItems = React.useMemo(\n () =>\n (shortcuts ?? []).map((shortcut, index) => {\n let shortcutValue: MGHDateRange = EMPTY_RANGE;\n try {\n shortcutValue = normalizeRange(shortcut.getValue({ isValid }));\n } catch {\n /* ignore */\n }\n return { shortcut, key: shortcut.id ?? `${shortcut.label}-${index}`, value: shortcutValue };\n }),\n [shortcuts, isValid]\n );\n\n const renderToolbar = () => (\n <div className=\"mgh-drp-toolbar\">\n <p className=\"mgh-drp-toolbar-title\" id={dialogTitleId}>\n {localeText.toolbarTitle}\n </p>\n <div className=\"mgh-drp-toolbar-range\">\n <button\n type=\"button\"\n className={cx(rangePosition === 'start' && 'mgh-drp-toolbar-range--active')}\n onClick={() => setRangePosition('start')}\n >\n {start ? formatDate(start, format) : localeText.start}\n </button>\n <span>{localeText.fieldSeparator}</span>\n <button\n type=\"button\"\n className={cx(rangePosition === 'end' && 'mgh-drp-toolbar-range--active')}\n onClick={() => setRangePosition('end')}\n >\n {end ? formatDate(end, format) : localeText.end}\n </button>\n </div>\n </div>\n );\n\n const renderActions = () =>\n actions.length > 0 && (\n <div className=\"mgh-drp-actions\">\n {actions.map((action) => (\n <button\n key={action}\n type=\"button\"\n className={cx('mgh-drp-btn', (action === 'accept' || action === 'today') && 'mgh-drp-btn--primary')}\n onClick={() => handleAction(action)}\n >\n {localeText[action]}\n </button>\n ))}\n </div>\n );\n\n const calendar = (\n <MGHDateRangeCalendar\n value={value}\n onChange={handleCalendarChange}\n rangePosition={rangePosition}\n onRangePositionChange={setRangePosition}\n calendars={calendars}\n referenceDate={referenceDate}\n minDate={minDate}\n maxDate={maxDate}\n disablePast={disablePast}\n disableFuture={disableFuture}\n shouldDisableDate={shouldDisableDate}\n showDaysOutsideCurrentMonth={showDaysOutsideCurrentMonth}\n fixedWeekNumber={fixedWeekNumber}\n dayOfWeekFormatter={dayOfWeekFormatter}\n disableHighlightToday={disableHighlightToday}\n showRangePreview={showRangePreview}\n onMonthChange={onMonthChange}\n localeText={localeText}\n themeMode={effectiveThemeMode}\n autoFocus\n />\n );\n\n /* ---- render ---- */\n const commonFieldProps = {\n size,\n fullWidth,\n disabled,\n readOnly,\n required,\n error: showError,\n };\n\n return (\n <div\n ref={setRootRef}\n className={cx('mgh-drp', fullWidth && 'mgh-drp--full-width', isMulti && 'mgh-drp--multi', className)}\n data-mgh-theme={effectiveThemeMode}\n style={themeStyle}\n >\n {isMulti ? (\n <div className=\"mgh-drp-fields\">\n <TextField\n {...commonFieldProps}\n multi\n id={startId}\n name={name ? `${name}-start` : undefined}\n label={localeText.start}\n value={startText}\n placeholder={placeholderProp ?? datePlaceholder}\n focused={focusedInput === 'start'}\n clickable={resolvedOpenOnClick}\n autoFocus={autoFocus}\n inputRef={inputRef}\n onChange={(text) => handleSideChange('start', text)}\n onFocus={() => {\n setFocusedInput('start');\n setRangePosition('start');\n }}\n onBlur={() => handleBlur('start')}\n onClick={() => resolvedOpenOnClick && openPicker('start')}\n onKeyDown={(event) => handleInputKeyDown(event, 'start')}\n />\n <span className=\"mgh-drp-fields-separator\" aria-hidden=\"true\">\n {localeText.fieldSeparator}\n </span>\n <TextField\n {...commonFieldProps}\n multi\n id={endId}\n name={name ? `${name}-end` : undefined}\n label={localeText.end}\n value={endText}\n placeholder={placeholderProp ?? datePlaceholder}\n focused={focusedInput === 'end'}\n clickable={resolvedOpenOnClick}\n adornment={\n <>\n {clearButton}\n {openButton}\n </>\n }\n onChange={(text) => handleSideChange('end', text)}\n onFocus={() => {\n setFocusedInput('end');\n setRangePosition('end');\n }}\n onBlur={() => handleBlur('end')}\n onClick={() => resolvedOpenOnClick && openPicker('end')}\n onKeyDown={(event) => handleInputKeyDown(event, 'end')}\n />\n </div>\n ) : (\n <TextField\n {...commonFieldProps}\n id={startId}\n name={name}\n label={label}\n value={singleText}\n placeholder={placeholderProp ?? `${datePlaceholder} ${localeText.fieldSeparator} ${datePlaceholder}`}\n focused={focusedInput === 'single'}\n clickable={resolvedOpenOnClick}\n autoFocus={autoFocus}\n inputRef={inputRef}\n ariaLabel={label == null ? localeText.toolbarTitle : undefined}\n adornment={\n <>\n {clearButton}\n {openButton}\n </>\n }\n onChange={handleSingleChange}\n onFocus={() => setFocusedInput('single')}\n onBlur={() => handleBlur('single')}\n onClick={() => resolvedOpenOnClick && openPicker()}\n onKeyDown={(event) => handleInputKeyDown(event, 'start')}\n />\n )}\n {helperText != null && helperText !== '' && (\n <div className={cx('mgh-drp-helper', showError && 'mgh-drp-helper--error')}>{helperText}</div>\n )}\n\n <Popover\n open={open}\n anchorEl={rootRef.current}\n placement={placement}\n onDismiss={handleDismiss}\n themeMode={effectiveThemeMode}\n className={popoverClassName}\n style={popoverThemeStyle}\n labelledBy={showToolbar ? dialogTitleId : undefined}\n >\n <div className={cx('mgh-drp-layout', showToolbar && 'mgh-drp-layout--with-toolbar')}>\n {showToolbar && renderToolbar()}\n <div className=\"mgh-drp-layout-main\">\n {shortcutItems.length > 0 && (\n <ul className=\"mgh-drp-shortcuts\" aria-label=\"Shortcuts\">\n {shortcutItems.map(({ shortcut, key, value: shortcutValue }) => (\n <li key={key}>\n <button\n type=\"button\"\n className={cx(\n 'mgh-drp-shortcut',\n hasValue &&\n isRangeEqual(shortcutValue, value) &&\n 'mgh-drp-shortcut--selected'\n )}\n disabled={disabled || readOnly}\n onClick={() => handleShortcut(shortcut)}\n >\n {shortcut.label}\n </button>\n </li>\n ))}\n </ul>\n )}\n {calendar}\n </div>\n {renderActions()}\n </div>\n </Popover>\n </div>\n );\n});\n\nMGHDateRangePicker.displayName = 'MGHDateRangePicker';\n\nexport default MGHDateRangePicker;\n"],"names":["useResponsive","query","start","end","theme","useTheme","mediaUp","useMediaQuery","breakpoints","up","mediaDown","down","mediaBetween","between","mediaOnly","only","CustomNoRowsOverlay","text","useSettingsContext","themeMode","palette","mode","StyledGridOverlay","styled","display","alignItems","justifyContent","height","fill","fillOpacity","React","createElement","Box","component","alt","src","sx","width","maxWidth","mb","canUseLocalStorage","window","localStorage","readLocalStorage","key","value","getItem","JSON","parse","writeLocalStorage","setItem","stringify","MGHDataGrid","header","rows","columns","onRowClick","onRowDoubleClick","pagination","pageSize","slots","slotProps","toolbarProps","initialState","pageSizeOptions","cardSx","flexGrow","boxSx","columnVisibilityModel","onColumnVisibilityModelChange","columnVisibilityStorageKey","columnOrderStorageKey","disableDensitySelector","disableRowSelectionOnClick","disableColumnFilter","disableColumnMenu","disableColumnSelector","checkboxSelectionVisibleOnly","renderHeaderEndContent","renderHeaderCenterContent","noRowsText","checkboxSelection","onRowSelectionModelChange","rowSelectionModel","getRowClassName","getDetailPanelContent","getDetailPanelHeight","loading","isRowSelectable","getRowHeight","showToolbar","hideFooterRowCount","onColumnOrderChange","defaultGroupingExpansionDepth","pinnedRows","keepNonExistentRowsSelected","smDown","persistedColumnVisibilityModel","useMemo","undefined","persistedOrderedFields","normalizeOrderedFields","orderedFields","length","columnFields","Set","map","column","field","filter","has","resolvedColumnVisibilityModel","handleColumnVisibilityModelChange","useCallback","model","details","handleColumnOrderChange","params","event","api","getAllColumns","mergedInitialState","density","paginationModel","filterModel","items","quickFilterExcludeHiddenColumns","Card","pr","CardHeader","title","gap","flexWrap","flexDirection","DataGridPremium","noRowsOverlay","toolbar","MGHGridToolbar","cursor","disableRowSelectionExcludeModel","showColumnsButton","showFilterButton","showExportButton","showQuickFilter","renderOtherButtons","renderDateRange","customMenuItem","showCsvOption","Toolbar","style","Tooltip","ColumnsPanelTrigger","render","ToolbarButton","GridViewColumnIcon","fontSize","FilterPanelTrigger","props","state","color","Badge","badgeContent","filterCount","variant","GridFilterListIcon","CustomGridToolbarExport","DataGridQuickFilter","csvOptions","allColumns","excelOptions","printOptions","other","GridToolbarExportContainer","el","GridCsvExportMenuItem","options","GridExcelExportMenuItem","GridPrintExportMenuItem","StyledQuickFilter","QuickFilter","StyledToolbarButton","ownerState","gridArea","zIndex","opacity","expanded","pointerEvents","transition","transitions","create","StyledTextField","TextField","overflowX","QuickFilterTrigger","triggerProps","enterDelay","GridSearchIcon","QuickFilterControl","ref","controlProps","inputRef","placeholder","size","input","startAdornment","InputAdornment","position","endAdornment","QuickFilterClear","edge","material","marginRight","GridCloseIcon","ConfirmDialog","content","action","open","onClose","Dialog","fullWidth","DialogTitle","pb","DialogContent","typography","DialogActions","Button","onClick","ExportingDialog","Fragment","p","textAlign","Typography","CircularProgress","Iconify","forwardRef","icon","Icon","StyledLabel","lightMode","filledVariant","outlinedVariant","softVariant","defaultStyle","common","white","grey","backgroundColor","primary","border","secondary","alpha","colorStyle","contrastText","main","minWidth","lineHeight","borderRadius","whiteSpace","textTransform","padding","spacing","pxToRem","fontWeight","fontWeightBold","duration","shorter","Label","children","startIcon","endIcon","iconStyles","objectFit","pl","mr","ml","GROUPING_COLUMN_FIELD","CHECKBOX_FIELD","DETAIL_PANEL_TOGGLE_FIELD","AGGREGATION_FOOTER_ID","INTERNAL_FIELDS","DENSITY_FACTORS","compact","standard","comfortable","DEFAULT_ROW_HEIGHT","DEFAULT_HEADER_HEIGHT","DEFAULT_COLUMN_MIN_WIDTH","isInternalField","isNil","isEmptyValue","Array","isArray","clamp","min","max","Math","cx","classNames","Boolean","join","uniqueId","counter","prefix","getRowIdFromRow","row","getRowId","id","normalizeSelectionModel","allIds","type","ids","forEach","add","toDate","Date","Number","isNaN","getTime","dayjs","isDayjs","isValid","d","parsed","formatDate","withTime","date","format","startOfUnit","startOf","valueOf","isValueOptionObject","option","getOptionValue","col","getOptionLabel","label","String","resolveValueOptions","valueOptions","getCellValue","raw","valueGetter","defaultFormatValue","match","find","isFinite","getFormattedValue","valueFormatter","formattedValueToString","formatted","collator","Intl","Collator","numeric","sensitivity","nilFirst","v1","v2","n1","n2","numberComparator","nil","stringComparator","s1","s2","compare","stringOrNumberComparator","p1","p2","dateComparator","d1","d2","booleanComparator","getDefaultComparator","lower","toLowerCase","hasValue","item","stringFilterOperators","inputType","getApplyFilterFn","needle","indexOf","s","lastIndexOf","requiresFilterValue","set","numberOperator","filterValue","cell","n","numberFilterOperators","a","b","v","dateOperator","filterDate","filterTime","cellDate","getDateFilterOperators","booleanFilterOperators","expected","singleSelectFilterOperators","getColumnFilterOperators","filterOperators","getDefaultFilterOperators","normalizeColumn","isNumber","isBoolean","isActions","headerName","align","headerAlign","sortable","filterable","hideable","resizable","pinnable","groupable","aggregable","editable","disableExport","internalColumn","disableReorder","CHECKBOX_COLUMN_DEF","DETAIL_PANEL_TOGGLE_COLUMN_DEF","UNITLESS_PROPERTIES","isSelectorKey","test","serializeDeclarations","block","Object","keys","property","kebab","replace","m","toKebabCase","formatCssValue","buildScopedCss","scope","out","charAt","inner","declarations","push","selector","scopeSelector","split","part","trim","numericValues","values","BUILT_IN_AGGREGATION_FUNCTIONS","sum","columnTypes","apply","nums","reduce","acc","avg","defined","every","dates","slice","sort","sorted","DEFAULT_LOCALE_TEXT","noRowsLabel","loadingLabel","toolbarColumns","toolbarFilters","toolbarExport","toolbarDensity","toolbarQuickFilterPlaceholder","toolbarQuickFilterLabel","toolbarExportCSV","toolbarExportExcel","toolbarExportPrint","densityCompact","densityStandard","densityComfortable","columnsPanelSearchPlaceholder","columnsPanelShowAll","columnsPanelHideAll","columnsPanelReset","filterPanelAddFilter","filterPanelRemoveAll","filterPanelDeleteIcon","filterPanelColumns","filterPanelOperator","filterPanelValue","filterPanelInputPlaceholder","filterPanelLogicOperator","filterPanelOperatorAnd","filterPanelOperatorOr","columnMenuSortAsc","columnMenuSortDesc","columnMenuUnsort","columnMenuFilter","columnMenuHideColumn","columnMenuManageColumns","columnMenuPinLeft","columnMenuPinRight","columnMenuUnpin","columnMenuGroup","name","columnMenuUngroup","columnMenuAggregation","aggregationMenuItemHeader","aggregationFunctionLabelNone","aggregationFunctionLabelSum","aggregationFunctionLabelAvg","aggregationFunctionLabelMin","aggregationFunctionLabelMax","aggregationFunctionLabelSize","footerRowSelected","count","toLocaleString","footerTotalRows","footerPaginationRowsPerPage","footerPaginationDisplayedRows","from","to","footerPaginationFirstPage","footerPaginationPreviousPage","footerPaginationNextPage","footerPaginationLastPage","checkboxSelectionHeaderName","checkboxSelectionSelectAllRows","checkboxSelectionUnselectAllRows","checkboxSelectionSelectRow","checkboxSelectionUnselectRow","booleanCellTrueLabel","booleanCellFalseLabel","detailPanelToggle","expandDetailPanel","collapseDetailPanel","groupingColumnHeaderName","groupColumn","unGroupColumn","actionsCellMore","columnHeaderSortIconLabel","columnMenuLabel","clearSearch","measureContext","measureText","font","document","canvas","getContext","downloadBlob","blob","fileName","url","URL","createObjectURL","anchor","href","download","body","appendChild","click","setTimeout","removeChild","revokeObjectURL","MGH_GRID_STYLE_ID","MGH_GRID_CSS","injected","useInsertion","useInsertionEffect","useLayoutEffect","useEffect","useMGHGridStyles","injectStyles","getElementById","setAttribute","textContent","head","MGHGridContext","createContext","displayName","useMGHGridContext","ctx","useContext","Error","useMGHGridApiContext","useMGHGridLocaleText","localeText","useMGHGridApiRef","useRef","useLatestRef","current","useControlledState","controlled","defaultValue","onChange","isControlled","internal","setInternal","useState","valueRef","controlledRef","onChangeRef","next","resolved","is","idCounter","buildExportTable","resolveExportColumns","all","fields","byField","Map","c","f","get","getVisibleColumns","getRowsToExport","getSortedRowIds","getRow","headers","sanitizeFileName","fallback","extension","base","endsWith","defaultFileBase","escapeCsvCell","delimiter","getDataAsCsv","includeHeaders","table","lines","h","cells","useRawValues","UTF8_BOM","fromCharCode","CRC_TABLE","Uint32Array","k","textEncoder","TextEncoder","encodeUtf8","encode","utf8","unescape","encodeURIComponent","Uint8Array","i","charCodeAt","concatBytes","chunks","total","offset","zipStore","entries","localChunks","centralChunks","entry","nameBytes","crc","bytes","crc32","data","local","lv","DataView","buffer","setUint32","setUint16","central","cv","centralDirectory","eocd","ev","concat","INVALID_XML_CHARS","RegExp","escapeXml","stripInvalidXml","columnLetter","index","letters","rem","floor","XML_HEADER","buildSheetXml","columnWidths","rowsXml","rowIndex","inlineString","xmlCells","UTC","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","lastCol","lastRow","cols","w","STYLES_XML","CONTENT_TYPES_XML","ROOT_RELS_XML","WORKBOOK_RELS_XML","buildWorkbookXml","sheetName","buildCoreXml","now","toISOString","APP_XML","buildXlsx","widths","explicit","columnsStyles","r","len","cleaned","sanitizeSheetName","escapeHtml","exportDataAsPrintTable","headerHtml","bodyHtml","html","pageStyle","iframe","right","bottom","cleanup","parentNode","onload","win","contentWindow","focus","onafterprint","print","doc","contentDocument","write","close","srcdoc","printGridElement","done","onDone","printGridElementUnsafe","error","console","cardElement","hideToolbar","hideFooter","copyStyles","clone","cloneNode","syncFormState","source","target","sourceInputs","querySelectorAll","targetInputs","t","tagName","dst","checked","indeterminate","sourceCanvases","targetCanvases","img","ownerDocument","toDataURL","cssText","replaceWith","remove","classList","removeAttribute","styles","links","styleSheets","sheet","rules","cssRules","rule","collectStyles","finished","finish","css","printStyle","h1","className","adoptNode","async","waitForImages","timeoutMs","Promise","resolve","images","complete","remaining","timer","onSettled","clearTimeout","addEventListener","once","onBeforePrint","run","keyToString","buildGroupTree","groupingFields","columnsByField","emptyLabel","build","depth","parentId","path","buckets","getGroupingValue","groupingValueGetter","keyStr","node","parent","groupingField","groupingKey","groupingLabel","childGroups","leaves","descendants","nodes","collectTreeLeaves","roots","root","aggregateRows","aggregationModel","functions","result","fnName","fn","createIcon","rest","viewBox","focusable","ViewColumnIcon","FilterListIcon","SearchIcon","CloseIcon","DownloadIcon","ArrowUpwardIcon","ArrowDownwardIcon","MoreVertIcon","CheckIcon","ExpandMoreIcon","ChevronRightIcon","ChevronLeftIcon","FirstPageIcon","LastPageIcon","PushPinIcon","DeleteIcon","AddIcon","DensitySmallIcon","DensityMediumIcon","DensityLargeIcon","DragIndicatorIcon","PrintIcon","TableChartIcon","DescriptionIcon","VisibilityOffIcon","FunctionsIcon","WorkspacesIcon","EmptyBoxIcon","active","IconButton","TextInput","Select","Field","htmlFor","Checkbox","forwardedRef","innerRef","setRef","Spinner","role","Popover","anchorEl","placement","autoFocus","ignoreOutsideClickOn","setPosition","top","left","ready","update","vw","innerWidth","vh","innerHeight","offsetWidth","offsetHeight","isConnected","getBoundingClientRect","prev","observer","ResizeObserver","observe","removeEventListener","disconnect","handlePointerDown","contains","some","closest","handleKeyDown","querySelector","stop","stopPropagation","createPortal","tabIndex","visibility","onDoubleClick","onMouseDown","onKeyDown","Menu","first","preventDefault","currentIndex","activeElement","MenuItem","selected","disabled","hideMenu","MenuDivider","MenuSection","MGHGridColumnsButton","isOpen","preferencePanel","openedPanelValue","hidePreferences","showPreferences","currentTarget","MGHGridFiltersButton","MGHGridDensitySelector","setAnchor","o","setDensity","MGHGridExportMenuItem","MGHGridExportMenu","showExcelOption","showPrintOption","rootProps","customItems","Children","child","isValidElement","cloneElement","resolvedPrintOptions","exportDataAsCsv","exportDataAsExcel","exportDataAsPrint","MGHGridQuickFilter","debounceMs","alwaysExpanded","externalValue","quickFilterValues","setText","setExpanded","delay","quickFilterDebounceMs","lastExternal","commit","setQuickFilterValues","clear","isExpanded","expand","handleChange","onBlur","blur","showDensitySelector","quickFilterPlaceholder","showColumns","showFilters","showDensity","MGHGridPagination","page","rowCount","pageCount","setPageSize","setPage","MGHGridFooter","selectedCount","showSelected","hideFooterSelectedRowCount","showPagination","hideFooterPagination","showRowCount","MGHGridColumnsPanel","visibleColumns","visibleFields","search","setSearch","filtered","setAll","visible","setColumnVisibilityModel","setColumnVisibility","useDebouncedValue","onCommit","setLocal","TextValueInput","MultiValueInput","joined","multiple","selectedOptions","FilterValueInput","operator","InputComponent","Component","applyValue","createFilterItem","MGHGridFilterPanel","filterableColumns","logicOperator","targetField","seeded","upsertFilterItem","updateItem","patch","canAddMore","disableMultipleColumnsFiltering","paddingTop","operators","op","showLogic","deleteFilterItem","setFilterLogicOperator","nextColumn","nextOperators","keepOperator","nextOperator","nextIsMulti","currentIsMulti","addItem","setFilterModel","MGHGridColumnMenu","panelAnchorEl","isGroupingColumn","sortItem","sortModel","pinned","isColumnPinned","isGrouped","rowGroupingModel","aggregation","canSort","disableColumnSorting","canFilter","canHide","canPin","disableColumnPinning","canGroup","disableRowGrouping","aggregationFunctions","availableAggregationFunctions","canAggregate","disableAggregation","anchorForPanel","sortColumn","showFilterPanel","transform","pinColumn","unpinColumn","removeRowGroupingCriteria","addRowGroupingCriteria","setAggregationModel","MGHGridNoRowsOverlay","imageSrc","MGHGridLoadingOverlay","MGHGridActionsCellItem","showInMenu","ActionsCell","actions","moreLabel","inline","inMenu","EMPTY_ARRAY","EMPTY_OBJECT","EMPTY_MAP","DEFAULT_SORTING_ORDER","DEFAULT_PAGE_SIZE_OPTIONS","DEFAULT_FILTER_MODEL","sanitizeStyle","toDateInputValue","pad","padStart","MGHGrid","columnsProp","disableCard","cardClassName","boxClassName","cardStyle","boxStyle","themeVars","localeTextProp","rowHeight","rowHeightProp","columnHeaderHeight","autoHeight","disableVirtualization","densityProp","onDensityChange","paginationModelProp","onPaginationModelChange","sortModelProp","onSortModelChange","sortingOrder","disableMultipleColumnsSorting","filterModelProp","onFilterModelChange","columnVisibilityModelProp","columnWidthStorageKey","pinnedColumnsStorageKey","onColumnWidthChange","disableColumnResize","disableColumnReorder","pinnedColumns","pinnedColumnsProp","onPinnedColumnsChange","disableMultipleRowSelection","rowSelectionModelProp","onCellClick","onCellDoubleClick","detailPanelExpandedRowIds","detailPanelExpandedRowIdsProp","onDetailPanelExpandedRowIdsChange","rowGroupingModelProp","onRowGroupingModelChange","groupingColDef","isGroupExpandedByDefault","aggregationModelProp","onAggregationModelChange","aggregationFunctionsProp","aggregationPosition","processRowUpdate","onProcessRowUpdateError","onCellEditStop","isCellEditable","apiRef","onStateChange","gridId","reactUseId","useId","useStableId","rootRef","cardRef","scrollerRef","toolbarRef","forceUpdate","setTick","useForceUpdate","latest","getDetails","apiObject","L","apiImpl","rowsById","getRowModels","getAllRowIds","rowEntries","e","getRowNode","nodesById","getSortedRows","sortedLeaves","getVisibleRows","pagedRows","dr","getRowIndexRelativeToVisibleRows","findIndex","updateRows","updates","existing","setRowOverride","orderedUserColumns","visibleUserColumns","getColumn","getColumnIndex","useVisibleColumns","getColumnVisibilityModel","isVisible","setColumnWidth","setColumnIndex","targetIndex","autosizeColumns","side","getPinnedColumns","setPinnedColumns","getSortModel","setSortModel","direction","allowMultipleSorting","getFilterModel","upsertFilterItems","targetColumnField","hideFilterPanel","panel","getSelectedRows","selectedIds","getRowSelectionModel","setRowSelectionModel","normalized","setSelectedIds","selectRow","isSelected","resetSelection","selectRows","isRowSelected","isRowSelectableFn","nextPage","setPaginationModel","nextPageSize","csv","bom","utf8WithBom","Blob","startPrint","toggleDetailPanel","setExpandedDetailPanels","getExpandedDetailPanels","expandedDetailPanels","getRowGroupingModel","setRowGroupingModel","groupingIndex","splice","setRowChildrenExpansion","getRowGroupChildren","groupId","group","groupsById","getAggregationModel","startCellEditMode","stopCellEditMode","ignoreModifications","getCellMode","editing","editingCell","setEditCellValue","setEditValue","getCellParams","buildCellParams","setCellFocus","pendingFocusRef","setFocusedCell","scrollToIndexes","scroll","scroller","scrollLeft","scrollTop","getScrollPosition","rootElementRef","persisted","order","sorting","rowGrouping","controlledExpandedDetail","detailPanel","expandedRowIds","controlledSelection","setOrderedFields","setColumnWidths","dims","dimensions","groupExpansion","setGroupExpansion","setEditingCell","editValue","focusedCell","setPreferencePanel","columnMenu","setColumnMenu","resizingField","setResizingField","printState","setPrintState","printing","drag","setDrag","setScrollTop","scrollRaf","lastClickedIdRef","overrideState","setOverrideState","rowOverrides","viewportWidth","viewportHeight","enabled","setSize","clientWidth","clientHeight","useElementSize","densityFactor","round","headerHeight","userColumns","groupingActive","groupingColumn","single","seen","isColumnVisible","wanted","layout","leftFields","rightFields","visibleByField","center","ordered","computeWidths","available","overrides","Infinity","override","flex","pool","fixedTotal","remainingSpace","remainingFlex","changed","share","fixed","idx","hasPinning","x","leftOffset","isLeft","isRight","isLastLeft","isFirstRight","rightOffset","totalWidth","leftCount","rightCount","allDisplayColumnsByField","activeFilters","quickFilterColumns","filteredEntries","logicAnd","quickAnd","quickFilterLogicOperator","apiRefLocal","quickFns","lowered","getApplyQuickFilterFn","custom","results","compareEntries","sorters","dir","comparator","sortComparator","sortEntries","aggregationActive","isGroupExpanded","leafIds","processed","displayRows","tree","groupingSort","sortGroupTree","compareGroups","sortLeaves","sortLevel","flattenGroupTree","visit","groupNode","toGroupNode","l","childVisible","leaf","leafNode","totalDisplayRows","paginate","ceil","footerAggregates","rowsForFooter","groupAggregatesCache","getGroupAggregates","cached","heights","rowHeights","detailHeights","offsets","hasAuto","dh","virtual","virtualRange","overscan","viewTop","viewBottom","lo","hi","mid","handleScroll","requestAnimationFrame","cancelAnimationFrame","selectionCandidates","selectedCandidateCount","allCandidatesSelected","someCandidatesSelected","updateSelection","updater","selectionModelsEqual","equal","delete","lastId","toggleAllCandidates","allowMultiple","persistOrder","persistWidths","targets","lc","computed","getComputedStyle","fontFamily","cellFont","headerFont","sample","isCellEditableFn","colDef","rowNode","reason","valueParser","parseEditValue","currentValue","applyRowUpdate","newRow","oldRow","then","rowId","catch","valueSetter","previousGroupingKey","formattedValue","hasFocus","cellMode","isEditable","buildRowParams","preventScroll","visibleTop","visibleBottom","scrollIntoView","colIndex","leftPinnedWidth","rightPinnedWidth","visibleLeft","visibleRight","moveFocus","rowDelta","colDelta","absolute","canReorder","resizeRef","totalRowCount","clamped","oldIndex","moveItem","list","unshift","nextItems","withId","random","toString","contextValue","renderCellContent","renderRow","kind","selectable","hideCount","hideDescendantCount","paddingLeft","agg","aggregates","sampleRow","cancel","renderEditCell","onValueChange","renderEditor","renderCell","getActions","cellStyle","pinnedClasses","rowIsClickable","renderRowElement","customClass","indexRelativeToCurrentPage","isFirstVisible","isFirst","isLastVisible","isLast","isAuto","minHeight","handleRowSelectionClick","allSelected","shiftKey","ctrlKey","metaKey","isFocused","isEditing","isAggregation","cellClassName","isCheckbox","isDetailToggle","toRenderRow","renderPinnedRows","renderHeaderCell","sortIndex","showMenu","draggable","isDragging","isDropTarget","overField","menuOpen","headerParams","headerClassName","renderHeader","description","onDragStart","dataTransfer","effectAllowed","setData","onDragOver","sourceLc","dropEffect","rect","clientX","onDragLeave","onDrop","handleDrop","targetLc","without","onDragEnd","onPointerDown","handleResizeStart","startX","startWidth","lastWidth","onMove","onUp","ToolbarSlot","FooterSlot","footer","NoRowsOverlaySlot","LoadingOverlaySlot","loadingOverlay","mergedToolbarProps","noRowsProps","loadingProps","showNoRows","menuColumn","cardStyles","boxStyles","rootStyles","scopedCss","grid","pageRows","onScroll","renderBodyRows","detailHeight","detailContent","detailAuto","rowAuto","Provider","MGH_DATE_RANGE_PICKER_STYLE_ID","MGH_DATE_RANGE_PICKER_CSS","useMGHDateRangePickerStyles","DateRangeIcon","extend","customParseFormat","EMPTY_RANGE","toDayjs","isSameDay","isSame","isBeforeDay","isBefore","isAfterDay","isAfter","isWithinRange","day","isRangeEqual","same","y","normalizeRange","parseDateText","trimmed","strict","fallbacks","validateDay","disablePast","disableFuture","minDate","maxDate","shouldDisableDate","validateRange","startError","endError","isDayDisabled","MGH_DATE_RANGE_DEFAULT_SHORTCUTS","getValue","today","endOf","subtract","defaultDayOfWeekFormatter","toUpperCase","MGHDateRangeCalendar","valueProp","rangePosition","rangePositionProp","onRangePositionChange","calendars","referenceDate","readOnly","showDaysOutsideCurrentMonth","fixedWeekNumber","dayOfWeekFormatter","disableHighlightToday","showRangePreview","onMonthChange","internalValue","setInternalValue","internalPosition","setInternalPosition","setRangePosition","validation","currentMonth","setCurrentMonth","visibleMonths","_","lastVisibleMonth","changeMonth","month","ensureVisible","lastSeenRef","canGoPrev","canGoNext","hoveredDay","setHoveredDay","preview","selectDay","nextPosition","focusedDay","setFocusedDay","focusDay","weekDays","formatter","full","getWeekDayLabels","previewStart","previewEnd","isRangeComplete","onMouseLeave","renderMonth","weeks","getMonthWeeks","firstOfMonth","weeksInMonth","diff","weekCount","weekStart","days","outsideMonth","tabbableDay","previousMonth","nextMonth","wd","week","dayIndex","hidden","isStart","isEnd","inRange","inPreview","dayDisabled","isTabbable","firstVisible","lastVisible","daysInMonth","onMouseEnter","onFocus","MGH_DATE_RANGE_PICKER_DEFAULT_LOCALE_TEXT","fieldSeparator","openPicker","accept","toolbarTitle","onDismiss","labelledBy","multi","required","focused","clickable","adornment","ariaLabel","hasLabel","shrink","inputMode","autoComplete","spellCheck","MGHDateRangePicker","onAccept","onError","openProp","onOpen","fieldVariant","clearable","openOnClick","disableOpenPicker","closeOnSelect","shortcuts","idProp","placeholderProp","errorProp","helperText","popoverClassName","popoverStyle","datePlaceholder","isMulti","resolvedOpenOnClick","resolvedCloseOnSelect","includes","reactId","baseId","startId","endId","dialogTitleId","validationError","range","lastErrorRef","setValue","shortcut","context","isOpenControlled","internalOpen","setInternalOpen","valueAtOpenRef","lastAcceptedRef","force","toggleRef","restoreFocusRef","inheritedTheme","setInheritedTheme","attr","parentElement","getAttribute","effectiveThemeMode","setRootRef","closePicker","acceptAndClose","handleDismiss","handleCalendarChange","_day","focusedInput","setFocusedInput","formatSingle","singleText","setSingleText","startText","setStartText","endText","setEndText","inputInvalid","setInputInvalid","parseSegment","invalid","handleSideChange","handleBlur","handleInputKeyDown","altKey","hasValidationError","showError","openButton","clearButton","themeStyle","popoverThemeStyle","shortcutItems","shortcutValue","calendar","commonFieldProps","parts","splitRangeText","ps","pe","handleShortcut","handleAction"],"mappings":"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"}