@opencorestack/opengridx 3.8.1 → 3.9.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/CHANGELOG.md +24 -0
- package/dist/index.d.ts +340 -1
- package/dist/opengridx.css +1 -1
- package/dist/opengridx.es.js +7529 -7285
- package/dist/opengridx.es.js.map +1 -1
- package/dist/opengridx.umd.js +16 -16
- package/dist/opengridx.umd.js.map +1 -1
- package/docs/API_REFERENCE.md +93 -4
- package/docs/customization/theming.md +11 -2
- package/docs/features/ai-toolkit.md +1 -1
- package/lib/components/AiAssistant/GridAiAssistantPanel.tsx +16 -14
- package/lib/components/Cell/CellErrorBoundary.tsx +17 -10
- package/lib/components/CellSelectionStats/CellSelectionStats.tsx +5 -3
- package/lib/components/ColumnResizeHandle/ColumnResizeHandle.tsx +3 -1
- package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.tsx +6 -4
- package/lib/components/DataGrid/GridAggregationFooter.tsx +3 -1
- package/lib/components/DataGrid/GridErrorOverlay.tsx +4 -2
- package/lib/components/DataGrid/GridListView.tsx +7 -5
- package/lib/components/DataGrid/GridLiveRegion.tsx +5 -3
- package/lib/components/DataGrid/GridLoadingOverlay.tsx +3 -1
- package/lib/components/DataGrid/GridPinnedRows.tsx +1 -1
- package/lib/components/DataGrid/GridRoot.tsx +8 -1
- package/lib/components/DataGrid/GridStandaloneColumnPanel.tsx +3 -1
- package/lib/components/DataGrid/GridViewport.tsx +3 -1
- package/lib/components/DataGrid/GridVirtualRows.tsx +1 -1
- package/lib/components/DataGrid/gridLocaleContext.ts +13 -0
- package/lib/components/FilterPanel/FilterPanel.tsx +18 -17
- package/lib/components/Header/ColumnMenu.css +5 -5
- package/lib/components/Header/ColumnMenu.tsx +17 -15
- package/lib/components/Header/Header.tsx +8 -6
- package/lib/components/HeaderFilter/HeaderFilterRow.tsx +3 -1
- package/lib/components/ListView/ListViewRow.tsx +3 -1
- package/lib/components/Pagination/Pagination.tsx +15 -18
- package/lib/components/QuickFilter/QuickFilter.tsx +5 -2
- package/lib/components/Row/Row.tsx +5 -3
- package/lib/components/Toolbar/GlobalSearch.tsx +6 -3
- package/lib/components/Toolbar/GridToolbar.tsx +35 -29
- package/lib/components/Toolbar/PivotPanel.tsx +26 -24
- package/lib/components/ui/Checkbox.css +5 -5
- package/lib/components/ui/DragHandleIcon.tsx +3 -1
- package/lib/components/ui/ExpandIcon.css +3 -3
- package/lib/components/ui/ExpandIcon.tsx +3 -1
- package/lib/hooks/core/useGridRowInteractions.ts +13 -3
- package/lib/hooks/core/useGridToolbarStack.ts +2 -2
- package/lib/hooks/core/useGridVirtualization.ts +40 -25
- package/lib/hooks/core/useShallowStableValue.ts +29 -0
- package/lib/hooks/features/useGridAiAssistant.ts +52 -22
- package/lib/theme/DataGridThemeProvider.tsx +9 -0
- package/lib/theme/types.ts +18 -0
- package/lib/types/locale.ts +344 -0
- package/lib/utils/gridLocale.ts +241 -0
- package/llms.txt +3 -1
- package/package.json +1 -1
package/docs/API_REFERENCE.md
CHANGED
|
@@ -243,7 +243,7 @@ Public CSS: `ogx__cell-fill-handle` (24 × 24 px hit area in the corner cell; th
|
|
|
243
243
|
|
|
244
244
|
| Prop | Type | Default | Description |
|
|
245
245
|
| :--- | :--- | :--- | :--- |
|
|
246
|
-
| `localeText` | `GridLocaleText` | — | Override user-visible strings: the Pagination labels, the empty-state label (`noRowsLabel`, which wins over the `noRowsLabel` prop), the cell-range announcement, the Ask AI button (`aiAssistantButton`)
|
|
246
|
+
| `localeText` | `GridLocaleText` | — | Override user-visible strings: the Pagination labels, the empty-state label (`noRowsLabel`, which wins over the `noRowsLabel` prop), the cell-range announcement, the Ask AI button (`aiAssistantButton`), the header filter row (`headerFilter*`, v3.6) and, since v3.9, every other built-in string (toolbar, column menu, filter, columns, pivot and AI panels, rows, overlays, live region). See [`GridLocaleText`](#gridlocaletext). |
|
|
247
247
|
|
|
248
248
|
#### Imperative Ref
|
|
249
249
|
|
|
@@ -663,8 +663,8 @@ Context provider for overriding the grid's visual system.
|
|
|
663
663
|
- **`colors`**: `primary`, `primaryDark`, `primaryLight`, `primaryFocus`, `secondary*`, `success`, `warning`, `error`, `info`, `white`, `black`, `gray` (`{ 50 … 900 }`). Toolbar, menu, selection and focus accents derive from `primary*` unless set directly.
|
|
664
664
|
- **`typography`**: `fontFamily`, `fontFamilyMono`, `fontSizeXs` … `fontSizeXl`.
|
|
665
665
|
- **`spacing`**: `xs` … `xxl`. **`borders`**: `widthThin/Medium/Thick`, `radiusSm` … `radiusXl`, `color`, `colorHover`. **`shadows`**: `sm` … `xl`.
|
|
666
|
-
- **`grid`**: surfaces (`background`, `borderColor`, `headerBackground`, `headerText`, `headerHoverBackground`, `headerSortedBackground`, `rowText`, `rowHoverBackground`, `rowAlternateBackground`, `rowSelectedBackground`, `rowSelectedHoverBackground`, `cellFocusBorder`, `rangeBackground`, `rangeBorder` (v3.3), `pinnedLeftShadow`, `pinnedRightShadow`, `checkboxBg`, `checkboxBorder`), sizing (`rowHeightCompact`, `rowHeightStandard`, `rowHeightComfortable`, `headerHeight` in px, read by the grid's layout; the `rowHeight` / `headerHeight` props win), `cellPaddingX`, `cellPaddingY`, `cellFontSize`, `headerFontSize`; v3.7: fonts (`headerFontFamily`, `headerFontWeight`, `cellFontFamily`, `cellFontWeight`), `headerPaddingX`, outer `borderWidth` and `borderRadius`, dividers (`columnDividerWidth`, `headerColumnDividerWidth`, `rowDividerWidth`, `columnDividerColor`, `rowDividerColor`; `0` hides a divider).
|
|
667
|
-
- **`overlays`**: colours (`background`, `text`, `border`, `shadow`, `item*`) and, v3.7, `fontFamily`, `fontWeight`, `fontSize` for menus and panels.
|
|
666
|
+
- **`grid`**: surfaces (`background`, `borderColor`, `headerBackground`, `headerText`, `headerHoverBackground`, `headerSortedBackground`, `rowText`, `rowHoverBackground`, `rowAlternateBackground`, `rowSelectedBackground`, `rowSelectedHoverBackground`, `cellFocusBorder`, `rangeBackground`, `rangeBorder` (v3.3), `pinnedLeftShadow`, `pinnedRightShadow`, `checkboxBg`, `checkboxBorder`; v3.9: `checkboxCheckedBackground`, `checkboxCheckmark`, `expandIconColor`, `expandIconHoverColor`), sizing (`rowHeightCompact`, `rowHeightStandard`, `rowHeightComfortable`, `headerHeight` in px, read by the grid's layout; the `rowHeight` / `headerHeight` props win), `cellPaddingX`, `cellPaddingY`, `cellFontSize`, `headerFontSize`; v3.7: fonts (`headerFontFamily`, `headerFontWeight`, `cellFontFamily`, `cellFontWeight`), `headerPaddingX`, outer `borderWidth` and `borderRadius`, dividers (`columnDividerWidth`, `headerColumnDividerWidth`, `rowDividerWidth`, `columnDividerColor`, `rowDividerColor`; `0` hides a divider).
|
|
667
|
+
- **`overlays`**: colours (`background`, `text`, `border`, `shadow`, `item*`) and, v3.7, `fontFamily`, `fontWeight`, `fontSize` for menus and panels; v3.9: `itemIndicatorColor` (the selection dot), `itemSelectedIcon`, `iconColor`, `sectionLabelText`, `dividerColor`.
|
|
668
668
|
- **`toolbar`**, **`scrollbar`** (`thumbColor`, `trackColor`, `size`), **`skeleton`** (`baseColor`, `highlightColor`), **`transitions`**.
|
|
669
669
|
|
|
670
670
|
#### Theme types
|
|
@@ -906,7 +906,7 @@ interface GridPivotValueField {
|
|
|
906
906
|
|
|
907
907
|
### `GridLocaleText`
|
|
908
908
|
|
|
909
|
-
Override user-visible strings
|
|
909
|
+
Override the grid's user-visible strings (visible text, `aria-label`, `title`, placeholder). All fields are optional; each one left out keeps its English default. Strings that contain a value (a header, a row id, a count) are functions.
|
|
910
910
|
|
|
911
911
|
```typescript
|
|
912
912
|
interface GridLocaleText {
|
|
@@ -931,9 +931,98 @@ interface GridLocaleText {
|
|
|
931
931
|
headerFilterTrue?: string; // "Yes"
|
|
932
932
|
headerFilterFalse?: string; // "No"
|
|
933
933
|
headerFilterOperators?: Partial<Record<GridFilterOperator, string>>; // operator names
|
|
934
|
+
|
|
935
|
+
// ── v3.9: every other UI string (default English shown) ──
|
|
936
|
+
// Grid, list view, overlays, live region
|
|
937
|
+
gridLabel; listViewLabel; // "Data grid", "Data grid list view" (the aria-label prop wins)
|
|
938
|
+
listViewItemCount(n); listViewPage(p, pc); listViewSelectedCount(n); // "3 items", "page 1 of 2", "2 selected"
|
|
939
|
+
loadingLabel; liveRegionLoading; // "Loading data", "Loading data..."
|
|
940
|
+
liveRegionError(message); liveRegionRowsFound(n); // "Error: …", "4 rows found"
|
|
941
|
+
errorOverlayTitle; errorOverlayRetry; // "Oops! Something went wrong", "Retry"
|
|
942
|
+
aggregationFooterLabel; // "Aggregation totals"
|
|
943
|
+
cellErrorLabel(field); cellErrorTooltip; // "Error in cell: name", "Render error"
|
|
944
|
+
// Header
|
|
945
|
+
headerRowReorderLabel; headerRowReorderTooltip; headerDetailPanelLabel;
|
|
946
|
+
headerSelectAllLabel; headerDeselectAllLabel; // "Select all rows", "Deselect all rows"
|
|
947
|
+
headerSortDescription(direction, priority, total); // "Sorted ascending, sort priority 1 of 2"
|
|
948
|
+
headerColumnMenuButtonLabel(header); // "Open column menu for Name"
|
|
949
|
+
headerColumnResizeLabel(field); headerFilterNoFilterLabel(header);
|
|
950
|
+
// Rows
|
|
951
|
+
rowSelectLabel(id); rowDeselectLabel(id); // "Select row 1", "Deselect row 1"
|
|
952
|
+
rowReorderLabel; rowDetailPanelExpandLabel; rowDetailPanelCollapseLabel; rowExpandLabel; rowCollapseLabel;
|
|
953
|
+
// Column menu
|
|
954
|
+
columnMenuLabel(header); columnMenuSortAscending; columnMenuSortDescending; columnMenuUnsort;
|
|
955
|
+
columnMenuPinColumn; columnMenuPinLeft; columnMenuPinLeftLabel; columnMenuPinRight; columnMenuPinRightLabel;
|
|
956
|
+
columnMenuUnpin; columnMenuUnpinLabel; columnMenuHideColumn; columnMenuHideColumnLabel(header);
|
|
957
|
+
columnMenuManageColumns; columnMenuManageColumnsLabel;
|
|
958
|
+
// Columns panel
|
|
959
|
+
columnsPanelSearchPlaceholder; columnsPanelDragToReorder; columnsPanelShowHideAll; columnsPanelReset; columnsPanelClose;
|
|
960
|
+
// Filter panel
|
|
961
|
+
filterPanelValueLabel(header); filterPanelOperatorLabel(header); filterPanelClearLabel(header); filterPanelClearTooltip;
|
|
962
|
+
filterPanelAny; filterPanelTrue; filterPanelFalse; filterPanelNumberPlaceholder; filterPanelValuePlaceholder;
|
|
963
|
+
filterPanelMatch; filterPanelAnd; filterPanelOr; filterPanelHiddenConditions(n); filterPanelNoColumns;
|
|
964
|
+
filterPanelOperators; // Partial<Record<GridFilterOperator, string>>, default: the operator id
|
|
965
|
+
// Toolbar and search (toolbarSearchPlaceholder also for QuickFilter)
|
|
966
|
+
toolbarLabel; toolbarSearchPlaceholder; toolbarSearchLabel; toolbarSearchClear;
|
|
967
|
+
toolbarColumns; toolbarColumnsLabel; toolbarColumnsPanelLabel;
|
|
968
|
+
toolbarFilters; toolbarFiltersLabel; toolbarFiltersActive; toolbarFiltersClearAll; toolbarFiltersClearAllTooltip;
|
|
969
|
+
toolbarFiltersClose; toolbarFiltersCloseTooltip; toolbarFiltersCloseLabel;
|
|
970
|
+
toolbarPivot; toolbarPivotLabel; toolbarPivotActive;
|
|
971
|
+
toolbarSummaries; toolbarSummariesLabel; toolbarSummariesActive(n); toolbarSummariesPanelLabel;
|
|
972
|
+
toolbarSummariesClearAll; toolbarSummariesClearAllTooltip; toolbarSummariesEmpty;
|
|
973
|
+
toolbarSummariesEmptyHintBefore; toolbarSummariesEmptyHintAfter;
|
|
974
|
+
toolbarAggregationFunctions; // Partial<Record<string, string>>, default: the function id
|
|
975
|
+
// Pivot panel
|
|
976
|
+
pivotPanelLabel; pivotMode; pivotReset; pivotResetTooltip;
|
|
977
|
+
pivotRowFields; pivotColumnFields; pivotValueFields;
|
|
978
|
+
pivotRowFieldsPlaceholder; pivotColumnFieldsPlaceholder; pivotValueFieldsPlaceholder;
|
|
979
|
+
pivotRemoveTooltip(header); pivotRemoveRowLabel(header); pivotRemoveColumnLabel(header); pivotRemoveValueLabel(header, fn);
|
|
980
|
+
pivotAggregationTooltip; pivotAggregationLabel(header);
|
|
981
|
+
pivotAggregationFunctions; // Partial<Record<string, string>>, default: the id in upper case
|
|
982
|
+
pivotAvailableFields; pivotAllFieldsInUse; pivotAddRow; pivotAddColumn; pivotAddValue;
|
|
983
|
+
pivotAddRowTooltip; pivotAddColumnTooltip; pivotAddValueTooltip;
|
|
984
|
+
pivotAddRowLabel(header); pivotAddColumnLabel(header); pivotAddValueLabel(header);
|
|
985
|
+
// AI assistant panel (aiAssistant.placeholder wins over aiAssistantPlaceholder)
|
|
986
|
+
aiAssistantTitle; aiAssistantClose; aiAssistantPromptLabel; aiAssistantPlaceholder;
|
|
987
|
+
aiAssistantStartDictation; aiAssistantStopDictation; aiAssistantAsk; aiAssistantStop; aiAssistantSuggestions;
|
|
988
|
+
aiAssistantAppliedChanges; aiAssistantRemoveChange(label); aiAssistantUndo; aiAssistantIgnored; aiAssistantIgnoredItem(message);
|
|
989
|
+
aiAssistantEarlier; aiAssistantThinking; aiAssistantStopped; aiAssistantUndone; aiAssistantChangeRemoved;
|
|
990
|
+
aiAssistantApplied(applied, ignored); aiAssistantNotValidated; aiAssistantFailed(message); aiAssistantUnknownError;
|
|
991
|
+
// Pagination buttons
|
|
992
|
+
paginationLabel; paginationFirstPageLabel; paginationFirstPageTooltip; paginationPreviousPageLabel;
|
|
993
|
+
paginationPreviousPageTooltip; paginationNextPageLabel; paginationNextPageTooltip;
|
|
994
|
+
paginationLastPageLabel; paginationLastPageTooltip;
|
|
995
|
+
// Cell selection stats bar
|
|
996
|
+
cellSelectionStatsCount; cellSelectionStatsSum; cellSelectionStatsAverage;
|
|
934
997
|
}
|
|
935
998
|
```
|
|
936
999
|
|
|
1000
|
+
Each key's English default and parameter types are documented on `GridLocaleText` in `lib/types/locale.ts` (shown by editors on hover).
|
|
1001
|
+
|
|
1002
|
+
### Locale text for every UI string (v3.9)
|
|
1003
|
+
|
|
1004
|
+
Since v3.9 every built-in string of the grid goes through `localeText`: the toolbar and its panels, the column menu, the filter, columns, pivot and AI assistant panels, the row and select-all checkboxes, the pagination buttons, the loading and error overlays, the aggregation footer and the live-region announcements. Pass only the keys you translate; the rest stay English.
|
|
1005
|
+
|
|
1006
|
+
```tsx
|
|
1007
|
+
<DataGrid
|
|
1008
|
+
rows={rows}
|
|
1009
|
+
columns={columns}
|
|
1010
|
+
slots={{ toolbar: GridToolbar }}
|
|
1011
|
+
localeText={{
|
|
1012
|
+
toolbarSearchPlaceholder: 'Rechercher…',
|
|
1013
|
+
columnMenuSortAscending: 'Tri croissant',
|
|
1014
|
+
columnMenuHideColumnLabel: (header) => `Masquer la colonne ${header}`,
|
|
1015
|
+
filterPanelOperators: { contains: 'contient' },
|
|
1016
|
+
rowSelectLabel: (id) => `Sélectionner la ligne ${id}`,
|
|
1017
|
+
}}
|
|
1018
|
+
/>
|
|
1019
|
+
```
|
|
1020
|
+
|
|
1021
|
+
- The strings reach portalled menus and panels through React context, so a custom toolbar slot that renders the built-in `GridToolbar` is translated too.
|
|
1022
|
+
- Components used outside a grid (`ColumnVisibilityPanel`, `GridToolbar`, `FilterPanel`, `Pagination`, `QuickFilter`) show English. Their own props (`placeholder`, `aiAssistantLabel`, `Pagination`'s `localeText`) still win.
|
|
1023
|
+
- Not covered: the grouping column's default header (`'Group'`, set `groupingColDef.headerName`), pivot's `'Grand Total'` row label, export file contents, the AI change chips' labels, and developer console warnings.
|
|
1024
|
+
- An inline object of strings is fine: while it holds the same entries as on the previous render (records such as `filterPanelOperators` compared one level deep), the grid keeps the resolved strings and the rows are not re-rendered. Functions are compared by identity, so define function entries (`rowSelectLabel: id => …`) outside the render, or keep the whole object in a module constant or `useMemo`.
|
|
1025
|
+
|
|
937
1026
|
### `GridRowMeta`
|
|
938
1027
|
|
|
939
1028
|
Available via `params.rowMeta` in `renderCell`. Undefined for non-hierarchy rows.
|
|
@@ -262,8 +262,12 @@ For visible gaps between cells instead of lines, set the divider colour to the g
|
|
|
262
262
|
| `--ogx-fill-handle-color` | `var(--ogx-range-border)` | `var(--ogx-range-border)` | The fill handle square (`ogx__cell-fill-handle`, v3.5). Unset in the stylesheet, where it falls back to `--ogx-range-border`; every theme of `DataGridThemeProvider` sets it to `var(--ogx-range-border)`. Theme key `grid.fillHandleColor` |
|
|
263
263
|
| `--ogx-grid-pinned-left-shadow` | `4px 0 24px...` | (darker) | Shadow on left-pinned columns |
|
|
264
264
|
| `--ogx-grid-pinned-right-shadow` | `-4px 0 24px...` | (darker) | Shadow on right-pinned columns |
|
|
265
|
-
| `--ogx-checkbox-bg` | — | `#1e293b` | Checkbox background (dark only) |
|
|
266
|
-
| `--ogx-checkbox-border` | — | `#64748b` | Checkbox border (dark only) |
|
|
265
|
+
| `--ogx-checkbox-bg` | — | `#1e293b` | Checkbox background (dark only). Theme key `grid.checkboxBg` |
|
|
266
|
+
| `--ogx-checkbox-border` | — | `#64748b` | Checkbox border (dark only). Theme key `grid.checkboxBorder` |
|
|
267
|
+
| `--ogx-checkbox-checked-bg` | primary | primary | Fill and border of a checked or indeterminate checkbox (v3.9). Theme key `grid.checkboxCheckedBackground` |
|
|
268
|
+
| `--ogx-checkbox-checkmark` | `white` | `white` | Check mark and indeterminate dash (v3.9). Theme key `grid.checkboxCheckmark` |
|
|
269
|
+
| `--ogx-expand-icon-color` | header text | header text | Expand / collapse chevron of group and tree rows (v3.9). Theme key `grid.expandIconColor` |
|
|
270
|
+
| `--ogx-expand-icon-hover-color` | row text | row text | The chevron on hover (v3.9). Theme key `grid.expandIconHoverColor` |
|
|
267
271
|
|
|
268
272
|
### Toolbar, Overlay and Scrollbar Colors
|
|
269
273
|
|
|
@@ -282,6 +286,11 @@ Read with a fallback, so a grid without a provider looks the same as before. Ins
|
|
|
282
286
|
| `--ogx-overlay-*` | `overlays.*` | white surface, gray border | Menus, panels, tooltips |
|
|
283
287
|
| `--ogx-overlay-item-selected-bg` / `-text` | `overlays.itemSelected*` | 8% primary / primary-dark | Selected menu item |
|
|
284
288
|
| `--ogx-overlay-item-danger-bg` / `-text` | `overlays.itemDanger*` | red tints | Remove-condition button in the filter panel |
|
|
289
|
+
| `--ogx-overlay-item-indicator` | `overlays.itemIndicatorColor` (v3.9) | the selected item text | Dot before the selected option of a menu group (sort, pin) |
|
|
290
|
+
| `--ogx-overlay-item-selected-icon` | `overlays.itemSelectedIcon` (v3.9) | primary | Icon of the selected menu option |
|
|
291
|
+
| `--ogx-overlay-icon` | `overlays.iconColor` (v3.9) | gray-400 | Menu item icons |
|
|
292
|
+
| `--ogx-overlay-section-label-text` | `overlays.sectionLabelText` (v3.9) | gray-400 | Menu section labels ("Pin column") |
|
|
293
|
+
| `--ogx-overlay-divider` | `overlays.dividerColor` (v3.9) | overlay border | Lines between menu sections |
|
|
285
294
|
| `--ogx-scrollbar-thumb` / `-track` / `-size` | `scrollbar.thumbColor` / `trackColor` / `size` | gray-300 / transparent / 8px | Grid viewport scrollbars |
|
|
286
295
|
| `--ogx-skeleton-base` / `-highlight` | `skeleton.baseColor` / `highlightColor` | light grays | Loading skeleton rows |
|
|
287
296
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AI Toolkit: Schema, Validator, Assistant & Agent Tools
|
|
2
2
|
|
|
3
|
-
*Since v3.4.0 (schema and validator); v3.5.0 (assistant panel, prompt handler, agent tools)* · Demos: [
|
|
3
|
+
*Since v3.4.0 (schema and validator); v3.5.0 (assistant panel, prompt handler, agent tools)* · Demos: [Grid Schema & Validator](https://opencorestack.github.io/OpenGridX/ai-schema), [AI Assistant](https://opencorestack.github.io/OpenGridX/ai-assistant)
|
|
4
4
|
|
|
5
5
|
Let users drive the grid in plain language ("paid orders over $10k in the North, biggest first") with the model your app already uses. The `@opencorestack/opengridx/ai` entry point gives you the pieces the grid can own:
|
|
6
6
|
|
|
@@ -3,6 +3,7 @@ import type { GridAiAssistantPanelProps } from '../../types';
|
|
|
3
3
|
import { Button } from '../ui/Button';
|
|
4
4
|
import { Input } from '../ui/Input';
|
|
5
5
|
import { useSpeechInput } from './useSpeechInput';
|
|
6
|
+
import { useGridLocale } from '../DataGrid/gridLocaleContext';
|
|
6
7
|
|
|
7
8
|
/** The sparkle of the Ask AI button and the panel title. */
|
|
8
9
|
export function AiSparkleIcon() {
|
|
@@ -33,6 +34,7 @@ export function GridAiAssistantPanel(props: GridAiAssistantPanelProps) {
|
|
|
33
34
|
status, statusText, message, errors, chips, history, suggestions, placeholder, voiceAvailable, canUndo,
|
|
34
35
|
submit, stop, undo, removeChip, close,
|
|
35
36
|
} = props;
|
|
37
|
+
const locale = useGridLocale();
|
|
36
38
|
const [text, setText] = useState('');
|
|
37
39
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
38
40
|
const speech = useSpeechInput(setText);
|
|
@@ -59,10 +61,10 @@ export function GridAiAssistantPanel(props: GridAiAssistantPanelProps) {
|
|
|
59
61
|
};
|
|
60
62
|
|
|
61
63
|
return (
|
|
62
|
-
<div className="ogx-ai-panel" role="dialog" aria-label=
|
|
64
|
+
<div className="ogx-ai-panel" role="dialog" aria-label={locale.aiAssistantTitle}>
|
|
63
65
|
<div className="ogx-ai-panel__header">
|
|
64
|
-
<span className="ogx-ai-panel__title"><AiSparkleIcon />
|
|
65
|
-
<Button size="small" className="ogx-ai-panel__close" aria-label=
|
|
66
|
+
<span className="ogx-ai-panel__title"><AiSparkleIcon />{locale.aiAssistantTitle}</span>
|
|
67
|
+
<Button size="small" className="ogx-ai-panel__close" aria-label={locale.aiAssistantClose} onClick={close}>×</Button>
|
|
66
68
|
</div>
|
|
67
69
|
|
|
68
70
|
<form className="ogx-ai-panel__form" onSubmit={handleSubmit}>
|
|
@@ -71,7 +73,7 @@ export function GridAiAssistantPanel(props: GridAiAssistantPanelProps) {
|
|
|
71
73
|
className="ogx-ai-panel__input"
|
|
72
74
|
value={text}
|
|
73
75
|
placeholder={placeholder}
|
|
74
|
-
aria-label=
|
|
76
|
+
aria-label={locale.aiAssistantPromptLabel}
|
|
75
77
|
autoComplete="off"
|
|
76
78
|
onChange={(event) => setText(event.target.value)}
|
|
77
79
|
/>
|
|
@@ -80,7 +82,7 @@ export function GridAiAssistantPanel(props: GridAiAssistantPanelProps) {
|
|
|
80
82
|
size="small"
|
|
81
83
|
variant="outlined"
|
|
82
84
|
className={`ogx-ai-panel__mic${speech.listening ? ' ogx-ai-panel__mic--on' : ''}`}
|
|
83
|
-
aria-label={speech.listening ?
|
|
85
|
+
aria-label={speech.listening ? locale.aiAssistantStopDictation : locale.aiAssistantStartDictation}
|
|
84
86
|
aria-pressed={speech.listening}
|
|
85
87
|
onClick={speech.toggle}
|
|
86
88
|
>
|
|
@@ -89,12 +91,12 @@ export function GridAiAssistantPanel(props: GridAiAssistantPanelProps) {
|
|
|
89
91
|
)}
|
|
90
92
|
{/* Separate keys: one reused <button> would turn into the submit button during the Stop click and submit again. */}
|
|
91
93
|
{running
|
|
92
|
-
? <Button key="stop" size="small" variant="outlined" onClick={thenFocusInput(stop)}>
|
|
93
|
-
: <Button key="ask" size="small" variant="contained" color="primary" type="submit" disabled={text.trim() === ''}>
|
|
94
|
+
? <Button key="stop" size="small" variant="outlined" onClick={thenFocusInput(stop)}>{locale.aiAssistantStop}</Button>
|
|
95
|
+
: <Button key="ask" size="small" variant="contained" color="primary" type="submit" disabled={text.trim() === ''}>{locale.aiAssistantAsk}</Button>}
|
|
94
96
|
</form>
|
|
95
97
|
|
|
96
98
|
{suggestions.length > 0 && (
|
|
97
|
-
<div className="ogx-ai-panel__suggestions" aria-label=
|
|
99
|
+
<div className="ogx-ai-panel__suggestions" aria-label={locale.aiAssistantSuggestions} role="group">
|
|
98
100
|
{suggestions.map((suggestion) => (
|
|
99
101
|
<button key={suggestion} type="button" className="ogx-ai-panel__suggestion" disabled={running} onClick={() => send(suggestion)}>
|
|
100
102
|
{suggestion}
|
|
@@ -108,29 +110,29 @@ export function GridAiAssistantPanel(props: GridAiAssistantPanelProps) {
|
|
|
108
110
|
|
|
109
111
|
{(chips.length > 0 || canUndo) && (
|
|
110
112
|
<div className="ogx-ai-panel__changes">
|
|
111
|
-
<ul className="ogx-ai-panel__chips" aria-label=
|
|
113
|
+
<ul className="ogx-ai-panel__chips" aria-label={locale.aiAssistantAppliedChanges}>
|
|
112
114
|
{chips.map((chip) => (
|
|
113
115
|
<li key={chip.id} className="ogx-ai-chip" data-part={chip.part}>
|
|
114
116
|
<span className="ogx-ai-chip__label">{chip.label}</span>
|
|
115
|
-
<button type="button" className="ogx-ai-chip__remove" aria-label={
|
|
117
|
+
<button type="button" className="ogx-ai-chip__remove" aria-label={locale.aiAssistantRemoveChange(chip.label)} onClick={thenFocusInput(() => removeChip(chip.id))}>×</button>
|
|
116
118
|
</li>
|
|
117
119
|
))}
|
|
118
120
|
</ul>
|
|
119
|
-
{canUndo && <Button size="small" variant="outlined" className="ogx-ai-panel__undo" onClick={thenFocusInput(undo)}>
|
|
121
|
+
{canUndo && <Button size="small" variant="outlined" className="ogx-ai-panel__undo" onClick={thenFocusInput(undo)}>{locale.aiAssistantUndo}</Button>}
|
|
120
122
|
</div>
|
|
121
123
|
)}
|
|
122
124
|
|
|
123
125
|
{errors.length > 0 && (
|
|
124
|
-
<ul className="ogx-ai-panel__errors" aria-label=
|
|
126
|
+
<ul className="ogx-ai-panel__errors" aria-label={locale.aiAssistantIgnored}>
|
|
125
127
|
{errors.map((error, i) => (
|
|
126
|
-
<li key={`${error.path}:${i}`}>{error.path ?
|
|
128
|
+
<li key={`${error.path}:${i}`}>{error.path ? locale.aiAssistantIgnoredItem(error.message) : error.message}</li>
|
|
127
129
|
))}
|
|
128
130
|
</ul>
|
|
129
131
|
)}
|
|
130
132
|
|
|
131
133
|
{history.length > 0 && (
|
|
132
134
|
<div className="ogx-ai-panel__history">
|
|
133
|
-
<div className="ogx-ai-panel__history-title">
|
|
135
|
+
<div className="ogx-ai-panel__history-title">{locale.aiAssistantEarlier}</div>
|
|
134
136
|
<ul>
|
|
135
137
|
{history.map((entry, i) => (
|
|
136
138
|
<li key={`${i}:${entry.prompt}`}>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { useGridLocale } from '../DataGrid/gridLocaleContext';
|
|
2
3
|
|
|
3
4
|
// Must live at module scope (not inline) so React sees a stable component type.
|
|
4
5
|
// Calling renderFn() here puts the throw one level BELOW CellErrorBoundary,
|
|
@@ -10,6 +11,21 @@ function CellRenderTarget({ renderFn }: { renderFn: () => React.ReactNode }) {
|
|
|
10
11
|
return <>{renderFn()}</>;
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
/** The cell content after `renderCell` threw: a warning sign labelled with the field. */
|
|
15
|
+
function CellErrorMarker({ field, message }: { field: string; message: string | undefined }) {
|
|
16
|
+
const locale = useGridLocale();
|
|
17
|
+
return (
|
|
18
|
+
<div
|
|
19
|
+
className="ogx__cell-error"
|
|
20
|
+
role="img"
|
|
21
|
+
aria-label={locale.cellErrorLabel(field)}
|
|
22
|
+
title={message ?? locale.cellErrorTooltip}
|
|
23
|
+
>
|
|
24
|
+
⚠
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
13
29
|
interface CellErrorBoundaryProps {
|
|
14
30
|
renderFn: () => React.ReactNode;
|
|
15
31
|
field: string;
|
|
@@ -59,16 +75,7 @@ export class CellErrorBoundary extends React.Component<CellErrorBoundaryProps, C
|
|
|
59
75
|
|
|
60
76
|
override render() {
|
|
61
77
|
if (this.state.hasError) {
|
|
62
|
-
return
|
|
63
|
-
<div
|
|
64
|
-
className="ogx__cell-error"
|
|
65
|
-
role="img"
|
|
66
|
-
aria-label={`Error in cell: ${this.props.field}`}
|
|
67
|
-
title={this.state.error?.message ?? 'Render error'}
|
|
68
|
-
>
|
|
69
|
-
⚠
|
|
70
|
-
</div>
|
|
71
|
-
);
|
|
78
|
+
return <CellErrorMarker field={this.props.field} message={this.state.error?.message} />;
|
|
72
79
|
}
|
|
73
80
|
return <CellRenderTarget renderFn={this.props.renderFn} />;
|
|
74
81
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { formatAggregationValue } from '../../utils/aggregation';
|
|
2
2
|
import type { GridCellSelectionStatsSlotProps } from '../../types';
|
|
3
|
+
import { useGridLocale } from '../DataGrid/gridLocaleContext';
|
|
3
4
|
|
|
4
5
|
export type CellSelectionStatsProps = GridCellSelectionStatsSlotProps & Record<string, unknown>;
|
|
5
6
|
|
|
@@ -9,21 +10,22 @@ export type CellSelectionStatsProps = GridCellSelectionStatsSlotProps & Record<s
|
|
|
9
10
|
* @since v3.3
|
|
10
11
|
*/
|
|
11
12
|
export function CellSelectionStats({ count, sum, average }: CellSelectionStatsProps) {
|
|
13
|
+
const locale = useGridLocale();
|
|
12
14
|
return (
|
|
13
15
|
<div className="ogx__cell-selection-stats">
|
|
14
16
|
<span className="ogx__cell-selection-stat">
|
|
15
|
-
<span className="ogx__cell-selection-stat-label">
|
|
17
|
+
<span className="ogx__cell-selection-stat-label">{locale.cellSelectionStatsCount}</span>
|
|
16
18
|
<span className="ogx__cell-selection-stat-value" data-stat="count">{count.toLocaleString()}</span>
|
|
17
19
|
</span>
|
|
18
20
|
{sum !== null && (
|
|
19
21
|
<span className="ogx__cell-selection-stat">
|
|
20
|
-
<span className="ogx__cell-selection-stat-label">
|
|
22
|
+
<span className="ogx__cell-selection-stat-label">{locale.cellSelectionStatsSum}</span>
|
|
21
23
|
<span className="ogx__cell-selection-stat-value" data-stat="sum">{formatAggregationValue(sum, 'sum')}</span>
|
|
22
24
|
</span>
|
|
23
25
|
)}
|
|
24
26
|
{average !== null && (
|
|
25
27
|
<span className="ogx__cell-selection-stat">
|
|
26
|
-
<span className="ogx__cell-selection-stat-label">
|
|
28
|
+
<span className="ogx__cell-selection-stat-label">{locale.cellSelectionStatsAverage}</span>
|
|
27
29
|
<span className="ogx__cell-selection-stat-value" data-stat="average">{formatAggregationValue(average, 'avg')}</span>
|
|
28
30
|
</span>
|
|
29
31
|
)}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { clampResizeWidth } from './clampResizeWidth';
|
|
3
3
|
import { isRtl, logicalArrowKey } from '../../utils/direction';
|
|
4
|
+
import { useGridLocale } from '../DataGrid/gridLocaleContext';
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
export interface ColumnResizeHandleProps {
|
|
@@ -49,6 +50,7 @@ function suppressNextClick(): void {
|
|
|
49
50
|
|
|
50
51
|
export function ColumnResizeHandle(props: ColumnResizeHandleProps) {
|
|
51
52
|
const { field, currentWidth, onResize, onAutosize, minWidth, maxWidth, edge = 'end' } = props;
|
|
53
|
+
const locale = useGridLocale();
|
|
52
54
|
const [isDragging, setIsDragging] = useState(false);
|
|
53
55
|
const activeRef = useRef<ActiveResize | null>(null);
|
|
54
56
|
|
|
@@ -164,7 +166,7 @@ export function ColumnResizeHandle(props: ColumnResizeHandleProps) {
|
|
|
164
166
|
onKeyDown={handleKeyDown}
|
|
165
167
|
role="separator"
|
|
166
168
|
aria-orientation="vertical"
|
|
167
|
-
aria-label={
|
|
169
|
+
aria-label={locale.headerColumnResizeLabel(field)}
|
|
168
170
|
aria-valuenow={Math.round(currentWidth)}
|
|
169
171
|
aria-valuemin={Math.round(Math.min(minWidth ?? 50, currentWidth))}
|
|
170
172
|
aria-valuemax={maxWidth}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useState, useMemo, useRef, useId } from 'react';
|
|
2
2
|
import { Checkbox } from '../ui/Checkbox';
|
|
3
3
|
import { Input } from '../ui/Input';
|
|
4
|
+
import { useGridLocale } from '../DataGrid/gridLocaleContext';
|
|
4
5
|
import type { GridColDef, GridRowModel, GridValidRowModel } from '../../types';
|
|
5
6
|
|
|
6
7
|
|
|
@@ -48,6 +49,7 @@ export function ColumnVisibilityPanel<R extends GridValidRowModel = GridRowModel
|
|
|
48
49
|
props: ColumnVisibilityPanelProps<R>
|
|
49
50
|
) {
|
|
50
51
|
const { columns, visibleColumns, onVisibilityChange, onShowAll, onHideAll, onColumnReorder, onColumnOrderReset, showNonHideableColumns } = props;
|
|
52
|
+
const locale = useGridLocale();
|
|
51
53
|
const [searchQuery, setSearchQuery] = useState('');
|
|
52
54
|
// Each checkbox is named by a <label htmlFor> holding the column name. (Wrapping Checkbox,
|
|
53
55
|
// which renders its own <label>, in another <label> nested labels and left the name to a
|
|
@@ -119,7 +121,7 @@ export function ColumnVisibilityPanel<R extends GridValidRowModel = GridRowModel
|
|
|
119
121
|
<Input
|
|
120
122
|
autoComplete="off"
|
|
121
123
|
inputClassName="ogx-column-visibility-panel__search-input"
|
|
122
|
-
placeholder=
|
|
124
|
+
placeholder={locale.columnsPanelSearchPlaceholder}
|
|
123
125
|
value={searchQuery}
|
|
124
126
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
125
127
|
/>
|
|
@@ -153,7 +155,7 @@ export function ColumnVisibilityPanel<R extends GridValidRowModel = GridRowModel
|
|
|
153
155
|
className="ogx-column-visibility-panel__drag-handle-wrapper"
|
|
154
156
|
draggable
|
|
155
157
|
onDragStart={handleDragStart(col.field)}
|
|
156
|
-
title=
|
|
158
|
+
title={locale.columnsPanelDragToReorder}
|
|
157
159
|
>
|
|
158
160
|
<DragHandleIcon />
|
|
159
161
|
</span>
|
|
@@ -185,7 +187,7 @@ export function ColumnVisibilityPanel<R extends GridValidRowModel = GridRowModel
|
|
|
185
187
|
onChange={handleToggleAll}
|
|
186
188
|
/>
|
|
187
189
|
<label htmlFor={`${idBase}-all`} className="ogx-column-visibility-panel__label">
|
|
188
|
-
|
|
190
|
+
{locale.columnsPanelShowHideAll}
|
|
189
191
|
</label>
|
|
190
192
|
</div>
|
|
191
193
|
<button
|
|
@@ -193,7 +195,7 @@ export function ColumnVisibilityPanel<R extends GridValidRowModel = GridRowModel
|
|
|
193
195
|
className="ogx-column-visibility-panel__reset-btn"
|
|
194
196
|
onClick={() => { onShowAll(); onColumnOrderReset?.(); }}
|
|
195
197
|
>
|
|
196
|
-
|
|
198
|
+
{locale.columnsPanelReset}
|
|
197
199
|
</button>
|
|
198
200
|
</div>
|
|
199
201
|
</div>
|
|
@@ -3,6 +3,7 @@ import { formatAggregateForColumn, isAggregationAllowed } from '../../utils/aggr
|
|
|
3
3
|
import type { GridColDef, GridAggregationModel, GridAggregationResult, GridColumnPinning } from '../../types';
|
|
4
4
|
import { calculatePinnedPositions, getPinnedEdgeFields, isColumnPinned } from '../../utils/pinning';
|
|
5
5
|
import { getRenderedColumnWidth } from '../../utils/columnWidth';
|
|
6
|
+
import { useGridLocale } from './gridLocaleContext';
|
|
6
7
|
|
|
7
8
|
const SYSTEM_COLUMN_WIDTH = 48;
|
|
8
9
|
|
|
@@ -41,6 +42,7 @@ export function GridAggregationFooter({
|
|
|
41
42
|
pinnedColumns,
|
|
42
43
|
loading = false,
|
|
43
44
|
}: GridAggregationFooterProps) {
|
|
45
|
+
const locale = useGridLocale();
|
|
44
46
|
// Same offsets as Row, so pinned totals sit exactly under their pinned body cells.
|
|
45
47
|
const pinnedOffsets = useMemo(
|
|
46
48
|
() => calculatePinnedPositions(
|
|
@@ -77,7 +79,7 @@ export function GridAggregationFooter({
|
|
|
77
79
|
<div
|
|
78
80
|
className={`ogx__aggregation-footer${loading ? ' ogx__aggregation-footer--loading' : ''}`}
|
|
79
81
|
role="row"
|
|
80
|
-
aria-label=
|
|
82
|
+
aria-label={locale.aggregationFooterLabel}
|
|
81
83
|
aria-live="polite"
|
|
82
84
|
aria-busy={loading || undefined}
|
|
83
85
|
style={{ minHeight: `${rowHeight}px` }}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getDataSourceErrorMessage } from '../../utils/dataSource';
|
|
2
|
+
import { useGridLocale } from './gridLocaleContext';
|
|
2
3
|
|
|
3
4
|
interface GridErrorOverlayProps {
|
|
4
5
|
error: unknown;
|
|
@@ -7,6 +8,7 @@ interface GridErrorOverlayProps {
|
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
export function GridErrorOverlay({ error, onRetry }: GridErrorOverlayProps) {
|
|
11
|
+
const locale = useGridLocale();
|
|
10
12
|
if (!error) return null;
|
|
11
13
|
const message = getDataSourceErrorMessage(error);
|
|
12
14
|
return (
|
|
@@ -17,7 +19,7 @@ export function GridErrorOverlay({ error, onRetry }: GridErrorOverlayProps) {
|
|
|
17
19
|
<line x1="12" y1="16" x2="12.01" y2="16" />
|
|
18
20
|
</svg>
|
|
19
21
|
<div className="ogx-error-overlay__title">
|
|
20
|
-
|
|
22
|
+
{locale.errorOverlayTitle}
|
|
21
23
|
</div>
|
|
22
24
|
<div className="ogx-error-overlay__message">
|
|
23
25
|
{message}
|
|
@@ -28,7 +30,7 @@ export function GridErrorOverlay({ error, onRetry }: GridErrorOverlayProps) {
|
|
|
28
30
|
onClick={onRetry}
|
|
29
31
|
className="ogx-button ogx-button--primary"
|
|
30
32
|
>
|
|
31
|
-
|
|
33
|
+
{locale.errorOverlayRetry}
|
|
32
34
|
</button>
|
|
33
35
|
)}
|
|
34
36
|
</div>
|
|
@@ -4,6 +4,7 @@ import { Pagination } from '../Pagination/Pagination';
|
|
|
4
4
|
import { ListViewRow } from '../ListView/ListViewRow';
|
|
5
5
|
import { getPageCount, normalizePageSize } from '../../utils/pagination';
|
|
6
6
|
import { useRowsScrollEndLatch } from '../../hooks/core/useRowsScrollEndLatch';
|
|
7
|
+
import { useGridLocale } from './gridLocaleContext';
|
|
7
8
|
import type {
|
|
8
9
|
GridColDef,
|
|
9
10
|
GridRowModel,
|
|
@@ -110,6 +111,7 @@ export function GridListView<R extends GridRowModel>({
|
|
|
110
111
|
selectable = false,
|
|
111
112
|
onToggleExpansion,
|
|
112
113
|
}: GridListViewProps<R>) {
|
|
114
|
+
const locale = useGridLocale();
|
|
113
115
|
const PaginationComponent = paginationSlot || Pagination;
|
|
114
116
|
|
|
115
117
|
// Roving tab stop: the list is one Tab stop, on the last focused row (the first row until then,
|
|
@@ -192,15 +194,15 @@ export function GridListView<R extends GridRowModel>({
|
|
|
192
194
|
<div
|
|
193
195
|
className="ogx-list-view"
|
|
194
196
|
role="grid"
|
|
195
|
-
aria-label={ariaLabel ||
|
|
197
|
+
aria-label={ariaLabel || locale.listViewLabel}
|
|
196
198
|
aria-rowcount={itemCount}
|
|
197
199
|
aria-multiselectable={multiselectable}
|
|
198
200
|
>
|
|
199
201
|
<div className="ogx-list-view__toolbar">
|
|
200
202
|
<span>
|
|
201
|
-
{itemCount}
|
|
202
|
-
{pagination ? ` ·
|
|
203
|
-
{selectedRowIds.size > 0 ? ` · ${selectedRowIds.size}
|
|
203
|
+
{locale.listViewItemCount(itemCount)}
|
|
204
|
+
{pagination ? ` · ${locale.listViewPage(currentPage + 1, pageCount)}` : ''}
|
|
205
|
+
{selectedRowIds.size > 0 ? ` · ${locale.listViewSelectedCount(selectedRowIds.size)}` : ''}
|
|
204
206
|
</span>
|
|
205
207
|
</div>
|
|
206
208
|
|
|
@@ -209,7 +211,7 @@ export function GridListView<R extends GridRowModel>({
|
|
|
209
211
|
{allRenderableRows.length === 0 && loading ? (
|
|
210
212
|
// The grid's live region announces loading; the list shows no "No Data" meanwhile.
|
|
211
213
|
<div className="ogx-list-view__loading">
|
|
212
|
-
{loadingOverlay ?? <div className="ogx__loading-bar" role="progressbar" aria-label=
|
|
214
|
+
{loadingOverlay ?? <div className="ogx__loading-bar" role="progressbar" aria-label={locale.loadingLabel} />}
|
|
213
215
|
</div>
|
|
214
216
|
) : allRenderableRows.length === 0 && noRowsOverlay ? (
|
|
215
217
|
<div className="ogx-list-view__empty">{noRowsOverlay}</div>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getDataSourceErrorMessage } from '../../utils/dataSource';
|
|
2
2
|
import type { GridFilterModel } from '../../types';
|
|
3
|
+
import { useGridLocale } from './gridLocaleContext';
|
|
3
4
|
|
|
4
5
|
interface GridLiveRegionProps {
|
|
5
6
|
loading: boolean;
|
|
@@ -22,15 +23,16 @@ interface GridLiveRegionProps {
|
|
|
22
23
|
* the size of the selected cell range; and the AI assistant's status.
|
|
23
24
|
*/
|
|
24
25
|
export function GridLiveRegion({ loading, error, noRowsLabel, filteredRowCount, dataRowCount, filterModel, cellSelectionAnnouncement, aiAssistantAnnouncement }: GridLiveRegionProps) {
|
|
26
|
+
const locale = useGridLocale();
|
|
25
27
|
return (
|
|
26
28
|
<div className="ogx-aria-live-status" role="status" aria-live="polite">
|
|
27
|
-
{loading ?
|
|
28
|
-
{error ?
|
|
29
|
+
{loading ? locale.liveRegionLoading : ''}
|
|
30
|
+
{error ? locale.liveRegionError(getDataSourceErrorMessage(error)) : ''}
|
|
29
31
|
{!loading && !error && (
|
|
30
32
|
filteredRowCount === 0
|
|
31
33
|
? noRowsLabel
|
|
32
34
|
: (filterModel && ((filterModel.quickFilterValues?.length || 0) > 0 || (filterModel.items?.length || 0) > 0))
|
|
33
|
-
?
|
|
35
|
+
? locale.liveRegionRowsFound(dataRowCount)
|
|
34
36
|
: ''
|
|
35
37
|
)}
|
|
36
38
|
{cellSelectionAnnouncement ? <span className="ogx-aria-live-status__cells"> {cellSelectionAnnouncement}</span> : null}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { useGridLocale } from './gridLocaleContext';
|
|
2
3
|
|
|
3
4
|
interface GridLoadingOverlayProps {
|
|
4
5
|
/** `slots.loadingOverlay`, rendered centred over the rows on a dimmed backdrop. */
|
|
@@ -12,6 +13,7 @@ interface GridLoadingOverlayProps {
|
|
|
12
13
|
* or the loading overlay in place of the rows, so this is not rendered.
|
|
13
14
|
*/
|
|
14
15
|
export function GridLoadingOverlay({ overlay }: GridLoadingOverlayProps) {
|
|
16
|
+
const locale = useGridLocale();
|
|
15
17
|
if (overlay) {
|
|
16
18
|
return (
|
|
17
19
|
<div className="ogx__loading-overlay ogx__loading-overlay--over-rows ogx__loading-overlay--custom">
|
|
@@ -21,7 +23,7 @@ export function GridLoadingOverlay({ overlay }: GridLoadingOverlayProps) {
|
|
|
21
23
|
}
|
|
22
24
|
return (
|
|
23
25
|
<div className="ogx__loading-overlay ogx__loading-overlay--over-rows">
|
|
24
|
-
<div className="ogx__loading-bar" role="progressbar" aria-label=
|
|
26
|
+
<div className="ogx__loading-bar" role="progressbar" aria-label={locale.loadingLabel} />
|
|
25
27
|
</div>
|
|
26
28
|
);
|
|
27
29
|
}
|
|
@@ -154,7 +154,7 @@ export function GridPinnedRows<R extends GridRowModel>({
|
|
|
154
154
|
rowSpanningCaches={rowSpanningCaches}
|
|
155
155
|
rowHeight={rowHeight}
|
|
156
156
|
rowMeta={rowMetaMap.get(id)}
|
|
157
|
-
editingCell={editingHandlers?.editingCell}
|
|
157
|
+
editingCell={editingHandlers?.editingCell?.id === id ? editingHandlers.editingCell : null}
|
|
158
158
|
onEditStart={editingHandlers?.startCellEdit}
|
|
159
159
|
onEditStop={editingHandlers?.stopCellEdit}
|
|
160
160
|
onEditCellValueChange={editingHandlers?.setEditCellValue}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { GridLocaleContext } from './gridLocaleContext';
|
|
3
|
+
import { resolveGridLocale } from '../../utils/gridLocale';
|
|
4
|
+
import { useShallowStableValue } from '../../hooks/core/useShallowStableValue';
|
|
2
5
|
import { GridToolbarHostContext } from '../../hooks/core/gridToolbarHostContext';
|
|
3
6
|
import { GridToolbarSlot } from './GridToolbarSlot';
|
|
4
7
|
import { GridAiAssistantArea } from '../AiAssistant/GridAiAssistantArea';
|
|
@@ -95,8 +98,11 @@ export function GridRoot<R extends GridRowModel>(props: GridRootProps<R>) {
|
|
|
95
98
|
// body shows skeletons or the loading overlay instead, and infinite scroll appends skeleton rows.
|
|
96
99
|
const showLoadingOverRows = effectiveLoading && allRenderableRows.length > 0 && paginationMode !== 'infinite';
|
|
97
100
|
const ToolbarSlot = slots?.toolbar;
|
|
101
|
+
const stableLocaleText = useShallowStableValue(localeText);
|
|
102
|
+
const locale = useMemo(() => resolveGridLocale(stableLocaleText), [stableLocaleText]);
|
|
98
103
|
|
|
99
104
|
return (
|
|
105
|
+
<GridLocaleContext.Provider value={locale}>
|
|
100
106
|
<div
|
|
101
107
|
ref={containerRef}
|
|
102
108
|
className={['ogx', className, autoHeight && 'ogx--auto-height', !autoHeight && height === undefined && style?.height === undefined && 'ogx--fill', hasRowSpanning && 'ogx--row-spanning', listView && 'ogx--list-view'].filter(Boolean).join(' ')}
|
|
@@ -235,5 +241,6 @@ export function GridRoot<R extends GridRowModel>(props: GridRootProps<R>) {
|
|
|
235
241
|
|
|
236
242
|
<GridErrorOverlay error={dataSourceError} onRetry={onRetry} />
|
|
237
243
|
</div>
|
|
244
|
+
</GridLocaleContext.Provider>
|
|
238
245
|
);
|
|
239
246
|
}
|