@ornery/ui-grid-react 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/UiGrid.d.ts +11 -0
- package/dist/UiGrid.d.ts.map +1 -0
- package/dist/gridStateMath.d.ts +8 -0
- package/dist/gridStateMath.d.ts.map +1 -0
- package/dist/index.d.ts +13 -155
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +541 -1054
- package/dist/index.mjs +434 -919
- package/dist/mountUiGrid.d.ts +4 -0
- package/dist/mountUiGrid.d.ts.map +1 -0
- package/dist/rustWasmGridEngine.d.ts +8 -0
- package/dist/rustWasmGridEngine.d.ts.map +1 -0
- package/dist/{index.d.mts → useGridState.d.ts} +5 -50
- package/dist/useGridState.d.ts.map +1 -0
- package/dist/useVirtualScroll.d.ts +20 -0
- package/dist/useVirtualScroll.d.ts.map +1 -0
- package/dist/virtualScrollMath.d.ts +17 -0
- package/dist/virtualScrollMath.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/UiGrid.test.tsx +2 -1
- package/src/UiGrid.tsx +174 -45
- package/src/index.ts +1 -0
- package/src/mountUiGrid.tsx +10 -0
- package/src/rustWasmGridEngine.ts +3 -1
- package/src/ui-grid.css +161 -1
- package/src/useGridState.ts +39 -27
- package/src/useVirtualScroll.ts +2 -0
- package/tsconfig.build.json +6 -0
- package/tsconfig.dts.json +15 -0
- package/CLAUDE.md +0 -283
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mountUiGrid.d.ts","sourceRoot":"","sources":["../src/mountUiGrid.tsx"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAEpD,wBAAgB,WAAW,CAAC,SAAS,EAAE,OAAO,GAAG,gBAAgB,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAI3F"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PipelineResult } from '@ornery/ui-grid';
|
|
2
|
+
type UiGridWasmModule = {
|
|
3
|
+
build_pipeline_js(context: unknown): PipelineResult;
|
|
4
|
+
};
|
|
5
|
+
export declare function registerReactUiGridWasmEngineFromModule(module: UiGridWasmModule): void;
|
|
6
|
+
export declare function enableReactUiGridWasmEngine(): Promise<void>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=rustWasmGridEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rustWasmGridEngine.d.ts","sourceRoot":"","sources":["../src/rustWasmGridEngine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA4B,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAMhF,KAAK,gBAAgB,GAAG;IACtB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,CAAC;CACrD,CAAC;AAEF,wBAAgB,uCAAuC,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAMtF;AAED,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjE"}
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
export { DEFAULT_GRID_LABELS, GridBenchmarkResult, GridCellEditableContext, GridCellTemplateContext, GridColumnDef, GridExpandableTemplateContext, GridLabels, GridOptions, GridRecord, GridRow, GridSavedState, SortState, UiGridApi } from '@ornery/ui-grid';
|
|
5
|
-
|
|
6
|
-
interface UiGridProps {
|
|
7
|
-
options: GridOptions;
|
|
8
|
-
onRegisterApi?: (api: UiGridApi) => void;
|
|
9
|
-
cellRenderer?: (context: GridCellTemplateContext) => React$1.ReactNode;
|
|
10
|
-
expandableRenderer?: (context: GridExpandableTemplateContext) => React$1.ReactNode;
|
|
11
|
-
className?: string;
|
|
12
|
-
}
|
|
13
|
-
declare function UiGrid({ options, onRegisterApi, cellRenderer, expandableRenderer, className, }: UiGridProps): react_jsx_runtime.JSX.Element;
|
|
14
|
-
|
|
15
|
-
interface UseGridStateResult {
|
|
1
|
+
import { UiGridApi, GridOptions, GridColumnDef, GridRow, GridBenchmarkResult, GridCellPosition, GridLabels, SortState } from '@ornery/ui-grid';
|
|
2
|
+
import type { DisplayItem, GroupItem, ExpandableItem, RowItem, PipelineResult, GridInfiniteScrollState, GridCellTemplateContext, GridExpandableTemplateContext } from '@ornery/ui-grid';
|
|
3
|
+
export interface UseGridStateResult {
|
|
16
4
|
pipeline: PipelineResult;
|
|
17
5
|
visibleColumns: GridColumnDef[];
|
|
18
6
|
labels: GridLabels;
|
|
@@ -118,38 +106,5 @@ interface UseGridStateResult {
|
|
|
118
106
|
exportCsv: () => void;
|
|
119
107
|
onViewportScroll: (startIndex: number) => void;
|
|
120
108
|
}
|
|
121
|
-
declare function useGridState(options: GridOptions, onRegisterApi?: (api: UiGridApi) => void): UseGridStateResult;
|
|
122
|
-
|
|
123
|
-
interface UseVirtualScrollOptions {
|
|
124
|
-
itemCount: number;
|
|
125
|
-
itemSize: number;
|
|
126
|
-
viewportHeight: number;
|
|
127
|
-
overscan?: number;
|
|
128
|
-
}
|
|
129
|
-
interface UseVirtualScrollResult {
|
|
130
|
-
visibleRange: {
|
|
131
|
-
start: number;
|
|
132
|
-
end: number;
|
|
133
|
-
};
|
|
134
|
-
totalHeight: number;
|
|
135
|
-
offsetY: number;
|
|
136
|
-
onScroll: (event: React.UIEvent<HTMLDivElement>) => void;
|
|
137
|
-
viewportRef: React.RefObject<HTMLDivElement | null>;
|
|
138
|
-
scrollTop: number;
|
|
139
|
-
}
|
|
140
|
-
declare function useVirtualScroll(options: UseVirtualScrollOptions): UseVirtualScrollResult;
|
|
141
|
-
|
|
142
|
-
declare function orderVisibleColumns(columns: readonly GridColumnDef[], order: readonly string[]): GridColumnDef[];
|
|
143
|
-
declare function buildGridTemplateColumns(columns: readonly GridColumnDef[]): string;
|
|
144
|
-
declare function resolveBenchmarkIterations(iterations?: number, configuredIterations?: number): number;
|
|
145
|
-
declare function formatPaginationSummary(totalItems: number, firstRowIndex: number, lastRowIndex: number): string;
|
|
146
|
-
declare function computeViewportHeightPx(viewportHeight?: number, autoViewportHeight?: number | null): string;
|
|
147
|
-
declare function computeViewportRows(viewportHeight?: number, rowHeight?: number): number;
|
|
148
|
-
|
|
149
|
-
type UiGridWasmModule = {
|
|
150
|
-
build_pipeline_js(context: unknown): PipelineResult;
|
|
151
|
-
};
|
|
152
|
-
declare function registerReactUiGridWasmEngineFromModule(module: UiGridWasmModule): void;
|
|
153
|
-
declare function enableReactUiGridWasmEngine(): Promise<void>;
|
|
154
|
-
|
|
155
|
-
export { UiGrid, type UiGridProps, type UseGridStateResult, type UseVirtualScrollOptions, type UseVirtualScrollResult, buildGridTemplateColumns, computeViewportHeightPx, computeViewportRows, enableReactUiGridWasmEngine, formatPaginationSummary, orderVisibleColumns, registerReactUiGridWasmEngineFromModule, resolveBenchmarkIterations, useGridState, useVirtualScroll };
|
|
109
|
+
export declare function useGridState(options: GridOptions, onRegisterApi?: (api: UiGridApi) => void): UseGridStateResult;
|
|
110
|
+
//# sourceMappingURL=useGridState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGridState.d.ts","sourceRoot":"","sources":["../src/useGridState.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface UseVirtualScrollOptions {
|
|
2
|
+
itemCount: number;
|
|
3
|
+
itemSize: number;
|
|
4
|
+
viewportHeight: number;
|
|
5
|
+
overscan?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface UseVirtualScrollResult {
|
|
8
|
+
visibleRange: {
|
|
9
|
+
start: number;
|
|
10
|
+
end: number;
|
|
11
|
+
};
|
|
12
|
+
totalHeight: number;
|
|
13
|
+
offsetY: number;
|
|
14
|
+
onScroll: (event: React.UIEvent<HTMLDivElement>) => void;
|
|
15
|
+
setScrollTop: (scrollTop: number) => void;
|
|
16
|
+
viewportRef: React.RefObject<HTMLDivElement | null>;
|
|
17
|
+
scrollTop: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function useVirtualScroll(options: UseVirtualScrollOptions): UseVirtualScrollResult;
|
|
20
|
+
//# sourceMappingURL=useVirtualScroll.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useVirtualScroll.d.ts","sourceRoot":"","sources":["../src/useVirtualScroll.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IACzD,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACpD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,sBAAsB,CA0BzF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface VirtualWindowRequest {
|
|
2
|
+
itemCount: number;
|
|
3
|
+
itemSize: number;
|
|
4
|
+
viewportHeight: number;
|
|
5
|
+
overscan?: number;
|
|
6
|
+
scrollTop: number;
|
|
7
|
+
}
|
|
8
|
+
export interface VirtualWindowResult {
|
|
9
|
+
visibleRange: {
|
|
10
|
+
start: number;
|
|
11
|
+
end: number;
|
|
12
|
+
};
|
|
13
|
+
totalHeight: number;
|
|
14
|
+
offsetY: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function calculateVirtualWindow(request: VirtualWindowRequest): VirtualWindowResult;
|
|
17
|
+
//# sourceMappingURL=virtualScrollMath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtualScrollMath.d.ts","sourceRoot":"","sources":["../src/virtualScrollMath.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,oBAAoB,GAAG,mBAAmB,CAqBzF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ornery/ui-grid-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "React wrapper for @ornery/ui-grid",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"peerDependencies": {
|
|
17
17
|
"react": "^18.0.0 || ^19.0.0",
|
|
18
18
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
19
|
-
"@ornery/ui-grid": "^0.1.
|
|
19
|
+
"@ornery/ui-grid": "^0.1.6"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@ornery/ui-grid": "file:../ui-grid",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"start": "vite serve demo --config demo/vite.config.ts",
|
|
37
|
-
"build": "tsup src/index.ts --format esm,cjs --
|
|
37
|
+
"build": "npm run build:library --prefix ../.. && tsup src/index.ts --format esm,cjs --tsconfig tsconfig.build.json --external react --external react-dom --external @ornery/ui-grid && tsc -p tsconfig.dts.json",
|
|
38
38
|
"test": "vitest run",
|
|
39
39
|
"test:watch": "vitest"
|
|
40
40
|
}
|
package/src/UiGrid.test.tsx
CHANGED
|
@@ -235,7 +235,8 @@ describe('UiGrid React component', () => {
|
|
|
235
235
|
});
|
|
236
236
|
|
|
237
237
|
expect(gridApi.core.getVisibleRows()).toHaveLength(5);
|
|
238
|
-
expect(container.querySelector('.grid-
|
|
238
|
+
expect(container.querySelector('.grid-virtual-spacer')).not.toBeNull();
|
|
239
|
+
expect(container.querySelector('.grid-virtual-body')).not.toBeNull();
|
|
239
240
|
});
|
|
240
241
|
|
|
241
242
|
it('paginates rows', () => {
|
package/src/UiGrid.tsx
CHANGED
|
@@ -63,13 +63,103 @@ export function UiGrid({
|
|
|
63
63
|
overscan: 3,
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
+
const headerGridRef = React.useRef<HTMLDivElement | null>(null);
|
|
67
|
+
const filterGridRef = React.useRef<HTMLDivElement | null>(null);
|
|
68
|
+
const [openPinMenuColumn, setOpenPinMenuColumn] = React.useState<string | null>(null);
|
|
69
|
+
const [headerStickyHeight, setHeaderStickyHeight] = React.useState(0);
|
|
70
|
+
const [filterStickyHeight, setFilterStickyHeight] = React.useState(0);
|
|
71
|
+
const stickyChromeHeight = headerStickyHeight + filterStickyHeight;
|
|
72
|
+
const scrollContainerHeight = `${(options.viewportHeight ?? 560) + stickyChromeHeight}px`;
|
|
73
|
+
|
|
74
|
+
const eventPathIncludesClass = React.useCallback((event: Event, className: string): boolean => {
|
|
75
|
+
const eventPath = typeof event.composedPath === 'function'
|
|
76
|
+
? event.composedPath()
|
|
77
|
+
: (event.target ? [event.target] : []);
|
|
78
|
+
|
|
79
|
+
return eventPath.some((target) => {
|
|
80
|
+
if (!target || typeof target !== 'object' || !('classList' in target)) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const classList = (target as { classList?: DOMTokenList }).classList;
|
|
85
|
+
return classList?.contains(className) ?? false;
|
|
86
|
+
});
|
|
87
|
+
}, []);
|
|
88
|
+
|
|
89
|
+
const isPinMenuOpen = React.useCallback(
|
|
90
|
+
(column: GridColumnDef) => openPinMenuColumn === column.name,
|
|
91
|
+
[openPinMenuColumn],
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const pinButtonLabel = React.useCallback(
|
|
95
|
+
(column: GridColumnDef) => (state.isPinned(column) ? labels.unpin : labels.pinColumn),
|
|
96
|
+
[labels, state],
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const onPinTrigger = React.useCallback(
|
|
100
|
+
(column: GridColumnDef, event?: React.MouseEvent) => {
|
|
101
|
+
event?.stopPropagation();
|
|
102
|
+
if (state.isPinned(column)) {
|
|
103
|
+
setOpenPinMenuColumn(null);
|
|
104
|
+
state.gridApi.pinning.pinColumn(column.name, 'none');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
setOpenPinMenuColumn((current) => (current === column.name ? null : column.name));
|
|
109
|
+
},
|
|
110
|
+
[state],
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const choosePinDirection = React.useCallback(
|
|
114
|
+
(column: GridColumnDef, direction: 'left' | 'right', event?: React.MouseEvent) => {
|
|
115
|
+
event?.stopPropagation();
|
|
116
|
+
setOpenPinMenuColumn(null);
|
|
117
|
+
state.gridApi.pinning.pinColumn(column.name, direction);
|
|
118
|
+
},
|
|
119
|
+
[state],
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
React.useLayoutEffect(() => {
|
|
123
|
+
setHeaderStickyHeight(headerGridRef.current?.offsetHeight ?? 0);
|
|
124
|
+
setFilterStickyHeight(filterGridRef.current?.offsetHeight ?? 0);
|
|
125
|
+
}, [visibleColumns, filteringFeature, options.enableFiltering]);
|
|
126
|
+
|
|
127
|
+
React.useEffect(() => {
|
|
128
|
+
if (!openPinMenuColumn) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const handleDocumentClick = (event: MouseEvent) => {
|
|
133
|
+
if (eventPathIncludesClass(event, 'pin-control')) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
setOpenPinMenuColumn(null);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const handleDocumentEscape = (event: KeyboardEvent) => {
|
|
141
|
+
if (event.key === 'Escape') {
|
|
142
|
+
setOpenPinMenuColumn(null);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
document.addEventListener('click', handleDocumentClick);
|
|
147
|
+
document.addEventListener('keydown', handleDocumentEscape);
|
|
148
|
+
|
|
149
|
+
return () => {
|
|
150
|
+
document.removeEventListener('click', handleDocumentClick);
|
|
151
|
+
document.removeEventListener('keydown', handleDocumentEscape);
|
|
152
|
+
};
|
|
153
|
+
}, [eventPathIncludesClass, openPinMenuColumn]);
|
|
154
|
+
|
|
66
155
|
const itemsToRender = virtualizationEnabled
|
|
67
156
|
? displayItems.slice(virtualScroll.visibleRange.start, virtualScroll.visibleRange.end)
|
|
68
157
|
: displayItems;
|
|
69
158
|
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
159
|
+
const onGridTableScroll = (event: React.UIEvent<HTMLDivElement>) => {
|
|
160
|
+
const bodyScrollTop = Math.max(0, event.currentTarget.scrollTop - stickyChromeHeight);
|
|
161
|
+
virtualScroll.setScrollTop(bodyScrollTop);
|
|
162
|
+
const startIndex = Math.floor(bodyScrollTop / rowSize);
|
|
73
163
|
state.onViewportScroll(startIndex);
|
|
74
164
|
};
|
|
75
165
|
|
|
@@ -320,21 +410,28 @@ export function UiGrid({
|
|
|
320
410
|
</p>
|
|
321
411
|
</div>
|
|
322
412
|
|
|
323
|
-
<div
|
|
413
|
+
<div
|
|
414
|
+
className="grid-table ui-grid-contents-wrapper"
|
|
415
|
+
data-part="grid-table"
|
|
416
|
+
style={virtualizationEnabled ? { height: scrollContainerHeight, overflowY: 'auto' } : undefined}
|
|
417
|
+
onScroll={virtualizationEnabled ? onGridTableScroll : undefined}
|
|
418
|
+
>
|
|
324
419
|
{/* Header row */}
|
|
325
420
|
<div
|
|
326
421
|
className="header-grid ui-grid-header ui-grid-header-canvas"
|
|
327
422
|
data-part="header"
|
|
328
423
|
role="row"
|
|
424
|
+
ref={headerGridRef}
|
|
329
425
|
style={{ gridTemplateColumns }}
|
|
330
426
|
>
|
|
331
427
|
{visibleColumns.map((column) => {
|
|
332
428
|
const pinned = state.isPinned(column);
|
|
333
429
|
const pinOffset = pinned ? state.pinnedOffset(column) : null;
|
|
430
|
+
const pinMenuOpen = isPinMenuOpen(column);
|
|
334
431
|
return (
|
|
335
432
|
<div
|
|
336
433
|
key={column.name}
|
|
337
|
-
className={`header-cell ui-grid-header-cell${sortingFeature && state.sortDirection(column) !== 'none' ? ' is-active' : ''}${pinned ? ' is-pinned' : ''}`}
|
|
434
|
+
className={`header-cell ui-grid-header-cell${sortingFeature && state.sortDirection(column) !== 'none' ? ' is-active' : ''}${pinned ? ' is-pinned' : ''}${pinMenuOpen ? ' is-pin-menu-open' : ''}`}
|
|
338
435
|
data-part="header-cell"
|
|
339
436
|
role="columnheader"
|
|
340
437
|
aria-sort={sortingFeature ? (state.sortAriaSort(column) as any) : undefined}
|
|
@@ -342,7 +439,7 @@ export function UiGrid({
|
|
|
342
439
|
position: pinned ? 'sticky' : undefined,
|
|
343
440
|
left: pinOffset?.side === 'left' ? pinOffset.offset : undefined,
|
|
344
441
|
right: pinOffset?.side === 'right' ? pinOffset.offset : undefined,
|
|
345
|
-
zIndex: pinned ? 2 : undefined,
|
|
442
|
+
zIndex: pinMenuOpen ? 8 : pinned ? 2 : undefined,
|
|
346
443
|
}}
|
|
347
444
|
>
|
|
348
445
|
<span className="header-label">{state.headerLabel(column)}</span>
|
|
@@ -386,21 +483,62 @@ export function UiGrid({
|
|
|
386
483
|
{state.pinningFeature &&
|
|
387
484
|
state.isPinningEnabled() &&
|
|
388
485
|
state.isColumnPinnable(column) && (
|
|
389
|
-
<
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
486
|
+
<div className={`pin-control${pinMenuOpen ? ' pin-control-open' : ''}`} onClick={(event) => event.stopPropagation()}>
|
|
487
|
+
<button
|
|
488
|
+
type="button"
|
|
489
|
+
className={`chip-action pin-trigger${pinned || pinMenuOpen ? ' chip-action-active' : ''}`}
|
|
490
|
+
data-part="pin-toggle"
|
|
491
|
+
aria-label={pinButtonLabel(column)}
|
|
492
|
+
title={pinButtonLabel(column)}
|
|
493
|
+
aria-haspopup={pinned ? undefined : 'menu'}
|
|
494
|
+
aria-expanded={pinned ? undefined : pinMenuOpen}
|
|
495
|
+
onClick={(event) => onPinTrigger(column, event)}
|
|
496
|
+
>
|
|
497
|
+
<svg viewBox="0 0 24 24" aria-hidden="true" focusable={false}>
|
|
498
|
+
<path d="M16 12V4h1V2H7v2h1v8l-2 2v2h5v6l1 1 1-1v-6h5v-2l-2-2z" />
|
|
499
|
+
</svg>
|
|
500
|
+
<span className="sr-only ui-grid-sr-only">{pinButtonLabel(column)}</span>
|
|
501
|
+
</button>
|
|
502
|
+
|
|
503
|
+
<div
|
|
504
|
+
className="pin-menu"
|
|
505
|
+
data-part="pin-menu"
|
|
506
|
+
role="menu"
|
|
507
|
+
aria-label="Pin options"
|
|
508
|
+
aria-hidden={!pinMenuOpen}
|
|
509
|
+
>
|
|
510
|
+
<button
|
|
511
|
+
type="button"
|
|
512
|
+
className="pin-menu-action"
|
|
513
|
+
data-part="pin-left-action"
|
|
514
|
+
role="menuitem"
|
|
515
|
+
aria-label={labels.pinLeft}
|
|
516
|
+
title={labels.pinLeft}
|
|
517
|
+
tabIndex={pinMenuOpen ? 0 : -1}
|
|
518
|
+
onClick={(event) => choosePinDirection(column, 'left', event)}
|
|
519
|
+
>
|
|
520
|
+
<svg viewBox="0 0 24 24" aria-hidden="true" focusable={false}>
|
|
521
|
+
<path d="M10 6 4 12l6 6v-4h10v-4H10V6z" />
|
|
522
|
+
</svg>
|
|
523
|
+
<span className="sr-only ui-grid-sr-only">{labels.pinLeft}</span>
|
|
524
|
+
</button>
|
|
525
|
+
<button
|
|
526
|
+
type="button"
|
|
527
|
+
className="pin-menu-action"
|
|
528
|
+
data-part="pin-right-action"
|
|
529
|
+
role="menuitem"
|
|
530
|
+
aria-label={labels.pinRight}
|
|
531
|
+
title={labels.pinRight}
|
|
532
|
+
tabIndex={pinMenuOpen ? 0 : -1}
|
|
533
|
+
onClick={(event) => choosePinDirection(column, 'right', event)}
|
|
534
|
+
>
|
|
535
|
+
<svg viewBox="0 0 24 24" aria-hidden="true" focusable={false}>
|
|
536
|
+
<path d="M14 6v4H4v4h10v4l6-6-6-6z" />
|
|
537
|
+
</svg>
|
|
538
|
+
<span className="sr-only ui-grid-sr-only">{labels.pinRight}</span>
|
|
539
|
+
</button>
|
|
540
|
+
</div>
|
|
541
|
+
</div>
|
|
404
542
|
)}
|
|
405
543
|
</div>
|
|
406
544
|
</div>
|
|
@@ -413,7 +551,8 @@ export function UiGrid({
|
|
|
413
551
|
<div
|
|
414
552
|
className="filter-grid ui-grid-header"
|
|
415
553
|
data-part="filters"
|
|
416
|
-
|
|
554
|
+
ref={filterGridRef}
|
|
555
|
+
style={{ gridTemplateColumns, ['--ui-grid-header-sticky-top' as string]: `${headerStickyHeight}px` }}
|
|
417
556
|
>
|
|
418
557
|
{visibleColumns.map((column) => {
|
|
419
558
|
const pinned = state.isPinned(column);
|
|
@@ -450,29 +589,19 @@ export function UiGrid({
|
|
|
450
589
|
{/* Body */}
|
|
451
590
|
{displayItems.length > 0 ? (
|
|
452
591
|
virtualizationEnabled ? (
|
|
453
|
-
<div
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
gridTemplateColumns,
|
|
467
|
-
position: 'absolute',
|
|
468
|
-
top: 0,
|
|
469
|
-
left: 0,
|
|
470
|
-
right: 0,
|
|
471
|
-
transform: `translateY(${virtualScroll.offsetY}px)`,
|
|
472
|
-
}}
|
|
473
|
-
>
|
|
474
|
-
{itemsToRender.map(renderDisplayItem)}
|
|
475
|
-
</div>
|
|
592
|
+
<div className="grid-virtual-spacer" style={{ height: `${virtualScroll.totalHeight}px` }}>
|
|
593
|
+
<div
|
|
594
|
+
className="body-grid ui-grid-canvas grid-virtual-body"
|
|
595
|
+
data-part="body"
|
|
596
|
+
role="rowgroup"
|
|
597
|
+
style={{
|
|
598
|
+
gridTemplateColumns,
|
|
599
|
+
position: 'absolute',
|
|
600
|
+
top: `${virtualScroll.offsetY}px`,
|
|
601
|
+
left: 0,
|
|
602
|
+
}}
|
|
603
|
+
>
|
|
604
|
+
{itemsToRender.map(renderDisplayItem)}
|
|
476
605
|
</div>
|
|
477
606
|
</div>
|
|
478
607
|
) : (
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { UiGrid } from './UiGrid';
|
|
2
2
|
export type { UiGridProps } from './UiGrid';
|
|
3
|
+
export { mountUiGrid } from './mountUiGrid';
|
|
3
4
|
export { useGridState } from './useGridState';
|
|
4
5
|
export type { UseGridStateResult } from './useGridState';
|
|
5
6
|
export { useVirtualScroll } from './useVirtualScroll';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createRoot, type Root } from 'react-dom/client';
|
|
3
|
+
|
|
4
|
+
import { UiGrid, type UiGridProps } from './UiGrid';
|
|
5
|
+
|
|
6
|
+
export function mountUiGrid(container: Element | DocumentFragment, props: UiGridProps): Root {
|
|
7
|
+
const root = createRoot(container);
|
|
8
|
+
root.render(React.createElement(UiGrid, props));
|
|
9
|
+
return root;
|
|
10
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { BuildGridPipelineContext, PipelineResult } from '@ornery/ui-grid';
|
|
2
2
|
import { registerRustWasmGridEngine } from '@ornery/ui-grid';
|
|
3
3
|
|
|
4
|
-
const uiGridWasmModulePath = '../../../dist/ui-grid-wasm/ui_grid_wasm.js';
|
|
4
|
+
const uiGridWasmModulePath = '../../../dist/ui-grid-wasm-web/ui_grid_wasm.js';
|
|
5
|
+
const uiGridWasmBinaryPath = '/dist/ui-grid-wasm-web/ui_grid_wasm_bg.wasm';
|
|
5
6
|
|
|
6
7
|
type UiGridWasmModule = {
|
|
7
8
|
build_pipeline_js(context: unknown): PipelineResult;
|
|
@@ -17,5 +18,6 @@ export function registerReactUiGridWasmEngineFromModule(module: UiGridWasmModule
|
|
|
17
18
|
|
|
18
19
|
export async function enableReactUiGridWasmEngine(): Promise<void> {
|
|
19
20
|
const module = await import(/* @vite-ignore */ uiGridWasmModulePath);
|
|
21
|
+
await module.default(uiGridWasmBinaryPath);
|
|
20
22
|
registerReactUiGridWasmEngineFromModule(module);
|
|
21
23
|
}
|