pixel-react 1.9.4 → 1.9.6

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.
Files changed (37) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/lib/ComponentProps/TreeNodeProps.d.ts +31 -0
  3. package/lib/components/Charts/MultiRadialChart/types.d.ts +2 -2
  4. package/lib/components/TableTree/Components/TableBody.d.ts +1 -1
  5. package/lib/components/TableTree/types.d.ts +3 -7
  6. package/lib/components/Tabs/Tabs.d.ts +1 -1
  7. package/lib/components/Tabs/types.d.ts +1 -0
  8. package/lib/index.d.ts +51 -11
  9. package/lib/index.esm.js +125 -34
  10. package/lib/index.esm.js.map +1 -1
  11. package/lib/index.js +126 -33
  12. package/lib/index.js.map +1 -1
  13. package/lib/tsconfig.tsbuildinfo +1 -1
  14. package/lib/utils/getTreeDetails/getTreeDetails.d.ts +10 -0
  15. package/lib/utils/handleTreeNodeSelect/handleTreeNodeSelect.d.ts +2 -0
  16. package/package.json +1 -1
  17. package/src/ComponentProps/TreeNodeProps.ts +31 -0
  18. package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.scss +6 -3
  19. package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.tsx +10 -4
  20. package/src/components/Charts/MultiRadialChart/types.ts +16 -17
  21. package/src/components/TableTree/Components/TableBody.tsx +22 -23
  22. package/src/components/TableTree/Components/TableCell.tsx +3 -3
  23. package/src/components/TableTree/Components/TableRow.tsx +0 -3
  24. package/src/components/TableTree/TableTree.scss +11 -1
  25. package/src/components/TableTree/TableTree.tsx +28 -15
  26. package/src/components/TableTree/data.ts +86 -1
  27. package/src/components/TableTree/types.ts +3 -8
  28. package/src/components/Tabs/Tabs.scss +44 -1
  29. package/src/components/Tabs/Tabs.stories.tsx +26 -0
  30. package/src/components/Tabs/Tabs.tsx +2 -0
  31. package/src/components/Tabs/types.ts +1 -0
  32. package/src/index.ts +17 -2
  33. package/src/utils/findAndInsert/findAndInsert.stories.tsx +1 -0
  34. package/src/utils/getTreeDetails/getTreeDetails.stories.tsx +167 -0
  35. package/src/utils/getTreeDetails/getTreeDetails.ts +65 -0
  36. package/src/utils/handleTreeNodeSelect/HandleTreeNodeSelect.stories.tsx +195 -0
  37. package/src/utils/handleTreeNodeSelect/handleTreeNodeSelect.ts +61 -0
@@ -5,6 +5,7 @@
5
5
  box-sizing: border-box;
6
6
 
7
7
  .ff-tab-row {
8
+ flex: 0 1 auto;
8
9
  &--default {
9
10
  display: flex;
10
11
  gap: 8px;
@@ -38,11 +39,13 @@
38
39
  font-size: 8px;
39
40
  font-weight: 600;
40
41
  padding: 0 2px;
42
+
41
43
  &--active {
42
44
  background-color: var(--tabs-label-active-color);
43
45
  }
44
46
  }
45
47
  }
48
+
46
49
  .ff-tab-bar {
47
50
  width: 100%;
48
51
  border-radius: 2px 2px 0 0;
@@ -69,8 +72,10 @@
69
72
  color: var(--tabs-label-active-color) !important;
70
73
  }
71
74
  }
