@opencorestack/opengridx 3.5.1 → 3.7.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 +53 -0
- package/README.md +2 -0
- package/dist/ai.cjs +4 -2
- package/dist/ai.cjs.map +1 -1
- package/dist/ai.d.ts +2 -2
- package/dist/ai.es.js +4 -2
- package/dist/ai.es.js.map +1 -1
- package/dist/index.d.ts +62 -0
- package/dist/opengridx.css +1 -1
- package/dist/opengridx.es.js +9643 -9024
- 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 +17 -3
- package/docs/README.md +2 -0
- package/docs/architecture/datagrid-orchestration.md +46 -29
- package/docs/architecture/grid-row-meta.md +1 -1
- package/docs/customization/slots-api.md +1 -1
- package/docs/customization/theming.md +43 -0
- package/docs/features/ai-toolkit.md +2 -2
- package/docs/features/export-guide.md +2 -0
- package/docs/features/header-filters.md +34 -0
- package/docs/features/keyboard-navigation.md +2 -0
- package/docs/features/nextjs.md +241 -0
- package/docs/features/pdf-export.md +2 -0
- package/docs/features/pinning.md +2 -0
- package/docs/features/rtl.md +58 -0
- package/docs/features/virtualization.md +16 -2
- package/docs/performance.md +89 -119
- package/docs/roadmap.md +4 -2
- package/lib/ai/promptHandler.ts +12 -8
- package/lib/ai/validate.ts +5 -2
- package/lib/components/AiAssistant/GridAiAssistantPanel.css +4 -2
- package/lib/components/Cell/Cell.css +31 -9
- package/lib/components/Cell/Cell.tsx +2 -2
- package/lib/components/ColumnGroupHeader/ColumnGroupHeader.css +4 -4
- package/lib/components/ColumnResizeHandle/ColumnResizeHandle.css +3 -3
- package/lib/components/ColumnResizeHandle/ColumnResizeHandle.tsx +18 -2
- package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.css +3 -1
- package/lib/components/DataGrid/DataGrid.css +19 -13
- package/lib/components/DataGrid/DataGrid.tsx +163 -670
- package/lib/components/DataGrid/GridAggregationFooter.tsx +3 -3
- package/lib/components/DataGrid/GridListView.tsx +3 -1
- package/lib/components/DataGrid/GridRoot.tsx +239 -0
- package/lib/components/DataGrid/GridViewport.tsx +314 -0
- package/lib/components/FilterPanel/FilterPanel.css +9 -8
- package/lib/components/Header/ColumnMenu.css +5 -4
- package/lib/components/Header/ColumnMenu.tsx +14 -6
- package/lib/components/Header/Header.css +23 -14
- package/lib/components/Header/Header.tsx +16 -9
- package/lib/components/Header/headerColumnStyle.ts +3 -2
- package/lib/components/HeaderFilter/HeaderFilter.css +9 -3
- package/lib/components/HeaderFilter/HeaderFilterCell.tsx +21 -18
- package/lib/components/HeaderFilter/HeaderFilterOperatorMenu.tsx +5 -4
- package/lib/components/HeaderFilter/HeaderFilterRow.tsx +9 -3
- package/lib/components/ListView/ListViewRow.tsx +1 -1
- package/lib/components/Pagination/Pagination.css +5 -1
- package/lib/components/Pagination/Pagination.tsx +4 -4
- package/lib/components/Row/Row.css +2 -2
- package/lib/components/Row/Row.tsx +3 -3
- package/lib/components/SkeletonRow/SkeletonRow.tsx +2 -2
- package/lib/components/Toolbar/GridToolbar.css +8 -7
- package/lib/components/Toolbar/GridToolbar.tsx +8 -28
- package/lib/components/Toolbar/PivotPanel.css +3 -3
- package/lib/components/Toolbar/PivotPanel.tsx +4 -7
- package/lib/components/ui/ExpandIcon.css +13 -0
- package/lib/components/ui/ExpandIcon.tsx +2 -4
- package/lib/hooks/core/useGridCellSelection.ts +20 -5
- package/lib/hooks/core/useGridColumns.tsx +2 -2
- package/lib/hooks/core/useGridDevWarnings.ts +3 -1
- package/lib/hooks/core/useGridEditPipeline.ts +55 -0
- package/lib/hooks/core/useGridKeyboardNavigation.ts +7 -4
- package/lib/hooks/core/useGridRangeEditing.ts +129 -0
- package/lib/hooks/core/useGridRenderWindow.ts +66 -0
- package/lib/hooks/core/useGridScrollSync.ts +28 -5
- package/lib/hooks/core/useGridScrollViewport.ts +42 -0
- package/lib/hooks/core/useGridSelectionAndStateApi.ts +61 -0
- package/lib/hooks/core/useGridToolbarStack.ts +49 -0
- package/lib/hooks/core/useGridViewApis.ts +46 -0
- package/lib/hooks/core/useLayout.ts +13 -6
- package/lib/hooks/useRowGrouping.ts +9 -9
- package/lib/styles/base/variables.css +12 -0
- package/lib/theme/DataGridThemeProvider.tsx +15 -0
- package/lib/theme/__baseline__/default-theme.darwin.chromium.json +1503 -0
- package/lib/theme/__baseline__/default-theme.darwin.firefox.json +1503 -0
- package/lib/theme/__baseline__/default-theme.darwin.webkit.json +1503 -0
- package/lib/theme/types.ts +31 -0
- package/lib/types/ai.ts +109 -0
- package/lib/types/api.ts +169 -0
- package/lib/types/columns.ts +341 -0
- package/lib/types/dataSource.ts +40 -0
- package/lib/types/editing.ts +77 -0
- package/lib/types/export.ts +164 -0
- package/lib/types/filtering.ts +52 -0
- package/lib/types/grouping.ts +27 -0
- package/lib/types/index.ts +18 -1672
- package/lib/types/locale.ts +51 -0
- package/lib/types/props.ts +405 -0
- package/lib/types/rows.ts +132 -0
- package/lib/types/selection.ts +66 -0
- package/lib/types/slots.ts +56 -0
- package/lib/types/sorting.ts +25 -0
- package/lib/types/state.ts +35 -0
- package/lib/utils/aggregation/index.ts +56 -1
- package/lib/utils/direction.ts +52 -0
- package/lib/utils/export/exportToExcelAdvanced.ts +9 -2
- package/lib/utils/export/exportToPdf.ts +2 -1
- package/lib/utils/filtering/index.ts +58 -6
- package/lib/utils/headerFilterLocale.ts +37 -0
- package/lib/utils/scroll/index.ts +5 -3
- package/lib/utils/sorting/index.ts +141 -26
- package/lib/utils/values.ts +10 -6
- package/llms.txt +4 -2
- package/package.json +4 -2
|
@@ -258,9 +258,9 @@ function CellImpl<R extends GridRowModel = GridRowModel>(props: CellProps<R>) {
|
|
|
258
258
|
|
|
259
259
|
if (isPinned && pinnedOffset !== undefined) {
|
|
260
260
|
if (pinnedPosition === 'left') {
|
|
261
|
-
style.
|
|
261
|
+
style.insetInlineStart = pinnedOffset;
|
|
262
262
|
} else {
|
|
263
|
-
style.
|
|
263
|
+
style.insetInlineEnd = pinnedOffset;
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
266
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
display: flex;
|
|
9
9
|
align-items: stretch;
|
|
10
10
|
background: var(--ogx-grid-header-background);
|
|
11
|
-
border-bottom:
|
|
11
|
+
border-bottom: var(--ogx-grid-row-divider-width) solid var(--ogx-grid-row-divider-color, var(--ogx-grid-border-color));
|
|
12
12
|
/* No overflow clipping: it would make the row the scroll container of its sticky (pinned) cells. */
|
|
13
13
|
flex-shrink: 0;
|
|
14
14
|
min-height: var(--ogx-header-height, 48px);
|
|
@@ -23,15 +23,15 @@
|
|
|
23
23
|
box-sizing: border-box;
|
|
24
24
|
position: relative;
|
|
25
25
|
overflow: hidden;
|
|
26
|
-
/* Same border UI as primary header cells: half-height
|
|
26
|
+
/* Same border UI as primary header cells: half-height divider on the end edge */
|
|
27
27
|
}
|
|
28
28
|
.ogx-col-group-cell:not(:last-child)::after {
|
|
29
29
|
content: '';
|
|
30
30
|
position: absolute;
|
|
31
|
-
|
|
31
|
+
inset-inline-end: 0;
|
|
32
32
|
top: 25%;
|
|
33
33
|
height: 50%;
|
|
34
|
-
width:
|
|
34
|
+
width: var(--ogx-grid-header-column-divider-width);
|
|
35
35
|
background-color: var(--ogx-color-gray-300, #cbd5e1);
|
|
36
36
|
opacity: 0.5;
|
|
37
37
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
position: absolute;
|
|
3
3
|
top: 0;
|
|
4
4
|
/* Inside the header cell: the cell clips overflow, so a handle straddling the border lost its outer half. */
|
|
5
|
-
|
|
5
|
+
inset-inline-end: 0;
|
|
6
6
|
width: 8px;
|
|
7
7
|
height: 100%;
|
|
8
8
|
cursor: col-resize;
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
}
|
|
17
17
|
/* Right-pinned columns grow leftwards: their handle sits on the left edge. */
|
|
18
18
|
.ogx-column-resize-handle--start {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
inset-inline-end: auto;
|
|
20
|
+
inset-inline-start: 0;
|
|
21
21
|
justify-content: flex-start;
|
|
22
22
|
}
|
|
23
23
|
.ogx-column-resize-handle:focus-visible .ogx-column-resize-handle__line {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { clampResizeWidth } from './clampResizeWidth';
|
|
3
|
+
import { isRtl, logicalArrowKey } from '../../utils/direction';
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
export interface ColumnResizeHandleProps {
|
|
@@ -23,6 +24,8 @@ interface ActiveResize {
|
|
|
23
24
|
pointerId: number;
|
|
24
25
|
startX: number;
|
|
25
26
|
startWidth: number;
|
|
27
|
+
/** The grid lays out right to left: the handle's edge grows the column towards the left. */
|
|
28
|
+
rtl: boolean;
|
|
26
29
|
lastUpdate: number;
|
|
27
30
|
moved: boolean;
|
|
28
31
|
}
|
|
@@ -53,7 +56,8 @@ export function ColumnResizeHandle(props: ColumnResizeHandleProps) {
|
|
|
53
56
|
useEffect(() => () => { activeRef.current = null; }, []);
|
|
54
57
|
|
|
55
58
|
const widthAt = useCallback((active: ActiveResize, clientX: number) => {
|
|
56
|
-
|
|
59
|
+
// Pointer movement towards the column's end edge, in screen pixels.
|
|
60
|
+
const deltaX = (clientX - active.startX) * (active.rtl ? -1 : 1);
|
|
57
61
|
const raw = active.startWidth + (edge === 'start' ? -deltaX : deltaX);
|
|
58
62
|
return clampResizeWidth(raw, active.startWidth, minWidth, maxWidth);
|
|
59
63
|
}, [edge, minWidth, maxWidth]);
|
|
@@ -67,6 +71,7 @@ export function ColumnResizeHandle(props: ColumnResizeHandleProps) {
|
|
|
67
71
|
startX: event.clientX,
|
|
68
72
|
// The logical stored width: reliable for pinned, flex, and normal columns.
|
|
69
73
|
startWidth: currentWidth,
|
|
74
|
+
rtl: isRtl(event.currentTarget),
|
|
70
75
|
lastUpdate: 0,
|
|
71
76
|
moved: false,
|
|
72
77
|
};
|
|
@@ -97,6 +102,16 @@ export function ColumnResizeHandle(props: ColumnResizeHandleProps) {
|
|
|
97
102
|
if (!active || event.pointerId !== active.pointerId) return;
|
|
98
103
|
activeRef.current = null;
|
|
99
104
|
setIsDragging(false);
|
|
105
|
+
// Release explicitly: the implicit release only follows a real pointerup, and a capture left on
|
|
106
|
+
// this handle (a synthetic press on the live mouse pointer, or an interrupted drag) would keep
|
|
107
|
+
// the pointer's later events from reaching the rest of the page.
|
|
108
|
+
if (event.currentTarget.hasPointerCapture?.(event.pointerId)) {
|
|
109
|
+
try {
|
|
110
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
111
|
+
} catch {
|
|
112
|
+
// Already released.
|
|
113
|
+
}
|
|
114
|
+
}
|
|
100
115
|
if (active.moved || event.clientX !== active.startX) {
|
|
101
116
|
// The drag may end over the header cell, which would take the synthesized click as a sort.
|
|
102
117
|
suppressNextClick();
|
|
@@ -114,7 +129,8 @@ export function ColumnResizeHandle(props: ColumnResizeHandleProps) {
|
|
|
114
129
|
if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return;
|
|
115
130
|
event.preventDefault();
|
|
116
131
|
event.stopPropagation();
|
|
117
|
-
const
|
|
132
|
+
const key = logicalArrowKey(event.key, isRtl(event.currentTarget));
|
|
133
|
+
const step = (event.shiftKey ? 50 : 10) * (key === 'ArrowRight' ? 1 : -1);
|
|
118
134
|
onResize(field, clampResizeWidth(currentWidth + step, currentWidth, minWidth, maxWidth));
|
|
119
135
|
}, [field, currentWidth, onResize, onAutosize, minWidth, maxWidth]);
|
|
120
136
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
background: var(--ogx-overlay-background, var(--ogx-color-white));
|
|
3
3
|
border: var(--ogx-border-width-thin) solid var(--ogx-overlay-border, var(--ogx-border-color));
|
|
4
4
|
border-radius: var(--ogx-border-radius-sm);
|
|
5
|
+
font-family: var(--ogx-overlay-font-family, inherit);
|
|
5
6
|
min-width: 250px;
|
|
6
7
|
max-width: 350px;
|
|
7
8
|
box-shadow: var(--ogx-shadow-lg);
|
|
@@ -120,7 +121,8 @@
|
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
.ogx-column-visibility-panel__label {
|
|
123
|
-
font-size: var(--ogx-font-size-xs);
|
|
124
|
+
font-size: var(--ogx-overlay-font-size, var(--ogx-font-size-xs));
|
|
125
|
+
font-weight: var(--ogx-overlay-font-weight, inherit);
|
|
124
126
|
color: var(--ogx-overlay-text, var(--ogx-color-gray-900));
|
|
125
127
|
user-select: none;
|
|
126
128
|
cursor: inherit;
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
flex-direction: column;
|
|
4
4
|
width: 100%;
|
|
5
5
|
background: var(--ogx-grid-background);
|
|
6
|
-
border:
|
|
7
|
-
border-radius: var(--ogx-border-radius-lg);
|
|
6
|
+
border: var(--ogx-grid-border-width) solid var(--ogx-grid-border-color);
|
|
7
|
+
border-radius: var(--ogx-grid-border-radius, var(--ogx-border-radius-lg));
|
|
8
8
|
font-family: var(--ogx-font-family);
|
|
9
9
|
position: relative;
|
|
10
10
|
box-shadow: var(--ogx-shadow-sm);
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
overflow: hidden;
|
|
13
13
|
}
|
|
14
14
|
.ogx > :first-child {
|
|
15
|
-
border-top-left-radius: calc(var(--ogx-border-radius-lg) -
|
|
16
|
-
border-top-right-radius: calc(var(--ogx-border-radius-lg) -
|
|
15
|
+
border-top-left-radius: max(0px, calc(var(--ogx-grid-border-radius, var(--ogx-border-radius-lg)) - var(--ogx-grid-border-width)));
|
|
16
|
+
border-top-right-radius: max(0px, calc(var(--ogx-grid-border-radius, var(--ogx-border-radius-lg)) - var(--ogx-grid-border-width)));
|
|
17
17
|
}
|
|
18
18
|
.ogx > :last-child {
|
|
19
|
-
border-bottom-left-radius: calc(var(--ogx-border-radius-lg) -
|
|
20
|
-
border-bottom-right-radius: calc(var(--ogx-border-radius-lg) -
|
|
19
|
+
border-bottom-left-radius: max(0px, calc(var(--ogx-grid-border-radius, var(--ogx-border-radius-lg)) - var(--ogx-grid-border-width)));
|
|
20
|
+
border-bottom-right-radius: max(0px, calc(var(--ogx-grid-border-radius, var(--ogx-border-radius-lg)) - var(--ogx-grid-border-width)));
|
|
21
21
|
}
|
|
22
22
|
.ogx:hover {
|
|
23
23
|
box-shadow: var(--ogx-shadow-md);
|
|
@@ -150,7 +150,7 @@
|
|
|
150
150
|
min-height: 0;
|
|
151
151
|
pointer-events: none;
|
|
152
152
|
z-index: var(--ogx-z-index-modal);
|
|
153
|
-
border-radius: var(--ogx-border-radius-lg);
|
|
153
|
+
border-radius: var(--ogx-grid-border-radius, var(--ogx-border-radius-lg));
|
|
154
154
|
overflow: hidden;
|
|
155
155
|
}
|
|
156
156
|
.ogx__loading-overlay--custom {
|
|
@@ -243,7 +243,7 @@
|
|
|
243
243
|
justify-content: center;
|
|
244
244
|
overflow: hidden;
|
|
245
245
|
box-sizing: border-box;
|
|
246
|
-
border-
|
|
246
|
+
border-inline-end: var(--ogx-grid-column-divider-width) solid var(--ogx-grid-column-divider-color, var(--ogx-grid-border-color));
|
|
247
247
|
position: relative;
|
|
248
248
|
}
|
|
249
249
|
.ogx__aggregation-cell--pinned-left,
|
|
@@ -265,7 +265,7 @@
|
|
|
265
265
|
background: var(--ogx-grid-header-background);
|
|
266
266
|
}
|
|
267
267
|
.ogx__aggregation-cell--pinned-right {
|
|
268
|
-
border-
|
|
268
|
+
border-inline-start: var(--ogx-grid-column-divider-width) solid var(--ogx-grid-column-divider-color, var(--ogx-grid-border-color));
|
|
269
269
|
}
|
|
270
270
|
.ogx__aggregation-cell--pinned-left-last {
|
|
271
271
|
overflow: visible;
|
|
@@ -274,26 +274,32 @@
|
|
|
274
274
|
content: '';
|
|
275
275
|
position: absolute;
|
|
276
276
|
top: 0;
|
|
277
|
-
|
|
277
|
+
inset-inline-end: -10px;
|
|
278
278
|
bottom: 0;
|
|
279
279
|
width: 10px;
|
|
280
280
|
pointer-events: none;
|
|
281
281
|
box-shadow: inset 10px 0 8px -8px rgba(0, 0, 0, 0.1);
|
|
282
282
|
}
|
|
283
283
|
.ogx__aggregation-cell--pinned-right-first {
|
|
284
|
-
margin-
|
|
284
|
+
margin-inline-start: auto;
|
|
285
285
|
overflow: visible;
|
|
286
286
|
}
|
|
287
287
|
.ogx__aggregation-cell--pinned-right-first::before {
|
|
288
288
|
content: '';
|
|
289
289
|
position: absolute;
|
|
290
290
|
top: 0;
|
|
291
|
-
|
|
291
|
+
inset-inline-start: -10px;
|
|
292
292
|
bottom: 0;
|
|
293
293
|
width: 10px;
|
|
294
294
|
pointer-events: none;
|
|
295
295
|
box-shadow: inset -10px 0 8px -8px rgba(0, 0, 0, 0.1);
|
|
296
296
|
}
|
|
297
|
+
.ogx__aggregation-cell--pinned-left-last:dir(rtl)::after {
|
|
298
|
+
box-shadow: inset -10px 0 8px -8px rgba(0, 0, 0, 0.1);
|
|
299
|
+
}
|
|
300
|
+
.ogx__aggregation-cell--pinned-right-first:dir(rtl)::before {
|
|
301
|
+
box-shadow: inset 10px 0 8px -8px rgba(0, 0, 0, 0.1);
|
|
302
|
+
}
|
|
297
303
|
.ogx__aggregation-label {
|
|
298
304
|
font-size: 0.7em;
|
|
299
305
|
text-transform: uppercase;
|
|
@@ -321,7 +327,7 @@
|
|
|
321
327
|
}
|
|
322
328
|
.ogx__group-cell-content {
|
|
323
329
|
font-weight: 500;
|
|
324
|
-
text-align:
|
|
330
|
+
text-align: start;
|
|
325
331
|
display: flex;
|
|
326
332
|
align-items: center;
|
|
327
333
|
gap: 4px;
|