@capillarytech/blaze-ui 0.1.6-alpha.38 → 0.1.6-alpha.4

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 (90) hide show
  1. package/CapHeading/CapHeading.js +71 -0
  2. package/CapHeading/index.js +1 -0
  3. package/CapHeading/styles.js +125 -0
  4. package/CapInfoNote/CapInfoNote.js +54 -0
  5. package/CapInfoNote/index.js +1 -0
  6. package/CapInfoNote/styles.js +63 -0
  7. package/CapInput/loadable.js +9 -0
  8. package/CapLabel/CapLabel.js +106 -0
  9. package/CapLabel/index.js +1 -0
  10. package/CapLabel/styles.js +221 -0
  11. package/CapRow/CapRow.js +22 -0
  12. package/CapRow/index.js +1 -0
  13. package/CapRow/styles.js +9 -0
  14. package/CapTable/loadable.js +4 -4
  15. package/CapTooltip/CapTooltip.js +36 -0
  16. package/CapTooltip/index.js +1 -0
  17. package/CapTooltip/styles.js +42 -0
  18. package/CapUnifiedSelect/CapUnifiedSelect.js +59 -260
  19. package/CapUnifiedSelect/index.js +4 -1
  20. package/CapUnifiedSelect/loadable.js +3 -0
  21. package/CapUnifiedSelect/styles.js +26 -255
  22. package/dist/235.index.js +2 -0
  23. package/dist/235.index.js.LICENSE.txt +29 -0
  24. package/dist/603.index.js +1 -0
  25. package/dist/CapInput/CapInput.js +66 -0
  26. package/dist/CapInput/Number.js +42 -0
  27. package/dist/CapInput/Search.js +35 -0
  28. package/dist/CapInput/TextArea.js +42 -0
  29. package/dist/CapInput/index.js +15 -0
  30. package/dist/CapInput/messages.js +32 -0
  31. package/dist/CapInput/styles.js +11 -0
  32. package/dist/CapTable/CapTable.js +148 -0
  33. package/dist/CapTable/index.js +9 -0
  34. package/dist/CapTable/loadable.js +23 -0
  35. package/dist/CapTable/styles.js +26 -0
  36. package/dist/LocaleHoc/index.js +40 -0
  37. package/dist/esm/CapHeading/CapHeading.js +41 -0
  38. package/dist/esm/CapHeading/index.js +1 -0
  39. package/dist/esm/CapHeading/styles.js +123 -0
  40. package/dist/esm/CapInfoNote/CapInfoNote.js +62 -0
  41. package/dist/esm/CapInfoNote/index.js +1 -0
  42. package/dist/esm/CapInfoNote/styles.js +6 -0
  43. package/dist/esm/CapInput/CapInput.js +57 -0
  44. package/dist/esm/CapInput/Number.js +35 -0
  45. package/dist/esm/CapInput/Search.js +28 -0
  46. package/dist/esm/CapInput/TextArea.js +35 -0
  47. package/dist/esm/CapInput/index.js +8 -0
  48. package/dist/esm/CapInput/loadable.js +9 -0
  49. package/dist/esm/CapInput/messages.js +25 -0
  50. package/dist/esm/CapInput/styles.js +3 -0
  51. package/dist/esm/CapLabel/CapLabel.js +50 -0
  52. package/dist/esm/CapLabel/index.js +1 -0
  53. package/dist/esm/CapLabel/styles.js +219 -0
  54. package/dist/esm/CapRow/CapRow.js +22 -0
  55. package/dist/esm/CapRow/index.js +1 -0
  56. package/dist/esm/CapRow/styles.js +5 -0
  57. package/dist/esm/CapTable/CapTable.js +140 -0
  58. package/dist/esm/CapTable/index.js +2 -0
  59. package/dist/esm/CapTable/loadable.js +12 -0
  60. package/dist/esm/CapTable/styles.js +17 -0
  61. package/dist/esm/CapTooltip/CapTooltip.js +34 -0
  62. package/dist/esm/CapTooltip/index.js +1 -0
  63. package/dist/esm/CapTooltip/styles.js +6 -0
  64. package/dist/esm/CapUnifiedSelect/CapUnifiedSelect.js +101 -0
  65. package/dist/esm/CapUnifiedSelect/index.js +3 -0
  66. package/dist/esm/CapUnifiedSelect/loadable.js +4 -0
  67. package/dist/esm/CapUnifiedSelect/messages.js +23 -0
  68. package/dist/esm/CapUnifiedSelect/styles.js +15 -0
  69. package/dist/esm/LocaleHoc/index.js +31 -0
  70. package/dist/esm/index.js +11 -0
  71. package/dist/esm/styled/index.js +5 -0
  72. package/dist/esm/styled/variables.js +88 -0
  73. package/dist/esm/translations/en.js +329 -0
  74. package/dist/index.js +39 -0
  75. package/dist/index.js.LICENSE.txt +7 -0
  76. package/dist/styled/index.js +22 -0
  77. package/dist/styled/variables.js +94 -0
  78. package/dist/translations/en.js +335 -0
  79. package/index.js +1 -7
  80. package/package.json +10 -6
  81. package/.DS_Store +0 -0
  82. package/CapSkeleton/CapSkeleton.js +0 -17
  83. package/CapSkeleton/index.js +0 -1
  84. package/CapSpin/CapSpin.js +0 -23
  85. package/CapSpin/index.js +0 -1
  86. package/CapTestSelect/CapTestSelect.js +0 -47
  87. package/CapTestSelect/index.js +0 -1
  88. package/assets/upload.svg +0 -3
  89. package/utils/index.js +0 -1
  90. package/utils/withStyles.js +0 -24
