@bitrise/bitkit 13.46.0 → 13.47.0
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/package.json +1 -1
- package/src/Components/Dropdown/Dropdown.theme.ts +158 -81
- package/src/Components/Dropdown/Dropdown.tsx +85 -40
- package/src/Components/Dropdown/DropdownButton.tsx +68 -7
- package/src/Components/Dropdown/DropdownProps.ts +37 -0
- package/src/Components/Form/Form.theme.ts +7 -3
- package/src/Components/Icon/Icon.tsx +2 -2
- package/src/Components/Icons/24x24/SelectChevron.tsx +14 -0
- package/src/Components/Icons/24x24/index.ts +1 -0
- package/src/index.ts +1 -1
package/package.json
CHANGED
|
@@ -1,90 +1,167 @@
|
|
|
1
|
+
import { DropdownProps } from './DropdownProps';
|
|
2
|
+
|
|
3
|
+
type DropdownStateProps = Pick<DropdownProps<string | null>, 'disabled' | 'readOnly' | 'isWarning' | 'isError'> & {
|
|
4
|
+
placeholder: boolean;
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const getCursor = ({ readOnly, disabled }: DropdownStateProps) => {
|
|
9
|
+
if (disabled) {
|
|
10
|
+
return 'not-allowed';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (readOnly) {
|
|
14
|
+
return 'default';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return 'pointer';
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const getBorderColor = ({ readOnly, disabled, isError }: DropdownStateProps) => {
|
|
21
|
+
if (isError) {
|
|
22
|
+
return 'border/error';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (readOnly || disabled) {
|
|
26
|
+
return 'border/disabled';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return 'border/strong';
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const getIconColor = ({ disabled, isOpen, readOnly }: DropdownStateProps) => {
|
|
33
|
+
if (isOpen) {
|
|
34
|
+
return 'icon/primary';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (disabled || readOnly) {
|
|
38
|
+
return 'icon/on-disabled';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return 'icon/secondary';
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const getHelperTextColor = ({ disabled, isWarning }: DropdownStateProps) => {
|
|
45
|
+
if (isWarning) {
|
|
46
|
+
return 'text/body';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (disabled) {
|
|
50
|
+
return 'text/disabled';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return 'input/text/helper';
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const getButtonContentColor = ({ disabled, placeholder }: DropdownStateProps) => {
|
|
57
|
+
if (disabled) {
|
|
58
|
+
return 'text/disabled';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (placeholder) {
|
|
62
|
+
return 'text/secondary';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return 'input/text/inputValue';
|
|
66
|
+
};
|
|
67
|
+
|
|
1
68
|
const DropdownTheme = {
|
|
2
|
-
baseStyle: (
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
69
|
+
baseStyle: (props: DropdownStateProps) => {
|
|
70
|
+
const { disabled, readOnly, isError } = props;
|
|
71
|
+
return {
|
|
72
|
+
field: {
|
|
73
|
+
_hover:
|
|
74
|
+
disabled || readOnly || isError
|
|
75
|
+
? undefined
|
|
76
|
+
: {
|
|
77
|
+
borderColor: 'border/hover',
|
|
78
|
+
color: 'text/primary',
|
|
79
|
+
},
|
|
80
|
+
alignItems: 'center',
|
|
81
|
+
backgroundColor: disabled || readOnly ? 'background/disabled' : 'transparent',
|
|
82
|
+
border: '0.0625rem solid',
|
|
83
|
+
borderColor: getBorderColor(props),
|
|
84
|
+
borderRadius: '4',
|
|
85
|
+
cursor: getCursor(props),
|
|
86
|
+
display: 'flex',
|
|
87
|
+
position: 'relative',
|
|
88
|
+
textAlign: 'start',
|
|
89
|
+
width: '100%',
|
|
90
|
+
},
|
|
91
|
+
buttonContent: {
|
|
92
|
+
color: getButtonContentColor(props),
|
|
93
|
+
},
|
|
94
|
+
buttonContentHover: {
|
|
95
|
+
color: disabled || readOnly ? undefined : 'text/primary',
|
|
96
|
+
},
|
|
97
|
+
group: {
|
|
98
|
+
alignItems: 'center',
|
|
99
|
+
display: 'flex',
|
|
100
|
+
flexDir: 'row',
|
|
101
|
+
gap: '12',
|
|
102
|
+
paddingX: '16',
|
|
103
|
+
paddingY: '8',
|
|
104
|
+
},
|
|
105
|
+
helperText: {
|
|
106
|
+
color: getHelperTextColor(props),
|
|
107
|
+
},
|
|
108
|
+
icon: {
|
|
109
|
+
color: getIconColor(props),
|
|
110
|
+
_groupHover: {
|
|
111
|
+
color: disabled || readOnly ? 'icon/on-disabled' : 'icon/primary',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
item: {
|
|
115
|
+
'&.bitkit-select__option-active': {
|
|
116
|
+
'&.bitkit-select__option-hover': {
|
|
117
|
+
backgroundColor: 'purple.93',
|
|
14
118
|
},
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
border: '0.0625rem solid',
|
|
18
|
-
borderColor: 'neutral.90',
|
|
19
|
-
borderRadius: '4',
|
|
20
|
-
color: disabled ? 'neutral.70' : 'purple.10',
|
|
21
|
-
display: 'flex',
|
|
22
|
-
pointerEvents: disabled && 'none',
|
|
23
|
-
position: 'relative',
|
|
24
|
-
textAlign: 'start',
|
|
25
|
-
width: '100%',
|
|
26
|
-
},
|
|
27
|
-
group: {
|
|
28
|
-
alignItems: 'center',
|
|
29
|
-
display: 'flex',
|
|
30
|
-
flexDir: 'row',
|
|
31
|
-
gap: '12',
|
|
32
|
-
paddingX: '16',
|
|
33
|
-
paddingY: '8',
|
|
34
|
-
},
|
|
35
|
-
icon: {
|
|
36
|
-
opacity: disabled && '0.2',
|
|
37
|
-
},
|
|
38
|
-
item: {
|
|
39
|
-
'&.bitkit-select__option-active': {
|
|
119
|
+
backgroundColor: 'purple.95',
|
|
120
|
+
},
|
|
40
121
|
'&.bitkit-select__option-hover': {
|
|
41
|
-
backgroundColor: '
|
|
122
|
+
backgroundColor: 'neutral.95',
|
|
42
123
|
},
|
|
43
|
-
|
|
124
|
+
_disabled: {
|
|
125
|
+
color: 'neutral.70',
|
|
126
|
+
cursor: 'not-allowed',
|
|
127
|
+
},
|
|
128
|
+
color: 'purple.10',
|
|
129
|
+
cursor: 'pointer',
|
|
130
|
+
paddingX: '16',
|
|
131
|
+
paddingY: '8',
|
|
132
|
+
textAlign: 'start',
|
|
133
|
+
userSelect: 'none',
|
|
134
|
+
w: '100%',
|
|
135
|
+
wordBreak: 'break-word',
|
|
44
136
|
},
|
|
45
|
-
|
|
46
|
-
backgroundColor: 'neutral.
|
|
137
|
+
list: {
|
|
138
|
+
backgroundColor: 'neutral.100',
|
|
139
|
+
border: '1px solid',
|
|
140
|
+
borderColor: 'neutral.93',
|
|
141
|
+
borderRadius: '4',
|
|
142
|
+
boxShadow: 'large',
|
|
143
|
+
display: 'flex',
|
|
144
|
+
flexDir: 'column',
|
|
145
|
+
flexShrink: 1,
|
|
146
|
+
maxH: 'max(min(var(--dropdown-floating-max, 16rem), var(--floating-available-height)), var(--dropdown-floating-min, 10rem))',
|
|
147
|
+
minH: 0,
|
|
148
|
+
zIndex: '1',
|
|
47
149
|
},
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
150
|
+
options: {
|
|
151
|
+
flexShrink: 1,
|
|
152
|
+
overflowY: 'auto',
|
|
153
|
+
paddingY: '12',
|
|
154
|
+
position: 'relative',
|
|
51
155
|
},
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
wordBreak: 'break-word',
|
|
60
|
-
},
|
|
61
|
-
list: {
|
|
62
|
-
backgroundColor: 'neutral.100',
|
|
63
|
-
border: '1px solid',
|
|
64
|
-
borderColor: 'neutral.93',
|
|
65
|
-
borderRadius: '4',
|
|
66
|
-
boxShadow: 'large',
|
|
67
|
-
display: 'flex',
|
|
68
|
-
flexDir: 'column',
|
|
69
|
-
flexShrink: 1,
|
|
70
|
-
maxH: 'max(min(var(--dropdown-floating-max, 16rem), var(--floating-available-height)), var(--dropdown-floating-min, 10rem))',
|
|
71
|
-
minH: 0,
|
|
72
|
-
zIndex: '1',
|
|
73
|
-
},
|
|
74
|
-
options: {
|
|
75
|
-
flexShrink: 1,
|
|
76
|
-
overflowY: 'auto',
|
|
77
|
-
paddingY: '12',
|
|
78
|
-
position: 'relative',
|
|
79
|
-
},
|
|
80
|
-
search: {
|
|
81
|
-
marginTop: '12',
|
|
82
|
-
mx: 16,
|
|
83
|
-
width: 'auto',
|
|
84
|
-
},
|
|
85
|
-
}),
|
|
156
|
+
search: {
|
|
157
|
+
marginTop: '12',
|
|
158
|
+
mx: 16,
|
|
159
|
+
width: 'auto',
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
},
|
|
86
163
|
sizes: {
|
|
87
|
-
|
|
164
|
+
lg: {
|
|
88
165
|
field: {
|
|
89
166
|
fontSize: '3',
|
|
90
167
|
gap: '0.625rem',
|
|
@@ -93,11 +170,11 @@ const DropdownTheme = {
|
|
|
93
170
|
paddingRight: '16',
|
|
94
171
|
},
|
|
95
172
|
},
|
|
96
|
-
|
|
173
|
+
md: {
|
|
97
174
|
field: {
|
|
98
175
|
fontSize: '2',
|
|
99
176
|
gap: '0.375rem',
|
|
100
|
-
height: '
|
|
177
|
+
height: '40',
|
|
101
178
|
paddingLeft: '12',
|
|
102
179
|
paddingRight: '12',
|
|
103
180
|
},
|
|
@@ -1,7 +1,24 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import React, {
|
|
2
|
+
cloneElement,
|
|
3
|
+
forwardRef,
|
|
4
|
+
ReactNode,
|
|
5
|
+
useCallback,
|
|
6
|
+
useEffect,
|
|
7
|
+
useId,
|
|
8
|
+
useMemo,
|
|
9
|
+
useRef,
|
|
10
|
+
useState,
|
|
11
|
+
} from 'react';
|
|
12
|
+
import {
|
|
13
|
+
chakra,
|
|
14
|
+
FormControl,
|
|
15
|
+
FormErrorMessage,
|
|
16
|
+
FormHelperText,
|
|
17
|
+
FormLabel,
|
|
18
|
+
useControllableState,
|
|
19
|
+
useMultiStyleConfig,
|
|
20
|
+
} from '@chakra-ui/react';
|
|
21
|
+
import { FloatingFocusManager } from '@floating-ui/react-dom-interactions';
|
|
5
22
|
import SearchInput from '../SearchInput/SearchInput';
|
|
6
23
|
import { DropdownEventArgs, DropdownProvider, useDropdownContext, useDropdownStyles } from './Dropdown.context';
|
|
7
24
|
import { DropdownDetailedOption, DropdownGroup, DropdownOption, DropdownOptionProps } from './DropdownOption';
|
|
@@ -9,6 +26,7 @@ import DropdownButton from './DropdownButton';
|
|
|
9
26
|
import useFloatingDropdown from './hooks/useFloatingDropdown';
|
|
10
27
|
import { NoResultsFound, useSimpleSearch } from './hooks/useSimpleSearch';
|
|
11
28
|
import { isSearchable } from './isNodeMatch';
|
|
29
|
+
import { DropdownProps } from './DropdownProps';
|
|
12
30
|
|
|
13
31
|
type DropdownSearchCustomProps = {
|
|
14
32
|
value: string;
|
|
@@ -62,31 +80,6 @@ const DropdownSearch = ({
|
|
|
62
80
|
};
|
|
63
81
|
export { DropdownOption, DropdownGroup, DropdownSearch, NoResultsFound, DropdownDetailedOption };
|
|
64
82
|
|
|
65
|
-
type DropdownInstance<T> = { value: T; name?: string };
|
|
66
|
-
type DropdownChangeEventHandler<T> = (ev: { target: DropdownInstance<T> }) => void;
|
|
67
|
-
export interface DropdownProps<T> extends ChakraProps {
|
|
68
|
-
id?: string;
|
|
69
|
-
name?: string;
|
|
70
|
-
onChange?: DropdownChangeEventHandler<T>;
|
|
71
|
-
onBlur?: DropdownChangeEventHandler<T>;
|
|
72
|
-
value?: T;
|
|
73
|
-
defaultValue?: T;
|
|
74
|
-
size?: 'small' | 'medium';
|
|
75
|
-
dropdownMaxHeight?: ChakraProps['maxH'];
|
|
76
|
-
dropdownMinHeight?: ChakraProps['minH'];
|
|
77
|
-
dropdownWidth?: ChakraProps['width'] | 'match';
|
|
78
|
-
placement?: UseFloatingProps['placement'];
|
|
79
|
-
readOnly?: boolean;
|
|
80
|
-
disabled?: boolean;
|
|
81
|
-
placeholder?: string;
|
|
82
|
-
'aria-label'?: string;
|
|
83
|
-
search?: ReactNode;
|
|
84
|
-
children?: ReactNode;
|
|
85
|
-
iconName?: TypeIconName;
|
|
86
|
-
formLabel?: ReactNode;
|
|
87
|
-
returnFocus?: boolean;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
83
|
function useOptionListWithIndexes({ children }: { children: ReactNode }) {
|
|
91
84
|
return useMemo(() => {
|
|
92
85
|
const childList = React.Children.toArray(children);
|
|
@@ -255,17 +248,30 @@ function useDropdown<T>({
|
|
|
255
248
|
const Dropdown = forwardRef<Element, DropdownProps<string | null>>(
|
|
256
249
|
(
|
|
257
250
|
{
|
|
251
|
+
'aria-label': ariaLabel,
|
|
252
|
+
buttonProps = {},
|
|
253
|
+
defaultValue,
|
|
254
|
+
disabled,
|
|
258
255
|
dropdownMaxHeight,
|
|
259
256
|
dropdownMinHeight,
|
|
260
257
|
dropdownWidth,
|
|
258
|
+
errorText,
|
|
261
259
|
formLabel: customFormLabel,
|
|
260
|
+
helperText,
|
|
261
|
+
iconName,
|
|
262
|
+
isError,
|
|
263
|
+
isWarning,
|
|
264
|
+
label,
|
|
262
265
|
name,
|
|
263
266
|
onBlur,
|
|
267
|
+
onChange,
|
|
264
268
|
placeholder,
|
|
269
|
+
placement,
|
|
265
270
|
readOnly,
|
|
266
271
|
returnFocus = true,
|
|
267
272
|
search,
|
|
268
|
-
size
|
|
273
|
+
size,
|
|
274
|
+
value,
|
|
269
275
|
...props
|
|
270
276
|
},
|
|
271
277
|
ref,
|
|
@@ -283,14 +289,28 @@ const Dropdown = forwardRef<Element, DropdownProps<string | null>>(
|
|
|
283
289
|
searchRef,
|
|
284
290
|
...rest
|
|
285
291
|
} = useDropdown({
|
|
292
|
+
defaultValue,
|
|
286
293
|
dropdownWidth,
|
|
294
|
+
isWarning,
|
|
287
295
|
name,
|
|
296
|
+
onChange,
|
|
288
297
|
optionsRef,
|
|
298
|
+
placement,
|
|
289
299
|
readOnly,
|
|
290
300
|
ref,
|
|
301
|
+
value,
|
|
291
302
|
...props,
|
|
292
303
|
});
|
|
293
|
-
const dropdownStyles = useMultiStyleConfig('Dropdown', {
|
|
304
|
+
const dropdownStyles = useMultiStyleConfig('Dropdown', {
|
|
305
|
+
disabled,
|
|
306
|
+
isError,
|
|
307
|
+
isOpen,
|
|
308
|
+
isWarning,
|
|
309
|
+
placeholder: !formLabel,
|
|
310
|
+
readOnly,
|
|
311
|
+
size,
|
|
312
|
+
...rest,
|
|
313
|
+
});
|
|
294
314
|
|
|
295
315
|
const blurHandler = () => {
|
|
296
316
|
if (!onBlur) {
|
|
@@ -309,19 +329,40 @@ const Dropdown = forwardRef<Element, DropdownProps<string | null>>(
|
|
|
309
329
|
[dropdownMinHeight, dropdownMaxHeight, dropdownStyles.list],
|
|
310
330
|
);
|
|
311
331
|
const searchElement = search === false ? null : search || <DropdownSearch />;
|
|
332
|
+
const buttonId = useId();
|
|
312
333
|
return (
|
|
313
334
|
<>
|
|
314
335
|
{name && formValue && <input name={name} type="hidden" value={formValue} />}
|
|
315
336
|
<DropdownProvider context={dropdownCtx} styles={dropdownStyles}>
|
|
316
|
-
<
|
|
317
|
-
{
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
337
|
+
<FormControl {...props} isDisabled={disabled} isInvalid={isError}>
|
|
338
|
+
{label && (
|
|
339
|
+
<FormLabel htmlFor={disabled || readOnly ? undefined : buttonId} marginBlockEnd="4">
|
|
340
|
+
{label}
|
|
341
|
+
</FormLabel>
|
|
342
|
+
)}
|
|
343
|
+
<DropdownButton
|
|
344
|
+
{...referenceProps}
|
|
345
|
+
{...buttonProps}
|
|
346
|
+
aria-label={ariaLabel}
|
|
347
|
+
id={buttonId}
|
|
348
|
+
iconName={iconName}
|
|
349
|
+
blurHandler={blurHandler}
|
|
350
|
+
disabled={disabled}
|
|
351
|
+
formLabel={customFormLabel ?? formLabel}
|
|
352
|
+
placeholder={placeholder}
|
|
353
|
+
readOnly={readOnly}
|
|
354
|
+
isError={isError}
|
|
355
|
+
isOpen={isOpen}
|
|
356
|
+
isWarning={isWarning}
|
|
357
|
+
size={size}
|
|
358
|
+
/>
|
|
359
|
+
{errorText && <FormErrorMessage as="p">{errorText}</FormErrorMessage>}
|
|
360
|
+
{!errorText && helperText && (
|
|
361
|
+
<FormHelperText data-disabled={disabled} as="p">
|
|
362
|
+
{helperText}
|
|
363
|
+
</FormHelperText>
|
|
364
|
+
)}
|
|
365
|
+
</FormControl>
|
|
325
366
|
{isOpen && (
|
|
326
367
|
<FloatingFocusManager context={floatingContext} initialFocus={searchRef} returnFocus={returnFocus}>
|
|
327
368
|
<chakra.div {...floatingProps} sx={listStyles}>
|
|
@@ -338,6 +379,10 @@ const Dropdown = forwardRef<Element, DropdownProps<string | null>>(
|
|
|
338
379
|
},
|
|
339
380
|
);
|
|
340
381
|
|
|
382
|
+
Dropdown.defaultProps = {
|
|
383
|
+
size: 'lg',
|
|
384
|
+
} as DropdownProps<string | null>;
|
|
385
|
+
|
|
341
386
|
export function typedDropdown<T>() {
|
|
342
387
|
return {
|
|
343
388
|
Dropdown: Dropdown as React.ForwardRefExoticComponent<DropdownProps<T> & React.RefAttributes<Element>>,
|
|
@@ -2,27 +2,88 @@ import { forwardRef, ReactNode } from 'react';
|
|
|
2
2
|
import { chakra, ChakraProps } from '@chakra-ui/react';
|
|
3
3
|
import Icon, { TypeIconName } from '../Icon/Icon';
|
|
4
4
|
import { useDropdownStyles } from './Dropdown.context';
|
|
5
|
+
import { DropdownProps } from './DropdownProps';
|
|
5
6
|
|
|
6
7
|
interface DropdownButtonProps extends ChakraProps {
|
|
8
|
+
'aria-label'?: string;
|
|
7
9
|
blurHandler: () => void;
|
|
10
|
+
id?: string;
|
|
8
11
|
readOnly?: boolean;
|
|
9
12
|
placeholder?: string;
|
|
10
13
|
formLabel?: ReactNode;
|
|
11
|
-
size:
|
|
14
|
+
size: DropdownProps<string | null>['size'];
|
|
12
15
|
children?: ReactNode;
|
|
13
16
|
iconName?: TypeIconName;
|
|
17
|
+
isWarning?: boolean;
|
|
18
|
+
isOpen?: boolean;
|
|
19
|
+
isError?: boolean;
|
|
20
|
+
disabled?: boolean;
|
|
14
21
|
}
|
|
15
22
|
const DropdownButton = forwardRef<HTMLButtonElement, DropdownButtonProps>(
|
|
16
|
-
(
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
(
|
|
24
|
+
{
|
|
25
|
+
blurHandler,
|
|
26
|
+
children,
|
|
27
|
+
disabled,
|
|
28
|
+
formLabel,
|
|
29
|
+
iconName,
|
|
30
|
+
placeholder,
|
|
31
|
+
readOnly,
|
|
32
|
+
size,
|
|
33
|
+
isWarning,
|
|
34
|
+
isError,
|
|
35
|
+
isOpen,
|
|
36
|
+
...rest
|
|
37
|
+
},
|
|
38
|
+
ref,
|
|
39
|
+
) => {
|
|
40
|
+
const { field, buttonContent, buttonContentHover, icon } = useDropdownStyles();
|
|
41
|
+
const iconSize = size === 'lg' ? '24' : '16';
|
|
42
|
+
|
|
43
|
+
const chevronStyle = {
|
|
44
|
+
...icon,
|
|
45
|
+
transform: isOpen ? 'rotate(180deg)' : undefined,
|
|
46
|
+
transition: 'transform 0.2s ease',
|
|
47
|
+
};
|
|
48
|
+
|
|
19
49
|
return (
|
|
20
|
-
<chakra.button
|
|
50
|
+
<chakra.button
|
|
51
|
+
ref={ref}
|
|
52
|
+
__css={field}
|
|
53
|
+
aria-readonly={readOnly}
|
|
54
|
+
disabled={disabled}
|
|
55
|
+
onBlur={blurHandler}
|
|
56
|
+
role={readOnly ? undefined : 'group'}
|
|
57
|
+
type="button"
|
|
58
|
+
{...rest}
|
|
59
|
+
>
|
|
21
60
|
{iconName && <Icon __css={icon} aria-hidden="true" name={iconName} size={iconSize} />}
|
|
22
|
-
<chakra.span
|
|
61
|
+
<chakra.span
|
|
62
|
+
__css={buttonContent}
|
|
63
|
+
_groupHover={buttonContentHover}
|
|
64
|
+
flexGrow={1}
|
|
65
|
+
overflow="hidden"
|
|
66
|
+
textOverflow="ellipsis"
|
|
67
|
+
whiteSpace="nowrap"
|
|
68
|
+
>
|
|
23
69
|
{formLabel || placeholder}
|
|
24
70
|
</chakra.span>
|
|
25
|
-
<Icon
|
|
71
|
+
{!isError && isWarning && <Icon aria-hidden="true" name="WarningColored" size={iconSize} />}
|
|
72
|
+
{isError && <Icon aria-hidden="true" color="icon/negative" name="ErrorCircleFilled" size={iconSize} />}
|
|
73
|
+
<Icon
|
|
74
|
+
__css={chevronStyle}
|
|
75
|
+
_groupActive={
|
|
76
|
+
readOnly || disabled
|
|
77
|
+
? undefined
|
|
78
|
+
: {
|
|
79
|
+
transform: 'rotate(180deg)',
|
|
80
|
+
transition: 'transform 0.2s ease',
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
aria-hidden="true"
|
|
84
|
+
name="SelectChevron"
|
|
85
|
+
size="24"
|
|
86
|
+
/>
|
|
26
87
|
</chakra.button>
|
|
27
88
|
);
|
|
28
89
|
},
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ChakraProps } from '@chakra-ui/react';
|
|
3
|
+
import { UseFloatingProps } from '@floating-ui/react-dom-interactions';
|
|
4
|
+
import { TypeIconName } from '../Icon/Icon';
|
|
5
|
+
|
|
6
|
+
type DropdownInstance<T> = { value: T; name?: string };
|
|
7
|
+
|
|
8
|
+
type DropdownChangeEventHandler<T> = (ev: { target: DropdownInstance<T> }) => void;
|
|
9
|
+
|
|
10
|
+
export interface DropdownProps<T> extends ChakraProps {
|
|
11
|
+
'aria-label'?: string;
|
|
12
|
+
buttonProps?: ChakraProps;
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
defaultValue?: T;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
dropdownMinHeight?: ChakraProps['minH'];
|
|
17
|
+
dropdownMaxHeight?: ChakraProps['maxH'];
|
|
18
|
+
dropdownWidth?: ChakraProps['width'] | 'match';
|
|
19
|
+
errorText?: ReactNode;
|
|
20
|
+
formLabel?: ReactNode;
|
|
21
|
+
helperText?: ReactNode;
|
|
22
|
+
iconName?: TypeIconName;
|
|
23
|
+
id?: string;
|
|
24
|
+
isError?: boolean;
|
|
25
|
+
isWarning?: boolean;
|
|
26
|
+
label?: ReactNode;
|
|
27
|
+
name?: string;
|
|
28
|
+
onBlur?: DropdownChangeEventHandler<T>;
|
|
29
|
+
onChange?: DropdownChangeEventHandler<T>;
|
|
30
|
+
placeholder?: string;
|
|
31
|
+
placement?: UseFloatingProps['placement'];
|
|
32
|
+
readOnly?: boolean;
|
|
33
|
+
returnFocus?: boolean;
|
|
34
|
+
search?: ReactNode;
|
|
35
|
+
size?: 'lg' | 'md';
|
|
36
|
+
value?: T;
|
|
37
|
+
}
|
|
@@ -5,7 +5,11 @@ const FormTheme = {
|
|
|
5
5
|
baseStyle: {
|
|
6
6
|
helperText: {
|
|
7
7
|
color: 'neutral.50',
|
|
8
|
+
_disabled: {
|
|
9
|
+
color: 'text/disabled',
|
|
10
|
+
},
|
|
8
11
|
marginTop: '4',
|
|
12
|
+
|
|
9
13
|
textStyle: 'comp/input/helperText',
|
|
10
14
|
},
|
|
11
15
|
} as ComponentStyleConfig,
|
|
@@ -13,7 +17,7 @@ const FormTheme = {
|
|
|
13
17
|
FormError: {
|
|
14
18
|
baseStyle: {
|
|
15
19
|
text: {
|
|
16
|
-
color: '
|
|
20
|
+
color: 'input/text/error',
|
|
17
21
|
marginTop: '4',
|
|
18
22
|
textStyle: 'comp/input/helperText',
|
|
19
23
|
},
|
|
@@ -22,9 +26,9 @@ const FormTheme = {
|
|
|
22
26
|
FormLabel: {
|
|
23
27
|
baseStyle: {
|
|
24
28
|
_disabled: {
|
|
25
|
-
color: '
|
|
29
|
+
color: 'text/disabled',
|
|
26
30
|
},
|
|
27
|
-
color: '
|
|
31
|
+
color: 'input/text/label',
|
|
28
32
|
textStyle: 'comp/input/label',
|
|
29
33
|
} as ComponentStyleConfig,
|
|
30
34
|
},
|
|
@@ -2,7 +2,7 @@ import { forwardRef, IconProps as ChakraIconProps } from '@chakra-ui/react';
|
|
|
2
2
|
import * as bigIcons from '../Icons/24x24';
|
|
3
3
|
import * as smallIcons from '../Icons/16x16';
|
|
4
4
|
|
|
5
|
-
export type TypeIconName = keyof typeof bigIcons
|
|
5
|
+
export type TypeIconName = keyof typeof bigIcons | keyof typeof smallIcons;
|
|
6
6
|
export interface IconProps extends ChakraIconProps {
|
|
7
7
|
name: TypeIconName;
|
|
8
8
|
size?: '16' | '24' | '32';
|
|
@@ -15,7 +15,7 @@ const Icon = forwardRef<IconProps, 'svg'>(({ name, size = '24', ...rest }, ref)
|
|
|
15
15
|
width: size,
|
|
16
16
|
...rest,
|
|
17
17
|
};
|
|
18
|
-
const ThisIcon = size === '16' ? smallIcons[name] : bigIcons[name];
|
|
18
|
+
const ThisIcon = size === '16' ? smallIcons[name as keyof typeof smallIcons] : bigIcons[name];
|
|
19
19
|
return <ThisIcon {...props} />;
|
|
20
20
|
});
|
|
21
21
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { forwardRef, Icon, IconProps } from '@chakra-ui/react';
|
|
2
|
+
|
|
3
|
+
const SelectChevron = forwardRef<IconProps, 'svg'>((props, ref) => (
|
|
4
|
+
<Icon ref={ref} viewBox="0 0 24 24" {...props}>
|
|
5
|
+
<path
|
|
6
|
+
fillRule="evenodd"
|
|
7
|
+
clipRule="evenodd"
|
|
8
|
+
d="M6.29285 10.2071L7.70706 8.79289L12 13.0858L16.2928 8.79289L17.7071 10.2071L12 15.9142L6.29285 10.2071Z"
|
|
9
|
+
fill="currentColor"
|
|
10
|
+
/>
|
|
11
|
+
</Icon>
|
|
12
|
+
));
|
|
13
|
+
|
|
14
|
+
export default SelectChevron;
|
|
@@ -183,6 +183,7 @@ export { default as Responsiveness } from './Responsiveness';
|
|
|
183
183
|
export { default as Save } from './Save';
|
|
184
184
|
export { default as Screenshare } from './Screenshare';
|
|
185
185
|
export { default as SecurityShield } from './SecurityShield';
|
|
186
|
+
export { default as SelectChevron } from './SelectChevron';
|
|
186
187
|
export { default as Settings } from './Settings';
|
|
187
188
|
export { default as SettingsSolid } from './SettingsSolid';
|
|
188
189
|
export { default as Ship } from './Ship';
|
package/src/index.ts
CHANGED
|
@@ -143,7 +143,7 @@ export { default as BreadcrumbLink } from './Components/Breadcrumb/BreadcrumbLin
|
|
|
143
143
|
export type { RibbonProps } from './Components/Ribbon/Ribbon';
|
|
144
144
|
export { default as Ribbon } from './Components/Ribbon/Ribbon';
|
|
145
145
|
|
|
146
|
-
export type { DropdownProps } from './Components/Dropdown/
|
|
146
|
+
export type { DropdownProps } from './Components/Dropdown/DropdownProps';
|
|
147
147
|
export {
|
|
148
148
|
default as Dropdown,
|
|
149
149
|
DropdownOption,
|