@noraent/nora-datagrid 0.0.39 → 0.0.40
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 +10 -8
- package/lib/cjs/buildPackage.json +1 -1
- package/lib/cjs/components/TwoDimensionalVirtualizedList.js +6 -1
- package/lib/cjs/hooks/external/usePublicTest.js +6 -3
- package/lib/cjs/hooks/internal/useInternalPrivateApi.js +9 -4
- package/lib/cjs/hooks/useGridInitialization.d.ts +3 -2
- package/lib/cjs/hooks/useGridInitialization.js +19 -7
- package/lib/cjs/provider/GridStoreContent.js +1 -1
- package/lib/cjs/types/dataGridProps.d.ts +17 -4
- package/lib/cjs/types/dataGridProps.js +1 -0
- package/lib/esm/App.js +10 -8
- package/lib/esm/buildPackage.json +1 -1
- package/lib/esm/components/TwoDimensionalVirtualizedList.js +6 -1
- package/lib/esm/hooks/external/usePublicTest.js +6 -3
- package/lib/esm/hooks/internal/useInternalPrivateApi.js +9 -4
- package/lib/esm/hooks/useGridInitialization.d.ts +3 -2
- package/lib/esm/hooks/useGridInitialization.js +19 -7
- package/lib/esm/provider/GridStoreContent.js +1 -1
- package/lib/esm/types/dataGridProps.d.ts +17 -4
- package/lib/esm/types/dataGridProps.js +1 -0
- package/package.json +1 -1
package/lib/cjs/App.js
CHANGED
|
@@ -7,13 +7,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
11
|
+
import { useEffect, useState } from "react";
|
|
12
12
|
import { DataGrid } from "./DataGrid";
|
|
13
13
|
import { useGridApiRef } from "./hooks/useGridApiRef";
|
|
14
14
|
const RenderCell = (params) => {
|
|
15
|
-
const [value, setValue] = useState(0);
|
|
16
|
-
const test = useDeferredValue(value);
|
|
15
|
+
// const [value, setValue] = useState(0);
|
|
16
|
+
// const test = useDeferredValue(value);
|
|
17
17
|
useEffect(() => {
|
|
18
18
|
const tt = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
19
|
let tt = 0;
|
|
@@ -33,13 +33,15 @@ const RenderCell = (params) => {
|
|
|
33
33
|
// height: Math.floor(Math.random() * 20) + 20,
|
|
34
34
|
};
|
|
35
35
|
});
|
|
36
|
-
setValue(tt);
|
|
36
|
+
// setValue(tt);
|
|
37
37
|
});
|
|
38
38
|
requestIdleCallback(() => {
|
|
39
39
|
tt();
|
|
40
40
|
});
|
|
41
41
|
}, []);
|
|
42
|
-
return (_jsxs("div", { style: { background: "green" }, children: [
|
|
42
|
+
return (_jsxs("div", { style: { background: "green" }, children: [_jsx("button", { onClick: () => {
|
|
43
|
+
params.gridRef.current.setRowHeight(1, 100);
|
|
44
|
+
}, children: "??" }), params.value] }));
|
|
43
45
|
};
|
|
44
46
|
const RenderEditCell = (params) => {
|
|
45
47
|
return (_jsx(_Fragment, { children: _jsx("input", Object.assign({}, params, { style: { background: "yellow" } })) }));
|
|
@@ -164,7 +166,7 @@ function App() {
|
|
|
164
166
|
const ref = useGridApiRef();
|
|
165
167
|
const [dataSource, setDataSource] = useState([]);
|
|
166
168
|
const handleDataSource = () => {
|
|
167
|
-
const data = Array.from({ length:
|
|
169
|
+
const data = Array.from({ length: 1000 }, (_, i) => {
|
|
168
170
|
return {
|
|
169
171
|
id: i,
|
|
170
172
|
code: `test-${i}`,
|
|
@@ -188,7 +190,7 @@ function App() {
|
|
|
188
190
|
}, children: "\uB370\uC774\uD130 set" }), _jsx("button", { onClick: () => {
|
|
189
191
|
const data = ref.current.getData();
|
|
190
192
|
console.log("!!!!!", data);
|
|
191
|
-
}, children: "
|
|
193
|
+
}, children: "\uD558" }), _jsx("div", { style: { width: "1200px", height: "300px" }, children: _jsx(DataGrid, { gridRef: ref, columns: columns, dataSource: dataSource }) }), _jsx("div", { style: { width: "1200px", height: "300px" }, children: _jsx(DataGrid, { columns: columns, dataSource: dataSource }) }), _jsx("button", { children: "dd" })] }));
|
|
192
194
|
}
|
|
193
195
|
export const initialItemsData = () => Array.from({ length: 10 }, (_, i) => {
|
|
194
196
|
return {
|
|
@@ -11,6 +11,7 @@ import { EditStatus } from "../types/dataGridCoreEnum";
|
|
|
11
11
|
import CellMode from "./cell/CellMode";
|
|
12
12
|
import ImeComponent from "./ime/IMEComponent";
|
|
13
13
|
import NoDataComponent from "./body/NoDataComponent";
|
|
14
|
+
import { useAddApi } from "../hooks/useGridInitialization";
|
|
14
15
|
const initialWindowWidth = 800;
|
|
15
16
|
export const initialWindowHeight = 500;
|
|
16
17
|
const overscanTopRow = 4;
|
|
@@ -72,6 +73,9 @@ const DynamicVirtualScroll = React.memo(({ children }) => {
|
|
|
72
73
|
const { dataSource } = useSelector((store) => ({
|
|
73
74
|
dataSource: store.state.dataSource,
|
|
74
75
|
}));
|
|
76
|
+
useSelector((store) => ({
|
|
77
|
+
__randomDataSourceKey: store.__randomDataSourceKey,
|
|
78
|
+
}));
|
|
75
79
|
const totalHeight = useMemo(() => dataSource.reduce((sum, item) => sum + item.height, 0), [dataSource]);
|
|
76
80
|
const totalWidth = useMemo(() => columns.reduce((sum, column) => sum + Number(column.width), 0) || 0, [columns]);
|
|
77
81
|
const binarySearchIndex = useCallback((items, target) => {
|
|
@@ -132,7 +136,7 @@ const DynamicVirtualScroll = React.memo(({ children }) => {
|
|
|
132
136
|
result.push(dataSource[rowIndex - 1]); // fixedIndex가 범위에 포함되지 않으면 첫 번째에 추가
|
|
133
137
|
}
|
|
134
138
|
return result;
|
|
135
|
-
}, [dataSource, start, end]);
|
|
139
|
+
}, [JSON.stringify(dataSource), start, end]);
|
|
136
140
|
const startColumnIndex = useMemo(() => Math.max(0, binarySearchIndex(cumulativeWidths, scrollLeft) - overscanColumn), [columns, cumulativeWidths, scrollLeft, binarySearchIndex, overscanColumn]);
|
|
137
141
|
const offsetTop = useMemo(() => cumulativeHeights[start] || 0, [cumulativeHeights, start]);
|
|
138
142
|
const offsetLeft = useMemo(() => cumulativeWidths[startColumnIndex] || 0, [cumulativeWidths, startColumnIndex]);
|
|
@@ -267,6 +271,7 @@ const VirtualItem = React.memo(({ column, row, isFocus, editStatus, rowIndex, })
|
|
|
267
271
|
export const TwoDimensionalVirtualizedList = React.memo(() => {
|
|
268
272
|
// 마우스 다운 시작지점점
|
|
269
273
|
const gridRef = useGridApiContext();
|
|
274
|
+
useAddApi(gridRef);
|
|
270
275
|
const mouseDownStartPointRef = useRef(0);
|
|
271
276
|
const mouseDownStartWidthRef = useRef(0);
|
|
272
277
|
const colIndexRef = useRef(0);
|
|
@@ -2,9 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { useGridApiMethod } from "../useGridApiMethod";
|
|
3
3
|
import { classes } from "../../types/classes";
|
|
4
4
|
import { defaultProps } from "../../common/constants";
|
|
5
|
-
import { useStore } from "../../provider/GridStoreContent";
|
|
6
5
|
export default function usePublicTest(apiRef) {
|
|
7
|
-
const store = useStore();
|
|
8
6
|
const getData = React.useCallback(() => {
|
|
9
7
|
return apiRef.current.store.state.dataSource;
|
|
10
8
|
}, []);
|
|
@@ -25,7 +23,12 @@ export default function usePublicTest(apiRef) {
|
|
|
25
23
|
}, []);
|
|
26
24
|
const setRowHeight = React.useCallback((rowIndex, height = defaultProps.height) => {
|
|
27
25
|
apiRef.current.store.state.dataSource[rowIndex] = Object.assign(Object.assign({}, apiRef.current.store.state.dataSource[rowIndex]), { height: height });
|
|
28
|
-
|
|
26
|
+
apiRef.current.store.__randomDataSourceKey = `${Math.random()}`;
|
|
27
|
+
console.log("!!!", apiRef.current.store.__randomDataSourceKey);
|
|
28
|
+
apiRef.current.store.updateKeyTemp.add("__randomDataSourceKey");
|
|
29
|
+
setTimeout(() => {
|
|
30
|
+
apiRef.current.getPublicApi().forceUpdate();
|
|
31
|
+
}, 0);
|
|
29
32
|
}, []);
|
|
30
33
|
const apiMethods = { addCellRange, getData, scrollToRowIndex, setRowHeight };
|
|
31
34
|
useGridApiMethod(apiRef, apiMethods, "public");
|
|
@@ -31,7 +31,11 @@ export default function useInternalPrivateApi(apiRef) {
|
|
|
31
31
|
const basicStore = setBasicStore(props);
|
|
32
32
|
apiRef.current = Object.assign(Object.assign({}, apiRef.current), { store: Object.assign(Object.assign({}, apiRef.current.store), { original: basicStore, state: Object.assign({}, basicStore),
|
|
33
33
|
// 현재 내부에서 사용되는 속성은 수동으로 초기화 해야함.
|
|
34
|
-
__cellRange: [], __cellRangeTemp: {}
|
|
34
|
+
__cellRange: [], __cellRangeTemp: {},
|
|
35
|
+
/**
|
|
36
|
+
* 누적 높이 캐싱
|
|
37
|
+
*/
|
|
38
|
+
cumulativeHeights: [], updateKeyTemp: new Set(), __randomDataSourceKey: "" }) });
|
|
35
39
|
return apiRef.current;
|
|
36
40
|
}, []);
|
|
37
41
|
const setBasicStore = React.useCallback((props) => {
|
|
@@ -121,16 +125,17 @@ export default function useInternalPrivateApi(apiRef) {
|
|
|
121
125
|
sum += (_a = row.height) !== null && _a !== void 0 ? _a : 32;
|
|
122
126
|
return sum;
|
|
123
127
|
});
|
|
124
|
-
apiRef.current.store.
|
|
128
|
+
apiRef.current.store.cumulativeHeights = heightCache;
|
|
129
|
+
return heightCache;
|
|
125
130
|
}, []);
|
|
126
131
|
const getScrollTop = React.useCallback((rowIndex) => {
|
|
127
132
|
let low = 0;
|
|
128
|
-
let high = apiRef.current.store.
|
|
133
|
+
let high = apiRef.current.store.cumulativeHeights.length - 1;
|
|
129
134
|
let result = 0;
|
|
130
135
|
while (low <= high) {
|
|
131
136
|
const mid = Math.floor((low + high) / 2);
|
|
132
137
|
if (mid < rowIndex) {
|
|
133
|
-
result = apiRef.current.store.
|
|
138
|
+
result = apiRef.current.store.cumulativeHeights[mid];
|
|
134
139
|
low = mid + 1;
|
|
135
140
|
}
|
|
136
141
|
else {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import DataGridBasicProps, { GirdApiCommon } from "../types/dataGridProps";
|
|
3
|
-
export declare function
|
|
2
|
+
import DataGridBasicProps, { DataGridPrivateApiModel, GirdApiCommon } from "../types/dataGridProps";
|
|
3
|
+
export declare function useAddApi(ref: React.MutableRefObject<GirdApiCommon<DataGridPrivateApiModel>>): void;
|
|
4
|
+
export declare function useGridInitialization(apiRef: DataGridBasicProps["gridRef"], props: DataGridBasicProps): React.MutableRefObject<GirdApiCommon<DataGridPrivateApiModel>>;
|
|
@@ -2,18 +2,30 @@ import React from "react";
|
|
|
2
2
|
import useTest from "./internal/useInternalPrivateApi";
|
|
3
3
|
import usePublicTest from "./external/usePublicTest";
|
|
4
4
|
import { useGridApiMethod } from "./useGridApiMethod";
|
|
5
|
+
import { useStore } from "../provider/GridStoreContent";
|
|
6
|
+
import useGridApiContext from "./useGridApiContext";
|
|
7
|
+
export function useAddApi(ref) {
|
|
8
|
+
const store = useStore();
|
|
9
|
+
const gridRef = useGridApiContext();
|
|
10
|
+
const forceUpdate = React.useCallback(() => {
|
|
11
|
+
gridRef.current.store.updateKeyTemp.forEach((v) => {
|
|
12
|
+
//타입 및 코드 정리 필요
|
|
13
|
+
// 그리드 외부에서 접근시
|
|
14
|
+
const value = v.split(",").reduce((acc, key) => acc === null || acc === void 0 ? void 0 : acc[key], gridRef.current.store);
|
|
15
|
+
store.setState([v.split(",")], value);
|
|
16
|
+
});
|
|
17
|
+
// store.setState(gridRef.current.store.updateKeyTemp)
|
|
18
|
+
}, []);
|
|
19
|
+
useGridApiMethod(ref, { forceUpdate }, "public");
|
|
20
|
+
}
|
|
5
21
|
export function useGridInitialization(apiRef, props) {
|
|
6
22
|
// const memoizedProps = React.useMemo(() => _.cloneDeep(props), [props]); // props를 메모이제이션
|
|
7
23
|
const privateAipRef = useGridApiInitialization(apiRef, Object.assign({}, props));
|
|
8
24
|
usePublicTest(privateAipRef);
|
|
9
25
|
useTest(privateAipRef);
|
|
10
|
-
//
|
|
11
|
-
const
|
|
12
|
-
//
|
|
13
|
-
const forceUpdate = React.useCallback(() => rawForceUpdate(() => privateAipRef.current.store.state),
|
|
14
|
-
// () => rawForceUpdate(() => privateAipRef.current.store),
|
|
15
|
-
[privateAipRef]);
|
|
16
|
-
useGridApiMethod(privateAipRef, { forceUpdate }, "public");
|
|
26
|
+
// const [, rawForceUpdate] = React.useState<any>();
|
|
27
|
+
// const forceUpdate = React.useCallback<DataGridPublicApi["forceUpdate"]>(() => rawForceUpdate(() => privateAipRef.current.store.state), [privateAipRef]);
|
|
28
|
+
// useGridApiMethod(privateAipRef, { forceUpdate }, "public");
|
|
17
29
|
return privateAipRef;
|
|
18
30
|
}
|
|
19
31
|
/**
|
|
@@ -89,7 +89,7 @@ export const useSelector = (selector) => {
|
|
|
89
89
|
const newPath = [...currentPath, prop];
|
|
90
90
|
const value = obj[prop];
|
|
91
91
|
// 정확한 경로 저장
|
|
92
|
-
if (currentPath.length > 0 || prop === "state") {
|
|
92
|
+
if (currentPath.length > 0 || prop === "state" || prop === "original" || prop === "__randomDataSourceKey") {
|
|
93
93
|
if (!isArrayInSet(accessedPaths.current, newPath)) {
|
|
94
94
|
accessedPaths.current.add(newPath);
|
|
95
95
|
}
|
|
@@ -52,11 +52,24 @@ export interface DataGridOptionPropsModel {
|
|
|
52
52
|
* @private
|
|
53
53
|
* @namespace NoraDataGrid.DataGridBasicStorePropsModel
|
|
54
54
|
*/
|
|
55
|
-
interface DataGridBasicStorePropsModel {
|
|
55
|
+
export interface DataGridBasicStorePropsModel {
|
|
56
56
|
gridContainer: React.RefObject<HTMLDivElement>;
|
|
57
|
-
|
|
57
|
+
/**
|
|
58
|
+
* 누적 높이 캐싱
|
|
59
|
+
*/
|
|
60
|
+
cumulativeHeights: number[];
|
|
58
61
|
__cellRange: Array<CellRangeDef>;
|
|
59
62
|
__cellRangeTemp: CellRangeTempDef;
|
|
63
|
+
/**
|
|
64
|
+
* 변경된 store를 Temp로 관리 합니다.
|
|
65
|
+
* 일괄 업데이트용으로 사용해주세요.
|
|
66
|
+
*/
|
|
67
|
+
updateKeyTemp: Set<string>;
|
|
68
|
+
/**
|
|
69
|
+
* dataSource 값이 변경되었을때 값이 변합니다.
|
|
70
|
+
* Object는 변경된 값을 감지하기 어렵기 때문에 별도 키 관리
|
|
71
|
+
*/
|
|
72
|
+
__randomDataSourceKey: string;
|
|
60
73
|
}
|
|
61
74
|
/**
|
|
62
75
|
* DataGrid를 구성하는 내부 메소드들을 관리 합니다.
|
|
@@ -124,7 +137,7 @@ export interface DataGridPrivateApiModel {
|
|
|
124
137
|
*/
|
|
125
138
|
setEditStatus: (editStatus: DataGridStoreDef["state"]["editStatus"]) => Promise<DataGridStoreDef["state"]["editStatus"]>;
|
|
126
139
|
/**
|
|
127
|
-
* 데이터에 있는 모든 행
|
|
140
|
+
* 데이터에 있는 모든 행 높의 누적값을 생성합니다.
|
|
128
141
|
* @private
|
|
129
142
|
* @namespace NoraDataGrid.DataGridPublicApiModel.getData
|
|
130
143
|
*/
|
|
@@ -176,7 +189,7 @@ export declare class Store<T> {
|
|
|
176
189
|
private updateNestedState;
|
|
177
190
|
private isPathAffected;
|
|
178
191
|
}
|
|
179
|
-
export interface DataGridStoreDef extends DataGridBasicStorePropsModel {
|
|
192
|
+
export interface DataGridStoreDef extends DataGridBasicStorePropsModel, DataGridBasicStorePropsModel {
|
|
180
193
|
original: DataGridBasicPropsModel & DataGridOptionPropsModel;
|
|
181
194
|
state: DataGridBasicPropsModel & DataGridOptionPropsModel;
|
|
182
195
|
}
|
|
@@ -19,6 +19,7 @@ export class Store {
|
|
|
19
19
|
}
|
|
20
20
|
setState(path, value, isUpdate) {
|
|
21
21
|
const fullPath = Array.isArray(path) ? path.map(String) : [String(path)];
|
|
22
|
+
console.log(">>>>", fullPath);
|
|
22
23
|
this.state = this.updateNestedState(this.state, fullPath, value);
|
|
23
24
|
this.notify(fullPath, isUpdate);
|
|
24
25
|
}
|
package/lib/esm/App.js
CHANGED
|
@@ -7,13 +7,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
11
|
+
import { useEffect, useState } from "react";
|
|
12
12
|
import { DataGrid } from "./DataGrid";
|
|
13
13
|
import { useGridApiRef } from "./hooks/useGridApiRef";
|
|
14
14
|
const RenderCell = (params) => {
|
|
15
|
-
const [value, setValue] = useState(0);
|
|
16
|
-
const test = useDeferredValue(value);
|
|
15
|
+
// const [value, setValue] = useState(0);
|
|
16
|
+
// const test = useDeferredValue(value);
|
|
17
17
|
useEffect(() => {
|
|
18
18
|
const tt = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
19
|
let tt = 0;
|
|
@@ -33,13 +33,15 @@ const RenderCell = (params) => {
|
|
|
33
33
|
// height: Math.floor(Math.random() * 20) + 20,
|
|
34
34
|
};
|
|
35
35
|
});
|
|
36
|
-
setValue(tt);
|
|
36
|
+
// setValue(tt);
|
|
37
37
|
});
|
|
38
38
|
requestIdleCallback(() => {
|
|
39
39
|
tt();
|
|
40
40
|
});
|
|
41
41
|
}, []);
|
|
42
|
-
return (_jsxs("div", { style: { background: "green" }, children: [
|
|
42
|
+
return (_jsxs("div", { style: { background: "green" }, children: [_jsx("button", { onClick: () => {
|
|
43
|
+
params.gridRef.current.setRowHeight(1, 100);
|
|
44
|
+
}, children: "??" }), params.value] }));
|
|
43
45
|
};
|
|
44
46
|
const RenderEditCell = (params) => {
|
|
45
47
|
return (_jsx(_Fragment, { children: _jsx("input", Object.assign({}, params, { style: { background: "yellow" } })) }));
|
|
@@ -164,7 +166,7 @@ function App() {
|
|
|
164
166
|
const ref = useGridApiRef();
|
|
165
167
|
const [dataSource, setDataSource] = useState([]);
|
|
166
168
|
const handleDataSource = () => {
|
|
167
|
-
const data = Array.from({ length:
|
|
169
|
+
const data = Array.from({ length: 1000 }, (_, i) => {
|
|
168
170
|
return {
|
|
169
171
|
id: i,
|
|
170
172
|
code: `test-${i}`,
|
|
@@ -188,7 +190,7 @@ function App() {
|
|
|
188
190
|
}, children: "\uB370\uC774\uD130 set" }), _jsx("button", { onClick: () => {
|
|
189
191
|
const data = ref.current.getData();
|
|
190
192
|
console.log("!!!!!", data);
|
|
191
|
-
}, children: "
|
|
193
|
+
}, children: "\uD558" }), _jsx("div", { style: { width: "1200px", height: "300px" }, children: _jsx(DataGrid, { gridRef: ref, columns: columns, dataSource: dataSource }) }), _jsx("div", { style: { width: "1200px", height: "300px" }, children: _jsx(DataGrid, { columns: columns, dataSource: dataSource }) }), _jsx("button", { children: "dd" })] }));
|
|
192
194
|
}
|
|
193
195
|
export const initialItemsData = () => Array.from({ length: 10 }, (_, i) => {
|
|
194
196
|
return {
|
|
@@ -11,6 +11,7 @@ import { EditStatus } from "../types/dataGridCoreEnum";
|
|
|
11
11
|
import CellMode from "./cell/CellMode";
|
|
12
12
|
import ImeComponent from "./ime/IMEComponent";
|
|
13
13
|
import NoDataComponent from "./body/NoDataComponent";
|
|
14
|
+
import { useAddApi } from "../hooks/useGridInitialization";
|
|
14
15
|
const initialWindowWidth = 800;
|
|
15
16
|
export const initialWindowHeight = 500;
|
|
16
17
|
const overscanTopRow = 4;
|
|
@@ -72,6 +73,9 @@ const DynamicVirtualScroll = React.memo(({ children }) => {
|
|
|
72
73
|
const { dataSource } = useSelector((store) => ({
|
|
73
74
|
dataSource: store.state.dataSource,
|
|
74
75
|
}));
|
|
76
|
+
useSelector((store) => ({
|
|
77
|
+
__randomDataSourceKey: store.__randomDataSourceKey,
|
|
78
|
+
}));
|
|
75
79
|
const totalHeight = useMemo(() => dataSource.reduce((sum, item) => sum + item.height, 0), [dataSource]);
|
|
76
80
|
const totalWidth = useMemo(() => columns.reduce((sum, column) => sum + Number(column.width), 0) || 0, [columns]);
|
|
77
81
|
const binarySearchIndex = useCallback((items, target) => {
|
|
@@ -132,7 +136,7 @@ const DynamicVirtualScroll = React.memo(({ children }) => {
|
|
|
132
136
|
result.push(dataSource[rowIndex - 1]); // fixedIndex가 범위에 포함되지 않으면 첫 번째에 추가
|
|
133
137
|
}
|
|
134
138
|
return result;
|
|
135
|
-
}, [dataSource, start, end]);
|
|
139
|
+
}, [JSON.stringify(dataSource), start, end]);
|
|
136
140
|
const startColumnIndex = useMemo(() => Math.max(0, binarySearchIndex(cumulativeWidths, scrollLeft) - overscanColumn), [columns, cumulativeWidths, scrollLeft, binarySearchIndex, overscanColumn]);
|
|
137
141
|
const offsetTop = useMemo(() => cumulativeHeights[start] || 0, [cumulativeHeights, start]);
|
|
138
142
|
const offsetLeft = useMemo(() => cumulativeWidths[startColumnIndex] || 0, [cumulativeWidths, startColumnIndex]);
|
|
@@ -267,6 +271,7 @@ const VirtualItem = React.memo(({ column, row, isFocus, editStatus, rowIndex, })
|
|
|
267
271
|
export const TwoDimensionalVirtualizedList = React.memo(() => {
|
|
268
272
|
// 마우스 다운 시작지점점
|
|
269
273
|
const gridRef = useGridApiContext();
|
|
274
|
+
useAddApi(gridRef);
|
|
270
275
|
const mouseDownStartPointRef = useRef(0);
|
|
271
276
|
const mouseDownStartWidthRef = useRef(0);
|
|
272
277
|
const colIndexRef = useRef(0);
|
|
@@ -2,9 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { useGridApiMethod } from "../useGridApiMethod";
|
|
3
3
|
import { classes } from "../../types/classes";
|
|
4
4
|
import { defaultProps } from "../../common/constants";
|
|
5
|
-
import { useStore } from "../../provider/GridStoreContent";
|
|
6
5
|
export default function usePublicTest(apiRef) {
|
|
7
|
-
const store = useStore();
|
|
8
6
|
const getData = React.useCallback(() => {
|
|
9
7
|
return apiRef.current.store.state.dataSource;
|
|
10
8
|
}, []);
|
|
@@ -25,7 +23,12 @@ export default function usePublicTest(apiRef) {
|
|
|
25
23
|
}, []);
|
|
26
24
|
const setRowHeight = React.useCallback((rowIndex, height = defaultProps.height) => {
|
|
27
25
|
apiRef.current.store.state.dataSource[rowIndex] = Object.assign(Object.assign({}, apiRef.current.store.state.dataSource[rowIndex]), { height: height });
|
|
28
|
-
|
|
26
|
+
apiRef.current.store.__randomDataSourceKey = `${Math.random()}`;
|
|
27
|
+
console.log("!!!", apiRef.current.store.__randomDataSourceKey);
|
|
28
|
+
apiRef.current.store.updateKeyTemp.add("__randomDataSourceKey");
|
|
29
|
+
setTimeout(() => {
|
|
30
|
+
apiRef.current.getPublicApi().forceUpdate();
|
|
31
|
+
}, 0);
|
|
29
32
|
}, []);
|
|
30
33
|
const apiMethods = { addCellRange, getData, scrollToRowIndex, setRowHeight };
|
|
31
34
|
useGridApiMethod(apiRef, apiMethods, "public");
|
|
@@ -31,7 +31,11 @@ export default function useInternalPrivateApi(apiRef) {
|
|
|
31
31
|
const basicStore = setBasicStore(props);
|
|
32
32
|
apiRef.current = Object.assign(Object.assign({}, apiRef.current), { store: Object.assign(Object.assign({}, apiRef.current.store), { original: basicStore, state: Object.assign({}, basicStore),
|
|
33
33
|
// 현재 내부에서 사용되는 속성은 수동으로 초기화 해야함.
|
|
34
|
-
__cellRange: [], __cellRangeTemp: {}
|
|
34
|
+
__cellRange: [], __cellRangeTemp: {},
|
|
35
|
+
/**
|
|
36
|
+
* 누적 높이 캐싱
|
|
37
|
+
*/
|
|
38
|
+
cumulativeHeights: [], updateKeyTemp: new Set(), __randomDataSourceKey: "" }) });
|
|
35
39
|
return apiRef.current;
|
|
36
40
|
}, []);
|
|
37
41
|
const setBasicStore = React.useCallback((props) => {
|
|
@@ -121,16 +125,17 @@ export default function useInternalPrivateApi(apiRef) {
|
|
|
121
125
|
sum += (_a = row.height) !== null && _a !== void 0 ? _a : 32;
|
|
122
126
|
return sum;
|
|
123
127
|
});
|
|
124
|
-
apiRef.current.store.
|
|
128
|
+
apiRef.current.store.cumulativeHeights = heightCache;
|
|
129
|
+
return heightCache;
|
|
125
130
|
}, []);
|
|
126
131
|
const getScrollTop = React.useCallback((rowIndex) => {
|
|
127
132
|
let low = 0;
|
|
128
|
-
let high = apiRef.current.store.
|
|
133
|
+
let high = apiRef.current.store.cumulativeHeights.length - 1;
|
|
129
134
|
let result = 0;
|
|
130
135
|
while (low <= high) {
|
|
131
136
|
const mid = Math.floor((low + high) / 2);
|
|
132
137
|
if (mid < rowIndex) {
|
|
133
|
-
result = apiRef.current.store.
|
|
138
|
+
result = apiRef.current.store.cumulativeHeights[mid];
|
|
134
139
|
low = mid + 1;
|
|
135
140
|
}
|
|
136
141
|
else {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import DataGridBasicProps, { GirdApiCommon } from "../types/dataGridProps";
|
|
3
|
-
export declare function
|
|
2
|
+
import DataGridBasicProps, { DataGridPrivateApiModel, GirdApiCommon } from "../types/dataGridProps";
|
|
3
|
+
export declare function useAddApi(ref: React.MutableRefObject<GirdApiCommon<DataGridPrivateApiModel>>): void;
|
|
4
|
+
export declare function useGridInitialization(apiRef: DataGridBasicProps["gridRef"], props: DataGridBasicProps): React.MutableRefObject<GirdApiCommon<DataGridPrivateApiModel>>;
|
|
@@ -2,18 +2,30 @@ import React from "react";
|
|
|
2
2
|
import useTest from "./internal/useInternalPrivateApi";
|
|
3
3
|
import usePublicTest from "./external/usePublicTest";
|
|
4
4
|
import { useGridApiMethod } from "./useGridApiMethod";
|
|
5
|
+
import { useStore } from "../provider/GridStoreContent";
|
|
6
|
+
import useGridApiContext from "./useGridApiContext";
|
|
7
|
+
export function useAddApi(ref) {
|
|
8
|
+
const store = useStore();
|
|
9
|
+
const gridRef = useGridApiContext();
|
|
10
|
+
const forceUpdate = React.useCallback(() => {
|
|
11
|
+
gridRef.current.store.updateKeyTemp.forEach((v) => {
|
|
12
|
+
//타입 및 코드 정리 필요
|
|
13
|
+
// 그리드 외부에서 접근시
|
|
14
|
+
const value = v.split(",").reduce((acc, key) => acc === null || acc === void 0 ? void 0 : acc[key], gridRef.current.store);
|
|
15
|
+
store.setState([v.split(",")], value);
|
|
16
|
+
});
|
|
17
|
+
// store.setState(gridRef.current.store.updateKeyTemp)
|
|
18
|
+
}, []);
|
|
19
|
+
useGridApiMethod(ref, { forceUpdate }, "public");
|
|
20
|
+
}
|
|
5
21
|
export function useGridInitialization(apiRef, props) {
|
|
6
22
|
// const memoizedProps = React.useMemo(() => _.cloneDeep(props), [props]); // props를 메모이제이션
|
|
7
23
|
const privateAipRef = useGridApiInitialization(apiRef, Object.assign({}, props));
|
|
8
24
|
usePublicTest(privateAipRef);
|
|
9
25
|
useTest(privateAipRef);
|
|
10
|
-
//
|
|
11
|
-
const
|
|
12
|
-
//
|
|
13
|
-
const forceUpdate = React.useCallback(() => rawForceUpdate(() => privateAipRef.current.store.state),
|
|
14
|
-
// () => rawForceUpdate(() => privateAipRef.current.store),
|
|
15
|
-
[privateAipRef]);
|
|
16
|
-
useGridApiMethod(privateAipRef, { forceUpdate }, "public");
|
|
26
|
+
// const [, rawForceUpdate] = React.useState<any>();
|
|
27
|
+
// const forceUpdate = React.useCallback<DataGridPublicApi["forceUpdate"]>(() => rawForceUpdate(() => privateAipRef.current.store.state), [privateAipRef]);
|
|
28
|
+
// useGridApiMethod(privateAipRef, { forceUpdate }, "public");
|
|
17
29
|
return privateAipRef;
|
|
18
30
|
}
|
|
19
31
|
/**
|
|
@@ -89,7 +89,7 @@ export const useSelector = (selector) => {
|
|
|
89
89
|
const newPath = [...currentPath, prop];
|
|
90
90
|
const value = obj[prop];
|
|
91
91
|
// 정확한 경로 저장
|
|
92
|
-
if (currentPath.length > 0 || prop === "state") {
|
|
92
|
+
if (currentPath.length > 0 || prop === "state" || prop === "original" || prop === "__randomDataSourceKey") {
|
|
93
93
|
if (!isArrayInSet(accessedPaths.current, newPath)) {
|
|
94
94
|
accessedPaths.current.add(newPath);
|
|
95
95
|
}
|
|
@@ -52,11 +52,24 @@ export interface DataGridOptionPropsModel {
|
|
|
52
52
|
* @private
|
|
53
53
|
* @namespace NoraDataGrid.DataGridBasicStorePropsModel
|
|
54
54
|
*/
|
|
55
|
-
interface DataGridBasicStorePropsModel {
|
|
55
|
+
export interface DataGridBasicStorePropsModel {
|
|
56
56
|
gridContainer: React.RefObject<HTMLDivElement>;
|
|
57
|
-
|
|
57
|
+
/**
|
|
58
|
+
* 누적 높이 캐싱
|
|
59
|
+
*/
|
|
60
|
+
cumulativeHeights: number[];
|
|
58
61
|
__cellRange: Array<CellRangeDef>;
|
|
59
62
|
__cellRangeTemp: CellRangeTempDef;
|
|
63
|
+
/**
|
|
64
|
+
* 변경된 store를 Temp로 관리 합니다.
|
|
65
|
+
* 일괄 업데이트용으로 사용해주세요.
|
|
66
|
+
*/
|
|
67
|
+
updateKeyTemp: Set<string>;
|
|
68
|
+
/**
|
|
69
|
+
* dataSource 값이 변경되었을때 값이 변합니다.
|
|
70
|
+
* Object는 변경된 값을 감지하기 어렵기 때문에 별도 키 관리
|
|
71
|
+
*/
|
|
72
|
+
__randomDataSourceKey: string;
|
|
60
73
|
}
|
|
61
74
|
/**
|
|
62
75
|
* DataGrid를 구성하는 내부 메소드들을 관리 합니다.
|
|
@@ -124,7 +137,7 @@ export interface DataGridPrivateApiModel {
|
|
|
124
137
|
*/
|
|
125
138
|
setEditStatus: (editStatus: DataGridStoreDef["state"]["editStatus"]) => Promise<DataGridStoreDef["state"]["editStatus"]>;
|
|
126
139
|
/**
|
|
127
|
-
* 데이터에 있는 모든 행
|
|
140
|
+
* 데이터에 있는 모든 행 높의 누적값을 생성합니다.
|
|
128
141
|
* @private
|
|
129
142
|
* @namespace NoraDataGrid.DataGridPublicApiModel.getData
|
|
130
143
|
*/
|
|
@@ -176,7 +189,7 @@ export declare class Store<T> {
|
|
|
176
189
|
private updateNestedState;
|
|
177
190
|
private isPathAffected;
|
|
178
191
|
}
|
|
179
|
-
export interface DataGridStoreDef extends DataGridBasicStorePropsModel {
|
|
192
|
+
export interface DataGridStoreDef extends DataGridBasicStorePropsModel, DataGridBasicStorePropsModel {
|
|
180
193
|
original: DataGridBasicPropsModel & DataGridOptionPropsModel;
|
|
181
194
|
state: DataGridBasicPropsModel & DataGridOptionPropsModel;
|
|
182
195
|
}
|
|
@@ -19,6 +19,7 @@ export class Store {
|
|
|
19
19
|
}
|
|
20
20
|
setState(path, value, isUpdate) {
|
|
21
21
|
const fullPath = Array.isArray(path) ? path.map(String) : [String(path)];
|
|
22
|
+
console.log(">>>>", fullPath);
|
|
22
23
|
this.state = this.updateNestedState(this.state, fullPath, value);
|
|
23
24
|
this.notify(fullPath, isUpdate);
|
|
24
25
|
}
|