@@ -1,12 +1,12 @@
1
- import CapSkeleton from '../CapSkeleton';
1
+ import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
2
2
  import { loadable } from '@capillarytech/cap-ui-utils';
3
3
  import React, { Suspense } from 'react';
4
4
 
5
5
  const LoadableComponent = loadable(() => import('./CapTable'));
6
6
 
7
- const CapTableLoadable = (props) => (
8
- <Suspense fallback={<CapSkeleton />}>
9
- <LoadableComponent {...props} />
7
+ const CapTableLoadable = () => (
8
+ <Suspense fallback={<CapSpin />}>
9
+ <LoadableComponent />
10
10
  </Suspense>
11
11
  );
12
12
 
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Tooltip } from 'antd';
4
+ import classNames from 'classnames';
5
+ import { TooltipWrapper } from './styles';
6
+
7
+ const CapTooltip = ({ overlayClassName, children, ...rest }) => {
8
+ return (
9
+ <TooltipWrapper>
10
+ <Tooltip
11
+ overlayClassName={classNames('cap-tooltip', overlayClassName)}
12
+ {...rest}
13
+ >
14
+ {children}
15
+ </Tooltip>
16
+ </TooltipWrapper>
17
+ );
18
+ };
19
+
20
+ /*
21
+ NOTE:
22
+ While using a disabled button with tooltip, wrap the button with an element with className "button-disabled-tooltip-wrapper".
23
+
24
+ <CapTooltip title="disabled button with tooltip">
25
+ <span className="button-disabled-tooltip-wrapper">
26
+ <CapButton disabled>Button</CapButton>
27
+ </span>
28
+ </CapTooltip>
29
+ */
30
+
31
+ CapTooltip.propTypes = {
32
+ overlayClassName: PropTypes.string,
33
+ children: PropTypes.node,
34
+ };
35
+
36
+ export default CapTooltip;
@@ -0,0 +1 @@
1
+ export { default } from './CapTooltip';
@@ -0,0 +1,42 @@
1
+ import styled from 'styled-components';
2
+ import * as styledVars from '../styled/variables';
3
+
4
+ export const TooltipWrapper = styled.span`
5
+ .cap-tooltip {
6
+ max-width: 324px;
7
+
8
+ .ant-tooltip-inner {
9
+ background-color: ${styledVars.FONT_COLOR_01};
10
+ font-size: ${styledVars.FONT_SIZE_M};
11
+ font-weight: ${styledVars.FONT_WEIGHT_MEDIUM};
12
+ padding: 6px 8px;
13
+ min-height: 32px;
14
+ border-radius: ${styledVars.RADIUS_04};
15
+ }
16
+
17
+ &.cap-bgcolor-tooltip {
18
+ .ant-tooltip-inner {
19
+ background-color: ${styledVars.FONT_COLOR_05};
20
+ }
21
+ }
22
+
23
+ &.hide-tooltip-pointer {
24
+ .ant-tooltip-arrow {
25
+ display: none;
26
+ }
27
+ }
28
+ }
29
+
30
+ .button-disabled-tooltip-wrapper {
31
+ display: inline-flex;
32
+ cursor: not-allowed;
33
+
34
+ .cap-button.ant-btn[disabled] {
35
+ pointer-events: none;
36
+ & > * {
37
+ pointer-events: auto;
38
+ cursor: not-allowed;
39
+ }
40
+ }
41
+ }
42
+ `;
@@ -1,322 +1,121 @@
1
- // Enhanced CapUnifiedSelect supporting 4 scenarios with advanced features in a single TreeSelect
2
- import React, { useState, useEffect } from 'react';
1
+ // CapUnifiedSelect component using Ant Design v5 Select and TreeSelect directly
2
+ import React from 'react';
3
3
  import PropTypes from 'prop-types';