75
+
72
76
  .tab-count {
73
77
  background-color: var(--input-hover-border-color);
78
+
74
79
  &--active {
75
80
  background-color: var(--tabs-label-active-color);
76
81
  }
@@ -125,11 +130,48 @@
125
130
  &--no-border {
126
131
  border: none;
127
132
  }
133
+
134
+ &--no-padding {
135
+ border-radius: 8px;
136
+ background: white;
137
+ padding: 0px;
138
+ justify-content: flex-start;
139
+ margin-right: 8px;
140
+
141
+ .ff-tab-button {
142
+ &--capsule {
143
+ background: transparent;
144
+ border: none;
145
+ padding: 3px 4px;
146
+ border-radius: 7px;
147
+ cursor: pointer;
148
+
149
+ &:hover {
150
+ .ff-tab-label {
151
+ color: var(--input-hover-border-color) !important;
152
+
153
+ &--active {
154
+ color: var(--tabs-label-active-color) !important;
155
+ }
156
+ }
157
+ }
158
+
159
+ &.active {
160
+ background-color: var(--slider-table-color);
161
+ }
162
+
163
+ .ff-tab-bar {
164
+ display: none;
165
+ }
166
+ }
167
+ }
168
+ }
128
169
  }
129
170
 
130
171
  .ff-tab-content {
131
172
  width: inherit;
132
173
  }
174
+
133
175
  .ff-defaultStatus {
134
176
  position: absolute;
135
177
  top: 2px;
@@ -143,9 +185,10 @@
143
185
  background-color: var(--confirm-tick-icon-color);
144
186
  box-shadow: 0px 1px 1px 0px var(--toggle-strip-shadow);
145
187
  }
188
+
146
189
  &.ff-dangerStatus {
147
190
  background-color: var(--delete-text-color);
148
191
  box-shadow: 0px 1px 1px 0px var(--toggle-strip-shadow);
149
192
  }
150
193
  }
151
- }
194
+ }
@@ -150,4 +150,30 @@ export const WithoutBorder: Story = {
150
150
  },
151
151
  };
152
152
 
153
+ export const WithoutPadding: Story = {
154
+ render: () => {
155
+ const [activeTabIdDefault, setActiveTabIdDefault] =
156
+ useState<string>('tab-1');
157
+
158
+ return (
159
+ <div style={{ display: 'flex', gap: '10px' }}>
160
+ <Tabs
161
+ tabsData={tabsData}
162
+ activeTabId={activeTabIdDefault}
163
+ onTabClick={setActiveTabIdDefault}
164
+ noPadding={true}
165
+ />{' '}
166
+ <hr />
167
+ <Tabs
168
+ variant="capsule"
169
+ tabsData={tabsData}
170
+ activeTabId={activeTabIdDefault}
171
+ onTabClick={setActiveTabIdDefault}
172
+ noPadding={true}
173
+ />
174
+ </div>
175
+ );
176
+ },
177
+ };
178
+
153
179
  export default meta;
