@opencorestack/opengridx 0.1.8 → 0.1.9

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.
@@ -62,39 +62,7 @@ function CellImpl<R extends GridRowModel = GridRowModel>(props: CellProps<R>) {
62
62
  isHiddenByRowSpan
63
63
  } = props;
64
64
 
65
- if (colSpanInfo?.spannedByColSpan) {
66
-
67
- return null;
68
- }
69
-
70
- if (isHiddenByRowSpan) {
71
-
72
- return (
73
- <div
74
- className="ogx__cell ogx__cell--hidden"
75
- style={{ width: width ?? colDef.width ?? 100 }}
76
- role="presentation"
77
- data-field={colDef.field}
78
- data-colindex={colIndex}
79
- />
80
- );
81
- }
82
-
83
- const handleClick = (e: React.MouseEvent) => {
84
- if (onCellClick) {
85
- e.stopPropagation();
86
- onCellClick({
87
- row,
88
- field: colDef.field,
89
- value,
90
- colDef,
91
- rowIndex,
92
- colIndex
93
- });
94
- }
95
- onClick?.(e);
96
- };
97
-
65
+ // All hooks must come before any early returns (Rules of Hooks)
98
66
  const handleValueChange = React.useCallback((newValue: any) => {
99
67
  if (onCellValueChange) {
100
68
  onCellValueChange(colDef.field, newValue);
@@ -103,17 +71,6 @@ function CellImpl<R extends GridRowModel = GridRowModel>(props: CellProps<R>) {
103
71
  }
104
72
  }, [onCellValueChange, onValueChange, colDef.field]);
105
73
 
106
- const handleDoubleClick = (e: React.MouseEvent) => {
107
- if (isEditable && (onEditStart || onCellEditStart)) {
108
- e.stopPropagation();
109
- if (onCellEditStart) {
110
- onCellEditStart(colDef.field, value);
111
- } else {
112
- onEditStart?.();
113
- }
114
- }
115
- };
116
-
117
74
  const formattedValue = React.useMemo(() => {
118
75
  if (colDef.valueFormatter) {
119
76
  return colDef.valueFormatter({
@@ -130,7 +87,6 @@ function CellImpl<R extends GridRowModel = GridRowModel>(props: CellProps<R>) {
130
87
  return String(value);
131
88
  }, [value, row, colDef]);
132
89
 
133
- // Render custom cell content OR Edit Content
134
90
  const cellContent = React.useMemo(() => {
135
91
  if (isEditing && (onCellValueChange || onValueChange) && onEditStop) {
136
92
  if (colDef.renderEditCell) {
@@ -172,8 +128,6 @@ function CellImpl<R extends GridRowModel = GridRowModel>(props: CellProps<R>) {
172
128
  return formattedValue;
173
129
  }, [value, row, colDef, rowIndex, colIndex, formattedValue, isEditing, handleValueChange, onEditStop, onCellValueChange, onValueChange]);
174
130
 
175
- const isPinned = pinnedPosition !== null && pinnedPosition !== undefined;
176
-
177
131
  const resolvedCellClassName = React.useMemo(() => {
178
132
  if (!colDef.cellClassName) return '';
179
133
  if (typeof colDef.cellClassName === 'function') {
@@ -182,6 +136,58 @@ function CellImpl<R extends GridRowModel = GridRowModel>(props: CellProps<R>) {
182
136
  return colDef.cellClassName;
183
137
  }, [colDef, value, row, rowIndex, colIndex]);
184
138
 
139
+ const cellRef = React.useRef<HTMLDivElement>(null);
140
+
141
+ React.useLayoutEffect(() => {
142
+ if (isFocused && cellRef.current) {
143
+ cellRef.current.focus({ preventScroll: true });
144
+ }
145
+ }, [isFocused]);
146
+
147
+ if (colSpanInfo?.spannedByColSpan) {
148
+ return null;
149
+ }
150
+
151
+ if (isHiddenByRowSpan) {
152
+ return (
153
+ <div
154
+ className="ogx__cell ogx__cell--hidden"
155
+ style={{ width: width ?? colDef.width ?? 100 }}
156
+ role="presentation"
157
+ data-field={colDef.field}
158
+ data-colindex={colIndex}
159
+ />
160
+ );
161
+ }
162
+
163
+ const handleClick = (e: React.MouseEvent) => {
164
+ if (onCellClick) {
165
+ e.stopPropagation();
166
+ onCellClick({
167
+ row,
168
+ field: colDef.field,
169
+ value,
170
+ colDef,
171
+ rowIndex,
172
+ colIndex
173
+ });
174
+ }
175
+ onClick?.(e);
176
+ };
177
+
178
+ const handleDoubleClick = (e: React.MouseEvent) => {
179
+ if (isEditable && (onEditStart || onCellEditStart)) {
180
+ e.stopPropagation();
181
+ if (onCellEditStart) {
182
+ onCellEditStart(colDef.field, value);
183
+ } else {
184
+ onEditStart?.();
185
+ }
186
+ }
187
+ };
188
+
189
+ const isPinned = pinnedPosition !== null && pinnedPosition !== undefined;
190
+
185
191
  const classNames = [
186
192
  'ogx__cell',
187
193
  `ogx__cell--align-${colDef.align || 'left'}`,
@@ -230,14 +236,6 @@ function CellImpl<R extends GridRowModel = GridRowModel>(props: CellProps<R>) {
230
236
  }
231
237
  }
232
238
 
233
- const cellRef = React.useRef<HTMLDivElement>(null);
234
-
235
- React.useLayoutEffect(() => {
236
- if (isFocused && cellRef.current) {
237
- cellRef.current.focus({ preventScroll: true });
238
- }
239
- }, [isFocused]);
240
-
241
239
  return (
242
240
  <div
243
241
  ref={cellRef}
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+ import { describe, it, expect } from 'vitest';
3
+ import { render, screen } from '@testing-library/react';
4
+ import { DataGrid } from './DataGrid';
5
+ import type { GridColDef } from '../../types';
6
+
7
+ const COLUMNS: GridColDef[] = [
8
+ { field: 'id', headerName: 'ID', width: 80 },
9
+ { field: 'name', headerName: 'Name', width: 150 },
10
+ { field: 'age', headerName: 'Age', width: 100, type: 'number' },
11
+ ];
12
+
13
+ const ROWS = [
14
+ { id: 1, name: 'Alice', age: 30 },
15
+ { id: 2, name: 'Bob', age: 25 },
16
+ { id: 3, name: 'Charlie', age: 35 },
17
+ ];
18
+
19
+ describe('DataGrid — smoke tests', () => {
20
+ it('renders without throwing', () => {
21
+ expect(() =>
22
+ render(<DataGrid rows={ROWS} columns={COLUMNS} />)
23
+ ).not.toThrow();
24
+ });
25
+
26
+ it('renders column headers', () => {
27
+ render(<DataGrid rows={ROWS} columns={COLUMNS} />);
28
+ expect(screen.getByText('Name')).toBeInTheDocument();
29
+ expect(screen.getByText('Age')).toBeInTheDocument();
30
+ });
31
+
32
+ it('renders row data', () => {
33
+ render(<DataGrid rows={ROWS} columns={COLUMNS} />);
34
+ expect(screen.getByText('Alice')).toBeInTheDocument();
35
+ expect(screen.getByText('Bob')).toBeInTheDocument();
36
+ expect(screen.getByText('Charlie')).toBeInTheDocument();
37
+ });
38
+
39
+ it('renders with empty rows without throwing', () => {
40
+ expect(() =>
41
+ render(<DataGrid rows={[]} columns={COLUMNS} />)
42
+ ).not.toThrow();
43
+ });
44
+
45
+ it('renders with empty columns without throwing', () => {
46
+ expect(() =>
47
+ render(<DataGrid rows={ROWS} columns={[]} />)
48
+ ).not.toThrow();
49
+ });
50
+
51
+ it('renders with checkboxSelection enabled', () => {
52
+ const { container } = render(
53
+ <DataGrid rows={ROWS} columns={COLUMNS} checkboxSelection />
54
+ );
55
+ const checkboxes = container.querySelectorAll('input[type="checkbox"]');
56
+ expect(checkboxes.length).toBeGreaterThan(0);
57
+ });
58
+ });