mgh-components 1.0.14 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +167 -53
- package/dist/components/CustomNoRowsOverlay/CustomNoRowsOverlay.types.d.ts +0 -0
- package/dist/components/Label/styles.d.ts +10 -6
- package/dist/components/MGHDataGrid/MGHDataGrid.d.ts +3 -2
- package/dist/components/MGHDataGrid/MGHDataGrid.types.d.ts +1 -1
- package/dist/components/MGHGrid/MGHGrid.d.ts +7 -0
- package/dist/components/MGHGrid/MGHGrid.styles.d.ts +10 -0
- package/dist/components/MGHGrid/MGHGrid.types.d.ts +708 -0
- package/dist/components/MGHGrid/components/ActionsCell.d.ts +22 -0
- package/dist/components/MGHGrid/components/ColumnMenu.d.ts +12 -0
- package/dist/components/MGHGrid/components/ColumnsPanel.d.ts +2 -0
- package/dist/components/MGHGrid/components/FilterPanel.d.ts +2 -0
- package/dist/components/MGHGrid/components/Footer.d.ts +3 -0
- package/dist/components/MGHGrid/components/Overlays.d.ts +5 -0
- package/dist/components/MGHGrid/components/Toolbar.d.ts +30 -0
- package/dist/components/MGHGrid/components/primitives.d.ts +81 -0
- package/dist/components/MGHGrid/context.d.ts +40 -0
- package/dist/components/MGHGrid/export.d.ts +18 -0
- package/dist/components/MGHGrid/grouping.d.ts +40 -0
- package/dist/components/MGHGrid/hooks.d.ts +23 -0
- package/dist/components/MGHGrid/icons.d.ts +32 -0
- package/dist/components/MGHGrid/index.d.ts +20 -0
- package/dist/components/MGHGrid/utils.d.ts +62 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,101 +2,215 @@
|
|
|
2
2
|
|
|
3
3
|
Metrolina Greenhouses (MGH) component library for React applications.
|
|
4
4
|
|
|
5
|
-
This package
|
|
5
|
+
This package ships two data grids:
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- **`MGHGrid`** – a self-contained data grid with **no MUI dependency** (and therefore no
|
|
8
|
+
`@mui/x-data-grid-premium` license). This is the grid to use going forward.
|
|
9
|
+
- **`MGHDataGrid`** – the legacy wrapper around MUI X Data Grid Premium. It is kept for backwards
|
|
10
|
+
compatibility and still requires the MUI peer dependencies.
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
Plus a few helpers built on MUI (`Label`, `ConfirmDialog`, `ExportingDialog`, `Iconify`).
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
npm install mgh-components
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Using pnpm:
|
|
14
|
+
## Install
|
|
16
15
|
|
|
17
16
|
```bash
|
|
17
|
+
npm install mgh-components
|
|
18
|
+
# or
|
|
18
19
|
pnpm add mgh-components
|
|
19
20
|
```
|
|
20
21
|
|
|
21
|
-
Using yarn:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
yarn add mgh-components
|
|
25
|
-
```
|
|
26
|
-
|
|
27
22
|
## Peer Dependencies
|
|
28
23
|
|
|
29
|
-
|
|
24
|
+
`MGHGrid` only needs:
|
|
30
25
|
|
|
31
26
|
- `react`
|
|
32
27
|
- `react-dom`
|
|
33
|
-
- `@mui/material`
|
|
34
|
-
- `@mui/x-data-grid-premium`
|
|
35
|
-
- `@mui/x-date-pickers-pro`
|
|
36
|
-
- `@emotion/styled`
|
|
37
28
|
|
|
38
|
-
|
|
29
|
+
(`dayjs` is a regular dependency and is used for date formatting.)
|
|
39
30
|
|
|
40
|
-
|
|
31
|
+
The legacy components (`MGHDataGrid`, `Label`, `ConfirmDialog`, …) additionally need
|
|
32
|
+
`@mui/material`, `@mui/x-data-grid-premium`, `@mui/x-date-pickers-pro`, `@emotion/styled` and `@iconify/react`.
|
|
41
33
|
|
|
42
|
-
|
|
43
|
-
import React from 'react';
|
|
44
|
-
import { MGHDataGrid } from 'mgh-components';
|
|
34
|
+
---
|
|
45
35
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
36
|
+
## MGHGrid (MUI-free)
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import { MGHGrid, type MGHGridColDef } from 'mgh-components';
|
|
40
|
+
|
|
41
|
+
interface Item {
|
|
42
|
+
id: number;
|
|
43
|
+
itemId: string;
|
|
44
|
+
locationId: string;
|
|
45
|
+
enterCount: number;
|
|
46
|
+
updatedAt: Date;
|
|
47
|
+
}
|
|
50
48
|
|
|
51
|
-
const columns = [
|
|
49
|
+
const columns: MGHGridColDef<Item>[] = [
|
|
52
50
|
{ field: 'itemId', headerName: 'Item', flex: 1 },
|
|
53
51
|
{ field: 'locationId', headerName: 'Location', flex: 1 },
|
|
54
|
-
{ field: 'enterCount', headerName: 'Count', type: 'number',
|
|
52
|
+
{ field: 'enterCount', headerName: 'Count', type: 'number', width: 110 },
|
|
53
|
+
{ field: 'updatedAt', headerName: 'Updated', type: 'dateTime', width: 170 },
|
|
55
54
|
];
|
|
56
55
|
|
|
57
|
-
export default function ExampleGrid() {
|
|
56
|
+
export default function ExampleGrid({ rows, loading }: { rows: Item[]; loading: boolean }) {
|
|
58
57
|
return (
|
|
59
|
-
<
|
|
58
|
+
<MGHGrid<Item>
|
|
60
59
|
header="Finished Goods - On Hand"
|
|
61
60
|
rows={rows}
|
|
62
61
|
columns={columns}
|
|
62
|
+
loading={loading}
|
|
63
|
+
boxStyle={{ height: '70vh' }}
|
|
64
|
+
checkboxSelection
|
|
65
|
+
columnOrderStorageKey="fg_onhand_column_order"
|
|
66
|
+
columnVisibilityStorageKey="fg_onhand_column_visibility"
|
|
63
67
|
noRowsText="No finished goods availability submissions found within your filters."
|
|
64
|
-
boxSx={{ height: '70vh' }}
|
|
65
68
|
initialState={{
|
|
66
|
-
pinnedColumns: { left: ['itemId']
|
|
69
|
+
pinnedColumns: { left: ['itemId'] },
|
|
70
|
+
sorting: { sortModel: [{ field: 'enterCount', sort: 'desc' }] },
|
|
67
71
|
}}
|
|
68
72
|
/>
|
|
69
73
|
);
|
|
70
74
|
}
|
|
71
75
|
```
|
|
72
76
|
|
|
73
|
-
|
|
77
|
+
Styles are injected automatically the first time a grid mounts – there is no CSS file to import.
|
|
78
|
+
|
|
79
|
+
### Features
|
|
80
|
+
|
|
81
|
+
| Area | Details |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| Columns | `width`, `minWidth`, `maxWidth`, `flex`, `align`, `headerAlign`, `valueGetter`, `valueFormatter`, `renderCell`, `renderHeader`, `cellClassName`, `headerClassName`, `description` |
|
|
84
|
+
| Column types | `string`, `number`, `date`, `dateTime`, `boolean`, `singleSelect` (`valueOptions`), `actions` (`getActions` + `MGHGridActionsCellItem`) |
|
|
85
|
+
| Sorting | Click header (multi-sort with **Shift**), `sortModel` / `onSortModelChange`, `sortComparator`, `sortingOrder` |
|
|
86
|
+
| Filtering | Filter panel (per-type operators, AND/OR), quick filter (debounced search), `filterModel` / `onFilterModelChange`, custom `filterOperators`, `getApplyQuickFilterFn` |
|
|
87
|
+
| Pagination | `pagination`, `pageSize`, `pageSizeOptions`, `paginationModel` / `onPaginationModelChange` |
|
|
88
|
+
| Selection | `checkboxSelection`, `checkboxSelectionVisibleOnly`, `disableRowSelectionOnClick`, `disableMultipleRowSelection`, `isRowSelectable`, `rowSelectionModel` (`{ type: 'include', ids: Set }`, arrays also accepted), `keepNonExistentRowsSelected` |
|
|
89
|
+
| Column management | Columns panel, column menu, drag-and-drop reorder, resize (double-click the handle to autosize), pin left/right, hide/show. Persist with `columnVisibilityStorageKey`, `columnOrderStorageKey`, `columnWidthStorageKey`, `pinnedColumnsStorageKey` |
|
|
90
|
+
| Rows | `getRowId`, `getRowClassName`, `getRowHeight` (number or `'auto'`), `rowHeight`, `density` (`compact` default), `pinnedRows` (top/bottom), `onRowClick`, `onRowDoubleClick`, `onCellClick` |
|
|
91
|
+
| Detail panels | `getDetailPanelContent`, `getDetailPanelHeight` (number or `'auto'`), `detailPanelExpandedRowIds` |
|
|
92
|
+
| Row grouping | `rowGroupingModel` / `onRowGroupingModelChange`, `defaultGroupingExpansionDepth`, `groupingColDef`, "Group by" in the column menu |
|
|
93
|
+
| Aggregation | `aggregationModel` (`sum`, `avg`, `min`, `max`, `size` or custom `aggregationFunctions`), footer row and/or group rows (`aggregationPosition`) |
|
|
94
|
+
| Editing | `editable` columns, double-click / Enter to edit, `processRowUpdate`, `onProcessRowUpdateError`, `valueParser`, `valueSetter`, `renderEditCell`, `isCellEditable` |
|
|
95
|
+
| Export | CSV, real `.xlsx` (no library), print. Export menu in the toolbar, or `apiRef.current.exportDataAsCsv()` / `exportDataAsExcel()` / `exportDataAsPrint()` |
|
|
96
|
+
| Performance | Row virtualization when row heights are known (`disableVirtualization` to opt out), `autoHeight` |
|
|
97
|
+
| Keyboard | Arrow keys, Home/End, PageUp/PageDown, Enter/F2 to edit, Space to select, Ctrl/Cmd+A |
|
|
98
|
+
| Theming | `themeMode="light" | "dark"`, `themeVars` (any `--mgh-grid-*` CSS variable), `className`/`style` props |
|
|
99
|
+
| Slots | `slots.toolbar`, `slots.footer`, `slots.noRowsOverlay`, `slots.loadingOverlay` + `slotProps` |
|
|
100
|
+
|
|
101
|
+
### Toolbar
|
|
102
|
+
|
|
103
|
+
The default toolbar mirrors the legacy one: Columns, Filters, Export (CSV / Excel / Print), an optional
|
|
104
|
+
density selector, an optional centre slot (`renderDateRange`), extra buttons and the expanding quick filter.
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
<MGHGrid
|
|
108
|
+
rows={rows}
|
|
109
|
+
columns={columns}
|
|
110
|
+
toolbarProps={{
|
|
111
|
+
showDensitySelector: true,
|
|
112
|
+
renderDateRange: <MyDateRangePicker />,
|
|
113
|
+
renderOtherButtons: <button>Refresh</button>,
|
|
114
|
+
customMenuItem: [
|
|
115
|
+
<MGHGridExportMenuItem key="pdf" onClick={() => downloadPdf()}>
|
|
116
|
+
Download as PDF
|
|
117
|
+
</MGHGridExportMenuItem>,
|
|
118
|
+
],
|
|
119
|
+
csvOptions: { fileName: 'on-hand', utf8WithBom: true },
|
|
120
|
+
}}
|
|
121
|
+
/>
|
|
122
|
+
```
|
|
74
123
|
|
|
75
|
-
|
|
124
|
+
Custom toolbars can use the building blocks (`MGHGridColumnsButton`, `MGHGridFiltersButton`,
|
|
125
|
+
`MGHGridExportMenu`, `MGHGridDensitySelector`, `MGHGridQuickFilter`) and `useMGHGridApiContext()`:
|
|
76
126
|
|
|
77
127
|
```tsx
|
|
78
|
-
import {
|
|
79
|
-
import { useSettingsContext } from 'src/contexts/SettingsContext';
|
|
128
|
+
import { MGHGrid, MGHGridQuickFilter, MGHGridExportMenu, useMGHGridApiContext } from 'mgh-components';
|
|
80
129
|
|
|
81
|
-
|
|
130
|
+
function MyToolbar() {
|
|
131
|
+
const api = useMGHGridApiContext();
|
|
82
132
|
return (
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
noRowsOverlay: {
|
|
89
|
-
text: 'No finished goods availability submissions found within your filters.',
|
|
90
|
-
useSettingsContext,
|
|
91
|
-
},
|
|
92
|
-
}}
|
|
93
|
-
/>
|
|
133
|
+
<div className="mgh-grid-toolbar">
|
|
134
|
+
<button onClick={() => api.setRowSelectionModel([])}>Clear selection</button>
|
|
135
|
+
<MGHGridExportMenu />
|
|
136
|
+
<MGHGridQuickFilter />
|
|
137
|
+
</div>
|
|
94
138
|
);
|
|
95
139
|
}
|
|
140
|
+
|
|
141
|
+
<MGHGrid rows={rows} columns={columns} slots={{ toolbar: MyToolbar }} />;
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
> The default toolbar component is exported as `MGHGridDefaultToolbar` because the legacy
|
|
145
|
+
> `MGHGridToolbar` export name belongs to the MUI-based grid.
|
|
146
|
+
|
|
147
|
+
### Imperative API
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
import { MGHGrid, useMGHGridApiRef } from 'mgh-components';
|
|
151
|
+
|
|
152
|
+
const apiRef = useMGHGridApiRef<Item>();
|
|
153
|
+
|
|
154
|
+
<MGHGrid apiRef={apiRef} rows={rows} columns={columns} />;
|
|
155
|
+
|
|
156
|
+
apiRef.current?.getSelectedRows(); // Map<id, row>
|
|
157
|
+
apiRef.current?.getSortedRows(); // filtered + sorted rows
|
|
158
|
+
apiRef.current?.exportDataAsExcel({ fileName: 'report' });
|
|
159
|
+
apiRef.current?.setQuickFilterValues(['LOC-1']);
|
|
160
|
+
apiRef.current?.setRowGroupingModel(['category']);
|
|
161
|
+
apiRef.current?.state; // current models (sort, filter, pagination, …)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Migrating from `MGHDataGrid`
|
|
165
|
+
|
|
166
|
+
1. Change the import: `MGHDataGrid` → `MGHGrid`, `GridColDef` → `MGHGridColDef`.
|
|
167
|
+
2. Column definitions keep the MUI v8 signatures (`valueGetter(value, row, column, api)`,
|
|
168
|
+
`valueFormatter(value, row, column, api)`, `renderCell(params)`), so most columns work unchanged.
|
|
169
|
+
3. `sx`, `cardSx` and `boxSx` are accepted but treated as plain inline styles (`cardStyle`, `boxStyle`,
|
|
170
|
+
`style` are the preferred names). Nested MUI selectors such as `'& .MuiDataGrid-row'` are ignored.
|
|
171
|
+
4. `rowSelectionModel` uses the same shape as MUI v8 (`{ type: 'include', ids: Set }`).
|
|
172
|
+
5. `slots.toolbar` components must be rewritten without MUI internals; use the exported building blocks.
|
|
173
|
+
6. Custom export menu items receive a `hideMenu` prop (like MUI) – use `MGHGridExportMenuItem`.
|
|
174
|
+
7. The no-rows overlay no longer needs `useSettingsContext`; pass `themeMode="dark"` to the grid instead.
|
|
175
|
+
|
|
176
|
+
### Theming
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
<MGHGrid
|
|
180
|
+
themeMode="dark"
|
|
181
|
+
themeVars={{ '--mgh-grid-primary': '#00a76f', '--mgh-grid-radius': '8px' }}
|
|
182
|
+
…
|
|
183
|
+
/>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Or globally in your CSS:
|
|
187
|
+
|
|
188
|
+
```css
|
|
189
|
+
.mgh-grid-card {
|
|
190
|
+
--mgh-grid-primary: #00a76f;
|
|
191
|
+
--mgh-grid-font-family: 'Public Sans', sans-serif;
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Legacy: MGHDataGrid (MUI X Premium)
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
import { MGHDataGrid } from 'mgh-components';
|
|
201
|
+
|
|
202
|
+
<MGHDataGrid
|
|
203
|
+
header="Finished Goods - On Hand"
|
|
204
|
+
rows={rows}
|
|
205
|
+
columns={columns}
|
|
206
|
+
boxSx={{ height: '70vh' }}
|
|
207
|
+
initialState={{ pinnedColumns: { left: ['itemId'], right: ['enterCount'] } }}
|
|
208
|
+
/>;
|
|
96
209
|
```
|
|
97
210
|
|
|
98
211
|
## Components
|
|
99
212
|
|
|
100
|
-
- `
|
|
101
|
-
|
|
102
|
-
- `CustomNoRowsOverlay`
|
|
213
|
+
- `MGHGrid` (+ `MGHGridDefaultToolbar`, `MGHGridQuickFilter`, `MGHGridExportMenu`, `MGHGridExportMenuItem`,
|
|
214
|
+
`MGHGridActionsCellItem`, `MGHGridNoRowsOverlay`, `MGHGridIcons`, `useMGHGridApiRef`, `useMGHGridApiContext`)
|
|
215
|
+
- `MGHDataGrid`, `MGHGridToolbar`, `DataGridQuickFilter`, `CustomNoRowsOverlay`, `CustomGridToolbarExport` (legacy, MUI)
|
|
216
|
+
- `Label`, `ConfirmDialog`, `ExportingDialog`, `Iconify`
|
|
File without changes
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import type { ComponentProps, ComponentType } from 'react';
|
|
2
|
+
import Box from '@mui/material/Box';
|
|
1
3
|
import { LabelColor, LabelVariant } from './types';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
interface StyledLabelOwnerState {
|
|
5
|
+
color: LabelColor;
|
|
6
|
+
variant: LabelVariant;
|
|
7
|
+
}
|
|
8
|
+
export declare const StyledLabel: ComponentType<ComponentProps<typeof Box> & {
|
|
9
|
+
ownerState: StyledLabelOwnerState;
|
|
10
|
+
}>;
|
|
11
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { JSX } from 'react';
|
|
2
2
|
import dayjs from 'dayjs';
|
|
3
3
|
import { DateRange } from '@mui/x-date-pickers-pro';
|
|
4
|
-
import { GridInitialStatePremium } from '@mui/x-data-grid-premium
|
|
4
|
+
import { GridInitialState as GridInitialStatePremium } from '@mui/x-data-grid-premium';
|
|
5
5
|
import { Theme, SxProps } from '@mui/material';
|
|
6
6
|
import { GridColDef, GridRowParams, GridToolbarProps, GridEventListener, GridSlotsComponent, GridCallbackDetails, GridRowHeightParams, GridCsvExportOptions, GridRowSelectionModel, ToolbarPropsOverrides, GridRowClassNameParams, GridExcelExportOptions, GridPrintExportOptions, GridSlotsComponentsProps, GridExportDisplayOptions, GridRowHeightReturnValue, GridColumnVisibilityModel, GridPinnedRowsProp } from '@mui/x-data-grid-premium';
|
|
7
7
|
interface CustomToolbarProps {
|
|
@@ -62,8 +62,9 @@ interface MGHDataGridProps {
|
|
|
62
62
|
onColumnOrderChange?: GridEventListener<'columnOrderChange'> | undefined;
|
|
63
63
|
defaultGroupingExpansionDepth?: number;
|
|
64
64
|
pinnedRows?: GridPinnedRowsProp;
|
|
65
|
+
keepNonExistentRowsSelected?: boolean;
|
|
65
66
|
}
|
|
66
|
-
export default function MGHDataGrid({ header, rows, columns, onRowClick, onRowDoubleClick, pagination, pageSize, slots, slotProps, toolbarProps, initialState, pageSizeOptions, sx, cardSx, 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, }: MGHDataGridProps): JSX.Element;
|
|
67
|
+
export default function MGHDataGrid({ header, rows, columns, onRowClick, onRowDoubleClick, pagination, pageSize, slots, slotProps, toolbarProps, initialState, pageSizeOptions, sx, cardSx, 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, }: MGHDataGridProps): JSX.Element;
|
|
67
68
|
interface MGHGridToolbarProps {
|
|
68
69
|
showColumnsButton?: boolean;
|
|
69
70
|
showFilterButton?: boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { JSX } from 'react';
|
|
2
2
|
import { SxProps, Theme } from '@mui/material';
|
|
3
3
|
import { DataGridPremiumProps, GridColDef, GridSlotsComponentsProps, GridToolbarProps, ToolbarPropsOverrides, GridColumnVisibilityModel } from '@mui/x-data-grid-premium';
|
|
4
|
-
import { GridInitialStatePremium } from '@mui/x-data-grid-premium
|
|
4
|
+
import { GridInitialState as GridInitialStatePremium } from '@mui/x-data-grid-premium';
|
|
5
5
|
export interface MGHDataGridProps extends DataGridPremiumProps {
|
|
6
6
|
rows: any[];
|
|
7
7
|
columns: GridColDef[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { MGHGridProps, MGHGridValidRowModel } from './MGHGrid.types';
|
|
3
|
+
declare function MGHGrid<R extends MGHGridValidRowModel = any>(props: MGHGridProps<R>): React.JSX.Element;
|
|
4
|
+
declare namespace MGHGrid {
|
|
5
|
+
var displayName: string;
|
|
6
|
+
}
|
|
7
|
+
export default MGHGrid;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const MGH_GRID_STYLE_ID = "mgh-grid-styles";
|
|
2
|
+
/**
|
|
3
|
+
* Stylesheet for MGHGrid. It is injected once into <head> the first time a grid mounts,
|
|
4
|
+
* so consumers do not need a CSS loader. All colours are CSS variables so the look can be
|
|
5
|
+
* customised globally (by redefining `--mgh-grid-*` on `.mgh-grid-card`) or per instance
|
|
6
|
+
* through the `themeVars` prop.
|
|
7
|
+
*/
|
|
8
|
+
export declare 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.mgh-grid-card *, .mgh-grid-card *::before, .mgh-grid-card *::after,\n.mgh-grid-popover *, .mgh-grid-popover *::before, .mgh-grid-popover *::after { box-sizing: border-box; }\n.mgh-grid-card--plain { box-shadow: none; border-radius: 0; background: transparent; }\n\n/* ---- card header ---- */\n.mgh-grid-card-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 0 8px 0 0; flex-wrap: wrap; }\n.mgh-grid-card-title { padding: 24px 24px 0; margin: 0 0 16px; font-size: 1.125rem; font-weight: 700; line-height: 1.5556; }\n.mgh-grid-card-header-center { flex: 1 1 auto; display: flex; align-items: center; }\n.mgh-grid-card-header-end { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; justify-content: flex-end; }\n@media (max-width: 599.95px) { .mgh-grid-card-header-end { gap: 8px; } }\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";
|
|
9
|
+
/** Injects the MGHGrid stylesheet once per document. Safe on the server (no-op). */
|
|
10
|
+
export declare const useMGHGridStyles: () => void;
|