@alaarab/ogrid-react 2.0.9 → 2.0.11
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/esm/components/MarchingAntsOverlay.js +5 -33
- package/dist/esm/hooks/index.js +1 -0
- package/dist/esm/hooks/useColumnHeaderMenuState.js +64 -2
- package/dist/esm/hooks/useDataGridState.js +23 -5
- package/dist/esm/hooks/useDebounce.js +1 -1
- package/dist/esm/hooks/usePaginationControls.js +19 -0
- package/dist/esm/index.js +1 -1
- package/dist/types/components/MarchingAntsOverlay.d.ts +11 -1
- package/dist/types/hooks/index.d.ts +2 -0
- package/dist/types/hooks/useColumnHeaderMenuState.d.ts +21 -1
- package/dist/types/hooks/useDataGridState.d.ts +8 -0
- package/dist/types/hooks/usePaginationControls.d.ts +20 -0
- package/dist/types/index.d.ts +2 -2
- package/package.json +4 -4
|
@@ -8,38 +8,9 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
8
8
|
* Uses SVG rects positioned via cell data-attribute measurements.
|
|
9
9
|
*/
|
|
10
10
|
import { useEffect, useRef, useState, useCallback } from 'react';
|
|
11
|
+
import { measureRange, injectGlobalStyles } from '@alaarab/ogrid-core';
|
|
11
12
|
const MARCHING_ANTS_ANIMATION = { animation: 'ogrid-marching-ants 0.5s linear infinite' };
|
|
12
|
-
|
|
13
|
-
function ensureKeyframes() {
|
|
14
|
-
if (typeof document === 'undefined')
|
|
15
|
-
return;
|
|
16
|
-
if (document.getElementById('ogrid-marching-ants-keyframes'))
|
|
17
|
-
return;
|
|
18
|
-
const style = document.createElement('style');
|
|
19
|
-
style.id = 'ogrid-marching-ants-keyframes';
|
|
20
|
-
style.textContent =
|
|
21
|
-
'@keyframes ogrid-marching-ants{to{stroke-dashoffset:-8}}';
|
|
22
|
-
document.head.appendChild(style);
|
|
23
|
-
}
|
|
24
|
-
/** Measure the bounding rect of a range within a container. */
|
|
25
|
-
function measureRange(container, range, colOffset) {
|
|
26
|
-
const startGlobalCol = range.startCol + colOffset;
|
|
27
|
-
const endGlobalCol = range.endCol + colOffset;
|
|
28
|
-
const topLeft = container.querySelector(`[data-row-index="${range.startRow}"][data-col-index="${startGlobalCol}"]`);
|
|
29
|
-
const bottomRight = container.querySelector(`[data-row-index="${range.endRow}"][data-col-index="${endGlobalCol}"]`);
|
|
30
|
-
if (!topLeft || !bottomRight)
|
|
31
|
-
return null;
|
|
32
|
-
const cRect = container.getBoundingClientRect();
|
|
33
|
-
const tlRect = topLeft.getBoundingClientRect();
|
|
34
|
-
const brRect = bottomRight.getBoundingClientRect();
|
|
35
|
-
return {
|
|
36
|
-
top: tlRect.top - cRect.top,
|
|
37
|
-
left: tlRect.left - cRect.left,
|
|
38
|
-
width: brRect.right - tlRect.left,
|
|
39
|
-
height: brRect.bottom - tlRect.top,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
export function MarchingAntsOverlay({ containerRef, selectionRange, copyRange, cutRange, colOffset, }) {
|
|
13
|
+
export function MarchingAntsOverlay({ containerRef, selectionRange, copyRange, cutRange, colOffset, items, visibleColumns, columnSizingOverrides, columnOrder, }) {
|
|
43
14
|
const [selRect, setSelRect] = useState(null);
|
|
44
15
|
const [clipRect, setClipRect] = useState(null);
|
|
45
16
|
const rafRef = useRef(0);
|
|
@@ -53,10 +24,11 @@ export function MarchingAntsOverlay({ containerRef, selectionRange, copyRange, c
|
|
|
53
24
|
}
|
|
54
25
|
setSelRect(selectionRange ? measureRange(container, selectionRange, colOffset) : null);
|
|
55
26
|
setClipRect(clipRange ? measureRange(container, clipRange, colOffset) : null);
|
|
56
|
-
|
|
27
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
28
|
+
}, [selectionRange, clipRange, containerRef, colOffset, items, visibleColumns, columnSizingOverrides, columnOrder]);
|
|
57
29
|
// Inject keyframes on mount
|
|
58
30
|
useEffect(() => {
|
|
59
|
-
|
|
31
|
+
injectGlobalStyles('ogrid-marching-ants-keyframes', '@keyframes ogrid-marching-ants{to{stroke-dashoffset:-8}}');
|
|
60
32
|
}, []);
|
|
61
33
|
// Measure when any range changes; re-measure on resize
|
|
62
34
|
useEffect(() => {
|
package/dist/esm/hooks/index.js
CHANGED
|
@@ -27,3 +27,4 @@ export { useTableLayout } from './useTableLayout';
|
|
|
27
27
|
export { useColumnReorder } from './useColumnReorder';
|
|
28
28
|
export { useVirtualScroll } from './useVirtualScroll';
|
|
29
29
|
export { useLatestRef } from './useLatestRef';
|
|
30
|
+
export { usePaginationControls } from './usePaginationControls';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useState, useCallback } from 'react';
|
|
2
2
|
/**
|
|
3
|
-
* Manages state for the column header menu (pin
|
|
3
|
+
* Manages state for the column header menu (pin, sort, autosize actions).
|
|
4
4
|
* Tracks which column's menu is open, anchor element, and action handlers.
|
|
5
5
|
*/
|
|
6
6
|
export function useColumnHeaderMenuState(params) {
|
|
7
|
-
const { pinnedColumns, onPinColumn, onUnpinColumn } = params;
|
|
7
|
+
const { pinnedColumns, onPinColumn, onUnpinColumn, sortBy, sortDirection, onColumnSort, onColumnResized, columns, data: _data, getRowId: _getRowId, } = params;
|
|
8
8
|
const [isOpen, setIsOpen] = useState(false);
|
|
9
9
|
const [openForColumn, setOpenForColumn] = useState(null);
|
|
10
10
|
const [anchorElement, setAnchorElement] = useState(null);
|
|
@@ -22,6 +22,10 @@ export function useColumnHeaderMenuState(params) {
|
|
|
22
22
|
const canPinLeft = currentPinState !== 'left';
|
|
23
23
|
const canPinRight = currentPinState !== 'right';
|
|
24
24
|
const canUnpin = !!currentPinState;
|
|
25
|
+
const currentColumn = columns.find((c) => c.columnId === openForColumn);
|
|
26
|
+
const currentSort = openForColumn === sortBy ? sortDirection : null;
|
|
27
|
+
const isSortable = currentColumn?.sortable !== false;
|
|
28
|
+
const isResizable = currentColumn?.resizable !== false;
|
|
25
29
|
const handlePinLeft = useCallback(() => {
|
|
26
30
|
if (openForColumn && canPinLeft) {
|
|
27
31
|
onPinColumn(openForColumn, 'left');
|
|
@@ -40,6 +44,56 @@ export function useColumnHeaderMenuState(params) {
|
|
|
40
44
|
close();
|
|
41
45
|
}
|
|
42
46
|
}, [openForColumn, canUnpin, onUnpinColumn, close]);
|
|
47
|
+
const handleSortAsc = useCallback(() => {
|
|
48
|
+
if (openForColumn && isSortable) {
|
|
49
|
+
onColumnSort(openForColumn);
|
|
50
|
+
close();
|
|
51
|
+
}
|
|
52
|
+
}, [openForColumn, isSortable, onColumnSort, close]);
|
|
53
|
+
const handleSortDesc = useCallback(() => {
|
|
54
|
+
if (openForColumn && isSortable) {
|
|
55
|
+
onColumnSort(openForColumn);
|
|
56
|
+
close();
|
|
57
|
+
}
|
|
58
|
+
}, [openForColumn, isSortable, onColumnSort, close]);
|
|
59
|
+
const handleClearSort = useCallback(() => {
|
|
60
|
+
if (openForColumn && isSortable) {
|
|
61
|
+
onColumnSort(openForColumn);
|
|
62
|
+
close();
|
|
63
|
+
}
|
|
64
|
+
}, [openForColumn, isSortable, onColumnSort, close]);
|
|
65
|
+
const handleAutosizeThis = useCallback(() => {
|
|
66
|
+
if (!openForColumn || !onColumnResized || !isResizable)
|
|
67
|
+
return;
|
|
68
|
+
// Measure column content width
|
|
69
|
+
const cells = document.querySelectorAll(`[data-column-id="${openForColumn}"]`);
|
|
70
|
+
let maxWidth = 100; // Minimum width
|
|
71
|
+
cells.forEach((cell) => {
|
|
72
|
+
const textContent = cell.textContent || '';
|
|
73
|
+
// Rough estimate: 8px per character + 32px padding
|
|
74
|
+
const estimatedWidth = Math.min(textContent.length * 8 + 32, 500);
|
|
75
|
+
maxWidth = Math.max(maxWidth, estimatedWidth);
|
|
76
|
+
});
|
|
77
|
+
onColumnResized(openForColumn, maxWidth);
|
|
78
|
+
close();
|
|
79
|
+
}, [openForColumn, onColumnResized, isResizable, close]);
|
|
80
|
+
const handleAutosizeAll = useCallback(() => {
|
|
81
|
+
if (!onColumnResized)
|
|
82
|
+
return;
|
|
83
|
+
columns.forEach((col) => {
|
|
84
|
+
if (col.resizable === false)
|
|
85
|
+
return;
|
|
86
|
+
const cells = document.querySelectorAll(`[data-column-id="${col.columnId}"]`);
|
|
87
|
+
let maxWidth = 100;
|
|
88
|
+
cells.forEach((cell) => {
|
|
89
|
+
const textContent = cell.textContent || '';
|
|
90
|
+
const estimatedWidth = Math.min(textContent.length * 8 + 32, 500);
|
|
91
|
+
maxWidth = Math.max(maxWidth, estimatedWidth);
|
|
92
|
+
});
|
|
93
|
+
onColumnResized(col.columnId, maxWidth);
|
|
94
|
+
});
|
|
95
|
+
close();
|
|
96
|
+
}, [columns, onColumnResized, close]);
|
|
43
97
|
return {
|
|
44
98
|
isOpen,
|
|
45
99
|
openForColumn,
|
|
@@ -49,8 +103,16 @@ export function useColumnHeaderMenuState(params) {
|
|
|
49
103
|
handlePinLeft,
|
|
50
104
|
handlePinRight,
|
|
51
105
|
handleUnpin,
|
|
106
|
+
handleSortAsc,
|
|
107
|
+
handleSortDesc,
|
|
108
|
+
handleClearSort,
|
|
109
|
+
handleAutosizeThis,
|
|
110
|
+
handleAutosizeAll,
|
|
52
111
|
canPinLeft,
|
|
53
112
|
canPinRight,
|
|
54
113
|
canUnpin,
|
|
114
|
+
currentSort,
|
|
115
|
+
isSortable,
|
|
116
|
+
isResizable,
|
|
55
117
|
};
|
|
56
118
|
}
|
|
@@ -150,11 +150,6 @@ export function useDataGridState(params) {
|
|
|
150
150
|
pinnedColumns,
|
|
151
151
|
onColumnPinned,
|
|
152
152
|
});
|
|
153
|
-
const headerMenuResult = useColumnHeaderMenuState({
|
|
154
|
-
pinnedColumns: pinningResult.pinnedColumns,
|
|
155
|
-
onPinColumn: pinningResult.pinColumn,
|
|
156
|
-
onUnpinColumn: pinningResult.unpinColumn,
|
|
157
|
-
});
|
|
158
153
|
const aggregation = useMemo(() => computeAggregations(items, visibleCols, cellSelection ? selectionRange : null), [items, visibleCols, selectionRange, cellSelection]);
|
|
159
154
|
const statusBarConfig = useMemo(() => {
|
|
160
155
|
const base = getDataGridStatusBarConfig(statusBar, items.length, selectedRowIds.size);
|
|
@@ -175,6 +170,18 @@ export function useDataGridState(params) {
|
|
|
175
170
|
const stableOnColumnSort = useCallback((columnKey) => onColumnSortRef.current?.(columnKey),
|
|
176
171
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
177
172
|
[]);
|
|
173
|
+
const headerMenuResult = useColumnHeaderMenuState({
|
|
174
|
+
pinnedColumns: pinningResult.pinnedColumns,
|
|
175
|
+
onPinColumn: pinningResult.pinColumn,
|
|
176
|
+
onUnpinColumn: pinningResult.unpinColumn,
|
|
177
|
+
sortBy,
|
|
178
|
+
sortDirection,
|
|
179
|
+
onColumnSort: stableOnColumnSort,
|
|
180
|
+
onColumnResized,
|
|
181
|
+
columns: flatColumns,
|
|
182
|
+
data: items,
|
|
183
|
+
getRowId: getRowId,
|
|
184
|
+
});
|
|
178
185
|
const stableOnFilterChange = useCallback((...args) => onFilterChangeRef.current?.(...args),
|
|
179
186
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
180
187
|
[]);
|
|
@@ -337,9 +344,17 @@ export function useDataGridState(params) {
|
|
|
337
344
|
handlePinLeft: headerMenuResult.handlePinLeft,
|
|
338
345
|
handlePinRight: headerMenuResult.handlePinRight,
|
|
339
346
|
handleUnpin: headerMenuResult.handleUnpin,
|
|
347
|
+
handleSortAsc: headerMenuResult.handleSortAsc,
|
|
348
|
+
handleSortDesc: headerMenuResult.handleSortDesc,
|
|
349
|
+
handleClearSort: headerMenuResult.handleClearSort,
|
|
350
|
+
handleAutosizeThis: headerMenuResult.handleAutosizeThis,
|
|
351
|
+
handleAutosizeAll: headerMenuResult.handleAutosizeAll,
|
|
340
352
|
canPinLeft: headerMenuResult.canPinLeft,
|
|
341
353
|
canPinRight: headerMenuResult.canPinRight,
|
|
342
354
|
canUnpin: headerMenuResult.canUnpin,
|
|
355
|
+
currentSort: headerMenuResult.currentSort,
|
|
356
|
+
isSortable: headerMenuResult.isSortable,
|
|
357
|
+
isResizable: headerMenuResult.isResizable,
|
|
343
358
|
},
|
|
344
359
|
}), [
|
|
345
360
|
pinningResult.pinnedColumns, pinningResult.pinColumn, pinningResult.unpinColumn,
|
|
@@ -347,7 +362,10 @@ export function useDataGridState(params) {
|
|
|
347
362
|
headerMenuResult.isOpen, headerMenuResult.openForColumn, headerMenuResult.anchorElement,
|
|
348
363
|
headerMenuResult.open, headerMenuResult.close, headerMenuResult.handlePinLeft,
|
|
349
364
|
headerMenuResult.handlePinRight, headerMenuResult.handleUnpin,
|
|
365
|
+
headerMenuResult.handleSortAsc, headerMenuResult.handleSortDesc, headerMenuResult.handleClearSort,
|
|
366
|
+
headerMenuResult.handleAutosizeThis, headerMenuResult.handleAutosizeAll,
|
|
350
367
|
headerMenuResult.canPinLeft, headerMenuResult.canPinRight, headerMenuResult.canUnpin,
|
|
368
|
+
headerMenuResult.currentSort, headerMenuResult.isSortable, headerMenuResult.isResizable,
|
|
351
369
|
]);
|
|
352
370
|
return {
|
|
353
371
|
layout: layoutState,
|
|
@@ -17,7 +17,7 @@ export function useDebounce(value, delayMs) {
|
|
|
17
17
|
* Each new call resets the timer.
|
|
18
18
|
*/
|
|
19
19
|
export function useDebouncedCallback(fn, delayMs) {
|
|
20
|
-
const timeoutRef = useRef();
|
|
20
|
+
const timeoutRef = useRef(undefined);
|
|
21
21
|
const fnRef = useRef(fn);
|
|
22
22
|
fnRef.current = fn;
|
|
23
23
|
const debounced = useCallback(((...args) => {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useMemo, useCallback } from 'react';
|
|
2
|
+
import { getPaginationViewModel } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Shared pagination controls logic for React UI packages.
|
|
5
|
+
* Computes pagination view model and provides standardized handlers.
|
|
6
|
+
*/
|
|
7
|
+
export function usePaginationControls(props) {
|
|
8
|
+
const { currentPage, pageSize, totalCount, onPageSizeChange, pageSizeOptions, entityLabelPlural } = props;
|
|
9
|
+
const labelPlural = entityLabelPlural ?? 'items';
|
|
10
|
+
const vm = useMemo(() => getPaginationViewModel(currentPage, pageSize, totalCount, pageSizeOptions ? { pageSizeOptions } : undefined), [currentPage, pageSize, totalCount, pageSizeOptions]);
|
|
11
|
+
const handlePageSizeChange = useCallback((value) => {
|
|
12
|
+
onPageSizeChange(value);
|
|
13
|
+
}, [onPageSizeChange]);
|
|
14
|
+
return {
|
|
15
|
+
labelPlural,
|
|
16
|
+
vm,
|
|
17
|
+
handlePageSizeChange,
|
|
18
|
+
};
|
|
19
|
+
}
|
package/dist/esm/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export { CHECKBOX_COLUMN_WIDTH, ROW_NUMBER_COLUMN_WIDTH, DEFAULT_MIN_COLUMN_WIDTH, CELL_PADDING, GRID_BORDER_RADIUS, } from '@alaarab/ogrid-core';
|
|
3
3
|
export { toUserLike, isInSelectionRange, normalizeSelectionRange } from './types';
|
|
4
4
|
// Hooks
|
|
5
|
-
export { useFilterOptions, useOGrid, useActiveCell, useCellEditing, useContextMenu, useCellSelection, useClipboard, useRowSelection, useKeyboardNavigation, useUndoRedo, useDebounce, useFillHandle, useDataGridState, useColumnHeaderFilterState, useTextFilterState, useMultiSelectFilterState, usePeopleFilterState, useDateFilterState, useColumnChooserState, useInlineCellEditorState, useColumnResize, useRichSelectState, useSideBarState, useTableLayout, useColumnReorder, useVirtualScroll, useLatestRef, } from './hooks';
|
|
5
|
+
export { useFilterOptions, useOGrid, useActiveCell, useCellEditing, useContextMenu, useCellSelection, useClipboard, useRowSelection, useKeyboardNavigation, useUndoRedo, useDebounce, useFillHandle, useDataGridState, useColumnHeaderFilterState, useTextFilterState, useMultiSelectFilterState, usePeopleFilterState, useDateFilterState, useColumnChooserState, useInlineCellEditorState, useColumnResize, useRichSelectState, useSideBarState, useTableLayout, useColumnReorder, useVirtualScroll, useLatestRef, usePaginationControls, } from './hooks';
|
|
6
6
|
// Components
|
|
7
7
|
export { OGridLayout } from './components/OGridLayout';
|
|
8
8
|
export { StatusBar } from './components/StatusBar';
|
|
@@ -11,5 +11,15 @@ export interface MarchingAntsOverlayProps {
|
|
|
11
11
|
cutRange: ISelectionRange | null;
|
|
12
12
|
/** Column offset — 1 when checkbox column is present, else 0 */
|
|
13
13
|
colOffset: number;
|
|
14
|
+
/** Items array — triggers re-measurement when data changes (e.g., sorting) */
|
|
15
|
+
items: readonly unknown[];
|
|
16
|
+
/** Visible columns — triggers re-measurement when columns are hidden/shown */
|
|
17
|
+
visibleColumns: Set<string> | undefined;
|
|
18
|
+
/** Column sizing overrides — triggers re-measurement when columns are resized */
|
|
19
|
+
columnSizingOverrides: Record<string, {
|
|
20
|
+
widthPx: number;
|
|
21
|
+
}>;
|
|
22
|
+
/** Column order — triggers re-measurement when columns are reordered */
|
|
23
|
+
columnOrder: readonly string[] | undefined;
|
|
14
24
|
}
|
|
15
|
-
export declare function MarchingAntsOverlay({ containerRef, selectionRange, copyRange, cutRange, colOffset, }: MarchingAntsOverlayProps): React.ReactElement | null;
|
|
25
|
+
export declare function MarchingAntsOverlay({ containerRef, selectionRange, copyRange, cutRange, colOffset, items, visibleColumns, columnSizingOverrides, columnOrder, }: MarchingAntsOverlayProps): React.ReactElement | null;
|
|
@@ -54,3 +54,5 @@ export type { UseColumnReorderParams, UseColumnReorderResult, } from './useColum
|
|
|
54
54
|
export { useVirtualScroll } from './useVirtualScroll';
|
|
55
55
|
export type { IVirtualScrollConfig, UseVirtualScrollParams, UseVirtualScrollResult, } from './useVirtualScroll';
|
|
56
56
|
export { useLatestRef } from './useLatestRef';
|
|
57
|
+
export { usePaginationControls } from './usePaginationControls';
|
|
58
|
+
export type { UsePaginationControlsProps, UsePaginationControlsResult, } from './usePaginationControls';
|
|
@@ -2,6 +2,18 @@ export interface UseColumnHeaderMenuStateParams {
|
|
|
2
2
|
pinnedColumns: Record<string, 'left' | 'right'>;
|
|
3
3
|
onPinColumn: (columnId: string, side: 'left' | 'right') => void;
|
|
4
4
|
onUnpinColumn: (columnId: string) => void;
|
|
5
|
+
sortBy?: string;
|
|
6
|
+
sortDirection: 'asc' | 'desc';
|
|
7
|
+
onColumnSort: (columnKey: string) => void;
|
|
8
|
+
onColumnResized?: (columnId: string, width: number) => void;
|
|
9
|
+
columns: Array<{
|
|
10
|
+
columnId: string;
|
|
11
|
+
width?: number;
|
|
12
|
+
sortable?: boolean;
|
|
13
|
+
resizable?: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
data: unknown[];
|
|
16
|
+
getRowId: (item: unknown) => string | number;
|
|
5
17
|
}
|
|
6
18
|
export interface UseColumnHeaderMenuStateResult {
|
|
7
19
|
isOpen: boolean;
|
|
@@ -12,12 +24,20 @@ export interface UseColumnHeaderMenuStateResult {
|
|
|
12
24
|
handlePinLeft: () => void;
|
|
13
25
|
handlePinRight: () => void;
|
|
14
26
|
handleUnpin: () => void;
|
|
27
|
+
handleSortAsc: () => void;
|
|
28
|
+
handleSortDesc: () => void;
|
|
29
|
+
handleClearSort: () => void;
|
|
30
|
+
handleAutosizeThis: () => void;
|
|
31
|
+
handleAutosizeAll: () => void;
|
|
15
32
|
canPinLeft: boolean;
|
|
16
33
|
canPinRight: boolean;
|
|
17
34
|
canUnpin: boolean;
|
|
35
|
+
currentSort: 'asc' | 'desc' | null;
|
|
36
|
+
isSortable: boolean;
|
|
37
|
+
isResizable: boolean;
|
|
18
38
|
}
|
|
19
39
|
/**
|
|
20
|
-
* Manages state for the column header menu (pin
|
|
40
|
+
* Manages state for the column header menu (pin, sort, autosize actions).
|
|
21
41
|
* Tracks which column's menu is open, anchor element, and action handlers.
|
|
22
42
|
*/
|
|
23
43
|
export declare function useColumnHeaderMenuState(params: UseColumnHeaderMenuStateParams): UseColumnHeaderMenuStateResult;
|
|
@@ -143,9 +143,17 @@ export interface DataGridPinningState {
|
|
|
143
143
|
handlePinLeft: () => void;
|
|
144
144
|
handlePinRight: () => void;
|
|
145
145
|
handleUnpin: () => void;
|
|
146
|
+
handleSortAsc: () => void;
|
|
147
|
+
handleSortDesc: () => void;
|
|
148
|
+
handleClearSort: () => void;
|
|
149
|
+
handleAutosizeThis: () => void;
|
|
150
|
+
handleAutosizeAll: () => void;
|
|
146
151
|
canPinLeft: boolean;
|
|
147
152
|
canPinRight: boolean;
|
|
148
153
|
canUnpin: boolean;
|
|
154
|
+
currentSort: 'asc' | 'desc' | null;
|
|
155
|
+
isSortable: boolean;
|
|
156
|
+
isResizable: boolean;
|
|
149
157
|
};
|
|
150
158
|
}
|
|
151
159
|
/** Grouped result from useDataGridState. */
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getPaginationViewModel } from '../utils';
|
|
2
|
+
export interface UsePaginationControlsProps {
|
|
3
|
+
currentPage: number;
|
|
4
|
+
pageSize: number;
|
|
5
|
+
totalCount: number;
|
|
6
|
+
onPageChange: (page: number) => void;
|
|
7
|
+
onPageSizeChange: (pageSize: number) => void;
|
|
8
|
+
pageSizeOptions?: number[];
|
|
9
|
+
entityLabelPlural?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface UsePaginationControlsResult {
|
|
12
|
+
labelPlural: string;
|
|
13
|
+
vm: ReturnType<typeof getPaginationViewModel>;
|
|
14
|
+
handlePageSizeChange: (value: number) => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Shared pagination controls logic for React UI packages.
|
|
18
|
+
* Computes pagination view model and provides standardized handlers.
|
|
19
|
+
*/
|
|
20
|
+
export declare function usePaginationControls(props: UsePaginationControlsProps): UsePaginationControlsResult;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { CHECKBOX_COLUMN_WIDTH, ROW_NUMBER_COLUMN_WIDTH, DEFAULT_MIN_COLUMN_WIDTH, CELL_PADDING, GRID_BORDER_RADIUS, } from '@alaarab/ogrid-core';
|
|
2
2
|
export type { ColumnFilterType, IColumnFilterDef, IColumnMeta, IColumnDef, IColumnGroupDef, IColumnDefinition, ICellValueChangedEvent, ICellEditorProps, CellEditorParams, IValueParserParams, UserLike, UserLikeInput, FilterValue, IFilters, IFetchParams, IPageResult, IDataSource, IGridColumnState, IOGridApi, IOGridProps, IOGridDataGridProps, RowSelectionMode, RowId, IRowSelectionChangeEvent, StatusBarPanel, IStatusBarProps, IActiveCell, ISelectionRange, HeaderCell, HeaderRow, SideBarPanelId, ISideBarDef, IDateFilterValue, IVirtualScrollConfig, IColumnReorderConfig, } from './types';
|
|
3
3
|
export { toUserLike, isInSelectionRange, normalizeSelectionRange } from './types';
|
|
4
|
-
export { useFilterOptions, useOGrid, useActiveCell, useCellEditing, useContextMenu, useCellSelection, useClipboard, useRowSelection, useKeyboardNavigation, useUndoRedo, useDebounce, useFillHandle, useDataGridState, useColumnHeaderFilterState, useTextFilterState, useMultiSelectFilterState, usePeopleFilterState, useDateFilterState, useColumnChooserState, useInlineCellEditorState, useColumnResize, useRichSelectState, useSideBarState, useTableLayout, useColumnReorder, useVirtualScroll, useLatestRef, } from './hooks';
|
|
5
|
-
export type { UseFilterOptionsResult, UseOGridResult, UseOGridPagination, UseOGridColumnChooser, UseOGridLayout, UseOGridFilters, ColumnChooserPlacement, UseActiveCellResult, UseCellEditingResult, EditingCell, UseContextMenuResult, ContextMenuPosition, UseCellSelectionResult, UseCellSelectionParams, UseClipboardResult, UseClipboardParams, UseRowSelectionResult, UseRowSelectionParams, UseKeyboardNavigationResult, UseKeyboardNavigationParams, UseUndoRedoResult, UseUndoRedoParams, UseFillHandleResult, UseFillHandleParams, UseDataGridStateParams, UseDataGridStateResult, DataGridLayoutState, DataGridRowSelectionState, DataGridEditingState, DataGridCellInteractionState, DataGridContextMenuState, DataGridViewModelState, UseColumnHeaderFilterStateParams, UseColumnHeaderFilterStateResult, UseTextFilterStateParams, UseTextFilterStateResult, UseMultiSelectFilterStateParams, UseMultiSelectFilterStateResult, UsePeopleFilterStateParams, UsePeopleFilterStateResult, UseDateFilterStateParams, UseDateFilterStateResult, UseColumnChooserStateParams, UseColumnChooserStateResult, UseInlineCellEditorStateParams, UseInlineCellEditorStateResult, InlineCellEditorType, UseColumnResizeParams, UseColumnResizeResult, UseRichSelectStateParams, UseRichSelectStateResult, UseSideBarStateParams, UseSideBarStateResult, UseTableLayoutParams, UseTableLayoutResult, UseColumnReorderParams, UseColumnReorderResult, UseVirtualScrollParams, UseVirtualScrollResult, } from './hooks';
|
|
4
|
+
export { useFilterOptions, useOGrid, useActiveCell, useCellEditing, useContextMenu, useCellSelection, useClipboard, useRowSelection, useKeyboardNavigation, useUndoRedo, useDebounce, useFillHandle, useDataGridState, useColumnHeaderFilterState, useTextFilterState, useMultiSelectFilterState, usePeopleFilterState, useDateFilterState, useColumnChooserState, useInlineCellEditorState, useColumnResize, useRichSelectState, useSideBarState, useTableLayout, useColumnReorder, useVirtualScroll, useLatestRef, usePaginationControls, } from './hooks';
|
|
5
|
+
export type { UseFilterOptionsResult, UseOGridResult, UseOGridPagination, UseOGridColumnChooser, UseOGridLayout, UseOGridFilters, ColumnChooserPlacement, UseActiveCellResult, UseCellEditingResult, EditingCell, UseContextMenuResult, ContextMenuPosition, UseCellSelectionResult, UseCellSelectionParams, UseClipboardResult, UseClipboardParams, UseRowSelectionResult, UseRowSelectionParams, UseKeyboardNavigationResult, UseKeyboardNavigationParams, UseUndoRedoResult, UseUndoRedoParams, UseFillHandleResult, UseFillHandleParams, UseDataGridStateParams, UseDataGridStateResult, DataGridLayoutState, DataGridRowSelectionState, DataGridEditingState, DataGridCellInteractionState, DataGridContextMenuState, DataGridViewModelState, UseColumnHeaderFilterStateParams, UseColumnHeaderFilterStateResult, UseTextFilterStateParams, UseTextFilterStateResult, UseMultiSelectFilterStateParams, UseMultiSelectFilterStateResult, UsePeopleFilterStateParams, UsePeopleFilterStateResult, UseDateFilterStateParams, UseDateFilterStateResult, UseColumnChooserStateParams, UseColumnChooserStateResult, UseInlineCellEditorStateParams, UseInlineCellEditorStateResult, InlineCellEditorType, UseColumnResizeParams, UseColumnResizeResult, UseRichSelectStateParams, UseRichSelectStateResult, UseSideBarStateParams, UseSideBarStateResult, UseTableLayoutParams, UseTableLayoutResult, UseColumnReorderParams, UseColumnReorderResult, UseVirtualScrollParams, UseVirtualScrollResult, UsePaginationControlsProps, UsePaginationControlsResult, } from './hooks';
|
|
6
6
|
export { OGridLayout } from './components/OGridLayout';
|
|
7
7
|
export type { OGridLayoutProps } from './components/OGridLayout';
|
|
8
8
|
export { StatusBar } from './components/StatusBar';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alaarab/ogrid-react",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.11",
|
|
4
4
|
"description": "OGrid React – React hooks, headless components, and utilities for OGrid data grids.",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"node": ">=18"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@alaarab/ogrid-core": "2.0.
|
|
39
|
+
"@alaarab/ogrid-core": "2.0.11"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@tanstack/react-virtual": "^3.0.0",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"@testing-library/jest-dom": "^6.9.1",
|
|
52
52
|
"@testing-library/react": "^16.3.2",
|
|
53
53
|
"@testing-library/user-event": "^14.6.1",
|
|
54
|
-
"@types/react": "^
|
|
55
|
-
"@types/react-dom": "^
|
|
54
|
+
"@types/react": "^19.0.0",
|
|
55
|
+
"@types/react-dom": "^19.0.0",
|
|
56
56
|
"react": "^18.3.1",
|
|
57
57
|
"react-dom": "^18.3.1"
|
|
58
58
|
},
|