@noraent/nora-datagrid 0.0.11 → 0.0.13

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/lib/cjs/App.js CHANGED
@@ -1,11 +1,17 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React from "react";
3
2
  import { DataGrid } from "./DataGrid";
3
+ import { useGridApiRef } from "./hooks/useGridApiRef";
4
+ const RenderCell = (params) => {
5
+ return _jsx("div", { style: { background: "green" }, children: params.value });
6
+ };
7
+ const RenderEditCell = (params) => {
8
+ return _jsx("input", Object.assign({}, params, { style: { background: "yellow" } }));
9
+ };
4
10
  function App() {
5
- const ref = React.useRef(null);
11
+ // const ref = React.useRef<GirdApi>(null);
12
+ const ref = useGridApiRef();
6
13
  return (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => {
7
- var _a;
8
- console.log("!!!!!", (_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.getData());
14
+ console.log("!!!!!", ref.current.getData());
9
15
  }, children: "dd" }), _jsx("button", { children: "dd" }), _jsx("div", { style: { width: "1200px", height: "100%", maxHeight: "600px" }, children: _jsx(DataGrid, { gridRef: ref, columns: [
10
16
  {
11
17
  fieldId: "firstName",
@@ -15,6 +21,8 @@ function App() {
15
21
  fieldId: "lastName",
16
22
  fieldName: "이름",
17
23
  width: "120",
24
+ renderCell: RenderCell,
25
+ renderEditCell: RenderEditCell,
18
26
  },
19
27
  {
20
28
  fieldId: "currency",
@@ -116,7 +124,7 @@ function App() {
116
124
  fieldName: "currency21",
117
125
  width: "120",
118
126
  },
119
- ], dataSource: Array.from({ length: 30 }, (_, i) => {
127
+ ], dataSource: Array.from({ length: 100 }, (_, i) => {
120
128
  return {
121
129
  id: i,
122
130
  firstName: `test-${i}`,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noraent/nora-datagrid",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "module": "./lib/esm/index.js",
5
5
  "main": "./lib/cjs/index.js",
6
6
  "private": false,
@@ -59,7 +59,6 @@ const DynamicVirtualScroll = React.memo(({ children }) => {
59
59
  window.addEventListener("focusout", (event) => {
60
60
  var _a;
61
61
  if (((_a = event.target.nextElementSibling) === null || _a === void 0 ? void 0 : _a.className) === "nora-data-grid-container") {
62
- console.log("???", gridRef.current.store.gridContainer.current);
63
62
  }
64
63
  });
65
64
  return () => {
@@ -210,7 +209,6 @@ const DynamicVirtualScroll = React.memo(({ children }) => {
210
209
  });
211
210
  }, [updateScroll, gridRef]);
212
211
  useEffect(() => {
213
- console.log("start, end!", start, end);
214
212
  gridRef.current.store.state.renderedRowStartEnd = [start, end];
215
213
  }, [start, end]);
216
214
  return (_jsxs("div", { style: { position: "relative" }, children: [_jsxs("div", { style: {
@@ -252,8 +250,6 @@ const VirtualListItem = React.memo(({ item, startColumnIndex, cumulativeWidths,
252
250
  const { start, end } = getItemRange();
253
251
  const visibleColumns = useMemo(() => columns.slice(start, end + 1), [start, end, columns]);
254
252
  const cellStyle = useMemo(() => ({ height: `${item.height}px` }), [item.height]);
255
- if (item.__dataRowindex === 0)
256
- console.log("row", row);
257
253
  return (_jsx(TableRow, { "aria-rowindex": item.__ariaRowindex, style: cellStyle, className: classes.TableClasses.body.row.root, children: visibleColumns.map((column) => (_jsx(VirtualItem, { column: column, row: row, rowIndex: item.__dataRowindex, isFocus: isColIndex === column.__ariaColindex, editStatus: isColIndex === column.__ariaColindex ? editStatus : undefined }, column.__uuid))) }, item.id));
258
254
  });
259
255
  const VirtualItem = React.memo(({ column, row, isFocus, editStatus, rowIndex, }) => {
@@ -314,17 +310,21 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
314
310
  if (clickTimer.current) {
315
311
  clearTimeout(clickTimer.current); // 더블 클릭 발생 시 실행 취소
316
312
  }
313
+ gridRef.current.setEditStatus(EditStatus.NON_EDITABLE).then((editState) => {
314
+ store.setState(["state", "editStatus"], editState);
315
+ });
317
316
  clickTimer.current = setTimeout(() => {
318
317
  if (gridRef.current.store.state.editStatus !== EditStatus.EDITING) {
319
- gridRef.current.setCellFocus(rowIndex, colIndex).then((res) => {
320
- store.setState(["state", "cellFocus"], res);
321
- gridRef.current.setEditStatus(EditStatus.NON_EDITABLE).then(() => {
322
- var _a;
323
- (_a = textAreaRef.current) === null || _a === void 0 ? void 0 : _a.focus(); // ime 활성화
318
+ gridRef.current.setEditStatus(EditStatus.NON_EDITABLE).then((editState) => {
319
+ var _a;
320
+ store.setState(["state", "editStatus"], editState);
321
+ (_a = textAreaRef.current) === null || _a === void 0 ? void 0 : _a.focus(); // ime 활성화
322
+ gridRef.current.setCellFocus(rowIndex, colIndex).then((res) => {
323
+ store.setState(["state", "cellFocus"], res);
324
324
  });
325
325
  });
326
326
  }
327
- }, 250); // 더블 클릭 판별 시간 (기본적으로 250ms 정도 사용)
327
+ }, 200); // 더블 클릭 판별 시간 (기본적으로 200ms 정도 사용)
328
328
  gridRef.current.setCellFocus(rowIndex, colIndex).then((res) => {
329
329
  store.setState(["state", "cellFocus"], res);
330
330
  });
@@ -373,6 +373,7 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
373
373
  e.key === "Shift" ||
374
374
  e.ctrlKey ||
375
375
  (e.ctrlKey && e.key === "c")) {
376
+ // e.preventDefault();
376
377
  return;
377
378
  }
378
379
  if (e.key === "Enter") {
@@ -385,9 +386,11 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
385
386
  if (cell && row) {
386
387
  const colIndex = Number(cell.getAttribute("aria-colindex"));
387
388
  const rowIndex = Number(row.getAttribute("aria-rowindex"));
388
- gridRef.current.setCellFocus(Math.min(rowIndex + 1, gridRef.current.store.state.dataSource.length), colIndex).then((res) => {
389
- store.setState(["state", "cellFocus"], res);
390
- });
389
+ setTimeout(() => {
390
+ gridRef.current.setCellFocus(Math.min(rowIndex + 1, gridRef.current.store.state.dataSource.length), colIndex).then((res) => {
391
+ store.setState(["state", "cellFocus"], res);
392
+ });
393
+ }, 0);
391
394
  }
392
395
  return;
393
396
  }
@@ -435,7 +438,6 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
435
438
  const handleArrowKey = React.useCallback((e) => {
436
439
  var _a;
437
440
  const { key } = e;
438
- console.log("!!!!", gridRef.current.store.state.editStatus);
439
441
  if (gridRef.current.store.state.editStatus === EditStatus.EDITING) {
440
442
  if (!(key === "Tab" || e.ctrlKey)) {
441
443
  return;
@@ -444,8 +446,9 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
444
446
  const { setCellFocus } = gridRef.current;
445
447
  const { gridContainer } = gridRef.current.store;
446
448
  const { cellFocus, columns, dataSource, renderedRowStartEnd } = gridRef.current.store.state;
447
- if (!cellFocus || (key !== "ArrowRight" && key !== "ArrowLeft" && key !== "ArrowDown" && key !== "ArrowUp" && key !== "Tab"))
449
+ if (!cellFocus || (key !== "ArrowRight" && key !== "ArrowLeft" && key !== "ArrowDown" && key !== "ArrowUp" && key !== "Tab")) {
448
450
  return;
451
+ }
449
452
  // e.preventDefault();
450
453
  const direction = (key === "Tab" && !e.shiftKey) || ["ArrowRight", "ArrowDown"].includes(key) ? 1 : -1;
451
454
  if (!cellFocus[1])
@@ -490,35 +493,37 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
490
493
  return;
491
494
  }
492
495
  if (rowIndex > 0 && colIndex > 0 && colIndex <= maxColIndex) {
493
- setCellFocus(rowIndex, colIndex).then((res) => {
494
- ReactDOM.flushSync(() => {
495
- store.setState(["state", "cellFocus"], res);
496
- if (bodyElement) {
497
- const scrollThreshold = Math.max(0, sumWidths[newColumnIndex] - bodyElement.clientWidth);
498
- const scrollRowThreshold = Math.max(0, sumHeights[newRowIndex] - (bodyElement.clientHeight - 40));
499
- if (key === "ArrowRight" || (!e.shiftKey && key === "Tab" && bodyElement.scrollLeft < scrollThreshold)) {
500
- bodyElement.scrollLeft = scrollThreshold;
501
- }
502
- if (key === "ArrowLeft" || (e.shiftKey && key === "Tab" && bodyElement)) {
503
- const targetStart = sumWidths[newColumnIndex];
504
- const scrollStart = bodyElement.scrollLeft;
505
- if (scrollStart >= targetStart) {
506
- bodyElement.scrollLeft = targetStart - widths[newColumnIndex];
496
+ setTimeout(() => {
497
+ setCellFocus(rowIndex, colIndex).then((res) => {
498
+ ReactDOM.flushSync(() => {
499
+ store.setState(["state", "cellFocus"], res);
500
+ if (bodyElement) {
501
+ const scrollThreshold = Math.max(0, sumWidths[newColumnIndex] - bodyElement.clientWidth);
502
+ const scrollRowThreshold = Math.max(0, sumHeights[newRowIndex] - (bodyElement.clientHeight - 40));
503
+ if (key === "ArrowRight" || (!e.shiftKey && key === "Tab" && bodyElement.scrollLeft < scrollThreshold)) {
504
+ bodyElement.scrollLeft = scrollThreshold;
507
505
  }
508
- }
509
- if (key === "ArrowDown" && bodyElement.scrollTop < scrollRowThreshold) {
510
- bodyElement.scrollTop = scrollRowThreshold;
511
- }
512
- if (key === "ArrowUp" && bodyElement) {
513
- const targetStart = sumHeights[newRowIndex];
514
- const scrollStart = bodyElement.scrollTop;
515
- if (scrollStart >= targetStart) {
516
- bodyElement.scrollTop = targetStart - heights[newRowIndex];
506
+ if (key === "ArrowLeft" || (e.shiftKey && key === "Tab" && bodyElement)) {
507
+ const targetStart = sumWidths[newColumnIndex];
508
+ const scrollStart = bodyElement.scrollLeft;
509
+ if (scrollStart >= targetStart) {
510
+ bodyElement.scrollLeft = targetStart - widths[newColumnIndex];
511
+ }
512
+ }
513
+ if (key === "ArrowDown" && bodyElement.scrollTop < scrollRowThreshold) {
514
+ bodyElement.scrollTop = scrollRowThreshold;
515
+ }
516
+ if (key === "ArrowUp" && bodyElement) {
517
+ const targetStart = sumHeights[newRowIndex];
518
+ const scrollStart = bodyElement.scrollTop;
519
+ if (scrollStart >= targetStart) {
520
+ bodyElement.scrollTop = targetStart - heights[newRowIndex];
521
+ }
517
522
  }
518
523
  }
519
- }
524
+ });
520
525
  });
521
- });
526
+ }, 0); // Tab시 한글 두번 입력되는 문제로 인해 넣음
522
527
  }
523
528
  }, []);
524
529
  const handleKeydown = useCallback((e) => {
@@ -1,10 +1,4 @@
1
1
  import React from "react";
2
- import { EditStatus } from "../../types/dataGridCoreEnum";
3
- import { DataGridPrivateColumnModel, DataGridPrivateDataSourceModel } from "../../types/dataGridCoreProps";
4
- declare const _default: React.MemoExoticComponent<({ column, value, editStatus, rowIndex, }: {
5
- column: DataGridPrivateColumnModel;
6
- value: keyof DataGridPrivateDataSourceModel;
7
- editStatus: EditStatus | undefined;
8
- rowIndex: number;
9
- }) => import("react/jsx-runtime").JSX.Element>;
2
+ import { GridCellPrams } from "../../types/dataGridCoreProps";
3
+ declare const _default: React.MemoExoticComponent<(props: GridCellPrams) => import("react/jsx-runtime").JSX.Element>;
10
4
  export default _default;
@@ -4,7 +4,8 @@ import { useStore } from "../../provider/GridStoreContent";
4
4
  import { EditStatus } from "../../types/dataGridCoreEnum";
5
5
  import useGridApiContext from "../../hooks/useGridApiContext";
6
6
  import { Input } from "../virtualized/_styled";
7
- const CellMode = ({ column, value, editStatus, rowIndex, }) => {
7
+ const CellMode = (props) => {
8
+ const { column, value, editStatus, rowIndex } = props;
8
9
  const gridRef = useGridApiContext();
9
10
  const [inputValue, setInputValue] = React.useState(value);
10
11
  const inputRef = React.useRef(null);
@@ -24,10 +25,14 @@ const CellMode = ({ column, value, editStatus, rowIndex, }) => {
24
25
  store.setState(["state", "dataSource"], dataSource, false);
25
26
  });
26
27
  }, [rowIndex]);
27
- if (editStatus === EditStatus.EDITING)
28
- return _jsx(Input, { autoFocus: true, ref: inputRef, value: inputValue, onChange: handleInputChange });
29
- if (editStatus === EditStatus.NON_EDITABLE)
30
- return _jsx(React.Fragment, { children: value });
31
- return _jsx(React.Fragment, { children: value });
28
+ const RenderEditCell = column.renderEditCell;
29
+ if (editStatus === EditStatus.EDITING) {
30
+ return (_jsx(React.Fragment, { children: RenderEditCell ? (_jsx(RenderEditCell, Object.assign({}, props, { onChange: handleInputChange }))) : (_jsx(Input, { autoFocus: true, ref: inputRef, value: inputValue, onChange: handleInputChange })) }));
31
+ }
32
+ const RenderCell = column.renderCell;
33
+ if (editStatus === EditStatus.NON_EDITABLE) {
34
+ return _jsx(React.Fragment, { children: RenderCell ? _jsx(RenderCell, Object.assign({}, props)) : value });
35
+ }
36
+ return _jsx(React.Fragment, { children: RenderCell ? _jsx(RenderCell, Object.assign({}, props)) : value });
32
37
  };
33
38
  export default React.memo(CellMode);
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import { GirdApi } from "../types/dataGridProps";
3
+ /**
4
+ * 그리드 Ref Hook
5
+ * @returns
6
+ */
7
+ export declare const useGridApiRef: <Api extends GirdApi>() => React.MutableRefObject<Api>;
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ /**
3
+ * 그리드 Ref Hook
4
+ * @returns
5
+ */
6
+ export const useGridApiRef = () => React.useRef({});
@@ -1 +1,2 @@
1
1
  export { DataGrid } from "./DataGrid";
2
+ export * from "./hooks/useGridApiRef";
package/lib/cjs/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export { DataGrid } from "./DataGrid";
2
+ export * from "./hooks/useGridApiRef";
@@ -1,3 +1,4 @@
1
+ import { EditStatus } from "./dataGridCoreEnum";
1
2
  export type DataGridColumn = DataGridColumnModel;
2
3
  export type DataGridColumns = Array<DataGridPrivateColumnModel>;
3
4
  export type DataGridDataSource = Array<DataGridPrivateDataSourceModel>;
@@ -10,6 +11,8 @@ interface DataGridColumnModel {
10
11
  fieldId: string;
11
12
  fieldName: string;
12
13
  width?: string;
14
+ renderCell?: (params: GridCellPrams) => React.ReactNode;
15
+ renderEditCell?: (params: GridEditCellPrams<any>) => React.ReactNode;
13
16
  }
14
17
  /**
15
18
  * Grid Column을 구성하는 내부적 구조 입니다.
@@ -68,4 +71,13 @@ export type CellRangeDef = {
68
71
  };
69
72
  export interface CellRangeTempDef extends Partial<CellRangeDef> {
70
73
  }
74
+ export interface GridCellPrams {
75
+ column: DataGridPrivateColumnModel;
76
+ value: keyof DataGridPrivateDataSourceModel;
77
+ editStatus: EditStatus | undefined;
78
+ rowIndex: number;
79
+ }
80
+ export interface GridEditCellPrams<T extends HTMLInputElement = any> extends GridCellPrams {
81
+ onChange?: React.ChangeEventHandler<T> | undefined;
82
+ }
71
83
  export {};
package/lib/esm/App.js CHANGED
@@ -1,11 +1,17 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React from "react";
3
2
  import { DataGrid } from "./DataGrid";
3
+ import { useGridApiRef } from "./hooks/useGridApiRef";
4
+ const RenderCell = (params) => {
5
+ return _jsx("div", { style: { background: "green" }, children: params.value });
6
+ };
7
+ const RenderEditCell = (params) => {
8
+ return _jsx("input", Object.assign({}, params, { style: { background: "yellow" } }));
9
+ };
4
10
  function App() {
5
- const ref = React.useRef(null);
11
+ // const ref = React.useRef<GirdApi>(null);
12
+ const ref = useGridApiRef();
6
13
  return (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => {
7
- var _a;
8
- console.log("!!!!!", (_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.getData());
14
+ console.log("!!!!!", ref.current.getData());
9
15
  }, children: "dd" }), _jsx("button", { children: "dd" }), _jsx("div", { style: { width: "1200px", height: "100%", maxHeight: "600px" }, children: _jsx(DataGrid, { gridRef: ref, columns: [
10
16
  {
11
17
  fieldId: "firstName",
@@ -15,6 +21,8 @@ function App() {
15
21
  fieldId: "lastName",
16
22
  fieldName: "이름",
17
23
  width: "120",
24
+ renderCell: RenderCell,
25
+ renderEditCell: RenderEditCell,
18
26
  },
19
27
  {
20
28
  fieldId: "currency",
@@ -116,7 +124,7 @@ function App() {
116
124
  fieldName: "currency21",
117
125
  width: "120",
118
126
  },
119
- ], dataSource: Array.from({ length: 30 }, (_, i) => {
127
+ ], dataSource: Array.from({ length: 100 }, (_, i) => {
120
128
  return {
121
129
  id: i,
122
130
  firstName: `test-${i}`,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noraent/nora-datagrid",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "module": "./lib/esm/index.js",
5
5
  "main": "./lib/cjs/index.js",
6
6
  "private": false,
@@ -59,7 +59,6 @@ const DynamicVirtualScroll = React.memo(({ children }) => {
59
59
  window.addEventListener("focusout", (event) => {
60
60
  var _a;
61
61
  if (((_a = event.target.nextElementSibling) === null || _a === void 0 ? void 0 : _a.className) === "nora-data-grid-container") {
62
- console.log("???", gridRef.current.store.gridContainer.current);
63
62
  }
64
63
  });
65
64
  return () => {
@@ -210,7 +209,6 @@ const DynamicVirtualScroll = React.memo(({ children }) => {
210
209
  });
211
210
  }, [updateScroll, gridRef]);
212
211
  useEffect(() => {
213
- console.log("start, end!", start, end);
214
212
  gridRef.current.store.state.renderedRowStartEnd = [start, end];
215
213
  }, [start, end]);
216
214
  return (_jsxs("div", { style: { position: "relative" }, children: [_jsxs("div", { style: {
@@ -252,8 +250,6 @@ const VirtualListItem = React.memo(({ item, startColumnIndex, cumulativeWidths,
252
250
  const { start, end } = getItemRange();
253
251
  const visibleColumns = useMemo(() => columns.slice(start, end + 1), [start, end, columns]);
254
252
  const cellStyle = useMemo(() => ({ height: `${item.height}px` }), [item.height]);
255
- if (item.__dataRowindex === 0)
256
- console.log("row", row);
257
253
  return (_jsx(TableRow, { "aria-rowindex": item.__ariaRowindex, style: cellStyle, className: classes.TableClasses.body.row.root, children: visibleColumns.map((column) => (_jsx(VirtualItem, { column: column, row: row, rowIndex: item.__dataRowindex, isFocus: isColIndex === column.__ariaColindex, editStatus: isColIndex === column.__ariaColindex ? editStatus : undefined }, column.__uuid))) }, item.id));
258
254
  });
259
255
  const VirtualItem = React.memo(({ column, row, isFocus, editStatus, rowIndex, }) => {
@@ -314,17 +310,21 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
314
310
  if (clickTimer.current) {
315
311
  clearTimeout(clickTimer.current); // 더블 클릭 발생 시 실행 취소
316
312
  }
313
+ gridRef.current.setEditStatus(EditStatus.NON_EDITABLE).then((editState) => {
314
+ store.setState(["state", "editStatus"], editState);
315
+ });
317
316
  clickTimer.current = setTimeout(() => {
318
317
  if (gridRef.current.store.state.editStatus !== EditStatus.EDITING) {
319
- gridRef.current.setCellFocus(rowIndex, colIndex).then((res) => {
320
- store.setState(["state", "cellFocus"], res);
321
- gridRef.current.setEditStatus(EditStatus.NON_EDITABLE).then(() => {
322
- var _a;
323
- (_a = textAreaRef.current) === null || _a === void 0 ? void 0 : _a.focus(); // ime 활성화
318
+ gridRef.current.setEditStatus(EditStatus.NON_EDITABLE).then((editState) => {
319
+ var _a;
320
+ store.setState(["state", "editStatus"], editState);
321
+ (_a = textAreaRef.current) === null || _a === void 0 ? void 0 : _a.focus(); // ime 활성화
322
+ gridRef.current.setCellFocus(rowIndex, colIndex).then((res) => {
323
+ store.setState(["state", "cellFocus"], res);
324
324
  });
325
325
  });
326
326
  }
327
- }, 250); // 더블 클릭 판별 시간 (기본적으로 250ms 정도 사용)
327
+ }, 200); // 더블 클릭 판별 시간 (기본적으로 200ms 정도 사용)
328
328
  gridRef.current.setCellFocus(rowIndex, colIndex).then((res) => {
329
329
  store.setState(["state", "cellFocus"], res);
330
330
  });
@@ -373,6 +373,7 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
373
373
  e.key === "Shift" ||
374
374
  e.ctrlKey ||
375
375
  (e.ctrlKey && e.key === "c")) {
376
+ // e.preventDefault();
376
377
  return;
377
378
  }
378
379
  if (e.key === "Enter") {
@@ -385,9 +386,11 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
385
386
  if (cell && row) {
386
387
  const colIndex = Number(cell.getAttribute("aria-colindex"));
387
388
  const rowIndex = Number(row.getAttribute("aria-rowindex"));
388
- gridRef.current.setCellFocus(Math.min(rowIndex + 1, gridRef.current.store.state.dataSource.length), colIndex).then((res) => {
389
- store.setState(["state", "cellFocus"], res);
390
- });
389
+ setTimeout(() => {
390
+ gridRef.current.setCellFocus(Math.min(rowIndex + 1, gridRef.current.store.state.dataSource.length), colIndex).then((res) => {
391
+ store.setState(["state", "cellFocus"], res);
392
+ });
393
+ }, 0);
391
394
  }
392
395
  return;
393
396
  }
@@ -435,7 +438,6 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
435
438
  const handleArrowKey = React.useCallback((e) => {
436
439
  var _a;
437
440
  const { key } = e;
438
- console.log("!!!!", gridRef.current.store.state.editStatus);
439
441
  if (gridRef.current.store.state.editStatus === EditStatus.EDITING) {
440
442
  if (!(key === "Tab" || e.ctrlKey)) {
441
443
  return;
@@ -444,8 +446,9 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
444
446
  const { setCellFocus } = gridRef.current;
445
447
  const { gridContainer } = gridRef.current.store;
446
448
  const { cellFocus, columns, dataSource, renderedRowStartEnd } = gridRef.current.store.state;
447
- if (!cellFocus || (key !== "ArrowRight" && key !== "ArrowLeft" && key !== "ArrowDown" && key !== "ArrowUp" && key !== "Tab"))
449
+ if (!cellFocus || (key !== "ArrowRight" && key !== "ArrowLeft" && key !== "ArrowDown" && key !== "ArrowUp" && key !== "Tab")) {
448
450
  return;
451
+ }
449
452
  // e.preventDefault();
450
453
  const direction = (key === "Tab" && !e.shiftKey) || ["ArrowRight", "ArrowDown"].includes(key) ? 1 : -1;
451
454
  if (!cellFocus[1])
@@ -490,35 +493,37 @@ export const TwoDimensionalVirtualizedList = React.memo(() => {
490
493
  return;
491
494
  }
492
495
  if (rowIndex > 0 && colIndex > 0 && colIndex <= maxColIndex) {
493
- setCellFocus(rowIndex, colIndex).then((res) => {
494
- ReactDOM.flushSync(() => {
495
- store.setState(["state", "cellFocus"], res);
496
- if (bodyElement) {
497
- const scrollThreshold = Math.max(0, sumWidths[newColumnIndex] - bodyElement.clientWidth);
498
- const scrollRowThreshold = Math.max(0, sumHeights[newRowIndex] - (bodyElement.clientHeight - 40));
499
- if (key === "ArrowRight" || (!e.shiftKey && key === "Tab" && bodyElement.scrollLeft < scrollThreshold)) {
500
- bodyElement.scrollLeft = scrollThreshold;
501
- }
502
- if (key === "ArrowLeft" || (e.shiftKey && key === "Tab" && bodyElement)) {
503
- const targetStart = sumWidths[newColumnIndex];
504
- const scrollStart = bodyElement.scrollLeft;
505
- if (scrollStart >= targetStart) {
506
- bodyElement.scrollLeft = targetStart - widths[newColumnIndex];
496
+ setTimeout(() => {
497
+ setCellFocus(rowIndex, colIndex).then((res) => {
498
+ ReactDOM.flushSync(() => {
499
+ store.setState(["state", "cellFocus"], res);
500
+ if (bodyElement) {
501
+ const scrollThreshold = Math.max(0, sumWidths[newColumnIndex] - bodyElement.clientWidth);
502
+ const scrollRowThreshold = Math.max(0, sumHeights[newRowIndex] - (bodyElement.clientHeight - 40));
503
+ if (key === "ArrowRight" || (!e.shiftKey && key === "Tab" && bodyElement.scrollLeft < scrollThreshold)) {
504
+ bodyElement.scrollLeft = scrollThreshold;
507
505
  }
508
- }
509
- if (key === "ArrowDown" && bodyElement.scrollTop < scrollRowThreshold) {
510
- bodyElement.scrollTop = scrollRowThreshold;
511
- }
512
- if (key === "ArrowUp" && bodyElement) {
513
- const targetStart = sumHeights[newRowIndex];
514
- const scrollStart = bodyElement.scrollTop;
515
- if (scrollStart >= targetStart) {
516
- bodyElement.scrollTop = targetStart - heights[newRowIndex];
506
+ if (key === "ArrowLeft" || (e.shiftKey && key === "Tab" && bodyElement)) {
507
+ const targetStart = sumWidths[newColumnIndex];
508
+ const scrollStart = bodyElement.scrollLeft;
509
+ if (scrollStart >= targetStart) {
510
+ bodyElement.scrollLeft = targetStart - widths[newColumnIndex];
511
+ }
512
+ }
513
+ if (key === "ArrowDown" && bodyElement.scrollTop < scrollRowThreshold) {
514
+ bodyElement.scrollTop = scrollRowThreshold;
515
+ }
516
+ if (key === "ArrowUp" && bodyElement) {
517
+ const targetStart = sumHeights[newRowIndex];
518
+ const scrollStart = bodyElement.scrollTop;
519
+ if (scrollStart >= targetStart) {
520
+ bodyElement.scrollTop = targetStart - heights[newRowIndex];
521
+ }
517
522
  }
518
523
  }
519
- }
524
+ });
520
525
  });
521
- });
526
+ }, 0); // Tab시 한글 두번 입력되는 문제로 인해 넣음
522
527
  }
523
528
  }, []);
524
529
  const handleKeydown = useCallback((e) => {
@@ -1,10 +1,4 @@
1
1
  import React from "react";
2
- import { EditStatus } from "../../types/dataGridCoreEnum";
3
- import { DataGridPrivateColumnModel, DataGridPrivateDataSourceModel } from "../../types/dataGridCoreProps";
4
- declare const _default: React.MemoExoticComponent<({ column, value, editStatus, rowIndex, }: {
5
- column: DataGridPrivateColumnModel;
6
- value: keyof DataGridPrivateDataSourceModel;
7
- editStatus: EditStatus | undefined;
8
- rowIndex: number;
9
- }) => import("react/jsx-runtime").JSX.Element>;
2
+ import { GridCellPrams } from "../../types/dataGridCoreProps";
3
+ declare const _default: React.MemoExoticComponent<(props: GridCellPrams) => import("react/jsx-runtime").JSX.Element>;
10
4
  export default _default;
@@ -4,7 +4,8 @@ import { useStore } from "../../provider/GridStoreContent";
4
4
  import { EditStatus } from "../../types/dataGridCoreEnum";
5
5
  import useGridApiContext from "../../hooks/useGridApiContext";
6
6
  import { Input } from "../virtualized/_styled";
7
- const CellMode = ({ column, value, editStatus, rowIndex, }) => {
7
+ const CellMode = (props) => {
8
+ const { column, value, editStatus, rowIndex } = props;
8
9
  const gridRef = useGridApiContext();
9
10
  const [inputValue, setInputValue] = React.useState(value);
10
11
  const inputRef = React.useRef(null);
@@ -24,10 +25,14 @@ const CellMode = ({ column, value, editStatus, rowIndex, }) => {
24
25
  store.setState(["state", "dataSource"], dataSource, false);
25
26
  });
26
27
  }, [rowIndex]);
27
- if (editStatus === EditStatus.EDITING)
28
- return _jsx(Input, { autoFocus: true, ref: inputRef, value: inputValue, onChange: handleInputChange });
29
- if (editStatus === EditStatus.NON_EDITABLE)
30
- return _jsx(React.Fragment, { children: value });
31
- return _jsx(React.Fragment, { children: value });
28
+ const RenderEditCell = column.renderEditCell;
29
+ if (editStatus === EditStatus.EDITING) {
30
+ return (_jsx(React.Fragment, { children: RenderEditCell ? (_jsx(RenderEditCell, Object.assign({}, props, { onChange: handleInputChange }))) : (_jsx(Input, { autoFocus: true, ref: inputRef, value: inputValue, onChange: handleInputChange })) }));
31
+ }
32
+ const RenderCell = column.renderCell;
33
+ if (editStatus === EditStatus.NON_EDITABLE) {
34
+ return _jsx(React.Fragment, { children: RenderCell ? _jsx(RenderCell, Object.assign({}, props)) : value });
35
+ }
36
+ return _jsx(React.Fragment, { children: RenderCell ? _jsx(RenderCell, Object.assign({}, props)) : value });
32
37
  };
33
38
  export default React.memo(CellMode);
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import { GirdApi } from "../types/dataGridProps";
3
+ /**
4
+ * 그리드 Ref Hook
5
+ * @returns
6
+ */
7
+ export declare const useGridApiRef: <Api extends GirdApi>() => React.MutableRefObject<Api>;
@@ -0,0 +1,6 @@
1
+ import React from "react";
2
+ /**
3
+ * 그리드 Ref Hook
4
+ * @returns
5
+ */
6
+ export const useGridApiRef = () => React.useRef({});
@@ -1 +1,2 @@
1
1
  export { DataGrid } from "./DataGrid";
2
+ export * from "./hooks/useGridApiRef";
package/lib/esm/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export { DataGrid } from "./DataGrid";
2
+ export * from "./hooks/useGridApiRef";
@@ -1,3 +1,4 @@
1
+ import { EditStatus } from "./dataGridCoreEnum";
1
2
  export type DataGridColumn = DataGridColumnModel;
2
3
  export type DataGridColumns = Array<DataGridPrivateColumnModel>;
3
4
  export type DataGridDataSource = Array<DataGridPrivateDataSourceModel>;
@@ -10,6 +11,8 @@ interface DataGridColumnModel {
10
11
  fieldId: string;
11
12
  fieldName: string;
12
13
  width?: string;
14
+ renderCell?: (params: GridCellPrams) => React.ReactNode;
15
+ renderEditCell?: (params: GridEditCellPrams<any>) => React.ReactNode;
13
16
  }
14
17
  /**
15
18
  * Grid Column을 구성하는 내부적 구조 입니다.
@@ -68,4 +71,13 @@ export type CellRangeDef = {
68
71
  };
69
72
  export interface CellRangeTempDef extends Partial<CellRangeDef> {
70
73
  }
74
+ export interface GridCellPrams {
75
+ column: DataGridPrivateColumnModel;
76
+ value: keyof DataGridPrivateDataSourceModel;
77
+ editStatus: EditStatus | undefined;
78
+ rowIndex: number;
79
+ }
80
+ export interface GridEditCellPrams<T extends HTMLInputElement = any> extends GridCellPrams {
81
+ onChange?: React.ChangeEventHandler<T> | undefined;
82
+ }
71
83
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noraent/nora-datagrid",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "module": "./lib/esm/index.js",
5
5
  "main": "./lib/cjs/index.js",
6
6
  "private": false,