@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 +13 -5
- package/lib/cjs/buildPackage.json +1 -1
- package/lib/cjs/components/TwoDimensionalVirtualizedList.js +45 -40
- package/lib/cjs/components/cell/CellMode.d.ts +2 -8
- package/lib/cjs/components/cell/CellMode.js +11 -6
- package/lib/cjs/hooks/useGridApiRef.d.ts +7 -0
- package/lib/cjs/hooks/useGridApiRef.js +6 -0
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/types/dataGridCoreProps.d.ts +12 -0
- package/lib/esm/App.js +13 -5
- package/lib/esm/buildPackage.json +1 -1
- package/lib/esm/components/TwoDimensionalVirtualizedList.js +45 -40
- package/lib/esm/components/cell/CellMode.d.ts +2 -8
- package/lib/esm/components/cell/CellMode.js +11 -6
- package/lib/esm/hooks/useGridApiRef.d.ts +7 -0
- package/lib/esm/hooks/useGridApiRef.js +6 -0
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/types/dataGridCoreProps.d.ts +12 -0
- package/package.json +1 -1
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
|
-
|
|
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:
|
|
127
|
+
], dataSource: Array.from({ length: 100 }, (_, i) => {
|
|
120
128
|
return {
|
|
121
129
|
id: i,
|
|
122
130
|
firstName: `test-${i}`,
|
|
@@ -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.
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
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
|
-
},
|
|
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
|
-
|
|
389
|
-
|
|
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
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
bodyElement.scrollLeft
|
|
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
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
if (
|
|
516
|
-
bodyElement.scrollTop =
|
|
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 {
|
|
3
|
-
|
|
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 = (
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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);
|
package/lib/cjs/index.d.ts
CHANGED
package/lib/cjs/index.js
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
127
|
+
], dataSource: Array.from({ length: 100 }, (_, i) => {
|
|
120
128
|
return {
|
|
121
129
|
id: i,
|
|
122
130
|
firstName: `test-${i}`,
|
|
@@ -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.
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
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
|
-
},
|
|
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
|
-
|
|
389
|
-
|
|
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
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
bodyElement.scrollLeft
|
|
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
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
if (
|
|
516
|
-
bodyElement.scrollTop =
|
|
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 {
|
|
3
|
-
|
|
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 = (
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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);
|
package/lib/esm/index.d.ts
CHANGED
package/lib/esm/index.js
CHANGED
|
@@ -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 {};
|