@noraent/nora-datagrid 1.1.0-beta.1 → 1.1.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.js +298 -0
- package/dist/DataGrid.d.ts +2 -2
- package/dist/DataGrid.js +193 -0
- package/dist/buildPackage.json +1 -86
- package/dist/common/constants/defaultProps.js +4 -0
- package/dist/common/constants/index.d.ts +2 -2
- package/dist/common/constants/index.js +2 -0
- package/dist/common/constants/path.js +45 -0
- package/dist/common/constants/useEnhancedEffect/index.js +1 -0
- package/dist/common/constants/useEnhancedEffect/useEnhancedEffect.js +3 -0
- package/dist/common/constants/useEventCallback.js +12 -0
- package/dist/common/constants/utils.d.ts +1 -1
- package/dist/common/constants/utils.js +208 -0
- package/dist/common/foundation/index.js +4 -0
- package/dist/common/foundation/palette.d.ts +1 -1
- package/dist/common/foundation/palette.js +198 -0
- package/dist/common/foundation/scale/color/color.js +46 -0
- package/dist/common/foundation/scale/color/index.d.ts +1 -1
- package/dist/common/foundation/scale/color/index.js +1 -0
- package/dist/common/foundation/scale/index.d.ts +2 -2
- package/dist/common/foundation/scale/index.js +2 -0
- package/dist/common/foundation/scale/layout/breakpoints.js +6 -0
- package/dist/common/foundation/scale/layout/index.d.ts +1 -1
- package/dist/common/foundation/scale/layout/index.js +1 -0
- package/dist/common/foundation/scale/layout/size.js +7 -0
- package/dist/common/styled/assets/components/index.d.ts +1 -1
- package/dist/common/styled/assets/components/index.js +1 -0
- package/dist/common/styled/assets/components/loading/Loading.d.ts +1 -1
- package/dist/common/styled/assets/components/loading/Loading.js +2 -0
- package/dist/common/styled/assets/index.d.ts +1 -1
- package/dist/common/styled/assets/index.js +1 -0
- package/dist/common/styled/index.d.ts +10 -10
- package/dist/common/styled/index.js +72 -0
- package/dist/components/GridBasicRows.d.ts +1 -1
- package/dist/components/GridBasicRows.js +88 -0
- package/dist/components/NoraDataGrid.d.ts +3 -2
- package/dist/components/NoraDataGrid.js +191 -0
- package/dist/components/TwoDimensionalVirtualizedList.d.ts +3 -6
- package/dist/components/TwoDimensionalVirtualizedList.js +654 -0
- package/dist/components/body/NoDataComponent.d.ts +1 -1
- package/dist/components/body/NoDataComponent.js +25 -0
- package/dist/components/body/_styled/index.d.ts +6 -6
- package/dist/components/body/_styled/index.js +27 -0
- package/dist/components/cell/CellMode.d.ts +2 -2
- package/dist/components/cell/CellMode.js +70 -0
- package/dist/components/cell/Checkbox.d.ts +1 -1
- package/dist/components/cell/Checkbox.js +48 -0
- package/dist/components/cell/CheckboxAll.d.ts +1 -1
- package/dist/components/cell/CheckboxAll.js +47 -0
- package/dist/components/cell/_styled/index.d.ts +2 -2
- package/dist/components/cell/_styled/index.js +8 -0
- package/dist/components/header/VirtualHorizontalHeader.d.ts +2 -2
- package/dist/components/header/VirtualHorizontalHeader.js +24 -0
- package/dist/components/ime/IMEComponent.d.ts +1 -1
- package/dist/components/ime/IMEComponent.js +145 -0
- package/dist/components/virtualized/_components/GridVirtualScroller.js +19 -0
- package/dist/components/virtualized/_components/RenderHeader.d.ts +1 -1
- package/dist/components/virtualized/_components/RenderHeader.js +7 -0
- package/dist/components/virtualized/_components/VirtualHeader.d.ts +3 -3
- package/dist/components/virtualized/_components/VirtualHeader.js +131 -0
- package/dist/components/virtualized/_constants/virtualHeaderConstants.js +1 -0
- package/dist/components/virtualized/_hooks/useGridVirtualScroller.d.ts +1 -1
- package/dist/components/virtualized/_hooks/useGridVirtualScroller.js +115 -0
- package/dist/components/virtualized/_styled/index.d.ts +16 -16
- package/dist/components/virtualized/_styled/index.js +339 -0
- package/dist/components/virtualized/_styled/virtualScrollerStyled.d.ts +4 -4
- package/dist/components/virtualized/_styled/virtualScrollerStyled.js +20 -0
- package/dist/hooks/external/usePublicTest.d.ts +2 -2
- package/dist/hooks/external/usePublicTest.js +125 -0
- package/dist/hooks/index.d.ts +3 -3
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/internal/useCellRange.d.ts +1 -1
- package/dist/hooks/internal/useCellRange.js +275 -0
- package/dist/hooks/internal/useInternalPrivateApi.d.ts +2 -2
- package/dist/hooks/internal/useInternalPrivateApi.js +330 -0
- package/dist/hooks/useGridApiContext.d.ts +1 -1
- package/dist/hooks/useGridApiContext.js +10 -0
- package/dist/hooks/useGridApiMethod.d.ts +2 -2
- package/dist/hooks/useGridApiMethod.js +23 -0
- package/dist/hooks/useGridApiRef.d.ts +2 -2
- package/dist/hooks/useGridApiRef.js +6 -0
- package/dist/hooks/useGridInitialization.d.ts +2 -2
- package/dist/hooks/useGridInitialization.js +101 -0
- package/dist/hooks/useMouseEvent.d.ts +21 -9
- package/dist/hooks/useMouseEvent.js +342 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -0
- package/dist/packageInfo.js +2 -0
- package/dist/provider/GridApiContext.d.ts +1 -1
- package/dist/provider/GridApiContext.js +5 -0
- package/dist/provider/GridStoreContent.d.ts +2 -2
- package/dist/provider/GridStoreContent.js +69 -0
- package/dist/provider/ThemeProvider.d.ts +3 -3
- package/dist/provider/ThemeProvider.js +20 -0
- package/dist/provider/store.js +28 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/classes/index.d.ts +1 -1
- package/dist/types/classes/index.js +1 -0
- package/dist/types/classes/styled.js +80 -0
- package/dist/types/dataGridCoreEnum.js +7 -0
- package/dist/types/dataGridCoreProps.d.ts +3 -3
- package/dist/types/dataGridCoreProps.js +1 -0
- package/dist/types/dataGridProps.d.ts +53 -8
- package/dist/types/dataGridProps.js +43 -0
- package/dist/types/index.d.ts +8 -8
- package/dist/types/index.js +4 -0
- package/dist/types/license/handleVerify.d.ts +1 -1
- package/dist/types/license/handleVerify.js +19 -0
- package/dist/types/license/licenseInfo.js +39 -0
- package/dist/types/license/verifyLicense.d.ts +1 -1
- package/dist/types/license/verifyLicense.js +124 -0
- package/dist/types/palette.d.ts +1 -1
- package/dist/types/palette.js +1 -0
- package/package.json +2 -1
- package/dist/nora_datagrid.cjs.js +0 -7
- package/dist/nora_datagrid.es.js +0 -11448
- package/dist/vite.svg +0 -1
package/dist/App.js
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React, { useEffect, useState } from "react";
|
|
3
|
+
import { DataGrid } from "./DataGrid";
|
|
4
|
+
import { useGridApiRef } from "./hooks/useGridApiRef";
|
|
5
|
+
import { createTheme, LicenseInfo } from "./types";
|
|
6
|
+
import ThemeProvider from "./provider/ThemeProvider";
|
|
7
|
+
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, MenuItem, Select } from "@mui/material";
|
|
8
|
+
LicenseInfo.setLicenseKey("eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJsaWNlbnNlZSI6Imxlb0Bub3JhZW50LmNvbSIsInBsYW4iOiJQcm8iLCJ2ZXJzaW9uIjoiPj0wLjAuMCA8MS4yLjAiLCJkZXZlbG9wZXJzIjoxLCJkZXNjcmlwdGlvbiI6IlxuICDsgqzsmqkg67KU7JyEOiBcbiAg6riI7KeAIOyCrO2VrTog6rWs66ek7ZWY7KeAIOyViuydgCDri6Trpbgg6rCc67Cc7J6Q7JmAIOudvOydtOyEoOyKpCDtgqTrpbwg6rO17Jyg7ZWY6rGw64KYIOyerO2MkOunpO2VmOuKlCDqsoPsnYAg7JeE6rKp7Z6IIOq4iOyngOuQqeuLiOuLpC4g7J2064qUIOyVveq0gCDsnITrsJjsnbTrqbAg66y064uoIOuPhOyaqeycvOuhnCDqsITso7zrkKnri4jri6RcbiAgIiwiaWF0IjoxNzYyNDA4MTI1fQ.rgc9CcY1PeFd74dUayjsFGuaLIKtvKmpCyzZw_-MeD-1PP32HTzZ6pwg-Y7_YyZ541XTqsuGyKxwxnFG5TM4-4jwfFzSXmapub0JhwhN63ntJcYzY-VjmK9DxiKXwtd9jfruAGNktHhkmkXrHyW7nRWTpiSPDqOqLivaPs3Tb0qrSRSWDiLpeyUSiy_V0FsYLdjc1RLFbnqyJnrwb-06Q-0QnraAixjyxwEqYw1wan9Xcti538RTqF1hOt_fAg_Fm0Pr8sptweKLTOgfrXQcE6aBUP2cfkiFdqH_n_05JSSgEprIZVgXVzCfJWqNYiXduPvWomSstUlOwntlCuQmhw");
|
|
9
|
+
const RenderCell = (params) => {
|
|
10
|
+
return (_jsxs("div", { style: { background: "green" }, children: [_jsx("button", { onClick: () => {
|
|
11
|
+
params.gridRef.current.setRowHeight(1, 100);
|
|
12
|
+
}, children: "??" }), params.value] }));
|
|
13
|
+
};
|
|
14
|
+
const RenderEditCell = (params) => {
|
|
15
|
+
const handleChange = (e) => {
|
|
16
|
+
var _a;
|
|
17
|
+
(_a = params.gridRef) === null || _a === void 0 ? void 0 : _a.current.setEditCellValue({
|
|
18
|
+
id: params.rowRef.current.id,
|
|
19
|
+
fieldId: "currency",
|
|
20
|
+
value: e.target.value,
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
return (_jsx("div", { children: _jsx(Select
|
|
24
|
+
// {...params as any}
|
|
25
|
+
// onChange={(e) => { console.log(e); }}
|
|
26
|
+
, {
|
|
27
|
+
// {...params as any}
|
|
28
|
+
// onChange={(e) => { console.log(e); }}
|
|
29
|
+
value: params.value, inputRef: params.ref, onChange: (e) => {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
(_a = params.gridRef) === null || _a === void 0 ? void 0 : _a.current.setEditCellValue({ id: params.rowRef.current.id, fieldId: "currency", value: e.target.value });
|
|
32
|
+
(_b = params.gridRef) === null || _b === void 0 ? void 0 : _b.current.setEditCellValue({ id: params.rowRef.current.id, fieldId: "code", value: "test" });
|
|
33
|
+
},
|
|
34
|
+
// MenuProps={{
|
|
35
|
+
// disablePortal: true,
|
|
36
|
+
// }}
|
|
37
|
+
autoFocus: true, fullWidth: true, size: "small", displayEmpty: true, children: _jsx(MenuItem, { value: "test", children: "test" }, "test") }) }));
|
|
38
|
+
};
|
|
39
|
+
function getRandomName() {
|
|
40
|
+
const firstNames = ["김", "이", "박", "최", "우", "정", "화"]; // 성
|
|
41
|
+
const lastNames = ["민준", "서연", "지훈", "하은", "지민", "태경", "유림", "라봉"]; // 이름
|
|
42
|
+
const randomFirstName = firstNames[Math.floor(Math.random() * firstNames.length)];
|
|
43
|
+
const randomLastName = lastNames[Math.floor(Math.random() * lastNames.length)];
|
|
44
|
+
return randomFirstName + randomLastName;
|
|
45
|
+
}
|
|
46
|
+
const generateRandomData = () => {
|
|
47
|
+
// const length = Math.round(Math.random() * 2000 + 1);
|
|
48
|
+
const length = Math.round(1000);
|
|
49
|
+
console.log("length", length);
|
|
50
|
+
return Array.from({ length }, (_, idx) => ({
|
|
51
|
+
id: idx + 1,
|
|
52
|
+
name: getRandomName(),
|
|
53
|
+
currency: getRandomName(),
|
|
54
|
+
code: Math.floor(Math.random() * 60) + 18,
|
|
55
|
+
height: Math.floor(Math.random() * 60) + 18,
|
|
56
|
+
}));
|
|
57
|
+
};
|
|
58
|
+
function App() {
|
|
59
|
+
// const ref = React.useRef<GirdApi>(null);
|
|
60
|
+
const ref = useGridApiRef();
|
|
61
|
+
const [dataSource, setDataSource] = useState([]);
|
|
62
|
+
const [testColumns, setTestColumns] = React.useState([
|
|
63
|
+
{
|
|
64
|
+
fieldId: "id",
|
|
65
|
+
fieldName: "코드",
|
|
66
|
+
width: 200,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
fieldId: "name",
|
|
70
|
+
fieldName: "이름",
|
|
71
|
+
width: 120,
|
|
72
|
+
renderCell: RenderCell,
|
|
73
|
+
renderEditCell: RenderEditCell,
|
|
74
|
+
editable: false,
|
|
75
|
+
sortable: false,
|
|
76
|
+
cellClassName: "custom-cell-border",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
fieldId: "currency",
|
|
80
|
+
fieldName: "성명",
|
|
81
|
+
width: 120,
|
|
82
|
+
renderCell: RenderCell,
|
|
83
|
+
renderEditCell: RenderEditCell,
|
|
84
|
+
editable: true,
|
|
85
|
+
singleClickEdit: true,
|
|
86
|
+
cellClassName: (params) => {
|
|
87
|
+
console.log("!!!!", params);
|
|
88
|
+
return "super-app super-app2";
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
fieldId: "code",
|
|
93
|
+
fieldName: "국가",
|
|
94
|
+
width: "120",
|
|
95
|
+
textAlign: "right",
|
|
96
|
+
editable: true,
|
|
97
|
+
singleClickEdit: true,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
fieldId: "currency5",
|
|
101
|
+
fieldName: "구매링크",
|
|
102
|
+
width: "120",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
fieldId: "currency6",
|
|
106
|
+
fieldName: "카드",
|
|
107
|
+
width: "130",
|
|
108
|
+
editable: true,
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
fieldId: "currency7",
|
|
112
|
+
fieldName: "7",
|
|
113
|
+
width: "130",
|
|
114
|
+
editable: true,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
fieldId: "currency8",
|
|
118
|
+
fieldName: "8",
|
|
119
|
+
width: "130",
|
|
120
|
+
editable: true,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
fieldId: "currency9",
|
|
124
|
+
fieldName: "9",
|
|
125
|
+
width: "130",
|
|
126
|
+
editable: true,
|
|
127
|
+
},
|
|
128
|
+
]);
|
|
129
|
+
const handleDataSource = () => {
|
|
130
|
+
// const data = Array.from({ length: 1000 }, (_, i) => {
|
|
131
|
+
// return {
|
|
132
|
+
// id: i,
|
|
133
|
+
// code: `test-${i}`,
|
|
134
|
+
// name: `name-${i}`,
|
|
135
|
+
// note: `note-${i}`,
|
|
136
|
+
// date: new Date(),
|
|
137
|
+
// currency4: `test=${i}`,
|
|
138
|
+
// // height: 30,
|
|
139
|
+
// // height: 20,
|
|
140
|
+
// // height: Math.floor(Math.random() * 20) + 20,
|
|
141
|
+
// };
|
|
142
|
+
// }) as Array<any>;
|
|
143
|
+
setDataSource(generateRandomData());
|
|
144
|
+
};
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
// handleDataSource();
|
|
147
|
+
}, []);
|
|
148
|
+
const test = React.useRef(1);
|
|
149
|
+
const [test2, setTest2] = React.useState(1);
|
|
150
|
+
const [loading, setLoading] = React.useState(false);
|
|
151
|
+
const [promiseArguments, setPromiseArguments] = useState(null);
|
|
152
|
+
// React.useEffect(() => {
|
|
153
|
+
// if (promiseArguments) {
|
|
154
|
+
// setTimeout(() => {
|
|
155
|
+
// promiseArguments.resolve(promiseArguments.newRow);
|
|
156
|
+
// }, 5000);
|
|
157
|
+
// }
|
|
158
|
+
// }, [promiseArguments]);
|
|
159
|
+
const [mode, setMode] = React.useState("light");
|
|
160
|
+
const theme = React.useMemo(() => createTheme({
|
|
161
|
+
mode: mode,
|
|
162
|
+
palette: {
|
|
163
|
+
primary: {
|
|
164
|
+
main: "#009dffff",
|
|
165
|
+
},
|
|
166
|
+
background: {
|
|
167
|
+
paper: "#1f2837",
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
components: {
|
|
171
|
+
HeaderCell: {
|
|
172
|
+
default: {
|
|
173
|
+
text: {
|
|
174
|
+
main: "#FFF",
|
|
175
|
+
},
|
|
176
|
+
backgroundColor: "#2a3341",
|
|
177
|
+
borderColor: "#404855",
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
Row: {
|
|
181
|
+
style: {
|
|
182
|
+
borderColor: "#404855",
|
|
183
|
+
"&.NoraDataGridRow-root": {
|
|
184
|
+
"& .custom-cell-border": {
|
|
185
|
+
border: "0px",
|
|
186
|
+
borderWidth: "0px 3px 0px",
|
|
187
|
+
borderStyle: "solid",
|
|
188
|
+
borderColor: "#ffb800",
|
|
189
|
+
},
|
|
190
|
+
"&:first-child": {
|
|
191
|
+
"& .custom-cell-border": {
|
|
192
|
+
border: "0px",
|
|
193
|
+
borderWidth: "3px 3px 0px",
|
|
194
|
+
borderStyle: "solid",
|
|
195
|
+
borderColor: "#ffb800",
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
"&:last-child": {
|
|
199
|
+
"& .custom-cell-border": {
|
|
200
|
+
border: "0px",
|
|
201
|
+
borderWidth: "0px 3px 3px",
|
|
202
|
+
borderStyle: "solid",
|
|
203
|
+
borderColor: "#ffb800",
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
default: {
|
|
209
|
+
text: {
|
|
210
|
+
main: "#fff",
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
hover: {
|
|
214
|
+
background: "#213e5c",
|
|
215
|
+
},
|
|
216
|
+
"focus-hover": {
|
|
217
|
+
background: "#264a71ff",
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
customVars: {
|
|
222
|
+
":root": {
|
|
223
|
+
"--noraDataGrid-skeleton-bg-1": "#25303eff",
|
|
224
|
+
"--noraDataGrid-skeleton-bg-2": "#26384bff",
|
|
225
|
+
"--noraDataGrid-skeleton-bg-3": "#25303eff",
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
}), [mode]);
|
|
229
|
+
const [, forceUpdate] = React.useState(0);
|
|
230
|
+
console.log("@@@", theme);
|
|
231
|
+
const processRowUpdate = React.useCallback((newRow, oldRow) => {
|
|
232
|
+
return new Promise((resolve, reject) => {
|
|
233
|
+
console.log("행 업데이트 요청:", newRow, oldRow);
|
|
234
|
+
// if (newRow.currency4 !== oldRow.currency4 || newRow.currency !== oldRow.currency || newRow.currency6 !== oldRow.currency6) {
|
|
235
|
+
// resolve(newRow);
|
|
236
|
+
// } else {
|
|
237
|
+
// reject(oldRow);
|
|
238
|
+
// }
|
|
239
|
+
// forceUpdate((v) => v + 1);
|
|
240
|
+
if (newRow.currency4 !== oldRow.currency4 ||
|
|
241
|
+
newRow.currency !== oldRow.currency ||
|
|
242
|
+
newRow.currency6 !== oldRow.currency6 ||
|
|
243
|
+
newRow.code !== oldRow.code) {
|
|
244
|
+
console.log(">>>>", newRow);
|
|
245
|
+
setPromiseArguments({ resolve, reject, newRow, oldRow });
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
resolve(newRow);
|
|
249
|
+
});
|
|
250
|
+
}, []);
|
|
251
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Dialog, { open: !!promiseArguments, children: [_jsx(DialogTitle, { children: "Dialog Title" }), _jsx(DialogContent, {}), _jsxs(DialogActions, { children: [_jsx(Button, { autoFocus: true, onClick: () => {
|
|
252
|
+
promiseArguments.reject();
|
|
253
|
+
setPromiseArguments(null);
|
|
254
|
+
}, children: "Cancel" }), _jsx(Button, { onClick: () => {
|
|
255
|
+
promiseArguments.resolve(promiseArguments.newRow);
|
|
256
|
+
setPromiseArguments(null);
|
|
257
|
+
}, children: "OK" })] })] }), _jsx("button", { onClick: () => setMode(mode === "light" ? "dark" : "light"), children: "\uD14C\uB9C8 \uC804\uD658" }), _jsxs(ThemeProvider, { theme: theme, children: [_jsx("br", {}), _jsx("button", { onClick: () => {
|
|
258
|
+
setDataSource(generateRandomData());
|
|
259
|
+
}, children: "\uB370\uC774\uD130 \uC18C\uC2A4 \uBCC0\uACBD" }), _jsx("button", { onClick: () => {
|
|
260
|
+
console.log("!!!", ref.current.getSelectedRow());
|
|
261
|
+
console.log("!!!", ref.current.getData());
|
|
262
|
+
}, children: "\uC120\uD0DD\uB41C \uD589 \uAC00\uC838\uC624\uAE30" }), _jsx("button", { onClick: () => {
|
|
263
|
+
const randomData = Math.random() * 50 + 5;
|
|
264
|
+
console.log("!!! loader 값 변경", randomData);
|
|
265
|
+
setTest2(randomData);
|
|
266
|
+
}, children: "loader \uAC12 \uBCC0\uACBD" }), _jsx("button", { onClick: () => { }, children: "validation check" }), _jsx("button", { onClick: () => {
|
|
267
|
+
setTestColumns([]);
|
|
268
|
+
}, children: "\uCEEC\uB7FC \uBCC0\uACBD" }), _jsx("button", { onClick: () => {
|
|
269
|
+
ref.current.scrollToRowIndex(6);
|
|
270
|
+
}, children: "414 \uC774\uB3D9" }), _jsx("button", { onClick: () => {
|
|
271
|
+
ref.current.scrollBottomRowIndex(18);
|
|
272
|
+
}, children: "\uC774\uB3D9" }), _jsx("button", { onClick: () => {
|
|
273
|
+
ref.current.scrollToRowIndex(1000000);
|
|
274
|
+
}, children: "1000000 \uC774\uB3D9" }), _jsx("button", { onClick: () => {
|
|
275
|
+
handleDataSource();
|
|
276
|
+
}, children: "\uB370\uC774\uD130 set" }), _jsx("button", { onClick: () => {
|
|
277
|
+
// const data = ref.current.getData();
|
|
278
|
+
console.log(ref.current.getSelectedRow());
|
|
279
|
+
}, children: "\uD558" }), _jsx("button", { onClick: () => {
|
|
280
|
+
// setLoading(!loading);
|
|
281
|
+
forceUpdate((v) => v + 1);
|
|
282
|
+
}, children: "\uB85C\uB529\uC2A4\uC704\uCE58" }), _jsx("div", { style: { width: "899px", height: "100%", border: "1px solid red", marginLeft: "200px" }, children: _jsx(DataGrid, { checkboxSelection: true, selectionMode: "single", gridRef: ref, columns: testColumns, dataSource: dataSource, loading: loading, imeEnabled: false, processRowUpdate: processRowUpdate }) }), _jsx("button", { onClick: () => {
|
|
283
|
+
ref.current.setSelection([0, 1]);
|
|
284
|
+
}, children: "dd" })] })] }));
|
|
285
|
+
}
|
|
286
|
+
export const initialItemsData = () => Array.from({ length: 10 }, (_, i) => {
|
|
287
|
+
return {
|
|
288
|
+
id: i,
|
|
289
|
+
// height: 36,
|
|
290
|
+
// height: Math.floor(Math.random() * 20) + 20,
|
|
291
|
+
columns: Array.from({ length: 20 }, (_, j) => ({
|
|
292
|
+
id: `${i}-${j}`,
|
|
293
|
+
width: 150,
|
|
294
|
+
content: `Cell ${i}-${j}-`,
|
|
295
|
+
})),
|
|
296
|
+
};
|
|
297
|
+
});
|
|
298
|
+
export default App;
|
package/dist/DataGrid.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { DataGridBasicPropsModel } from './types/dataGridProps';
|
|
2
1
|
import * as React from "react";
|
|
3
|
-
|
|
2
|
+
import { DataGridBasicPropsModel } from "./types/dataGridProps";
|
|
3
|
+
export declare const DataGrid: React.NamedExoticComponent<import("./types/dataGridCoreProps").DeepOmitStartsWith<Pick<DataGridBasicPropsModel, "columns" | "dataSource">, "__"> & Partial<import("./types/dataGridProps").DataGridOptionPropsModel> & React.RefAttributes<HTMLDivElement>>;
|
package/dist/DataGrid.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
+
import * as React from "react";
|
|
12
|
+
import { useGridInitialization } from "./hooks/useGridInitialization";
|
|
13
|
+
import { GridApiContext } from "./provider/GridApiContext";
|
|
14
|
+
import { NoraDataGrid } from "./components/NoraDataGrid";
|
|
15
|
+
import { TwoDimensionalVirtualizedList } from "./components/TwoDimensionalVirtualizedList";
|
|
16
|
+
import { GridStoreContentProvider, useStore } from "./provider/GridStoreContent";
|
|
17
|
+
import { Spinner, StyledNoneContent, Typography } from "./common/styled";
|
|
18
|
+
import useGridApiContext from "./hooks/useGridApiContext";
|
|
19
|
+
import { sorting } from "./components/virtualized/_components/VirtualHeader";
|
|
20
|
+
import { generateGridTheme } from "./common/foundation/palette";
|
|
21
|
+
import ThemeProvider, { useThemeContext } from "./provider/ThemeProvider";
|
|
22
|
+
import { css, Global } from "@emotion/react";
|
|
23
|
+
import _ from "lodash";
|
|
24
|
+
import { WatermarStyled } from "./components/virtualized/_styled";
|
|
25
|
+
import { LicenseInfo } from "./types/license/licenseInfo";
|
|
26
|
+
import { Box } from "@mui/material";
|
|
27
|
+
console.info(`%c
|
|
28
|
+
███╗ ██╗ ██████╗ ██████╗ █████╗
|
|
29
|
+
████╗ ██║██╔═══██╗██╔══██╗██╔══██╗
|
|
30
|
+
██╔██╗ ██║██║ ██║██████╔╝███████║
|
|
31
|
+
██║╚██╗██║██║ ██║██╔══██╗██╔══██║
|
|
32
|
+
██║ ╚████║╚██████╔╝██║ ██║██║ ██║
|
|
33
|
+
╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝
|
|
34
|
+
|
|
35
|
+
██████╗ █████╗ ████████╗ █████╗ ██████╗ ██████╗ ██╗██████╗
|
|
36
|
+
██╔══██╗██╔══██╗╚══██╔══╝██╔══██╗ ██╔════╝ ██╔══██╗██║██╔══██╗
|
|
37
|
+
██║ ██║███████║ ██║ ███████║█████╗██║ ███╗██████╔╝██║██║ ██║
|
|
38
|
+
██║ ██║██╔══██║ ██║ ██╔══██║╚════╝██║ ██║██╔══██╗██║██║ ██║
|
|
39
|
+
██████╔╝██║ ██║ ██║ ██║ ██║ ╚██████╔╝██║ ██║██║██████╔╝
|
|
40
|
+
╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═════╝ Beta3(v${import.meta.env.VITE_REACT_APP_VERSION})_${import.meta.env.VITE_RREACT_APP_ENV}
|
|
41
|
+
`, "color:#22577A");
|
|
42
|
+
const DataGridMain = (props) => {
|
|
43
|
+
const gridRef = useGridApiContext();
|
|
44
|
+
const [isInit, setIsInit] = React.useState(false);
|
|
45
|
+
const prevProps = React.useRef(null);
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
prevProps.current = props;
|
|
48
|
+
gridRef.current.setInitialStore(props);
|
|
49
|
+
gridRef.current.initHeightCache();
|
|
50
|
+
setIsInit(true);
|
|
51
|
+
}, []);
|
|
52
|
+
if (!isInit) {
|
|
53
|
+
return (_jsxs(StyledNoneContent, { children: [_jsx(Spinner, {}), _jsx(Typography, { style: { marginTop: "8px", fontSize: "14px" }, children: "\uB85C\uB529\uC911" })] }));
|
|
54
|
+
}
|
|
55
|
+
return (_jsx(GridStoreContentProvider, { value: gridRef, children: _jsx(DataGridContent, { props: props, prevProps: prevProps }) }));
|
|
56
|
+
};
|
|
57
|
+
const DataGridContent = React.memo(({ props, prevProps }) => {
|
|
58
|
+
const gridRef = useGridApiContext();
|
|
59
|
+
const store = useStore();
|
|
60
|
+
React.useEffect(() => {
|
|
61
|
+
if (prevProps.current) {
|
|
62
|
+
Object.keys(props).forEach((key) => {
|
|
63
|
+
var _a;
|
|
64
|
+
const typedKey = key;
|
|
65
|
+
if (((_a = prevProps.current) === null || _a === void 0 ? void 0 : _a[typedKey]) !== props[typedKey]) {
|
|
66
|
+
const basicStore = gridRef.current.setBasicStore(props);
|
|
67
|
+
gridRef.current.setStoreState(typedKey, basicStore[typedKey]);
|
|
68
|
+
store.setState(["state", typedKey], basicStore[typedKey]);
|
|
69
|
+
if (key === "dataSource") {
|
|
70
|
+
gridRef.current.store.__selectionList = [];
|
|
71
|
+
// 다시 정렬
|
|
72
|
+
if (gridRef.current.store.state.sortingMode === "client") {
|
|
73
|
+
const sortedData = sorting(basicStore[typedKey], gridRef.current.store.sortModel);
|
|
74
|
+
gridRef.current.setStoreState(typedKey, sortedData);
|
|
75
|
+
store.setState(["state", "dataSource"], sortedData);
|
|
76
|
+
}
|
|
77
|
+
const heightCache = gridRef.current.initHeightCache();
|
|
78
|
+
gridRef.current.reloadRange();
|
|
79
|
+
store.setState(["cumulativeHeights"], heightCache);
|
|
80
|
+
store.setState(["__reloadRangeRandomKey"], window.crypto.randomUUID());
|
|
81
|
+
store.setState("__selectionList", []);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
prevProps.current = props;
|
|
87
|
+
}, [props]);
|
|
88
|
+
React.useEffect(() => {
|
|
89
|
+
// cellClassName 함수형 처리
|
|
90
|
+
const temp = new Set();
|
|
91
|
+
gridRef.current.store.state.columns.forEach((col) => {
|
|
92
|
+
if (typeof col.cellClassName === "function") {
|
|
93
|
+
const cellClassNameFunc = col.cellClassName({
|
|
94
|
+
columns: gridRef.current.store.state.columns,
|
|
95
|
+
column: gridRef.current.store.state.columns.find((c) => c.fieldId === col.fieldId),
|
|
96
|
+
});
|
|
97
|
+
temp.add({
|
|
98
|
+
fieldId: col.fieldId,
|
|
99
|
+
className: cellClassNameFunc,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
else if (col === null || col === void 0 ? void 0 : col.cellClassName) {
|
|
103
|
+
temp.add({
|
|
104
|
+
fieldId: col.fieldId,
|
|
105
|
+
className: col.cellClassName,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
store.setState("cellClassName", [
|
|
109
|
+
...(gridRef.current.store.cellClassName = gridRef.current.store.cellClassName.filter((c) => c.fieldId !== col.fieldId)),
|
|
110
|
+
...temp,
|
|
111
|
+
]);
|
|
112
|
+
});
|
|
113
|
+
}, []);
|
|
114
|
+
React.useEffect(() => {
|
|
115
|
+
// 랜더링 없이 구독된 이벤트를 콜백 합니다.
|
|
116
|
+
gridRef.current.subscribeEvent("onSelectionRowClick", (row) => {
|
|
117
|
+
gridRef.current.store.state.onSelectionRowClick(row);
|
|
118
|
+
});
|
|
119
|
+
gridRef.current.subscribeEvent("onSelectionRowChange", (row) => {
|
|
120
|
+
gridRef.current.store.state.onSelectionRowChange(row);
|
|
121
|
+
});
|
|
122
|
+
gridRef.current.subscribeEvent("onSelectionRowChangeBefore", (newRows, oldRows) => __awaiter(void 0, void 0, void 0, function* () {
|
|
123
|
+
try {
|
|
124
|
+
const result = yield gridRef.current.store.state.onSelectionRowChangeBefore(newRows, oldRows);
|
|
125
|
+
gridRef.current.store.__selectionList = result.flatMap((r) => r.__uuid);
|
|
126
|
+
store.setState("__selectionList", result.flatMap((r) => r.__uuid));
|
|
127
|
+
if (!_.isEqual(newRows, oldRows)) {
|
|
128
|
+
gridRef.current.publishEvent("onSelectionRowChange", result);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
gridRef.current.store.__selectionList = oldRows.flatMap((r) => r.__uuid);
|
|
133
|
+
store.setState("__selectionList", oldRows.flatMap((r) => r.__uuid));
|
|
134
|
+
}
|
|
135
|
+
}));
|
|
136
|
+
gridRef.current.subscribeEvent("onSelectionRowClickBefore", (row, selected, selectionModel) => __awaiter(void 0, void 0, void 0, function* () {
|
|
137
|
+
var _a, _b;
|
|
138
|
+
try {
|
|
139
|
+
const oldRows = gridRef.current.store.state.dataSource.filter((v) => gridRef.current.store.__selectionList.includes(v.__uuid));
|
|
140
|
+
const newRows = [...oldRows, row];
|
|
141
|
+
const result = yield gridRef.current.store.state.onSelectionRowClickBefore(row, selected, selectionModel);
|
|
142
|
+
const mode = gridRef.current.store.__selectionMode;
|
|
143
|
+
if (mode === "single") {
|
|
144
|
+
if (result) {
|
|
145
|
+
gridRef.current.store.__selectionList = [row.__uuid];
|
|
146
|
+
store.setState("__selectionList", [row.__uuid]);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
gridRef.current.store.__selectionList = [];
|
|
150
|
+
store.setState("__selectionList", []);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
if (result) {
|
|
155
|
+
gridRef.current.store.__selectionList = [...selectionModel, row.__uuid];
|
|
156
|
+
store.setState("__selectionList", [...selectionModel, row.__uuid]);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
gridRef.current.store.__selectionList = selectionModel.filter((uuid) => uuid !== row.__uuid);
|
|
160
|
+
store.setState("__selectionList", selectionModel.filter((uuid) => uuid !== row.__uuid));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
if (typeof ((_a = gridRef.current.store.state) === null || _a === void 0 ? void 0 : _a.onSelectionRowClick) === "function") {
|
|
164
|
+
gridRef.current.publishEvent("onSelectionRowClick", row);
|
|
165
|
+
}
|
|
166
|
+
if (typeof ((_b = gridRef.current.store.state) === null || _b === void 0 ? void 0 : _b.onSelectionRowChangeBefore) === "function") {
|
|
167
|
+
if (!_.isEqual(newRows, oldRows)) {
|
|
168
|
+
gridRef.current.publishEvent("onSelectionRowChangeBefore", newRows, oldRows);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
catch (error) { }
|
|
174
|
+
}));
|
|
175
|
+
}, []);
|
|
176
|
+
const imeRef = React.useRef(null);
|
|
177
|
+
return (_jsx(NoraDataGrid.Body, { imeRef: imeRef, children: _jsx(TwoDimensionalVirtualizedList, { imeRef: imeRef }) }));
|
|
178
|
+
});
|
|
179
|
+
const DataGridMaster = React.forwardRef((props, _ref) => {
|
|
180
|
+
const { gridRef, style } = props;
|
|
181
|
+
const apiRef = useGridInitialization(gridRef, props);
|
|
182
|
+
const containerRef = React.useRef(null);
|
|
183
|
+
const themeContext = useThemeContext();
|
|
184
|
+
const theme = themeContext ? themeContext : generateGridTheme("light");
|
|
185
|
+
React.useEffect(() => {
|
|
186
|
+
apiRef.current.setGridContainer(containerRef);
|
|
187
|
+
}, []);
|
|
188
|
+
const isValidLicense = LicenseInfo.isValid();
|
|
189
|
+
return (_jsxs(GridApiContext.Provider, { value: apiRef, children: [_jsx(Global, { styles: css `
|
|
190
|
+
${theme.customVars}
|
|
191
|
+
` }), _jsx(Box, { style: { position: "absolute", zIndex: "100", top: 0, background: "red" }, children: Math.random() }), _jsx(ThemeProvider, { theme: theme, children: _jsxs(NoraDataGrid, { ref: containerRef, style: style, children: [_jsx(NoraDataGrid.Title, {}), _jsx(DataGridMain, Object.assign({}, props)), !isValidLicense && _jsx(WatermarStyled, {})] }) })] }));
|
|
192
|
+
});
|
|
193
|
+
export const DataGrid = React.memo(DataGridMaster);
|
package/dist/buildPackage.json
CHANGED
|
@@ -1,88 +1,3 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
"version": "1.1.0-beta.1",
|
|
4
|
-
"module": "./dist/nora_datagrid.es.js",
|
|
5
|
-
"main": "./dist/nora_datagrid.cjs.js",
|
|
6
|
-
"private": false,
|
|
7
|
-
"files": [
|
|
8
|
-
"dist/"
|
|
9
|
-
],
|
|
10
|
-
"exports": {
|
|
11
|
-
".": {
|
|
12
|
-
"types": "./dist/index.d.ts",
|
|
13
|
-
"import": "./dist/nora_datagrid.es.js",
|
|
14
|
-
"require": "./dist/nora_datagrid.cjs.js"
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"type": "module",
|
|
18
|
-
"sideEffects": false,
|
|
19
|
-
"scripts": {
|
|
20
|
-
"start": "vite --mode on-local",
|
|
21
|
-
"build:local": "tsc -b && vite build --mode on-local",
|
|
22
|
-
"build:dev": "tsc -b && vite build --mode dev",
|
|
23
|
-
"build:production": "tsc -b && vite build --mode production",
|
|
24
|
-
"clean": "pnpm run clean:build && rimraf ./node_modules",
|
|
25
|
-
"clean:build": "rimraf ./dist",
|
|
26
|
-
"lint": "eslint .",
|
|
27
|
-
"preview": "vite preview",
|
|
28
|
-
"test": "jest",
|
|
29
|
-
"tsc-build": "tsc -p tsconfig-esm.json && tsc -p tsconfig-cjs.json && npm run vite-build && npm run copy-scss",
|
|
30
|
-
"vite-build": "tsc -b && vite build --mode production",
|
|
31
|
-
"publish:npm": "rm -rf dist && mkdir dist && npm run vite-build && npm run copy-package",
|
|
32
|
-
"copy-package": "cp package.json dist/buildPackage.json && cp package.json lib/cjs/buildPackage.json&& cp package.json lib/esm/buildPackage.json ",
|
|
33
|
-
"copy-scss": "cpx \"src/**/*.scss\" lib/cjs && cpx \"src/**/*.scss\" lib/esm"
|
|
34
|
-
},
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"@emotion/css": "^11.13.5",
|
|
37
|
-
"@noraent/nora-datagrid": "file:",
|
|
38
|
-
"jose": "^6.1.0",
|
|
39
|
-
"lodash": "^4.17.21",
|
|
40
|
-
"rimraf": "^6.0.1",
|
|
41
|
-
"sass-embedded": "^1.87.0"
|
|
42
|
-
},
|
|
43
|
-
"peerDependencies": {
|
|
44
|
-
"@emotion/react": "^11.14.0",
|
|
45
|
-
"@emotion/styled": "^11.14.0",
|
|
46
|
-
"react": "^18.0.0 || ^19.0.0",
|
|
47
|
-
"react-dom": "^18.0.0 || ^19.0.0"
|
|
48
|
-
},
|
|
49
|
-
"devDependencies": {
|
|
50
|
-
"@babel/cli": "^7.27.2",
|
|
51
|
-
"@babel/preset-react": "^7.27.1",
|
|
52
|
-
"@eslint/js": "^9.9.0",
|
|
53
|
-
"@types/lodash": "^4.17.16",
|
|
54
|
-
"@types/node": "^22.15.14",
|
|
55
|
-
"@types/react": "^19.0.0",
|
|
56
|
-
"@types/react-dom": "^19.0.0",
|
|
57
|
-
"@vitejs/plugin-react": "^4.3.4",
|
|
58
|
-
"cpx": "^1.5.0",
|
|
59
|
-
"eslint": "^9.9.0",
|
|
60
|
-
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
|
|
61
|
-
"eslint-plugin-react-refresh": "^0.4.9",
|
|
62
|
-
"globals": "^15.9.0",
|
|
63
|
-
"react": "^19.0.0",
|
|
64
|
-
"react-dom": "^19.0.0",
|
|
65
|
-
"terser": "^5.39.0",
|
|
66
|
-
"typescript": "~5.8.3",
|
|
67
|
-
"typescript-eslint": "^8.24.1",
|
|
68
|
-
"vite": "^6.2.0",
|
|
69
|
-
"vite-plugin-dts": "^4.5.3",
|
|
70
|
-
"vite-plugin-svgr": "^4.3.0",
|
|
71
|
-
"vite-tsconfig-paths": "^5.1.4"
|
|
72
|
-
},
|
|
73
|
-
"peerDependenciesMeta": {
|
|
74
|
-
"@emotion/react": {
|
|
75
|
-
"optional": true
|
|
76
|
-
},
|
|
77
|
-
"@emotion/styled": {
|
|
78
|
-
"optional": true
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
"babel": {
|
|
82
|
-
"presets": [
|
|
83
|
-
"@babel/preset-env",
|
|
84
|
-
"@babel/preset-react"
|
|
85
|
-
]
|
|
86
|
-
},
|
|
87
|
-
"packageManager": "pnpm@10.6.5+sha512.cdf928fca20832cd59ec53826492b7dc25dc524d4370b6b4adbf65803d32efaa6c1c88147c0ae4e8d579a6c9eec715757b50d4fa35eea179d868eada4ed043af"
|
|
2
|
+
"version": "배포시 버전 표시"
|
|
88
3
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
1
|
+
export * from "./defaultProps";
|
|
2
|
+
export * from "./useEventCallback";
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export const GUIDE_PATH = {
|
|
2
|
+
path: "/",
|
|
3
|
+
GUIDE: {
|
|
4
|
+
path: "guide",
|
|
5
|
+
GETTING_STARTED: {
|
|
6
|
+
pathname: "시작하기",
|
|
7
|
+
path: "getting-started",
|
|
8
|
+
},
|
|
9
|
+
VALIDATION: {
|
|
10
|
+
pathname: "유요성 검증 가이드",
|
|
11
|
+
path: "validation",
|
|
12
|
+
icon: "🚀",
|
|
13
|
+
REACT_HOOK_FORM_VALIDATION: {
|
|
14
|
+
pathname: "react-hook-form을 통한 유효성 검증",
|
|
15
|
+
path: "react-hook-form",
|
|
16
|
+
},
|
|
17
|
+
REACT_HOOK_FORM_AND_ZOD_VALIDATION: {
|
|
18
|
+
pathname: "ZOD를 통한 유효성 검증",
|
|
19
|
+
path: "zod",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
export const buildGuidePath = (...paths) => `/${paths.join("/")}`;
|
|
25
|
+
export const buildFullPath = (path) => {
|
|
26
|
+
const tracePath = (target, currentPath = "") => {
|
|
27
|
+
// 현재 객체에서 path가 있는 경우
|
|
28
|
+
for (const key in target) {
|
|
29
|
+
if (target[key] && typeof target[key] === "object") {
|
|
30
|
+
const newPath = currentPath ? `${currentPath}/${target[key].path}` : target[key].path;
|
|
31
|
+
// 하위 객체 탐색
|
|
32
|
+
if (target[key].path === path) {
|
|
33
|
+
return newPath;
|
|
34
|
+
}
|
|
35
|
+
// 재귀적으로 하위 경로를 추적
|
|
36
|
+
const nestedPath = tracePath(target[key], newPath);
|
|
37
|
+
if (nestedPath)
|
|
38
|
+
return nestedPath;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return "";
|
|
42
|
+
};
|
|
43
|
+
// 전체 경로를 반환
|
|
44
|
+
return "/" + tracePath(GUIDE_PATH);
|
|
45
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './useEnhancedEffect';
|