@opencorestack/opengridx 1.2.2 → 1.2.3
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 +16 -0
- package/dist/index.d.ts +3 -1
- package/dist/opengridx.es.js +2141 -2136
- package/dist/opengridx.es.js.map +1 -1
- package/dist/opengridx.umd.js +10 -10
- package/dist/opengridx.umd.js.map +1 -1
- package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.test.tsx +85 -0
- package/lib/components/ColumnVisibilityPanel/ColumnVisibilityPanel.tsx +7 -4
- package/lib/components/Toolbar/GridToolbar.tsx +8 -1
- package/package.json +1 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { ColumnVisibilityPanel } from './ColumnVisibilityPanel';
|
|
4
|
+
import type { GridColDef } from '../../types';
|
|
5
|
+
|
|
6
|
+
const columns: GridColDef[] = [
|
|
7
|
+
{ field: 'name', headerName: 'Name' },
|
|
8
|
+
{ field: 'department', headerName: 'Department' },
|
|
9
|
+
{ field: 'groupKey', headerName: 'Group Key', hideable: false },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
const visibleColumns = new Set(['name', 'department', 'groupKey']);
|
|
13
|
+
|
|
14
|
+
const noop = () => {};
|
|
15
|
+
|
|
16
|
+
describe('ColumnVisibilityPanel', () => {
|
|
17
|
+
it('excludes hideable:false columns from the list by default', () => {
|
|
18
|
+
render(
|
|
19
|
+
<ColumnVisibilityPanel
|
|
20
|
+
columns={columns}
|
|
21
|
+
visibleColumns={visibleColumns}
|
|
22
|
+
onVisibilityChange={noop}
|
|
23
|
+
onShowAll={noop}
|
|
24
|
+
onHideAll={noop}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
expect(screen.getByText('Name')).toBeInTheDocument();
|
|
28
|
+
expect(screen.getByText('Department')).toBeInTheDocument();
|
|
29
|
+
expect(screen.queryByText('Group Key')).not.toBeInTheDocument();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('shows hideable:false columns as disabled when showNonHideableColumns is true', () => {
|
|
33
|
+
render(
|
|
34
|
+
<ColumnVisibilityPanel
|
|
35
|
+
columns={columns}
|
|
36
|
+
visibleColumns={visibleColumns}
|
|
37
|
+
onVisibilityChange={noop}
|
|
38
|
+
onShowAll={noop}
|
|
39
|
+
onHideAll={noop}
|
|
40
|
+
showNonHideableColumns
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
expect(screen.getByText('Name')).toBeInTheDocument();
|
|
44
|
+
expect(screen.getByText('Department')).toBeInTheDocument();
|
|
45
|
+
expect(screen.getByText('Group Key')).toBeInTheDocument();
|
|
46
|
+
|
|
47
|
+
// 3 columns shown + 1 "Show/Hide All" checkbox in footer = 4 checkboxes
|
|
48
|
+
// The 3rd column (Group Key, hideable:false) must be the disabled one
|
|
49
|
+
const checkboxes = screen.getAllByRole('checkbox');
|
|
50
|
+
const disabledCheckboxes = checkboxes.filter(cb => (cb as HTMLInputElement).disabled);
|
|
51
|
+
expect(disabledCheckboxes).toHaveLength(1);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('does not render a disabled checkbox for hideable:false columns by default', () => {
|
|
55
|
+
render(
|
|
56
|
+
<ColumnVisibilityPanel
|
|
57
|
+
columns={columns}
|
|
58
|
+
visibleColumns={visibleColumns}
|
|
59
|
+
onVisibilityChange={noop}
|
|
60
|
+
onShowAll={noop}
|
|
61
|
+
onHideAll={noop}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
const checkboxes = screen.getAllByRole('checkbox');
|
|
65
|
+
const disabledCheckboxes = checkboxes.filter(cb => (cb as HTMLInputElement).disabled);
|
|
66
|
+
expect(disabledCheckboxes).toHaveLength(0);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('never shows hideable:false columns even when search would match them', () => {
|
|
70
|
+
// Without showNonHideableColumns, hideable:false columns are not in the base list
|
|
71
|
+
// so they cannot appear regardless of search. This test verifies the base list,
|
|
72
|
+
// not a dynamic search interaction.
|
|
73
|
+
render(
|
|
74
|
+
<ColumnVisibilityPanel
|
|
75
|
+
columns={columns}
|
|
76
|
+
visibleColumns={visibleColumns}
|
|
77
|
+
onVisibilityChange={noop}
|
|
78
|
+
onShowAll={noop}
|
|
79
|
+
onHideAll={noop}
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
// "Group Key" is hideable:false — must not appear in the default panel
|
|
83
|
+
expect(screen.queryByText('Group Key')).not.toBeInTheDocument();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -11,6 +11,8 @@ export interface ColumnVisibilityPanelProps<R extends GridRowModel = GridRowMode
|
|
|
11
11
|
onHideAll: () => void;
|
|
12
12
|
onColumnReorder?: (fromField: string, toField: string) => void;
|
|
13
13
|
onColumnOrderReset?: () => void;
|
|
14
|
+
/** Show columns with `hideable: false` in the panel as disabled rows. Default: false. */
|
|
15
|
+
showNonHideableColumns?: boolean;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
function SearchIcon() {
|
|
@@ -44,7 +46,7 @@ function DragHandleIcon() {
|
|
|
44
46
|
export function ColumnVisibilityPanel<R extends GridRowModel = GridRowModel>(
|
|
45
47
|
props: ColumnVisibilityPanelProps<R>
|
|
46
48
|
) {
|
|
47
|
-
const { columns, visibleColumns, onVisibilityChange, onShowAll, onHideAll, onColumnReorder, onColumnOrderReset } = props;
|
|
49
|
+
const { columns, visibleColumns, onVisibilityChange, onShowAll, onHideAll, onColumnReorder, onColumnOrderReset, showNonHideableColumns } = props;
|
|
48
50
|
const [searchQuery, setSearchQuery] = useState('');
|
|
49
51
|
const [dragOverField, setDragOverField] = useState<string | null>(null);
|
|
50
52
|
const dragFieldRef = useRef<string | null>(null);
|
|
@@ -53,12 +55,13 @@ export function ColumnVisibilityPanel<R extends GridRowModel = GridRowModel>(
|
|
|
53
55
|
const allVisible = hideableColumns.every(col => visibleColumns.has(col.field));
|
|
54
56
|
|
|
55
57
|
const filteredColumns = useMemo(() => {
|
|
56
|
-
|
|
58
|
+
const base = showNonHideableColumns ? columns : hideableColumns;
|
|
59
|
+
if (!searchQuery) return base;
|
|
57
60
|
const lowerQuery = searchQuery.toLowerCase();
|
|
58
|
-
return
|
|
61
|
+
return base.filter(col =>
|
|
59
62
|
(col.headerName || col.field).toLowerCase().includes(lowerQuery)
|
|
60
63
|
);
|
|
61
|
-
}, [columns, searchQuery]);
|
|
64
|
+
}, [columns, hideableColumns, searchQuery, showNonHideableColumns]);
|
|
62
65
|
|
|
63
66
|
const handleToggleAll = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
64
67
|
if (e.target.checked) {
|
|
@@ -74,6 +74,8 @@ export interface GridToolbarProps {
|
|
|
74
74
|
renderQuickFilter?: (props: ToolbarQuickFilterRenderProps) => React.ReactNode;
|
|
75
75
|
/** Additional CSS class applied to the toolbar root element. */
|
|
76
76
|
className?: string;
|
|
77
|
+
/** Show columns with `hideable: false` in the Columns panel as disabled rows. Default: false. */
|
|
78
|
+
showNonHideableColumns?: boolean;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
const AGGREGATION_FUNCTIONS = ['none', 'sum', 'avg', 'count', 'min', 'max'] as const;
|
|
@@ -248,7 +250,8 @@ function ColumnsPanelWrapper({
|
|
|
248
250
|
onHideAll,
|
|
249
251
|
onColumnReorder,
|
|
250
252
|
onColumnOrderReset,
|
|
251
|
-
onClose
|
|
253
|
+
onClose,
|
|
254
|
+
showNonHideableColumns,
|
|
252
255
|
}: {
|
|
253
256
|
anchorRef: React.RefObject<HTMLElement | null>;
|
|
254
257
|
columns: GridColDef[];
|
|
@@ -259,6 +262,7 @@ function ColumnsPanelWrapper({
|
|
|
259
262
|
onColumnReorder?: (fromField: string, toField: string) => void;
|
|
260
263
|
onColumnOrderReset?: () => void;
|
|
261
264
|
onClose: () => void;
|
|
265
|
+
showNonHideableColumns?: boolean;
|
|
262
266
|
}) {
|
|
263
267
|
const panelRef = useRef<HTMLDivElement>(null);
|
|
264
268
|
const [pos, setPos] = useState<PanelPosition>({ top: 0, right: 0 });
|
|
@@ -317,6 +321,7 @@ function ColumnsPanelWrapper({
|
|
|
317
321
|
onHideAll={onHideAll}
|
|
318
322
|
onColumnReorder={onColumnReorder}
|
|
319
323
|
onColumnOrderReset={onColumnOrderReset}
|
|
324
|
+
showNonHideableColumns={showNonHideableColumns}
|
|
320
325
|
/>
|
|
321
326
|
</div>
|
|
322
327
|
);
|
|
@@ -464,6 +469,7 @@ export function GridToolbar({
|
|
|
464
469
|
renderExportButton,
|
|
465
470
|
renderQuickFilter,
|
|
466
471
|
className,
|
|
472
|
+
showNonHideableColumns,
|
|
467
473
|
}: GridToolbarProps) {
|
|
468
474
|
const [aggOpen, setAggOpen] = useState(false);
|
|
469
475
|
const [pivotOpen, setPivotOpen] = useState(false);
|
|
@@ -631,6 +637,7 @@ export function GridToolbar({
|
|
|
631
637
|
onColumnReorder={onColumnReorder}
|
|
632
638
|
onColumnOrderReset={onColumnOrderReset}
|
|
633
639
|
onClose={() => { setColsOpen(false); onColumnsPanelClose?.(); }}
|
|
640
|
+
showNonHideableColumns={showNonHideableColumns}
|
|
634
641
|
/>
|
|
635
642
|
)}
|
|
636
643
|
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opencorestack/opengridx",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "OpenGridX: High-performance React data infrastructure. Unlock advanced Row Grouping, Excel Export, and Column Pinning without the usual \"Pro\" gatekeeping. Built for speed, scale, and complete architectural freedom. Fully open, virtualization-ready, and feature-complete.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/opengridx.umd.js",
|