4
- import classnames from 'classnames';
5
- import { TreeSelect, Tooltip, Input, Button } from 'antd';
6
- import styled from 'styled-components';
7
- import uploadIcon from '../assets/upload.svg';
4
+ import { Select, TreeSelect } from 'antd';
5
+ import { SelectWrapper, HeaderWrapper, StyledInfoIcon } from './styles';
6
+ import CapLabel from '../CapLabel';
7
+ import CapTooltip from '../CapTooltip';
8
8
 
9
- import { InfoCircleOutlined, SearchOutlined, WarningFilled, DownOutlined } from '@ant-design/icons';
10
-
11
- import withStyles from '../utils/withStyles';
12
- import { SelectWrapper, HeaderWrapper, selectStyles } from './styles';
13
-
14
- const StyledTreeSelect = styled(TreeSelect)`
15
- ${selectStyles}
16
- `;
17
-
18
- const CapUnifiedSelect = ({
9
+ function CapUnifiedSelect({
19
10
  type,
20
11
  options = [],
12
+ treeData,
21
13
  value,
22
14
  onChange,
23
15
  placeholder = 'Select an option',
24
16
  className,
25
17
  style,
26
- isError = false,
27
- errorMessage,
28
- popupClassName,
29
18
  allowClear = false,
30
- headerLabel,
19
+ showSearch = false,
20
+ label,
31
21
  tooltip,
32
- bylineText,
33
22
  disabled = false,
34
- showUpload = false,
35
- customPopupRender = true,
36
- showSearch = true,
37
- searchBasedOn = 'label',
38
- onConfirm,
39
- onCancel,
40
- ...rest
41
- }) => {
42
-
43
- const [searchText, setSearchText] = useState('');
44
- const [tempValue, setTempValue] = useState(value);
45
- const [allSelected, setAllSelected] = useState(false);
46
- const [dropdownOpen, setDropdownOpen] = useState(false);
47
-
48
- useEffect(() => {
49
- setTempValue(value);
50
- }, [value]);
23
+ }) {
24
+ const selectVirtualizationProps = {
25
+ listHeight: 256,
26
+ };
51
27
 
52
28
  const treeSelectVirtualizationProps = {
53
29
  listHeight: 256,
54
30
  listItemHeight: 32,
55
31
  };
56
32
 
57
- const NoResult = () => (
58
- <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: 200, color: '#8c8c8c', fontSize: 14 }}>
59
- <WarningFilled style={{ fontSize: 36, marginBottom: 8, color: '#bfbfbf' }} />
60
- <div style={{ fontWeight: 500 }}>No results found</div>
61
- </div>
62
- );
63
-
64
- const getFilteredTreeData = (data, search) => {
65
- if (!search) return data;
66
-
67
- const filterNode = node => {
68
- if (searchBasedOn === 'value') {
69
- const valueText = String(node.value || '').toLowerCase();
70
- return valueText.includes(search.toLowerCase());
71
- } else if (searchBasedOn === 'key') {
72
- const keyText = String(node.key || '').toLowerCase();
73
- return keyText.includes(search.toLowerCase());
74
- } else {
75
- // Default case, fall back to label
76
- const labelText = node.label?.toLowerCase() || '';
77
- return labelText.includes(search.toLowerCase());
78
- }
79
- };
80
-
81
- const loop = data =>
82
- data.map(item => {
83
- const children = item.children ? loop(item.children) : [];
84
- if (filterNode(item) || children.length) {
85
- return { ...item, children };
86
- }
87
- return null;
88
- }).filter(Boolean);
89
-
90
- return loop(data);
91
- };
92
-
93
- const flattenLeafValues = nodes =>
94
- nodes?.flatMap(node => node.children ? flattenLeafValues(node.children) : [node.value]) || [];
95
-
96
- const isMulti = type === 'multiSelect' || type === 'multiTreeSelect';
97
- const isTree = type === 'treeSelect' || type === 'multiTreeSelect';
98
-
99
- const dataSource = isTree ? options : options.map(opt => ({ title: opt.label, value: opt.value, key: opt.key || opt.value }));
100
-
101
- const filteredTree = getFilteredTreeData(dataSource, searchText);
102
- const leafValues = flattenLeafValues(filteredTree);
103
-
104
- const handleSelectAll = () => {
105
- console.log('Select All clicked');
106
- const availableValues = leafValues;
107
- if (allSelected) {
108
- // If currently all selected, then unselect all
109
- setTempValue([]);
110
- setAllSelected(false);
111
- } else {
112
- // Otherwise select all available options
113
- setTempValue(availableValues);
114
- setAllSelected(true);
115
- }
116
- };
117
-
118
- useEffect(() => {
119
- if (isMulti && Array.isArray(tempValue)) {
120
- setAllSelected(tempValue.length > 0 && tempValue.length === leafValues.length);
121
- }
122
- }, [tempValue, leafValues, isMulti]);
123
-
124
- const handleConfirm = () => {
125
- console.log('Confirm clicked');
126
- if (onChange) onChange(tempValue);
127
- setDropdownOpen(false);
128
- };
129
-
130
- const handleCancel = () => {
131
- console.log('Cancel clicked');
132
- setTempValue(value);
133
- setDropdownOpen(false);
134
- };
135
-
136
- const handleTempChange = newValue => {
137
- setTempValue(newValue);
138
- };
139
-
140
- const handleDropdownVisibilityChange = open => {
141
- if (!open) {
142
- setTempValue(value);
143
- }
144
- setDropdownOpen(open);
145
- };
146
-
147
- const suffix = isMulti && Array.isArray(value) && value?.length > 1 ? (
148
- <>
149
- <span>+{value.length - 1} more <DownOutlined /></span>
150
- </>
151
- ) : (
152
- <DownOutlined />
153
- );
154
-
155
- const prefix = () => {
156
- if (isMulti && Array.isArray(value) && value?.length > 0) {
157
- const selectedLabels = options.filter(opt => value.includes(opt.value)).map(opt => opt.label);
158
- return selectedLabels[0];
159
- }
160
- return null;
161
- };
162
-
163
33
  const renderHeader = () => {
164
- if (!headerLabel && !tooltip) return null;
34
+ if (!label && !tooltip) return null;
35
+
165
36
  return (
166
- <>
167
- <HeaderWrapper className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header')}>
168
- {headerLabel && <label type="label16" className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-label')}>{headerLabel}</label>}
37
+ <HeaderWrapper className={disabled ? 'disabled' : ''}>
38
+ {label && (
39
+ <CapLabel type="label16" className={disabled ? 'disabled' : ''}>
40
+ {label}
41
+ </CapLabel>
42
+ )}
169
43
  {tooltip && (
170
- <Tooltip title={tooltip} rootClassName="cap-unified-tooltip" className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-tooltip')}>
171
- <InfoCircleOutlined />
172
- </Tooltip>
44
+ <CapTooltip title={tooltip}>
45
+ <StyledInfoIcon className={disabled ? 'disabled' : ''} />
46
+ </CapTooltip>
173
47
  )}
174
48
  </HeaderWrapper>
175
- <div className="cap-unified-select-header-byline-text">
176
- {bylineText && <label className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-byline-text')}>{bylineText}</label>}
177
- </div>
178
- </>
179
49
  );
180
50
  };
181
51
 
182
52
  const renderDropdown = () => {
183
- const currentItems = filteredTree;
184
- const selectedCount = Array.isArray(tempValue)
185
- ? isTree
186
- ? tempValue.filter(val => leafValues.includes(val)).length
187
- : tempValue.length
188
- : (tempValue ? 1 : 0);
189
-
190
- const renderCustomDropdown = menu => {
191
- if (!customPopupRender) return menu;
192
-
53
+ if (type === 'treeSelect' || type === 'multiTreeSelect') {
193
54
  return (
194
- <div className={classnames(popupClassName, `${type}-popup-container`)}>
195
- {showSearch && (
196
- <div style={{ borderBottom: '1px solid #f0f0f0' }}>
197
- <Input
198
- prefix={<SearchOutlined style={{ color: '#B3BAC5' }} />}
199
- placeholder="Search"
200
- variant="borderless"
201
- value={searchText}
202
- onChange={e => setSearchText(e.target.value)}
203
- onKeyDown={e => e.stopPropagation()}
204
- />
205
- </div>
206
- )}
207
- {isMulti && showUpload && (
208
- <div style={{ cursor: 'pointer', display: 'flex', alignItems: 'center', borderBottom: '1px solid #f0f0f0' , height: '36px'}}>
209
- <Button
210
- type="link"
211
- icon={<img src={uploadIcon} alt="upload" style={{ width: "16px", height: "20px" }} />}
212
- onClick={() => {}}
213
- style={{
214
- color: '#2466EA', // AntD primary blue
215
- display: 'flex',
216
- alignItems: 'center',
217
- fontSize: '14px',
218
- fontWeight: '400',
219
- lineHeight: '20px',
220
- }}
221
- >
222
- Upload
223
- </Button>
224
- </div>
225
- )}
226
- {isMulti && currentItems.length > 0 && (
227
- <div style={{ padding: '8px 12px', cursor: 'pointer', display: 'flex', alignItems: 'center', borderBottom: '1px solid #f0f0f0' }} onClick={e => { e.stopPropagation(); handleSelectAll(); }}>
228
- <input type="checkbox" checked={allSelected} readOnly style={{ cursor: 'pointer' }} onClick={e => e.stopPropagation()} />
229
- <label style={{ marginLeft: 8, cursor: 'pointer' }}>Select all</label>
230
- </div>
231
- )}
232
-
233
- {currentItems.length === 0 ? <NoResult /> : menu}
234
-
235
- {currentItems.length > 0 && isMulti && (
236
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '8px 12px', borderTop: '1px solid #f0f0f0' }}>
237
- <div>
238
- <Button type="primary" size="small" style={{ marginRight: 8 }} onClick={e => { e.stopPropagation(); handleConfirm(); }}>Confirm</Button>
239
- <Button type="text" size="small" onClick={e => { e.stopPropagation(); handleCancel(); }}>Cancel</Button>
240
- </div>
241
- {selectedCount > 0 && <span style={{ color: '#8c8c8c', fontSize: '14px' }}>{selectedCount} selected</span>}
242
- </div>
243
- )}
244
- </div>
245
- );
246
- };
247
-
248
- return (
249
- <>
250
- <StyledTreeSelect
251
- {...rest}
252
- type={type}
253
- treeData={filteredTree}
254
- value={customPopupRender ? tempValue : value}
255
- onChange={customPopupRender ? handleTempChange : onChange}
55
+ <TreeSelect
56
+ treeData={treeData || options}
57
+ value={value}
58
+ onChange={onChange}
256
59
  placeholder={placeholder}
257
- maxTagCount={0}
258
- maxTagPlaceholder={() => null}
259
- prefix={isMulti && value.length > 0 && prefix()}
260
- suffixIcon={suffix}
261
- className={classnames(`cap-unified-tree-select ${className || ''}`)}
60
+ className={className}
262
61
  style={style}
263
- status={isError ? 'error' : ''}
264
62
  allowClear={allowClear}
265
- multiple={isMulti}
266
- treeCheckable={isMulti}
267
- showCheckedStrategy={TreeSelect.SHOW_PARENT}
63
+ showSearch={showSearch}
64
+ multiple={type === 'multiTreeSelect' ? true : false}
268
65
  virtual
66
+ treeDefaultExpandAll
269
67
  disabled={disabled}
270
- filterTreeNode={false}
271
- open={dropdownOpen}
272
- onOpenChange={handleDropdownVisibilityChange}
273
68
  {...treeSelectVirtualizationProps}
274
- popupRender={renderCustomDropdown}
275
69
  />
276
- {isError && <div style={{ color: '#E83135' }} className="cap-unified-select-status">{errorMessage}</div>}
277
- </>
70
+ );
71
+ }
72
+
73
+ return (
74
+ <Select
75
+ value={value}
76
+ onChange={onChange}
77
+ placeholder={placeholder}
78
+ className={className}
79
+ style={style}
80
+ allowClear={allowClear}
81
+ showSearch={showSearch}
82
+ options={options}
83
+ mode={type === 'multiSelect' ? 'multiple' : undefined}
84
+ virtual
85
+ disabled={disabled}
86
+ {...selectVirtualizationProps}
87
+ />
278
88
  );
279
89
  };
