@capillarytech/blaze-ui 0.1.6-alpha.9 → 0.1.10

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