@capillarytech/blaze-ui 0.1.6-alpha.43 → 0.1.6-alpha.45

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.
@@ -26,6 +26,7 @@ const CapUnifiedSelect = ({
26
26
  popupClassName,
27
27
  allowClear = false,
28
28
  headerLabel,
29
+ onUpload,
29
30
  tooltip,
30
31
  bylineText,
31
32
  disabled = false,
@@ -35,13 +36,15 @@ const CapUnifiedSelect = ({
35
36
  searchBasedOn = 'label',
36
37
  onConfirm,
37
38
  onCancel,
38
- noResultText = 'No results found',
39
+ noResultCustomText = 'No results found',
40
+ noResultCustomIcon = 'warning',
39
41
  ...rest
40
42
  }) => {
41
43
 
42
44
  const [searchText, setSearchText] = useState('');
43
45
  const [tempValue, setTempValue] = useState(value);
44
46
  const [allSelected, setAllSelected] = useState(false);
47
+ const [dropdownOpen, setDropdownOpen] = useState(false);
45
48
 
46
49
 
47
50
  useEffect(() => {
@@ -53,14 +56,14 @@ const CapUnifiedSelect = ({
53
56
  listItemHeight: 32,
54
57
  };
55
58
 
56
- const NoResult = memo(({ noResultText, className }) => (
59
+ const NoResult = memo(({ noResultCustomText, className }) => (
57
60
  <CapRow
58
61
  className={classnames(className, "cap-unified-select-no-result")}
59
62
  align="middle"
60
63
  gap={8}
61
64
  >
62
- <CapIcon type="warning" size="s" />
63
- <CapLabel className="cap-unified-select-no-result-text">{noResultText}</CapLabel>
65
+ <CapIcon type={noResultCustomIcon} size="m" />
66
+ <CapLabel className="cap-unified-select-no-result-text">{showUpload && options.length === 0 ? noResultCustomText : 'No results found'}</CapLabel>
64
67
  </CapRow>
65
68
  ));
66
69
 
@@ -125,33 +128,51 @@ const CapUnifiedSelect = ({
125
128
 
126
129
  const handleConfirm = useCallback(() => {
127
130
  if (onChange) onChange(tempValue);
131
+ setDropdownOpen(false);
128
132
  }, [onChange, tempValue]);
129
133
 
130
134
  const handleCancel = useCallback(() => {
131
135
  setTempValue(value);
136
+ setDropdownOpen(false);
132
137
  }, [value]);
133
138
 
134
139
  const handleTempChange = useCallback(newValue => {
135
140
  setTempValue(newValue);
136
141
  }, []);
137
142
 
143
+ const handleDropdownVisibilityChange = open => {
144
+ if (!open) {
145
+ setTempValue(value);
146
+ }
147
+ setDropdownOpen(open);
148
+ };
149
+
138
150
  const suffix = useMemo(() => {
139
- return isMulti && Array.isArray(value) && value?.length > 1 ? (
151
+ const displayValue = dropdownOpen ? tempValue : value;
152
+ return isMulti && Array.isArray(displayValue) && displayValue?.length > 1 ? (
140
153
  <>
141
- <span>+{value.length - 1} more <CapIcon type="down" size="s" /></span>
154
+ <span>+{displayValue.length - 1} more <CapIcon type="down" size="s" /></span>
142
155
  </>
143
156
  ) : (
144
157
  <CapIcon type="down" size="s" />
145
158
  );
146
- }, [isMulti, value]);
159
+ }, [isMulti, value, tempValue, dropdownOpen]);
147
160
 
148
161
  const prefix = useMemo(() => {
149
- if (isMulti && Array.isArray(value) && value?.length > 0) {
150
- const selectedLabels = options.filter(opt => value.includes(opt.value)).map(opt => opt.label);
151
- return selectedLabels[0];
162
+ if (isMulti) {
163
+ if (Array.isArray(tempValue) && tempValue?.length > 0) {
164
+ const firstSelectedValue = tempValue[0];
165
+ const firstSelectedOption = options.find(opt => opt.value === firstSelectedValue);
166
+ return firstSelectedOption?.label || null;
167
+ }
168
+ else if (Array.isArray(value) && value?.length > 0) {
169
+ const firstSelectedValue = value[0];
170
+ const firstSelectedOption = options.find(opt => opt.value === firstSelectedValue);
171
+ return firstSelectedOption?.label || null;
172
+ }
152
173
  }
153
174
  return null;
154
- }, [isMulti, value, options]);
175
+ }, [isMulti, value, tempValue, options]);
155
176
 
156
177
  const renderHeader = useCallback(() => {
157
178
  if (!headerLabel && !tooltip) return null;
@@ -195,48 +216,54 @@ const CapUnifiedSelect = ({
195
216
  variant="borderless"
196
217
  value={searchText}
197
218
  onChange={e => setSearchText(e.target.value)}
198
- onKeyDown={e => e.stopPropagation()}
199
219
  />
200
220
  </CapRow>
201
221
  )}
202
222
  {isMulti && showUpload && (
203
- <CapRow className={classnames("cap-unified-select-upload-container")} align="middle">
204
- <Button
205
- type="link"
206
- icon={<CapIcon type="upload" size="s" />}
207
- onClick={() => {}}
208
- className={classnames("cap-unified-select-upload-button")}
209
- >
210
- Upload
211
- </Button>
223
+ <CapRow className={classnames("cap-unified-select-upload-container")} align="middle" onClick={onUpload}>
224
+ <CapIcon type="upload" size="s" style={{ color: styledVars.CAP_SECONDARY.base }}/>
225
+ <CapLabel type="label14" className={classnames("cap-unified-select-upload-label")}>Upload</CapLabel>
212
226
  </CapRow>
213
227
  )}
214
228
  {isMulti && currentItems.length > 0 && (
215
229
  <CapRow
216
230
  className={classnames("cap-unified-select-select-all-container")}
217
- onClick={e => { e.stopPropagation(); handleSelectAll(); }}
231
+ onClick={handleSelectAll}
218
232
  align="middle"
219
- gap={8}
233
+ gap={7}
220
234
  >
221
- <input type="checkbox" checked={allSelected} className={classnames("cap-unified-select-select-all-checkbox")} onClick={e => e.stopPropagation()} />
222
- <CapLabel className={classnames("cap-unified-select-select-all-label")}>Select all</CapLabel>
235
+ <input readOnly type="checkbox" checked={allSelected} className={classnames("cap-unified-select-select-all-checkbox")} onClick={handleSelectAll} />
236
+ <CapLabel type="label14" className={classnames("cap-unified-select-select-all-label")}>Select all</CapLabel>
223
237
  </CapRow>
224
238
  )}
225
239
 
226
- {currentItems.length === 0 ? <NoResult noResultText={noResultText} className={classnames(className, "cap-unified-select-no-result")}/> : menu}
240
+ {currentItems.length === 0 ? <NoResult noResultCustomText={noResultCustomText} className={classnames(className, "cap-unified-select-no-result")}/> : menu}
227
241
 
228
242
  {currentItems.length > 0 && isMulti && (
229
- <CapRow
230
- className={classnames("cap-unified-select-confirm-container")}
231
- justify="space-between"
232
- align="middle"
233
- >
234
- <CapRow gap={8}>
235
- <Button type="primary" size="small" className={classnames("cap-unified-select-confirm-button")} onClick={e => { e.stopPropagation(); handleConfirm(); }}>Confirm</Button>
236
- <Button type="text" size="small" onClick={e => { e.stopPropagation(); handleCancel(); }}>Cancel</Button>
237
- </CapRow>
238
- {selectedCount > 0 && <CapLabel className={classnames("cap-unified-select-selected-count")}>{selectedCount} selected</CapLabel>}
239
- </CapRow>
243
+ <div className="cap-unified-select-confirm-container">
244
+ <div className="cap-unified-select-confirm-button-group">
245
+ <Button
246
+ type="primary"
247
+ size="small"
248
+ className="cap-unified-select-confirm-button"
249
+ onClick={handleConfirm}
250
+ >
251
+ Confirm
252
+ </Button>
253
+ <Button
254
+ type="text"
255
+ className="cap-unified-select-cancel-button"
256
+ size="small"
257
+ onClick={handleCancel}
258
+ >
259
+ Cancel
260
+ </Button>
261
+ <CapLabel className="cap-unified-select-selected-count">
262
+ {selectedCount} selected
263
+ </CapLabel>
264
+ </div>
265
+ </div>
266
+
240
267
  )}
241
268
  </div>
242
269
  );
@@ -254,14 +281,16 @@ const CapUnifiedSelect = ({
254
281
  showSearch={false}
255
282
  maxTagCount={0}
256
283
  maxTagPlaceholder={() => null}
257
- prefix={isMulti && value.length > 0 && prefix}
284
+ prefix={tempValue?.length > 0 ? prefix : undefined}
258
285
  suffixIcon={suffix}
259
- className={classnames(`cap-unified-tree-select ${className || ''}`)}
286
+ className={classnames(`cap-unified-tree-select cap-unified-tree-select-${size}`, className)}
260
287
  style={style}
261
288
  status={isError ? 'error' : ''}
262
289
  allowClear={allowClear}
263
290
  multiple={isMulti}
264
291
  treeCheckable={isMulti}
292
+ open={dropdownOpen}
293
+ onOpenChange={handleDropdownVisibilityChange}
265
294
  showCheckedStrategy={TreeSelect.SHOW_PARENT}
266
295
  virtual
267
296
  disabled={disabled}
@@ -303,6 +332,7 @@ CapUnifiedSelect.propTypes = {
303
332
  errorMessage: PropTypes.string,
304
333
  popupClassName: PropTypes.string,
305
334
  showUpload: PropTypes.bool,
335
+ onUpload: PropTypes.func,
306
336
  };
307
337
 
308
338
  CapUnifiedSelect.defaultProps = {
@@ -318,7 +348,8 @@ CapUnifiedSelect.defaultProps = {
318
348
  disabled: false,
319
349
  showUpload: false,
320
350
  isError: false,
321
- noResultText: 'No results found'
351
+ noResultText: 'No results found',
352
+ onUpload: () => {}
322
353
  };
323
354
 
324
355
  export default withStyles(CapUnifiedSelect, selectStyles);
@@ -95,78 +95,136 @@ export const StyledInfoIcon = styled.span`
95
95
 
96
96
  export const selectStyles = css`
97
97
  &.cap-unified-select-container {
98
+ text-align: justify;
99
+ .ant-btn-variant-solid:not(:disabled):not(.ant-btn-disabled):hover{
100
+ background-color: #42b040;
101
+ }
98
102
  .ant-tree-select-dropdown{
99
- padding: 0px !important;
103
+ padding: 0px;
104
+ }
105
+ .cap-unified-tree-select-s{
106
+ height: 40px;
107
+ width: 160px;
108
+ }
109
+ .cap-unified-tree-select-m{
110
+ height: 40px;
111
+ width: 340px;
112
+ }
113
+ .cap-unified-tree-select-l{
114
+ height: 40px;
115
+ width: 400px;
100
116
  }
101
- .cap-unified-tree-select{
102
- height: 40px !important;
103
- width: 340px !important;
117
+ .cap-unified-tree-select-xl{
118
+ height: 40px;
119
+ width: 480px;
104
120
  }
105
121
  .cap-unified-select-upload-container{
106
- cursor: pointer !important;
107
- display: flex !important;
108
- align-items: center !important;
109
- border-bottom: 1px solid #f0f0f0 !important;
110
- height: 40px !important;
122
+ cursor: pointer;
123
+ display: flex;
124
+ align-items: center;
125
+ border-bottom: 1px solid #f0f0f0;
126
+ height: 40px;
127
+ padding-left: 15px;
128
+
129
+ .cap-unified-select-upload-label{
130
+ margin-left: 12px;
131
+ color: #2466EA;
132
+ }
111
133
  }
112
134
  .cap-unified-select-select-all-container{
113
- padding: 8px 12px !important;
114
- cursor: pointer !important;
115
- display: flex !important;
116
- align-items: center !important;
117
- border-bottom: 1px solid #f0f0f0 !important;
118
- height: 40px !important;
135
+ padding: 9px 9px;
136
+ cursor: pointer;
137
+ display: flex;
138
+ align-items: center;
139
+ border-bottom: 1px solid #f0f0f0;
140
+ height: 40px;
119
141
  }
120
142
  .ant-select-dropdown{
121
- margin-top: -5px !important;
122
- border-radius: 4px !important;
123
- box-shadow: 0px 4px 8px -2px #091E4240, 0px 0px 1px 0px #091E424F !important;
143
+ margin-top: -5px;
144
+ border-radius: 4px;
145
+ box-shadow: 0px 4px 8px -2px #091E4240, 0px 0px 1px 0px #091E424F;
146
+ max-height: 368px;
124
147
  }
125
148
  .ant-select-prefix{
126
- font-size: 14px !important;
127
- font-weight: 400 !important;
128
- color: #091E42 !important;
129
- line-height: 20px !important;
149
+ font-size: 14px;
150
+ font-weight: 400;
151
+ color: #091E42;
152
+ line-height: 20px;
130
153
  }
131
154
  .cap-unified-select-header-label{
132
- font-family: ${styledVars.FONT_FAMILY} !important;
133
- font-weight: 500 !important;
134
- font-size: 14px !important;
135
- line-height: 20px !important;
136
- letter-spacing: 0px !important;
137
- }
138
- .cap-unified-select-header-tooltip{
139
- width: 16px !important;
140
- height: 16px !important;
141
- color: ${styledVars.CAP_G06} !important;
155
+ font-family: ${styledVars.FONT_FAMILY};
156
+ font-weight: 500;
157
+ font-size: 14px;
158
+ line-height: 20px;
159
+ letter-spacing: 0px;
142
160
  }
143
161
  .cap-unified-select-header-byline-text{
144
- font-family: ${styledVars.FONT_FAMILY} !important;
145
- font-weight: 400 !important;
146
- font-size: 12px !important;
162
+ font-family: ${styledVars.FONT_FAMILY};
163
+ font-weight: 400;
164
+ font-size: 12px;
147
165
  margin-top: -10px;
148
- letter-spacing: 0px !important;
149
- color: #97A0AF !important;
166
+ letter-spacing: 0px;
167
+ color: #97A0AF;
168
+ }
169
+ .ant-input-affix-wrapper .ant-input-prefix{
170
+ left: 13px;
171
+ }
172
+ .ant-select-tree {
173
+ .ant-select-tree-node-content-wrapper{
174
+ background-color: transparent;
175
+ }
176
+ .ant-select-tree-node-content-wrapper:hover {
177
+ background-color: transparent;
178
+ }
179
+ }
180
+ .ant-select-tree .ant-select-tree-switcher:not(.ant-select-tree-switcher-noop):hover:before{
181
+ background-color: transparent;
182
+ }
183
+ .ant-select-selection-item{
184
+ background: transparent;
150
185
  }
151
186
  .cap-unified-tree-select .ant-select-selector:hover{
152
- border: 1px solid #7A869A !important;
187
+ border: 1px solid #7A869A;
188
+ }
189
+ .cap-unified-tree-select .ant-select-selector:focus{
190
+ border: 1px solid #7A869A;
191
+ }
192
+ .cap-unified-tree-select .cap-unified-select-select-all-checkbox{
193
+ height: 18px;
194
+ width: 18px;
195
+ border-color: #B3BAC5;
196
+ border-radius: 2px;
153
197
  }
154
198
  .cap-unified-tree-select .select-popup-container .ant-select-tree-switcher-noop,
155
199
  .cap-unified-tree-select .multiSelect-popup-container .ant-select-tree-switcher-noop {
156
- display: none !important;
200
+ display: none;
157
201
  }
158
- .ant-tree-select-dropdown .treeSelect-popup-container .ant-select-tree .ant-select-tree-treenode{
159
- margin: 0px !important;
202
+ .cap-unified-tree-select .multiSelect-popup-container .ant-select-tree-treenode{
203
+ padding-left: 15px;
160
204
  }
161
205
  .ant-tree-select-dropdown .ant-select-tree .ant-select-tree-treenode{
162
- line-height: 40px !important;
163
- margin-bottom: 0px !important;
206
+ line-height: 40px;
207
+ margin-bottom: 0px;
208
+ .ant-select-tree-checkbox .ant-select-tree-checkbox-inner{
209
+ height: 18px;
210
+ width: 18px;
211
+ border: 2px solid #B3BAC5;
212
+ }
213
+ &:hover{
214
+ background-color: #FFFBE6;
215
+ border-radius: 4px;
216
+ }
217
+ &:not(.ant-select-tree-treenode-disabled) .ant-select-tree-node-content-wrapper:hover{
218
+ background-color: none;
219
+ }
164
220
  }
165
- .cap-unified-tree-select .multiSelect-popup-container .ant-tree-select-dropdown .ant-select-tree .ant-select-tree-treenode{
166
- margin-left: 10px !important;
221
+ .ant-tree-select-dropdown .ant-select-tree .ant-select-tree-node-content-wrapper{
222
+ border-radius: 0px;
223
+ padding-left: 12px;
167
224
  }
168
- .multiSelect-popup-container .ant-select-tree-treenode{
169
- margin-left: 10px !important;
225
+ .ant-select-tree-treenode.ant-select-tree-treenode-selected{
226
+ background-color: #E9F0FE;
227
+ color: #2466EA;
170
228
  }
171
229
  .cap-unified-select-no-result{
172
230
  display: flex;
@@ -186,42 +244,84 @@ export const selectStyles = css`
186
244
  font-weight: 500;
187
245
  }
188
246
  .ant-tree-select:hover .ant-select-selector {
189
- border-color: #7A869A !important;
247
+ border-color: #7A869A;
190
248
  }
191
249
  .ant-tree-select-focused .ant-select-selector,
192
250
  .ant-tree-select-open .ant-select-selector {
193
- border-color: #7A869A !important;
194
- box-shadow: none !important;
195
- outline: none !important; /* remove blue outline */
251
+ border-color: #7A869A;
252
+ box-shadow: none;
253
+ outline: none;
196
254
  }
197
255
  .cap-unified-select-search-container{
198
256
  border-bottom: 1px solid #EBECF0 !important;
199
257
  line-height: 40px !important;
258
+ .ant-input-affix-wrapper{
259
+ padding-left: 8px;
260
+ }
200
261
  }
201
262
  .cap-unified-select-upload-button{
202
- color: ${styledVars.CAP_BLUE01} !important;
203
- display: flex !important;
204
- align-items: center !important;
205
- font-size: 14px !important;
206
- font-weight: 400 !important;
207
- line-height: 20px !important;
208
- }
209
- .cap-unified-select-confirm-container{
210
- display: flex !important;
211
- justify-content: space-between !important;
212
- align-items: center !important;
213
- padding: 8px 12px !important;
214
- border-top: 1px solid #f0f0f0 !important;
215
- }
216
- .cap-unified-select-confirm-button{
217
- margin-right: 8px !important;
218
- }
219
- .cap-unified-select-selected-count{
220
- color: ${styledVars.CAP_G05} !important;
221
- font-size: 14px !important;
263
+ border: none;
264
+ padding-left: 15px;
265
+ }
266
+ .cap-unified-select-confirm-container {
267
+ display: flex;
268
+ align-items: center;
269
+ height: 48px;
270
+ padding: 7px;
271
+ border-top: 1px solid #EBECF0;
272
+ }
273
+ .cap-unified-select-confirm-button-group {
274
+ display: flex;
275
+ padding-left: 8px;
276
+ align-items: center;
277
+ width: 100%; /* so it can push the label */
278
+ button{
279
+ height: 32px;
280
+ width: 94px;
281
+ }
282
+ .cap-unified-select-confirm-button{
283
+ background-color: #6ebd6e;
284
+ }
285
+ .cap-unified-select-cancel-button{
286
+ border: transparent;
287
+ box-shadow: none;
288
+ }
289
+ }
290
+ .cap-unified-select-selected-count {
291
+ display: flex;
292
+ margin-left: auto; /* pushes to far right */
293
+ font-size: 12px;
294
+ font-weight: 400;
295
+ line-height: 16px;
296
+ color: #5E6C84;
222
297
  }
223
298
  .cap-unified-select-status{
224
- color: #E83135 !important;
299
+ color: #E83135;
300
+ }
301
+ .cap-unified-select-search-container {
302
+ .ant-input-affix-wrapper {
303
+ border: none;
304
+ box-shadow: none;
305
+ border-radius: 0;
306
+ }
307
+
308
+ .ant-input-affix-wrapper:hover {
309
+ border: none;
310
+ box-shadow: none;
311
+ border-bottom: 1px solid #EBECF0;
312
+ }
313
+
314
+ .ant-input-affix-wrapper:focus-within {
315
+ border: none;
316
+ box-shadow: none;
317
+ border-bottom: 1px solid #091E42;
318
+ outline: none;
319
+ }
320
+
321
+ .ant-input {
322
+ border: none !important;
323
+ box-shadow: none !important;
324
+ }
225
325
  }
226
326
  }
227
327
  `;
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.43",
4
+ "version": "0.1.6-alpha.45",
5
5
  "description": "Capillary UI component library with Ant Design v5",
6
6
  "main": "./index.js",
7
7
  "sideEffects": [