@capillarytech/blaze-ui 0.1.6-alpha.39 → 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 -249
  19. package/CapUnifiedSelect/index.js +4 -1
  20. package/CapUnifiedSelect/loadable.js +3 -0
  21. package/CapUnifiedSelect/styles.js +26 -272
  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,311 +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
- noResultText = 'No results found',
41
- ...rest
42
- }) => {
43
-
44
- const [searchText, setSearchText] = useState('');
45
- const [tempValue, setTempValue] = useState(value);
46
- const [allSelected, setAllSelected] = useState(false);
47
-
48
-
49
- useEffect(() => {
50
- setTempValue(value);
51
- }, [value]);
23
+ }) {
24
+ const selectVirtualizationProps = {
25
+ listHeight: 256,
26
+ };
52
27
 
53
28
  const treeSelectVirtualizationProps = {
54
29
  listHeight: 256,
55
30
  listItemHeight: 32,
56
31
  };
57
32
 
58
- const NoResult = ({ noResultText, className }) => (
59
- <div className={classnames(className, "cap-unified-select-no-result")}>
60
- <WarningFilled className="cap-unified-select-no-result-icon" />
61
- <div className="cap-unified-select-no-result-text">{noResultText}</div>
62
- </div>
63
- );
64
-
65
- const getFilteredTreeData = (data, search) => {
66
- if (!search) return data;
67
-
68
- const filterNode = node => {
69
- if (searchBasedOn === 'value') {
70
- const valueText = String(node.value || '').toLowerCase();
71
- return valueText.includes(search.toLowerCase());
72
- } else if (searchBasedOn === 'key') {
73
- const keyText = String(node.key || '').toLowerCase();
74
- return keyText.includes(search.toLowerCase());
75
- } else {
76
- // Default case, fall back to label
77
- const labelText = node.label?.toLowerCase() || '';
78
- return labelText.includes(search.toLowerCase());
79
- }
80
- };
81
-
82
- const loop = data =>
83
- data.map(item => {
84
- const children = item.children ? loop(item.children) : [];
85
- if (filterNode(item) || children.length) {
86
- return { ...item, children };
87
- }
88
- return null;
89
- }).filter(Boolean);
90
-
91
- return loop(data);
92
- };
93
-
94
- const flattenLeafValues = nodes =>
95
- nodes?.flatMap(node => node.children ? flattenLeafValues(node.children) : [node.value]) || [];
96
-
97
- const isMulti = type === 'multiSelect' || type === 'multiTreeSelect';
98
- const isTree = type === 'treeSelect' || type === 'multiTreeSelect';
99
-
100
- const dataSource = isTree ? options : options.map(opt => ({ title: opt.label, value: opt.value, key: opt.key || opt.value }));
101
-
102
- const filteredTree = getFilteredTreeData(dataSource, searchText);
103
- const leafValues = flattenLeafValues(filteredTree);
104
-
105
- const handleSelectAll = () => {
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
- };
128
-
129
- const handleCancel = () => {
130
- console.log('Cancel clicked');
131
- setTempValue(value);
132
- };
133
-
134
- const handleTempChange = newValue => {
135
- setTempValue(newValue);
136
- };
137
-
138
- const suffix = isMulti && Array.isArray(value) && value?.length > 1 ? (
139
- <>
140
- <span>+{value.length - 1} more <DownOutlined /></span>
141
- </>
142
- ) : (
143
- <DownOutlined />
144
- );
145
-
146
- const prefix = () => {
147
- if (isMulti && Array.isArray(value) && value?.length > 0) {
148
- const selectedLabels = options.filter(opt => value.includes(opt.value)).map(opt => opt.label);
149
- return selectedLabels[0];
150
- }
151
- return null;
152
- };
153
-
154
33
  const renderHeader = () => {
155
- if (!headerLabel && !tooltip) return null;
34
+ if (!label && !tooltip) return null;
35
+
156
36
  return (
157
- <>
158
- <HeaderWrapper className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header')}>
159
- {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
+ )}
160
43
  {tooltip && (
161
- <Tooltip title={tooltip} rootClassName="cap-unified-tooltip" className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-tooltip')}>
162
- <InfoCircleOutlined />
163
- </Tooltip>
44
+ <CapTooltip title={tooltip}>
45
+ <StyledInfoIcon className={disabled ? 'disabled' : ''} />
46
+ </CapTooltip>
164
47
  )}
165
48
  </HeaderWrapper>
166
- <div className="cap-unified-select-header-byline-text">
167
- {bylineText && <label className={classnames(disabled ? 'disabled' : '', 'cap-unified-select-header-byline-text')}>{bylineText}</label>}
168
- </div>
169
- </>
170
49
  );
171
50
  };
172
51
 