280
90
 
281
91
  return (
282
- <SelectWrapper className={classnames(`cap-unified-select-container ${className || ''}`)}>
92
+ <SelectWrapper>
283
93
  {renderHeader()}
284
94
  {renderDropdown()}
285
95
  </SelectWrapper>
286
96
  );
287
- };
97
+ }
288
98
 
289
99
  CapUnifiedSelect.propTypes = {
290
100
  type: PropTypes.oneOf(['select', 'multiSelect', 'treeSelect', 'multiTreeSelect']),
291
101
  options: PropTypes.array,
102
+ treeData: PropTypes.array,
292
103
  value: PropTypes.any,
293
104
  onChange: PropTypes.func,
294
105
  placeholder: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
295
106
  className: PropTypes.string,
296
107
  style: PropTypes.object,
297
108
  allowClear: PropTypes.bool,
298
- headerLabel: PropTypes.string,
109
+ showSearch: PropTypes.bool,
110
+ label: PropTypes.string,
299
111
  tooltip: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
300
112
  disabled: PropTypes.bool,
301
- customPopupRender: PropTypes.bool,
302
- showSearch: PropTypes.bool,
303
- searchBasedOn: PropTypes.oneOf(['label', 'value', 'key']),
304
- onConfirm: PropTypes.func,
305
- onCancel: PropTypes.func,
306
- isError: PropTypes.bool,
307
- errorMessage: PropTypes.string,
308
- popupClassName: PropTypes.string,
309
- showUpload: PropTypes.bool,
310
113
  };
311
114
 
312
115
  CapUnifiedSelect.defaultProps = {
313
116
  type: 'select',
314
117
  allowClear: false,
315
- customPopupRender: false,
316
- showSearch: true,
317
- searchBasedOn: 'label',
318
- className: '',
319
- popupClassName: '',
118
+ showSearch: false,
320
119
  };
321
120
 
322
- export default withStyles(CapUnifiedSelect, selectStyles);
121
+ export default CapUnifiedSelect;
@@ -1 +1,4 @@
1
- export { default } from './CapUnifiedSelect';
1
+ import CapUnifiedSelect from './CapUnifiedSelect';
2
+ import CapUnifiedSelectLoadable from './loadable';
3
+
4
+ export default CapUnifiedSelectLoadable;
@@ -0,0 +1,3 @@
1
+ import loadable from '@loadable/component';
2
+
3
+ export default loadable(() => import('./CapUnifiedSelect'));