@@ -10,12 +10,14 @@ const Tabs = ({
10
10
  activeTabId,
11
11
  onTabClick,
12
12
  noBorder = false,
13
+ noPadding = false,
13
14
  }: TabsProps) => {
14
15
  return (
15
16
  <div className={`ff-tabs-container`}>
16
17
  <div
17
18
  className={classNames(`ff-tab-row--${variant}`, {
18
19
  'ff-tab-row--no-border': noBorder,
20
+ 'ff-tab-row--no-padding': noPadding,
19
21
  })}
20
22
  >
21
23
  {tabsData.map((tab) => (
@@ -46,4 +46,5 @@ export interface TabsProps {
46
46
  * noBorder:true , removes the outer border from tabs
47
47
  */
48
48
  noBorder?: boolean;
49
+ noPadding?:boolean
49
50
  }
package/src/index.ts CHANGED
@@ -105,7 +105,13 @@ import ConditionalDropdown from './components/ConditionalDropdown/ConditionalDro
105
105
  import { hasDuplicateFile } from './utils/checkDuplicates/checkDuplicates';
106
106
  import PhoneInputField from './components/PhoneInput';
107
107
  import { useKeyboardActions } from './utils/keyBoardActionUtil/UseKeyboardActions';
108
- import { rearrangeDragItem } from './utils/swapArrayItem/dragAndDropUtils'
108
+ import { rearrangeDragItem } from './utils/swapArrayItem/dragAndDropUtils';
109
+
110
+ import { getTreeDetails } from './utils/getTreeDetails/getTreeDetails';
111
+ import { handleTreeNodeSect } from './utils/handleTreeNodeSelect/handleTreeNodeSelect';
112
+
113
+ import { TreeNodeProps } from './ComponentProps/TreeNodeProps';
114
+
109
115
  import {
110
116
  EMAIL_REGEX,
111
117
  URL_REGEX,
@@ -163,7 +169,10 @@ import {
163
169
  ELEMENTS_WHITE_SPACE_REGEX,
164
170
  PARAMETER_ALPHANUMERIC_REGEX,
165
171
  } from './validations/regex';
166
- import { getFromIndexedDB, saveToIndexedDB } from './utils/indexDBStore/indexDB';
172
+ import {
173
+ getFromIndexedDB,
174
+ saveToIndexedDB,
175
+ } from './utils/indexDBStore/indexDB';
167
176
 
168
177
  export {
169
178
  Button,
@@ -275,7 +284,13 @@ export {
275
284
  saveToIndexedDB,
276
285
  getFromIndexedDB,
277
286
  rearrangeDragItem,
287
+ getTreeDetails,
288
+ handleTreeNodeSect,
289
+
290
+ //types
291
+ TreeNodeProps,
278
292
 
293
+ //Regex
279
294
  EMAIL_REGEX,
280
295
  URL_REGEX,
281
296
  PHONE_REGEX,
@@ -1,6 +1,7 @@
1
1
  // findAndInsert.stories.tsx
2
2
  import { useState } from 'react';
3
3
  import { findAndInsert, AnyObject } from './findAndInsert';
4
+ import React from 'react';
4
5
 
5
6
  export default {
6
7
  title: 'Utils/findAndInsert',
@@ -0,0 +1,167 @@
1
+ import { useState } from 'react';
2
+ import { getTreeDetails, TreeNode, TreeDetailsResult } from './getTreeDetails';
3
+ import React from 'react';
4
+
5
+ export default {
6
+ title: 'Utils/getTreeDetails',
7
+ component: getTreeDetails,
8
+ };
9
+
10
+ const initialData: TreeNode[] = [
11
+ {
12
+ createdBy: 'USR4705',
13
+ modifiedBy: '--',
14
+ createdByUname: 'Saqeb',
15
+ modifiedByUname: '--',
16
+ createdOn: '2023-05-31T10:54:33.296Z',
17
+ modifiedOn: '2023-05-31T10:54:33.296Z',
18
+ state: 'APPROVED',
19
+ path: '/Root',
20
+ searchKey: '/PAG1010',
21
+ key: 'PAG1010',
22
+ name: 'Root',
23
+ projectId: 'PJT1006',
24
+ hierarchy: 0,
25
+ executionOrder: 0,
26
+ subContainerCount: 1,
27
+ resourceCount: 0,
28
+ totalSubContainerCount: 1,
29
+ totalResourceCount: 2,
30
+ totalProjectElementCount: 0,
31
+ totalSharedElementCount: 0,
32
+ container: false,
33
+ localDelete: false,
34
+ defaultEntity: false,
35
+ lastResource: false,
36
+ platform: '',
37
+ },
38
+ {
39
+ createdBy: 'USR4705',
40
+ modifiedBy: '--',
41
+ createdByUname: 'Saqeb',
42
+ modifiedByUname: '--',
43
+ createdOn: '2023-05-31T10:57:31.721Z',
44
+ modifiedOn: '2023-05-31T10:57:31.721Z',
45
+ state: 'APPROVED',
46
+ path: '/Root/page1',
47
+ searchKey: '/PAG1010/PAG1011',
48
+ key: 'PAG1011',
49
+ name: 'page1',
50
+ projectId: 'PJT1006',
51
+ hierarchy: 0,
52
+ executionOrder: 1,
53
+ subContainerCount: 0,
54
+ resourceCount: 3,
55
+ totalSubContainerCount: 0,
56
+ totalResourceCount: 1,
57
+ totalProjectElementCount: 0,
58
+ totalSharedElementCount: 0,
59
+ container: false,
60
+ localDelete: false,
61
+ defaultEntity: false,
62
+ lastResource: true,
63
+ platform: '',
64
+ },
65
+ ];
66
+
67
+ export const InteractivePlayground = () => {
68
+ const [data, setData] = useState<TreeNode[]>(initialData);
69
+ const [newData, setNewData] = useState<TreeNode[]>([]);
70
+ const [action, setAction] = useState<'above' | 'below' | 'expand' | 'collapse' | 'start'>('below');
71
+ const [index, setIndex] = useState<number | undefined>(undefined);
72
+ const [result, setResult] = useState<TreeDetailsResult | null>(null);
73
+
74
+ const handleGetTreeDetails = () => {
75
+ try {
76
+ const treeDetails = getTreeDetails(action, data, newData, index);
77
+ setData(treeDetails.treeDataList);
78
+ setResult(treeDetails);
79
+ } catch (error) {
80
+ alert(error instanceof Error ? error.message : 'An error occurred');
81
+ }
82
+ };
83
+
84
+ return (
85
+ <div>
86
+ <h1>Interactive Playground for getTreeDetails</h1>
87
+
88
+ <div>
89
+ <label htmlFor="action">Action:</label>
90
+ <select
91
+ id="action"
92
+ value={action}
93
+ onChange={(e) =>
94
+ setAction(e.target.value as 'above' | 'below' | 'expand' | 'collapse' | 'start')
95
+ }
96
+ >
97
+ <option value="above">Above</option>
98
+ <option value="below">Below</option>
99
+ <option value="expand">Expand</option>
100
+ <option value="collapse">Collapse</option>
101
+ <option value="start">Start</option>
102
+ </select>
103
+ </div>
104
+
105
+ {(action === 'expand' || action === 'collapse') && (
106
+ <div>
107
+ <label htmlFor="index">Index (for expand/collapse):</label>
108
+ <input
109
+ type="number"
110
+ id="index"
111
+ value={index !== undefined ? index : ''}
112
+ onChange={(e) =>
113
+ setIndex(e.target.value ? parseInt(e.target.value, 10) : undefined)
114
+ }
115
+ disabled={action !== 'expand' && action !== 'collapse'}
116
+ />
117
+ </div>
118
+ )}
119
+
120
+ <div>
121
+ <label htmlFor="newData">New Data (JSON):</label>
122
+ <textarea
123
+ id="newData"
124
+ value={JSON.stringify(newData, null, 2)}
125
+ onChange={(e) => {
126
+ try {
127
+ setNewData(JSON.parse(e.target.value));
128
+ } catch {
129
+ alert('Invalid JSON');
130
+ }
131
+ }}
132
+ />
133
+ </div>
134
+
135
+ <button onClick={handleGetTreeDetails}>Get Tree Details</button>
136
+
137
+ <h2>Result:</h2>
138
+ {result ? (
139
+ <div>
140
+ {result.root && (
141
+ <>
142
+ <h3>Root:</h3>
143
+ <pre>{JSON.stringify(result.root, null, 2)}</pre>
144
+ </>
145
+ )}
146
+ <p>
147
+ <strong>Next:</strong> {result.next.toString()}
148
+ </p>
149
+ <p>
150
+ <strong>Previous:</strong> {result.previous.toString()}
151
+ </p>
152
+ <p>
153
+ <strong>Start ID:</strong> {result.startId}
154
+ </p>
155
+ <p>
156
+ <strong>End ID:</strong> {result.endId}
157
+ </p>
158
+ </div>
159
+ ) : (
160
+ <p>No result yet. Perform an action to see the details.</p>
161
+ )}
162
+
163
+ <h2>Current Tree Data:</h2>
164
+ <pre>{JSON.stringify(data, null, 2)}</pre>
165
+ </div>
166
+ );
167
+ };
@@ -0,0 +1,65 @@
1
+ import { TreeNodeProps as TreeNode } from '../../ComponentProps/TreeNodeProps';
2
+
3
+ export interface TreeDetailsResult {
4
+ treeDataList: TreeNode[];
5
+ next: boolean;
6
+ previous: boolean;
7
+ startId: string;
8
+ endId: string;
9
+ root?: TreeNode;
10
+ }
11
+
12
+ export const getTreeDetails = (
13
+ action: 'above' | 'below' | 'expand' | 'collapse' | 'start',
14
+ oldData: TreeNode[],
15
+ newData: TreeNode[],
16
+ index?: number
17
+ ): TreeDetailsResult => {
18
+ let treeDataList: TreeNode[];
19
+ let root: TreeNode | undefined = undefined;
20
+
21
+ switch (action) {
22
+ case 'above':
23
+ treeDataList = [...newData, ...oldData].slice(0, 40);
24
+ break;
25
+ case 'below':
26
+ treeDataList = [...oldData, ...newData].slice(0, 40);
27
+ break;
28
+ case 'expand':
29
+ case 'collapse':
30
+ if (typeof index === 'number') {
31
+ treeDataList = [...oldData.slice(0, index + 1), ...newData];
32
+ } else {
33
+ throw new Error(
34
+ "Index is required for 'expand' or 'collapse' actions."
35
+ );
36
+ }
37
+ break;
38
+ case 'start':
39
+ if (oldData.length > 0) {
40
+ root = oldData[0];
41
+ treeDataList = oldData.slice(1);
42
+ } else {
43
+ throw new Error('Tree data list is empty, cannot determine root.');
44
+ }
45
+ break;
46
+ default:
47
+ throw new Error(`Invalid action: ${action}`);
48
+ }
49
+
50
+ if (treeDataList.length === 0 && action !== 'start') {
51
+ throw new Error('Tree data list is empty.');
52
+ }
53
+
54
+ const firstNode = treeDataList[0] || root!;
55
+ const lastNode = treeDataList[treeDataList.length - 1]!;
56
+
57
+ return {
58
+ treeDataList,
59
+ next: !lastNode.lastResource,
60
+ previous: !firstNode.lastResource,
61
+ startId: firstNode.key,
62
+ endId: lastNode.key,
63
+ root,
64
+ };
65
+ };
@@ -0,0 +1,195 @@
1
+ import React, { useState } from 'react';
2
+ import { handleTreeNodeSect, TreeNode } from './handleTreeNodeSelect'; // Ensure this imports the utility function
3
+
4
+ export default {
5
+ title: 'Utils/handleTreeNodeSect',
6
+ component: handleTreeNodeSect,
7
+ };
8
+
9
+ const initialData: TreeNode[] = [
10
+ {
11
+ createdBy: 'USR4705',
12
+ modifiedBy: '--',
13
+ createdByUname: 'Saqeb',
14
+ modifiedByUname: '--',
15
+ createdOn: '2023-05-31T10:54:33.296Z',
16
+ modifiedOn: '2023-05-31T10:54:33.296Z',
17
+ state: 'APPROVED',
18
+ path: '/Root',
19
+ searchKey: '/PAG1010',
20
+ key: 'PAG1010',
21
+ name: 'Root',
22
+ projectId: 'PJT1006',
23
+ hierarchy: 0,
24
+ executionOrder: 0,
25
+ subContainerCount: 1,
26
+ resourceCount: 0,
27
+ totalSubContainerCount: 1,
28
+ totalResourceCount: 2,
29
+ totalProjectElementCount: 0,
30
+ totalSharedElementCount: 0,
31
+ container: false,
32
+ localDelete: false,
33
+ defaultEntity: false,
34
+ lastResource: false,
35
+ platform: '',
36
+ },
37
+ {
38
+ createdBy: 'USR4705',
39
+ modifiedBy: '--',
40
+ createdByUname: 'Saqeb',
41
+ modifiedByUname: '--',
42
+ createdOn: '2023-05-31T10:57:31.721Z',
43
+ modifiedOn: '2023-05-31T10:57:31.721Z',
44
+ state: 'APPROVED',
45
+ path: '/Root/page1',
46
+ searchKey: '/PAG1010/PAG1011',
47
+ parentId: 'PAG1010',
48
+ parentName: 'Root Page',
49
+ key: 'PAG1011',
50
+ name: 'page1',
51
+ projectId: 'PJT1006',
52
+ hierarchy: 1,
53
+ executionOrder: 1,
54
+ subContainerCount: 0,
55
+ resourceCount: 3,
56
+ totalSubContainerCount: 0,
57
+ totalResourceCount: 1,
58
+ totalProjectElementCount: 0,
59
+ totalSharedElementCount: 0,
60
+ container: false,
61
+ localDelete: false,
62
+ defaultEntity: false,
63
+ lastResource: true,
64
+ },
65
+ {
66
+ createdBy: 'USR4705',
67
+ modifiedBy: '--',
68
+ createdByUname: 'Saqeb',
69
+ modifiedByUname: '--',
70
+ createdOn: '2023-05-31T11:00:00.000Z',
71
+ modifiedOn: '2023-05-31T11:00:00.000Z',
72
+ state: 'APPROVED',
73
+ path: '/Root/page2',
74
+ searchKey: '/PAG1010/PAG1012',
75
+ parentId: 'PAG1010',
76
+ parentName: 'Root Page',
77
+ key: 'PAG1012',
78
+ name: 'page2',
79
+ projectId: 'PJT1006',
80
+ hierarchy: 1,
81
+ executionOrder: 2,
82
+ subContainerCount: 2,
83
+ resourceCount: 5,
84
+ totalSubContainerCount: 2,
85
+ totalResourceCount: 7,
86
+ totalProjectElementCount: 0,
87
+ totalSharedElementCount: 0,
88
+ container: true,
89
+ localDelete: false,
90
+ defaultEntity: false,
91
+ lastResource: false,
92
+ },
93
+ {
94
+ createdBy: 'USR4705',
95
+ modifiedBy: '--',
96
+ createdByUname: 'Saqeb',
97
+ modifiedByUname: '--',
98
+ createdOn: '2023-05-31T11:05:00.000Z',
99
+ modifiedOn: '2023-05-31T11:05:00.000Z',
100
+ state: 'APPROVED',
101
+ path: '/Root/page2/subpage1',
102
+ searchKey: '/PAG1010/PAG1012/PAG1013',
103
+ parentId: 'PAG1012',
104
+ parentName: 'page2',
105
+ key: 'PAG1013',
106
+ name: 'subpage1',
107
+ projectId: 'PJT1006',
108
+ hierarchy: 2,
109
+ executionOrder: 1,
110
+ subContainerCount: 0,
111
+ resourceCount: 2,
112
+ totalSubContainerCount: 0,
113
+ totalResourceCount: 2,
114
+ totalProjectElementCount: 0,
115
+ totalSharedElementCount: 0,
116
+ container: false,
117
+ localDelete: false,
118
+ defaultEntity: false,
119
+ lastResource: true,
120
+ },
121
+ {
122
+ createdBy: 'USR4705',
123
+ modifiedBy: '--',
124
+ createdByUname: 'Saqeb',
125
+ modifiedByUname: '--',
126
+ createdOn: '2023-05-31T11:10:00.000Z',
127
+ modifiedOn: '2023-05-31T11:10:00.000Z',
128
+ state: 'APPROVED',
129
+ path: '/Root/page2/subpage2',
130
+ searchKey: '/PAG1010/PAG1012/PAG1014',
131
+ parentId: 'PAG1012',
132
+ parentName: 'page2',
133
+ key: 'PAG1014',
134
+ name: 'subpage2',
135
+ projectId: 'PJT1006',
136
+ hierarchy: 2,
137
+ executionOrder: 2,
138
+ subContainerCount: 0,
139
+ resourceCount: 4,
140
+ totalSubContainerCount: 0,
141
+ totalResourceCount: 4,
142
+ totalProjectElementCount: 0,
143
+ totalSharedElementCount: 0,
144
+ container: false,
145
+ localDelete: false,
146
+ defaultEntity: false,
147
+ lastResource: true,
148
+ },
149
+ // Repeat similar patterns to generate 50 entries, modifying hierarchy, executionOrder, and other attributes as needed.
150
+ ];
151
+
152
+ export const InteractiveTreeSelector = () => {
153
+ const [data, setData] = useState<TreeNode[]>(initialData);
154
+ const [selectedKey, setSelectedKey] = useState<string>('');
155
+ const [isChecked, setIsChecked] = useState<boolean>(false);
156
+
157
+ const handleUpdateTree = () => {
158
+ const updatedTree = handleTreeNodeSect(data, selectedKey, isChecked);
159
+ setData([...updatedTree]);
160
+ };
161
+
162
+ return (
163
+ <div style={{ fontFamily: 'Arial, sans-serif', padding: '20px' }}>
164
+ <h1>Interactive Tree Selector</h1>
165
+ <div>
166
+ <label htmlFor="nodeKey">Node Key:</label>
167
+ <input
168
+ id="nodeKey"
169
+ type="text"
170
+ value={selectedKey}
171
+ onChange={(e) => setSelectedKey(e.target.value)}
172
+ placeholder="Enter node key"
173
+ />
174
+ </div>
175
+ <div>
176
+ <label>
177
+ <input
178
+ type="checkbox"
179
+ checked={isChecked}
180
+ onChange={(e) => setIsChecked(e.target.checked)}
181
+ />
182
+ Set Checked
183
+ </label>
184
+ </div>
185
+ <button onClick={handleUpdateTree} style={{ marginTop: '10px' }}>
186
+ Update Tree
187
+ </button>
188
+
189
+ <h2>Tree Data:</h2>
190
+ <pre style={{ backgroundColor: '#f4f4f4', padding: '10px' }}>
191
+ {JSON.stringify(data, null, 2)}
192
+ </pre>
193
+ </div>
194
+ );
195
+ };
@@ -0,0 +1,61 @@
1
+ import { TreeNodeProps as TreeNode } from '../../ComponentProps/TreeNodeProps';
2
+
3
+ export const handleTreeNodeSect = (
4
+ data: TreeNode[],
5
+ key: string,
6
+ isChecked: boolean | 'partial'
7
+ ): TreeNode[] => {
8
+ const nodesMap = new Map<string, TreeNode>();
9
+
10
+ // Build a map for quick access to nodes by key
11
+ data.forEach((node) => nodesMap.set(node.key, node));
12
+
13
+ // Helper to update child nodes
14
+ function updateChildren(nodeKey: string, checkedStatus: boolean | 'partial') {
15
+ for (const node of data) {
16
+ if (node.parentId === nodeKey) {
17
+ node.checked = checkedStatus;
18
+ updateChildren(node.key, checkedStatus);
19
+ }
20
+ }
21
+ }
22
+
23
+ // Helper to update parent nodes
24
+ function updateParents(nodeKey: string) {
25
+ const node = nodesMap.get(nodeKey);
26
+ if (node && node.parentId) {
27
+ const parentNode = nodesMap.get(node.parentId);
28
+ if (parentNode) {
29
+ const siblings = data.filter(
30
+ (sibling) => sibling.parentId === parentNode.key
31
+ );
32
+ const allChecked = siblings.every(
33
+ (sibling) => sibling.checked === true
34
+ );
35
+ const someChecked = siblings.some(
36
+ (sibling) => sibling.checked === true || sibling.checked === 'partial'
37
+ );
38
+
39
+ parentNode.checked = allChecked
40
+ ? true
41
+ : someChecked
42
+ ? 'partial'
43
+ : false;
44
+
45
+ updateParents(parentNode.key);
46
+ }
47
+ }
48
+ }
49
+
50
+ // Find the target node and update its state
51
+ const targetNode = nodesMap.get(key);
52
+ if (targetNode) {
53
+ targetNode.checked = isChecked;
54
+ // Update children recursively
55
+ updateChildren(key, isChecked);
56
+ // Update parents recursively
57
+ updateParents(key);
58
+ }
59
+
60
+ return data;
61
+ };