@capillarytech/blaze-ui 0.1.6-alpha.60 → 0.1.6-alpha.61

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/.DS_Store ADDED
Binary file
@@ -1,4 +1,3 @@
1
- // Enhanced CapUnifiedSelect supporting 4 scenarios with advanced features in a single TreeSelect
2
1
  import React, { useState, useEffect, useMemo, useCallback, memo } from 'react';
3
2
  import PropTypes from 'prop-types';
4
3
  import classnames from 'classnames';
@@ -14,6 +13,121 @@ const StyledTreeSelect = styled(TreeSelect)`
14
13
  ${selectStyles}
15
14
  `;
16
15
 
16
+ const NoResult = memo(({ noResultCustomText, className, showUpload, options, noResultCustomIcon }) => (
17
+ <CapRow
18
+ className={classnames(className, 'cap-unified-select-no-result')}
19
+ align="middle"
20
+ gap={8}
21
+ >
22
+ <CapIcon type={noResultCustomIcon} size="m" />
23
+ <CapLabel className="cap-unified-select-no-result-text">
24
+ {showUpload && options?.length === 0
25
+ ? noResultCustomText
26
+ : 'No results found'}
27
+ </CapLabel>
28
+ </CapRow>
29
+ ));
30
+
31
+ const SelectAllCheckbox = memo(({ currentItems, tempValue, setTempValue, processTreeData }) => {
32
+ const { leafValues } = processTreeData(currentItems);
33
+ const totalAvailable = leafValues.length;
34
+ const leafSet = new Set(leafValues);
35
+ const selectedInScope = Array.isArray(tempValue)
36
+ ? tempValue.filter((v) => leafSet.has(v)).length
37
+ : 0;
38
+
39
+ const allChecked = totalAvailable > 0 && selectedInScope === totalAvailable;
40
+ const indeterminate = selectedInScope > 0 && selectedInScope < totalAvailable;
41
+
42
+ const handleChange = (e) => {
43
+ if (e.target.checked) {
44
+ const merged = new Set(Array.isArray(tempValue) ? tempValue : []);
45
+ leafValues.forEach((v) => merged.add(v));
46
+ setTempValue(Array.from(merged));
47
+ } else {
48
+ const toRemove = new Set(leafValues);
49
+ const next = (Array.isArray(tempValue) ? tempValue : []).filter(
50
+ (v) => !toRemove.has(v)
51
+ );
52
+ setTempValue(next);
53
+ }
54
+ };
55
+
56
+ return (
57
+ <CapRow className="cap-unified-select-select-all-container" align="middle">
58
+ <Checkbox
59
+ className="cap-unified-select-select-all-checkbox"
60
+ checked={allChecked}
61
+ indeterminate={indeterminate}
62
+ onChange={handleChange}
63
+ >
64
+ <CapLabel type="label14" className="cap-unified-select-select-all-label">Select all</CapLabel>
65
+ </Checkbox>
66
+ </CapRow>
67
+ );
68
+ });
69
+
70
+ const buildTreeMaps = (nodes) => {
71
+ const result = {
72
+ leafValues: [],
73
+ parentChildMap: {},
74
+ nodeMap: {},
75
+ };
76
+ if (!nodes) return result;
77
+
78
+ const traverse = (items) => {
79
+ items.forEach((item) => {
80
+ result.nodeMap[item.value] = item;
81
+ if (item.children && item.children.length > 0) {
82
+ result.parentChildMap[item.value] = item.children.map(child => child.value);
83
+ traverse(item.children);
84
+ } else {
85
+ result.leafValues.push(item.value);
86
+ }
87
+ });
88
+ };
89
+ traverse(nodes);
90
+ return result;
91
+ };
92
+
93
+ const countSelectedLeaves = (treeMaps, selectedValues) => {
94
+ if (!Array.isArray(selectedValues) || !selectedValues.length) return 0;
95
+ const expandedSet = new Set(selectedValues);
96
+ const processNode = (value) => {
97
+ const children = treeMaps.parentChildMap[value];
98
+ if (!children) return;
99
+ children.forEach(childValue => {
100
+ expandedSet.add(childValue);
101
+ processNode(childValue);
102
+ });
103
+ };
104
+ selectedValues.forEach(processNode);
105
+ return treeMaps.leafValues.reduce((count, leaf) => expandedSet.has(leaf) ? count + 1 : count, 0);
106
+ };
107
+
108
+ const filterTreeData = (data, search, searchBasedOn) => {
109
+ if (!data?.length || !search) return data;
110
+ const searchLower = search.toLowerCase();
111
+ const nodeMatchesSearch = (node) => {
112
+ const target = searchBasedOn === 'value'
113
+ ? String(node.value ?? '')
114
+ : searchBasedOn === 'key'
115
+ ? String(node.key ?? '')
116
+ : String(node.label ?? node.title ?? '');
117
+ return target.toLowerCase().includes(searchLower);
118
+ };
119
+ const loop = (items) =>
120
+ items.reduce((acc, item) => {
121
+ if (!item) return acc;
122
+ const children = item.children?.length ? loop(item.children) : [];
123
+ if (nodeMatchesSearch(item) || children.length) {
124
+ acc.push({ ...item, children });
125
+ }
126
+ return acc;
127
+ }, []);
128
+ return loop(data);
129
+ };
130
+
17
131
  const CapUnifiedSelect = ({
18
132
  type,
19
133
  options = [],
@@ -38,7 +152,6 @@ const CapUnifiedSelect = ({
38
152
  searchBasedOn = 'label',
39
153
  onConfirm,
40
154
  onCancel,
41
- size = 'm',
42
155
  noResultCustomText = 'No results found',
43
156
  noResultCustomIcon = 'warning',
44
157
  ...rest
@@ -48,142 +161,17 @@ const CapUnifiedSelect = ({
48
161
  const [dropdownOpen, setDropdownOpen] = useState(false);
49
162
 
50
163
  useEffect(() => {
51
- setTempValue(value);
164
+ const isEqual = Array.isArray(value) && Array.isArray(tempValue)
165
+ ? value.length === tempValue.length && value.every((v) => tempValue.includes(v))
166
+ : value === tempValue;
167
+ if (!isEqual) setTempValue(value);
52
168
  }, [value]);
53
169
 
54
- const treeSelectVirtualizationProps = {
55
- listHeight: 256,
56
- listItemHeight: 32,
57
- };
58
-
59
- const NoResult = ({ noResultCustomText, className, showUpload, options }) => (
60
- <CapRow
61
- className={classnames(className, 'cap-unified-select-no-result')}
62
- align="middle"
63
- gap={8}
64
- >
65
- <CapIcon type={noResultCustomIcon} size="m" />
66
- <CapLabel className="cap-unified-select-no-result-text">
67
- {showUpload && options?.length === 0
68
- ? noResultCustomText
69
- : 'No results found'}
70
- </CapLabel>
71
- </CapRow>
72
- );
73
-
74
- const getFilteredTreeData = useCallback(
75
- (data, search) => {
76
- if (!search || !data || data.length === 0) return data;
77
- const searchLower = search.toLowerCase();
78
-
79
- const filterNode = (node) => {
80
- if (!node) return false;
81
-
82
- let textToSearch = '';
83
-
84
- if (searchBasedOn === 'value') {
85
- textToSearch = String(node.value || '').toLowerCase();
86
- } else if (searchBasedOn === 'key') {
87
- textToSearch = String(node.key || '').toLowerCase();
88
- } else {
89
- textToSearch = String(node.label || node.title || '').toLowerCase();
90
- }
91
-
92
- return textToSearch.includes(searchLower);
93
- };
94
-
95
- const loop = (data) => {
96
- if (!data) return [];
97
-
98
- return data
99
- .map((item) => {
100
- if (!item) return null;
101
-
102
- const children =
103
- item.children && item.children.length > 0
104
- ? loop(item.children)
105
- : [];
106
-
107
- if (filterNode(item) || children.length > 0) {
108
- return { ...item, children };
109
- }
110
- return null;
111
- })
112
- .filter(Boolean);
113
- };
114
-
115
- return loop(data);
116
- },
117
- [searchBasedOn],
118
- );
119
-
120
- const processTreeData = useCallback((nodes, selectedValues = null) => {
121
- const result = {
122
- leafValues: [],
123
- parentChildMap: {},
124
- nodeMap: {},
125
- selectedCount: 0,
126
- };
127
-
128
- if (!nodes) return result;
129
-
130
- const traverse = (items) => {
131
- items.forEach((item) => {
132
- result.nodeMap[item.value] = item;
133
-
134
- if (item.children && item.children.length > 0) {
135
- result.parentChildMap[item.value] = item.children.map(
136
- (child) => child.value,
137
- );
138
- traverse(item.children);
139
- } else {
140
- result.leafValues.push(item.value);
141
- }
142
- });
143
- };
144
- traverse(nodes);
145
-
146
- if (
147
- selectedValues &&
148
- Array.isArray(selectedValues) &&
149
- selectedValues.length > 0
150
- ) {
151
- const expandedSet = new Set(selectedValues);
152
-
153
- const processNode = (value) => {
154
- const children = result.parentChildMap[value];
155
- if (!children) return;
156
-
157
- children.forEach((childValue) => {
158
- expandedSet.add(childValue);
159
- processNode(childValue);
160
- });
161
- };
162
-
163
- selectedValues.forEach(processNode);
164
-
165
- result.leafValues.forEach((value) => {
166
- if (expandedSet.has(value)) result.selectedCount++;
167
- });
168
- }
169
-
170
- return result;
171
- }, []);
172
-
173
- const isMulti = useMemo(
174
- () => type === 'multiSelect' || type === 'multiTreeSelect',
175
- [type],
176
- );
177
- const isTree = useMemo(
178
- () => type === 'treeSelect' || type === 'multiTreeSelect',
179
- [type],
180
- );
170
+ const isMulti = useMemo(() => type === 'multiSelect' || type === 'multiTreeSelect', [type]);
171
+ const isTree = useMemo(() => type === 'treeSelect' || type === 'multiTreeSelect', [type]);
181
172
 
182
173
  const dataSource = useMemo(() => {
183
- // Skip transformation if options is empty or undefined
184
- if (!options || options.length === 0) return [];
185
-
186
- // Only transform if not a tree select
174
+ if (!options?.length) return [];
187
175
  return isTree
188
176
  ? options
189
177
  : options.map((opt) => ({
@@ -193,88 +181,69 @@ const CapUnifiedSelect = ({
193
181
  }));
194
182
  }, [isTree, options]);
195
183
 
196
- const filteredTree = useMemo(() => {
197
- // Skip filtering if search text is empty
198
- if (!searchText) return dataSource;
199
-
200
- return getFilteredTreeData(dataSource, searchText);
201
- }, [dataSource, searchText, getFilteredTreeData]);
202
-
203
- const handleConfirm = useCallback(() => {
204
- if (onChange) onChange(tempValue);
205
- setDropdownOpen(false);
206
- if (onConfirm) onConfirm(tempValue);
207
- }, [onChange, onConfirm, tempValue]);
208
-
209
- const handleCancel = useCallback(() => {
210
- setTempValue(value);
211
- setDropdownOpen(false);
212
- if (onCancel) onCancel();
213
- }, [value, onCancel]);
184
+ const filteredTree = useMemo(
185
+ () => filterTreeData(dataSource, searchText, searchBasedOn),
186
+ [dataSource, searchText, searchBasedOn]
187
+ );
214
188
 
215
- const handleTempChange = useCallback((newValue) => {
216
- setTempValue(newValue);
217
- }, []);
189
+ const treeMaps = useMemo(() => buildTreeMaps(options), [options]);
190
+ const selectedLeafCount = useMemo(() => countSelectedLeaves(treeMaps, tempValue), [treeMaps, tempValue]);
218
191
 
219
- const handleDropdownVisibilityChange = useCallback(
220
- (open) => {
221
- if (open === false && !customPopupRender) {
222
- if (onChange) onChange(tempValue);
223
- } else if (open === false) {
224
- setTempValue(value);
225
- }
226
- setDropdownOpen(open);
227
- },
228
- [value, onChange, tempValue, customPopupRender],
229
- );
192
+ const displayValue = dropdownOpen ? tempValue : value;
230
193
 
231
194
  const suffix = useMemo(() => {
232
- const displayValue = dropdownOpen ? tempValue : value;
233
- const showMore = isMulti && Array.isArray(displayValue) && displayValue.length > 1;
195
+ const count = Array.isArray(displayValue) ? displayValue.length : (displayValue ? 1 : 0);
234
196
  return (
235
197
  <>
236
- {showMore && <span>+{displayValue.length - 1} more </span>}
237
- <CapIcon className="cap-unified-select-suffix-icon" type={dropdownOpen ? 'up' : 'down'} size="s" />
198
+ {isMulti && count > 1 && <span>+{count - 1} more </span>}
199
+ <CapIcon
200
+ className="cap-unified-select-suffix-icon"
201
+ type={dropdownOpen ? 'up' : 'down'}
202
+ size="s"
203
+ />
238
204
  </>
239
205
  );
240
- }, [isMulti, value, tempValue, dropdownOpen]);
206
+ }, [isMulti, displayValue, dropdownOpen]);
241
207
 
242
208
  const prefix = useMemo(() => {
243
- if (isMulti) {
244
- if (Array.isArray(tempValue) && tempValue?.length > 0) {
245
- const firstSelectedValue = tempValue[0];
246
- const firstSelectedOption = options?.find(
247
- (opt) => opt?.value === firstSelectedValue,
248
- );
249
- return firstSelectedOption?.label || null;
250
- } else if (Array.isArray(value) && value?.length > 0) {
251
- const firstSelectedValue = value[0];
252
- const firstSelectedOption = options?.find(
253
- (opt) => opt?.value === firstSelectedValue,
254
- );
255
- return firstSelectedOption?.label || null;
256
- }
209
+ if (isMulti && Array.isArray(displayValue) && displayValue.length > 0) {
210
+ const firstLeafValue = displayValue.find(val => treeMaps.leafValues.includes(val));
211
+ return treeMaps.nodeMap[firstLeafValue]?.label || treeMaps.nodeMap[firstLeafValue]?.title || null;
257
212
  }
258
213
  return null;
259
- }, [isMulti, value, tempValue, options]);
214
+ }, [isMulti, displayValue, treeMaps]);
215
+
216
+ const handleConfirm = useCallback(() => {
217
+ onChange?.(tempValue);
218
+ setDropdownOpen(false);
219
+ setSearchText('');
220
+ onConfirm?.(tempValue);
221
+ }, [onChange, onConfirm, tempValue]);
222
+
223
+ const handleCancel = useCallback(() => {
224
+ setTempValue(value);
225
+ setDropdownOpen(false);
226
+ onCancel?.();
227
+ }, [value, onCancel]);
228
+
229
+ const handleDropdownVisibilityChange = useCallback((open) => {
230
+ if (!open && !customPopupRender) {
231
+ onChange?.(tempValue);
232
+ } else if (!open) {
233
+ setTempValue(value);
234
+ }
235
+ setDropdownOpen(open);
236
+ }, [customPopupRender, value, onChange, tempValue]);
260
237
 
261
- const renderHeader = useCallback(() => {
238
+ const renderHeader = useMemo(() => {
262
239
  if (!headerLabel && !tooltip) return null;
263
240
  return (
264
241
  <>
265
- <HeaderWrapper
266
- className={classnames(
267
- disabled ? 'disabled' : '',
268
- 'cap-unified-select-header',
269
- )}
270
- >
242
+ <HeaderWrapper className={classnames(disabled && 'disabled', 'cap-unified-select-header')}>
271
243
  {headerLabel && (
272
244
  <CapLabel
273
245
  type="label16"
274
- className={classnames(
275
- disabled ? 'disabled' : '',
276
- 'cap-unified-select-header-label',
277
- )}
246
+ className={classnames(disabled && 'disabled', 'cap-unified-select-header-label')}
278
247
  >
279
248
  {headerLabel}
280
249
  </CapLabel>
@@ -282,10 +251,7 @@ const CapUnifiedSelect = ({
282
251
  {tooltip && (
283
252
  <CapTooltipWithInfo
284
253
  title={tooltip}
285
- className={classnames(
286
- disabled ? 'disabled' : '',
287
- 'cap-unified-select-header-tooltip',
288
- )}
254
+ className={classnames(disabled && 'disabled', 'cap-unified-select-header-tooltip')}
289
255
  iconProps={{ disabled }}
290
256
  />
291
257
  )}
@@ -293,10 +259,7 @@ const CapUnifiedSelect = ({
293
259
  {bylineText && (
294
260
  <div className="cap-unified-select-header-byline-text">
295
261
  <CapLabel
296
- className={classnames(
297
- disabled ? 'disabled' : '',
298
- 'cap-unified-select-header-byline-text',
299
- )}
262
+ className={classnames(disabled && 'disabled', 'cap-unified-select-header-byline-text')}
300
263
  >
301
264
  {bylineText}
302
265
  </CapLabel>
@@ -306,253 +269,153 @@ const CapUnifiedSelect = ({
306
269
  );
307
270
  }, [headerLabel, tooltip, bylineText, disabled]);
308
271
 
309
- const renderDropdown = useCallback(() => {
310
- const currentItems = filteredTree;
311
- const selectedCount = Array.isArray(tempValue)
312
- ? isTree
313
- ? processTreeData(dataSource, tempValue).selectedCount
314
- : tempValue?.length || 0
315
- : tempValue
316
- ? 1
317
- : 0;
318
-
319
- const renderCustomDropdown = useCallback(
320
- (menu) => {
321
- if (!customPopupRender) return menu;
322
-
323
- return (
324
- <div
325
- className={classnames(popoverClassName, `${type}-popup-container`)}
326
- >
327
- {showSearch && (
328
- <CapRow
329
- className={classnames('cap-unified-select-search-container')}
330
- align="middle"
331
- >
332
- <Input
333
- prefix={
334
- <CapIcon
335
- type="search"
336
- size="s"
337
- style={{ color: styledVars.CAP_G06 }}
338
- />
339
- }
340
- placeholder="Search"
341
- variant="borderless"
342
- value={searchText}
343
- onChange={(e) => setSearchText(e.target.value)}
344
- />
345
- </CapRow>
346
- )}
347
- {isMulti && showUpload && (
348
- <CapRow
349
- className={classnames('cap-unified-select-upload-container')}
350
- align="middle"
351
- onClick={onUpload}
352
- >
353
- <CapIcon
354
- type="upload"
355
- size="s"
356
- style={{ color: styledVars.CAP_SECONDARY.base }}
357
- />
358
- <CapLabel
359
- type="label14"
360
- className={classnames('cap-unified-select-upload-label')}
272
+ const renderCustomDropdown = useCallback(
273
+ (menu) => {
274
+ if (!customPopupRender) return menu;
275
+ const currentItems = filteredTree;
276
+
277
+ return (
278
+ <div className={classnames(popoverClassName, `${type}-popup-container`)}>
279
+ {showSearch && (
280
+ <CapRow className="cap-unified-select-search-container" align="middle">
281
+ <Input
282
+ prefix={<CapIcon type="search" size="s" style={{ color: styledVars.CAP_G06 }} />}
283
+ placeholder="Search"
284
+ variant="borderless"
285
+ value={searchText}
286
+ onChange={(e) => setSearchText(e.target.value)}
287
+ allowClear
288
+ />
289
+ </CapRow>
290
+ )}
291
+
292
+ {isMulti && showUpload && (
293
+ <CapRow className="cap-unified-select-upload-container" align="middle" onClick={onUpload}>
294
+ <CapIcon type="upload" size="s" style={{ color: styledVars.CAP_SECONDARY.base }} />
295
+ <CapLabel type="label14" className="cap-unified-select-upload-label">Upload</CapLabel>
296
+ </CapRow>
297
+ )}
298
+
299
+ {isMulti && currentItems.length > 0 && (
300
+ <SelectAllCheckbox
301
+ currentItems={currentItems}
302
+ tempValue={tempValue}
303
+ setTempValue={setTempValue}
304
+ processTreeData={buildTreeMaps}
305
+ />
306
+ )}
307
+
308
+ {currentItems.length === 0 ? (
309
+ <NoResult
310
+ noResultCustomText={noResultCustomText}
311
+ className={className}
312
+ showUpload={showUpload}
313
+ options={options}
314
+ noResultCustomIcon={noResultCustomIcon}
315
+ />
316
+ ) : (
317
+ menu
318
+ )}
319
+
320
+ {currentItems.length > 0 && isMulti && (
321
+ <div className="cap-unified-select-confirm-container">
322
+ <div className="cap-unified-select-confirm-button-group">
323
+ <Button
324
+ type="primary"
325
+ size="small"
326
+ className="cap-unified-select-confirm-button"
327
+ onClick={handleConfirm}
361
328
  >
362
- Upload
329
+ Confirm
330
+ </Button>
331
+ <Button
332
+ type="text"
333
+ className="cap-unified-select-cancel-button"
334
+ size="small"
335
+ onClick={handleCancel}
336
+ >
337
+ Cancel
338
+ </Button>
339
+ <CapLabel className="cap-unified-select-selected-count">
340
+ {selectedLeafCount} selected
363
341
  </CapLabel>
364
- </CapRow>
365
- )}
366
- {isMulti &&
367
- currentItems.length > 0 &&
368
- (() => {
369
- const { leafValues } = processTreeData(currentItems);
370
- const totalAvailable = leafValues.length;
371
- const selectedInScope = processTreeData(
372
- currentItems,
373
- tempValue,
374
- ).selectedCount;
375
-
376
- return (
377
- <CapRow
378
- className={classnames(
379
- 'cap-unified-select-select-all-container',
380
- )}
381
- align="middle"
382
- >
383
- <Checkbox
384
- className={classnames(
385
- 'cap-unified-select-select-all-checkbox',
386
- )}
387
- checked={
388
- totalAvailable > 0 && selectedInScope === totalAvailable
389
- }
390
- indeterminate={
391
- selectedInScope > 0 && selectedInScope < totalAvailable
392
- }
393
- onChange={(e) => {
394
- setTempValue(e.target.checked ? leafValues : []);
395
- }}
396
- >
397
- <CapLabel
398
- type="label14"
399
- className={classnames(
400
- 'cap-unified-select-select-all-label',
401
- )}
402
- >
403
- Select all
404
- </CapLabel>
405
- </Checkbox>
406
- </CapRow>
407
- );
408
- })()}
409
-
410
- {currentItems.length === 0 ? (
411
- <NoResult
412
- noResultCustomText={noResultCustomText}
413
- className={classnames(
414
- className,
415
- 'cap-unified-select-no-result',
416
- )}
417
- showUpload={showUpload}
418
- options={options}
419
- />
420
- ) : (
421
- menu
422
- )}
423
-
424
- {currentItems.length > 0 && isMulti && (
425
- <div className="cap-unified-select-confirm-container">
426
- <div className="cap-unified-select-confirm-button-group">
427
- <Button
428
- type="primary"
429
- size="small"
430
- className="cap-unified-select-confirm-button"
431
- onClick={handleConfirm}
432
- >
433
- Confirm
434
- </Button>
435
- <Button
436
- type="text"
437
- className="cap-unified-select-cancel-button"
438
- size="small"
439
- onClick={handleCancel}
440
- >
441
- Cancel
442
- </Button>
443
- <CapLabel className="cap-unified-select-selected-count">
444
- {selectedCount} selected
445
- </CapLabel>
446
- </div>
447
342
  </div>
448
- )}
449
- </div>
450
- );
451
- },
452
- [
453
- customPopupRender,
454
- popoverClassName,
455
- type,
456
- showSearch,
457
- searchText,
458
- isMulti,
459
- showUpload,
460
- currentItems,
461
- tempValue,
462
- className,
463
- noResultCustomText,
464
- onUpload,
465
- handleConfirm,
466
- handleCancel,
467
- processTreeData,
468
- ],
469
- );
470
-
471
- return (
472
- <>
473
- <StyledTreeSelect
474
- type={type}
475
- treeData={filteredTree}
476
- value={customPopupRender ? tempValue : value}
477
- onChange={onChange}
478
- placeholder={placeholder}
479
- showSearch={false}
480
- maxTagCount={0}
481
- maxTagPlaceholder={() => null}
482
- prefix={tempValue?.length > 0 ? prefix : undefined}
483
- suffixIcon={suffix}
484
- className={classnames(
485
- containerClassName,
486
- `cap-unified-tree-select`,
487
- className,
343
+ </div>
488
344
  )}
489
- classNames={{
490
- popup: { root: classnames('custom-popup-container', className) },
491
- }}
492
- style={style}
493
- status={isError ? 'error' : ''}
494
- allowClear={allowClear}
495
- multiple={isMulti}
496
- treeCheckable={isMulti}
497
- open={dropdownOpen}
498
- onOpenChange={handleDropdownVisibilityChange}
499
- showCheckedStrategy={TreeSelect.SHOW_PARENT}
500
- virtual
501
- disabled={disabled}
502
- filterTreeNode={false}
503
- {...treeSelectVirtualizationProps}
504
- popupRender={renderCustomDropdown}
505
- {...rest}
506
- />
507
- {isError && (
508
- <CapLabel
509
- className={classnames('cap-unified-select-status')}
510
- style={{ color: 'red' }}
511
- >
512
- {errorMessage}
513
- </CapLabel>
514
- )}
515
- </>
516
- );
517
- }, [
518
- filteredTree,
519
- tempValue,
520
- value,
521
- prefix,
522
- suffix,
523
- className,
524
- style,
525
- isError,
526
- errorMessage,
527
- allowClear,
528
- isMulti,
529
- isTree,
530
- dropdownOpen,
531
- customPopupRender,
532
- handleTempChange,
533
- onChange,
534
- disabled,
535
- handleDropdownVisibilityChange,
536
- treeSelectVirtualizationProps,
537
- dataSource,
538
- processTreeData,
539
- ]);
345
+ </div>
346
+ );
347
+ },
348
+ [
349
+ customPopupRender,
350
+ filteredTree,
351
+ searchText,
352
+ isMulti,
353
+ showUpload,
354
+ onUpload,
355
+ noResultCustomText,
356
+ noResultCustomIcon,
357
+ options,
358
+ type,
359
+ tempValue,
360
+ handleConfirm,
361
+ handleCancel,
362
+ popoverClassName,
363
+ className,
364
+ selectedLeafCount,
365
+ ]
366
+ );
367
+
368
+ const combinedClassName = useMemo(
369
+ () => classnames(containerClassName, 'cap-unified-tree-select', className),
370
+ [containerClassName, className]
371
+ );
540
372
 
541
373
  return (
542
374
  <CapRow className={classnames(className, 'cap-unified-select-container')}>
543
- {renderHeader()}
544
- {renderDropdown()}
375
+ {renderHeader}
376
+ <StyledTreeSelect
377
+ type={type}
378
+ treeData={filteredTree}
379
+ value={customPopupRender ? tempValue : value}
380
+ onChange={isMulti ? setTempValue : onChange}
381
+ placeholder={placeholder}
382
+ showSearch={false}
383
+ maxTagCount={0}
384
+ maxTagPlaceholder={() => null}
385
+ prefix={prefix || undefined}
386
+ suffixIcon={suffix}
387
+ className={combinedClassName}
388
+ classNames={{
389
+ popup: { root: classnames('custom-popup-container', className) },
390
+ }}
391
+ style={style}
392
+ status={isError ? 'error' : ''}
393
+ allowClear={allowClear}
394
+ multiple={isMulti}
395
+ treeCheckable={isMulti}
396
+ treeCheckStrictly={false}
397
+ showCheckedStrategy={TreeSelect.SHOW_CHILD}
398
+ open={dropdownOpen}
399
+ onOpenChange={handleDropdownVisibilityChange}
400
+ virtual
401
+ disabled={disabled}
402
+ filterTreeNode={false}
403
+ listHeight={256}
404
+ listItemHeight={32}
405
+ popupRender={renderCustomDropdown}
406
+ {...rest}
407
+ />
408
+ {isError && (
409
+ <CapLabel className="cap-unified-select-status" style={{ color: 'red' }}>
410
+ {errorMessage}
411
+ </CapLabel>
412
+ )}
545
413
  </CapRow>
546
414
  );
547
415
  };
548
416
 
549
417
  CapUnifiedSelect.propTypes = {
550
- type: PropTypes.oneOf([
551
- 'select',
552
- 'multiSelect',
553
- 'treeSelect',
554
- 'multiTreeSelect',
555
- ]),
418
+ type: PropTypes.oneOf(['select', 'multiSelect', 'treeSelect', 'multiTreeSelect']),
556
419
  options: PropTypes.array,
557
420
  value: PropTypes.any,
558
421
  onChange: PropTypes.func,
@@ -573,7 +436,6 @@ CapUnifiedSelect.propTypes = {
573
436
  popupClassName: PropTypes.string,
574
437
  showUpload: PropTypes.bool,
575
438
  onUpload: PropTypes.func,
576
- size: PropTypes.oneOf(['s', 'm', 'l', 'xl']),
577
439
  };
578
440
 
579
441
  CapUnifiedSelect.defaultProps = {
@@ -583,7 +445,6 @@ CapUnifiedSelect.defaultProps = {
583
445
  noResultCustomText: 'No results found',
584
446
  noResultCustomIcon: 'warning',
585
447
  options: [],
586
- size: 'm',
587
448
  allowClear: false,
588
449
  customPopupRender: true,
589
450
  showSearch: true,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/blaze-ui",
3
3
  "author": "Capillary Technologies",
4
- "version": "0.1.6-alpha.60",
4
+ "version": "0.1.6-alpha.61",
5
5
  "description": "Capillary UI component library with Ant Design v5",
6
6
  "main": "./index.js",
7
7
  "sideEffects": [