173
52
  const renderDropdown = () => {
174
- const currentItems = filteredTree;
175
- const selectedCount = Array.isArray(tempValue)
176
- ? isTree
177
- ? tempValue.filter(val => leafValues.includes(val)).length
178
- : tempValue.length
179
- : (tempValue ? 1 : 0);
180
-
181
- const renderCustomDropdown = menu => {
182
- if (!customPopupRender) return menu;
183
-
53
+ if (type === 'treeSelect' || type === 'multiTreeSelect') {
184
54
  return (
185
- <div className={classnames(popupClassName, `${type}-popup-container`)}>
186
- {showSearch && (
187
- <div style={{ borderBottom: '1px solid #f0f0f0' }}>
188
- <Input
189
- prefix={<SearchOutlined style={{ color: '#B3BAC5' }} />}
190
- placeholder="Search"
191
- variant="borderless"
192
- value={searchText}
193
- onChange={e => setSearchText(e.target.value)}
194
- onKeyDown={e => e.stopPropagation()}
195
- />
196
- </div>
197
- )}
198
- {isMulti && showUpload && (
199
- <div style={{ cursor: 'pointer', display: 'flex', alignItems: 'center', borderBottom: '1px solid #f0f0f0' , height: '36px'}}>
200
- <Button
201
- type="link"
202
- icon={<img src={uploadIcon} alt="upload" style={{ width: "16px", height: "20px" }} />}
203
- onClick={() => {}}
204
- style={{
205
- color: '#2466EA', // AntD primary blue
206
- display: 'flex',
207
- alignItems: 'center',
208
- fontSize: '14px',
209
- fontWeight: '400',
210
- lineHeight: '20px',
211
- }}
212
- >
213
- Upload
214
- </Button>
215
- </div>
216
- )}
217
- {isMulti && currentItems.length > 0 && (
218
- <div style={{ padding: '8px 12px', cursor: 'pointer', display: 'flex', alignItems: 'center', borderBottom: '1px solid #f0f0f0' }} onClick={e => { e.stopPropagation(); handleSelectAll(); }}>
219
- <input type="checkbox" checked={allSelected} readOnly style={{ cursor: 'pointer' }} onClick={e => e.stopPropagation()} />
220
- <label style={{ marginLeft: 8, cursor: 'pointer' }}>Select all</label>
221
- </div>
222
- )}
223
-
224
- {currentItems.length === 0 ? <NoResult noResultText={noResultText} className={classnames(className, "cap-unified-select-no-result")}/> : menu}
225
-
226
- {currentItems.length > 0 && isMulti && (
227
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '8px 12px', borderTop: '1px solid #f0f0f0' }}>
228
- <div>
229
- <Button type="primary" size="small" style={{ marginRight: 8 }} onClick={e => { e.stopPropagation(); handleConfirm(); }}>Confirm</Button>
230
- <Button type="text" size="small" onClick={e => { e.stopPropagation(); handleCancel(); }}>Cancel</Button>
231
- </div>
232
- {selectedCount > 0 && <span style={{ color: '#8c8c8c', fontSize: '14px' }}>{selectedCount} selected</span>}
233
- </div>
234
- )}
235
- </div>
236
- );
237
- };
238
-
239
- return (
240
- <>
241
- <StyledTreeSelect
242
- {...rest}
243
- type={type}
244
- treeData={filteredTree}
245
- value={customPopupRender ? tempValue : value}
246
- onChange={customPopupRender ? handleTempChange : onChange}
55
+ <TreeSelect
56
+ treeData={treeData || options}
57
+ value={value}
58
+ onChange={onChange}
247
59
  placeholder={placeholder}
248
- maxTagCount={0}
249
- maxTagPlaceholder={() => null}
250
- prefix={isMulti && value.length > 0 && prefix()}
251
- suffixIcon={suffix}
252
- className={classnames(`cap-unified-tree-select ${className || ''}`)}
60
+ className={className}
253
61
  style={style}
254
- status={isError ? 'error' : ''}
255
62
  allowClear={allowClear}
256
- multiple={isMulti}
257
- treeCheckable={isMulti}
258
- showCheckedStrategy={TreeSelect.SHOW_PARENT}
63
+ showSearch={showSearch}
64
+ multiple={type === 'multiTreeSelect' ? true : false}
259
65
  virtual
66
+ treeDefaultExpandAll
260
67
  disabled={disabled}
261
- filterTreeNode={false}
262
68
  {...treeSelectVirtualizationProps}
263
- popupRender={renderCustomDropdown}
264
69
  />
265
- {isError && <div style={{ color: '#E83135' }} className="cap-unified-select-status">{errorMessage}</div>}
266
- </>
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
+ />
267
88
  );
268
89
  };
269
90
 
270
91
  return (
271
- <SelectWrapper className={classnames(className, 'cap-unified-select-container')}>
92
+ <SelectWrapper>
272
93
  {renderHeader()}
273
94
  {renderDropdown()}
274
95
  </SelectWrapper>
275
96
  );
276
- };
97
+ }
277
98
 
278
99
  CapUnifiedSelect.propTypes = {
279
100
  type: PropTypes.oneOf(['select', 'multiSelect', 'treeSelect', 'multiTreeSelect']),
280
101
  options: PropTypes.array,
102
+ treeData: PropTypes.array,
281
103
  value: PropTypes.any,
282
104
  onChange: PropTypes.func,
283
105
  placeholder: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
284
106
  className: PropTypes.string,
285
107
  style: PropTypes.object,
286
108
  allowClear: PropTypes.bool,
287
- headerLabel: PropTypes.string,
109
+ showSearch: PropTypes.bool,
110
+ label: PropTypes.string,
288
111
  tooltip: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
289
112
  disabled: PropTypes.bool,
290
- customPopupRender: PropTypes.bool,
291
- showSearch: PropTypes.bool,
292
- searchBasedOn: PropTypes.oneOf(['label', 'value', 'key']),
293
- onConfirm: PropTypes.func,
294
- onCancel: PropTypes.func,
295
- isError: PropTypes.bool,
296
- errorMessage: PropTypes.string,
297
- popupClassName: PropTypes.string,
298
- showUpload: PropTypes.bool,
299
113
  };
300
114
 
301
115
  CapUnifiedSelect.defaultProps = {
302
116
  type: 'select',
303
117
  allowClear: false,
304
- customPopupRender: false,
305
- showSearch: true,
306
- searchBasedOn: 'label',
307
- className: '',
308
- popupClassName: '',
118
+ showSearch: false,
309
119
  };
310
120
 
311
- 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'));