@coinbase/cds-mobile 8.25.0 → 8.26.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/CHANGELOG.md +19 -0
- package/dts/alpha/select/DefaultSelectControl.d.ts +2 -8
- package/dts/alpha/select/DefaultSelectControl.d.ts.map +1 -1
- package/dts/alpha/select/DefaultSelectDropdown.d.ts.map +1 -1
- package/dts/alpha/select/DefaultSelectOptionGroup.d.ts +8 -0
- package/dts/alpha/select/DefaultSelectOptionGroup.d.ts.map +1 -0
- package/dts/alpha/select/Select.d.ts +23 -366
- package/dts/alpha/select/Select.d.ts.map +1 -1
- package/dts/alpha/select/index.d.ts +2 -0
- package/dts/alpha/select/index.d.ts.map +1 -1
- package/dts/alpha/select/types.d.ts +486 -0
- package/dts/alpha/select/types.d.ts.map +1 -0
- package/dts/alpha/select-chip/SelectChip.d.ts +26 -0
- package/dts/alpha/select-chip/SelectChip.d.ts.map +1 -0
- package/dts/alpha/select-chip/SelectChipControl.d.ts +14 -0
- package/dts/alpha/select-chip/SelectChipControl.d.ts.map +1 -0
- package/dts/alpha/select-chip/index.d.ts +3 -0
- package/dts/alpha/select-chip/index.d.ts.map +1 -0
- package/dts/chips/Chip.d.ts.map +1 -1
- package/dts/chips/SelectChip.d.ts +8 -0
- package/dts/chips/SelectChip.d.ts.map +1 -1
- package/dts/examples/ExampleScreen.d.ts +26 -1
- package/dts/examples/ExampleScreen.d.ts.map +1 -1
- package/esm/alpha/select/DefaultSelectControl.js +46 -8
- package/esm/alpha/select/DefaultSelectDropdown.js +100 -31
- package/esm/alpha/select/DefaultSelectOption.js +1 -1
- package/esm/alpha/select/DefaultSelectOptionGroup.js +90 -0
- package/esm/alpha/select/Select.js +10 -26
- package/esm/alpha/select/index.js +3 -1
- package/esm/alpha/select/types.js +50 -0
- package/esm/alpha/select-chip/SelectChip.js +31 -0
- package/esm/alpha/select-chip/SelectChipControl.js +111 -0
- package/esm/alpha/select-chip/__stories__/SelectChip.stories.js +538 -0
- package/esm/alpha/select-chip/index.js +2 -0
- package/esm/banner/__stories__/Banner.stories.js +133 -294
- package/esm/banner/__stories__/BannerActions.stories.js +276 -0
- package/esm/banner/__stories__/BannerLayout.stories.js +329 -0
- package/esm/cells/__stories__/ListCell.stories.js +1 -17
- package/esm/cells/__stories__/ListCellFallback.stories.js +1 -0
- package/esm/chips/Chip.js +4 -1
- package/esm/chips/SelectChip.js +9 -0
- package/esm/examples/ExampleScreen.js +79 -58
- package/esm/icons/__stories__/IconSheet.js +35 -13
- package/esm/illustrations/__stories__/HeroSquare.stories.js +70 -2
- package/esm/illustrations/__stories__/Pictogram.stories.js +70 -2
- package/esm/illustrations/__stories__/SpotIcon.stories.js +70 -2
- package/esm/illustrations/__stories__/SpotRectangle.stories.js +68 -2
- package/esm/illustrations/__stories__/SpotSquare.stories.js +68 -2
- package/esm/media/__stories__/CarouselMedia.stories.js +2 -5
- package/esm/numpad/__stories__/Numpad.stories.js +8 -5
- package/esm/page/__stories__/PageFooter.stories.js +5 -4
- package/esm/page/__stories__/PageFooterInPage.stories.js +20 -19
- package/esm/page/__stories__/PageHeader.stories.js +4 -4
- package/esm/page/__stories__/PageHeaderInErrorEmptyState.stories.js +6 -4
- package/esm/page/__stories__/PageHeaderInPage.stories.js +20 -18
- package/esm/section-header/__stories__/SectionHeader.stories.js +4 -4
- package/esm/sticky-footer/__stories__/StickyFooter.stories.js +6 -8
- package/esm/tour/__stories__/Tour.stories.js +13 -166
- package/esm/typography/__stories__/TextBody.stories.js +2 -0
- package/esm/typography/__stories__/TextCaption.stories.js +2 -0
- package/esm/typography/__stories__/TextCore.stories.js +2 -0
- package/esm/typography/__stories__/TextDisplay1.stories.js +2 -0
- package/esm/typography/__stories__/TextDisplay2.stories.js +2 -0
- package/esm/typography/__stories__/TextDisplay3.stories.js +2 -0
- package/esm/typography/__stories__/TextHeadline.stories.js +2 -0
- package/esm/typography/__stories__/TextLabel1.stories.js +2 -0
- package/esm/typography/__stories__/TextLabel2.stories.js +2 -0
- package/esm/typography/__stories__/TextLegal.stories.js +2 -0
- package/esm/typography/__stories__/TextTitle1.stories.js +2 -0
- package/esm/typography/__stories__/TextTitle2.stories.js +2 -0
- package/esm/typography/__stories__/TextTitle3.stories.js +2 -0
- package/esm/typography/__stories__/TextTitle4.stories.js +2 -0
- package/package.json +2 -2
- package/esm/icons/__stories__/Icon.stories.js +0 -98
- package/esm/illustrations/__stories__/getIllustrationSheet.js +0 -164
- /package/esm/alpha/select/__stories__/{Select.stories.js → AlphaSelect.stories.js} +0 -0
- /package/esm/alpha/tabbed-chips/__stories__/{TabbedChips.stories.js → AlphaTabbedChips.stories.js} +0 -0
|
@@ -13,9 +13,11 @@ import { HStack } from '../../layout/HStack';
|
|
|
13
13
|
import { VStack } from '../../layout/VStack';
|
|
14
14
|
import { AnimatedCaret } from '../../motion/AnimatedCaret';
|
|
15
15
|
import { Text } from '../../typography/Text';
|
|
16
|
-
import {
|
|
16
|
+
import { isSelectOptionGroup } from './Select';
|
|
17
|
+
|
|
17
18
|
// The height is smaller for the inside label variant since the label takes
|
|
18
19
|
// up space above the input.
|
|
20
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
21
|
const LABEL_VARIANT_INSIDE_HEIGHT = 24;
|
|
20
22
|
const COMPACT_HEIGHT = 40;
|
|
21
23
|
const DEFAULT_HEIGHT = 56;
|
|
@@ -56,6 +58,42 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
|
|
|
56
58
|
const shouldShowCompactLabel = compact && label && !isMultiSelect;
|
|
57
59
|
const hasValue = value !== null && !(Array.isArray(value) && value.length === 0);
|
|
58
60
|
|
|
61
|
+
// Map of options to their values
|
|
62
|
+
// If multiple options share the same value, the first occurrence wins (matches native HTML select behavior)
|
|
63
|
+
const optionsMap = useMemo(() => {
|
|
64
|
+
const map = new Map();
|
|
65
|
+
const isDev = process.env.NODE_ENV !== 'production';
|
|
66
|
+
options.forEach((option, optionIndex) => {
|
|
67
|
+
if (isSelectOptionGroup(option)) {
|
|
68
|
+
option.options.forEach((groupOption, groupOptionIndex) => {
|
|
69
|
+
if (groupOption.value !== null) {
|
|
70
|
+
const optionValue = groupOption.value;
|
|
71
|
+
// Only set if not already present (first wins)
|
|
72
|
+
if (!map.has(optionValue)) {
|
|
73
|
+
map.set(optionValue, groupOption);
|
|
74
|
+
} else if (isDev) {
|
|
75
|
+
console.warn("[Select] Duplicate option value detected: \"" + optionValue + "\". " + "The first occurrence will be used for display. " + ("Found duplicate in group \"" + option.label + "\" at index " + groupOptionIndex + ". ") + ("First occurrence was at option index " + optionIndex + "."));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
const singleOption = option;
|
|
81
|
+
if (singleOption.value !== null) {
|
|
82
|
+
const optionValue = singleOption.value;
|
|
83
|
+
// Only set if not already present (first wins)
|
|
84
|
+
if (!map.has(optionValue)) {
|
|
85
|
+
map.set(optionValue, singleOption);
|
|
86
|
+
} else if (isDev) {
|
|
87
|
+
var _ref2, _existingOption$label;
|
|
88
|
+
const existingOption = map.get(optionValue);
|
|
89
|
+
console.warn("[Select] Duplicate option value detected: \"" + optionValue + "\". " + "The first occurrence will be used for display. " + ("Found duplicate at option index " + optionIndex + ". ") + ("First occurrence label: \"" + ((_ref2 = (_existingOption$label = existingOption == null ? void 0 : existingOption.label) != null ? _existingOption$label : existingOption == null ? void 0 : existingOption.value) != null ? _ref2 : 'unknown') + "\"."));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
return map;
|
|
95
|
+
}, [options]);
|
|
96
|
+
|
|
59
97
|
// Prop value doesn't have default value because it affects the color of the
|
|
60
98
|
// animated caret
|
|
61
99
|
const focusedVariant = useInputVariant(!!open, variant != null ? variant : 'foregroundMuted');
|
|
@@ -83,15 +121,15 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
|
|
|
83
121
|
})
|
|
84
122
|
}) : label, [disabled, label, labelVariant, setOpen, shouldShowCompactLabel, styles == null ? void 0 : styles.controlLabelNode]);
|
|
85
123
|
const valueNode = useMemo(() => {
|
|
86
|
-
var
|
|
124
|
+
var _ref5, _ref6, _option$label2;
|
|
87
125
|
if (hasValue && isMultiSelect) {
|
|
88
126
|
const valuesToShow = value.length <= maxSelectedOptionsToShow ? value : value.slice(0, maxSelectedOptionsToShow);
|
|
89
|
-
const optionsToShow = valuesToShow.map(value =>
|
|
127
|
+
const optionsToShow = valuesToShow.map(value => optionsMap.get(value)).filter(option => option !== undefined);
|
|
90
128
|
return /*#__PURE__*/_jsxs(HStack, {
|
|
91
129
|
flexWrap: "wrap",
|
|
92
130
|
gap: 1,
|
|
93
131
|
children: [optionsToShow.map(option => {
|
|
94
|
-
var _option$value,
|
|
132
|
+
var _option$value, _ref3, _ref4, _option$label;
|
|
95
133
|
const accessibilityLabel = typeof option.label === 'string' ? option.label : typeof option.description === 'string' ? option.description : (_option$value = option.value) != null ? _option$value : '';
|
|
96
134
|
return /*#__PURE__*/_jsx(InputChip, {
|
|
97
135
|
compact: true,
|
|
@@ -104,7 +142,7 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
|
|
|
104
142
|
event == null || event.stopPropagation();
|
|
105
143
|
onChange == null || onChange(option.value);
|
|
106
144
|
},
|
|
107
|
-
children: (
|
|
145
|
+
children: (_ref3 = (_ref4 = (_option$label = option.label) != null ? _option$label : option.description) != null ? _ref4 : option.value) != null ? _ref3 : ''
|
|
108
146
|
}, option.value);
|
|
109
147
|
}), value.length - maxSelectedOptionsToShow > 0 && /*#__PURE__*/_jsx(InputChip, {
|
|
110
148
|
compact: true,
|
|
@@ -115,8 +153,8 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
|
|
|
115
153
|
})]
|
|
116
154
|
});
|
|
117
155
|
}
|
|
118
|
-
const option =
|
|
119
|
-
const label = (
|
|
156
|
+
const option = !isMultiSelect ? optionsMap.get(value) : undefined;
|
|
157
|
+
const label = (_ref5 = (_ref6 = (_option$label2 = option == null ? void 0 : option.label) != null ? _option$label2 : option == null ? void 0 : option.description) != null ? _ref6 : option == null ? void 0 : option.value) != null ? _ref5 : placeholder;
|
|
120
158
|
const content = hasValue ? label : placeholder;
|
|
121
159
|
return typeof content === 'string' ? /*#__PURE__*/_jsx(Text, {
|
|
122
160
|
color: hasValue ? 'fg' : 'fgMuted',
|
|
@@ -125,7 +163,7 @@ export const DefaultSelectControlComponent = /*#__PURE__*/memo(/*#__PURE__*/forw
|
|
|
125
163
|
textAlign: shouldShowCompactLabel ? 'right' : 'left',
|
|
126
164
|
children: content
|
|
127
165
|
}) : content;
|
|
128
|
-
}, [hasValue, isMultiSelect,
|
|
166
|
+
}, [hasValue, isMultiSelect, optionsMap, placeholder, shouldShowCompactLabel, value, maxSelectedOptionsToShow, hiddenSelectedOptionsLabel, removeSelectedOptionAccessibilityLabel, onChange]);
|
|
129
167
|
const inputNode = useMemo(() => /*#__PURE__*/_jsx(TouchableOpacity, _extends({
|
|
130
168
|
ref: ref,
|
|
131
169
|
accessibilityHint: accessibilityHint,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const _excluded = ["type", "options", "value", "onChange", "open", "setOpen", "controlRef", "disabled", "style", "styles", "compact", "label", "end", "selectAllLabel", "emptyOptionsLabel", "clearAllLabel", "hideSelectAll", "accessory", "media", "SelectOptionComponent", "SelectAllOptionComponent", "SelectEmptyDropdownContentsComponent", "accessibilityRoles"],
|
|
2
|
-
_excluded2 = ["Component", "media", "accessory", "end"];
|
|
1
|
+
const _excluded = ["type", "options", "value", "onChange", "open", "setOpen", "controlRef", "disabled", "style", "styles", "compact", "label", "end", "selectAllLabel", "emptyOptionsLabel", "clearAllLabel", "hideSelectAll", "accessory", "media", "SelectOptionComponent", "SelectAllOptionComponent", "SelectEmptyDropdownContentsComponent", "SelectOptionGroupComponent", "accessibilityRoles"],
|
|
2
|
+
_excluded2 = ["Component", "media", "accessory", "end", "disabled"];
|
|
3
3
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
4
4
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
5
5
|
import { forwardRef, memo, useCallback, useMemo } from 'react';
|
|
@@ -12,7 +12,8 @@ import { Tray } from '../../overlays/tray/Tray';
|
|
|
12
12
|
import { DefaultSelectAllOption } from './DefaultSelectAllOption';
|
|
13
13
|
import { DefaultSelectEmptyDropdownContents } from './DefaultSelectEmptyDropdownContents';
|
|
14
14
|
import { DefaultSelectOption } from './DefaultSelectOption';
|
|
15
|
-
import {
|
|
15
|
+
import { DefaultSelectOptionGroup } from './DefaultSelectOptionGroup';
|
|
16
|
+
import { defaultAccessibilityRoles, isSelectOptionGroup } from './Select';
|
|
16
17
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
17
18
|
const DefaultSelectDropdownComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
18
19
|
let {
|
|
@@ -37,6 +38,7 @@ const DefaultSelectDropdownComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef
|
|
|
37
38
|
SelectOptionComponent = DefaultSelectOption,
|
|
38
39
|
SelectAllOptionComponent = DefaultSelectAllOption,
|
|
39
40
|
SelectEmptyDropdownContentsComponent = DefaultSelectEmptyDropdownContents,
|
|
41
|
+
SelectOptionGroupComponent = DefaultSelectOptionGroup,
|
|
40
42
|
accessibilityRoles = defaultAccessibilityRoles
|
|
41
43
|
} = _ref,
|
|
42
44
|
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
@@ -48,20 +50,65 @@ const DefaultSelectDropdownComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef
|
|
|
48
50
|
optionDescription: styles == null ? void 0 : styles.optionDescription,
|
|
49
51
|
selectAllDivider: styles == null ? void 0 : styles.selectAllDivider
|
|
50
52
|
}), [styles == null ? void 0 : styles.optionCell, styles == null ? void 0 : styles.optionContent, styles == null ? void 0 : styles.optionLabel, styles == null ? void 0 : styles.optionDescription, styles == null ? void 0 : styles.selectAllDivider]);
|
|
53
|
+
const optionGroupStyles = useMemo(() => ({
|
|
54
|
+
optionGroup: styles == null ? void 0 : styles.optionGroup,
|
|
55
|
+
option: styles == null ? void 0 : styles.option,
|
|
56
|
+
optionBlendStyles: styles == null ? void 0 : styles.optionBlendStyles,
|
|
57
|
+
optionCell: styles == null ? void 0 : styles.optionCell,
|
|
58
|
+
optionContent: styles == null ? void 0 : styles.optionContent,
|
|
59
|
+
optionLabel: styles == null ? void 0 : styles.optionLabel,
|
|
60
|
+
optionDescription: styles == null ? void 0 : styles.optionDescription,
|
|
61
|
+
selectAllDivider: styles == null ? void 0 : styles.selectAllDivider
|
|
62
|
+
}), [styles == null ? void 0 : styles.optionGroup, styles == null ? void 0 : styles.option, styles == null ? void 0 : styles.optionBlendStyles, styles == null ? void 0 : styles.optionCell, styles == null ? void 0 : styles.optionContent, styles == null ? void 0 : styles.optionLabel, styles == null ? void 0 : styles.optionDescription, styles == null ? void 0 : styles.selectAllDivider]);
|
|
51
63
|
const emptyDropdownContentsStyles = useMemo(() => ({
|
|
52
64
|
emptyContentsContainer: styles == null ? void 0 : styles.emptyContentsContainer,
|
|
53
65
|
emptyContentsText: styles == null ? void 0 : styles.emptyContentsText
|
|
54
66
|
}), [styles == null ? void 0 : styles.emptyContentsContainer, styles == null ? void 0 : styles.emptyContentsText]);
|
|
67
|
+
|
|
68
|
+
// Flatten options for Select All logic, excluding disabled options and options from disabled groups
|
|
69
|
+
const flatOptionsForSelectAll = useMemo(() => {
|
|
70
|
+
if (disabled) return [];
|
|
71
|
+
const result = [];
|
|
72
|
+
options.forEach(option => {
|
|
73
|
+
if (isSelectOptionGroup(option)) {
|
|
74
|
+
// It's a group, add its enabled options if the group itself is not disabled
|
|
75
|
+
if (!option.disabled) {
|
|
76
|
+
option.options.forEach(groupOption => {
|
|
77
|
+
if (!groupOption.disabled) {
|
|
78
|
+
result.push(groupOption);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
// It's a single option, add if not disabled
|
|
84
|
+
if (!option.disabled) {
|
|
85
|
+
result.push(option);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return result;
|
|
90
|
+
}, [options, disabled]);
|
|
55
91
|
const isMultiSelect = type === 'multi';
|
|
56
92
|
const isSomeOptionsSelected = isMultiSelect ? value.length > 0 : false;
|
|
57
|
-
|
|
93
|
+
// Only count non-disabled options when determining if all are selected
|
|
94
|
+
const enabledOptionsCount = flatOptionsForSelectAll.filter(o => o.value !== null).length;
|
|
95
|
+
const isAllOptionsSelected = isMultiSelect ? enabledOptionsCount > 0 && value.length === enabledOptionsCount : false;
|
|
58
96
|
const toggleSelectAll = useCallback(() => {
|
|
59
|
-
if (isAllOptionsSelected) onChange(null);else onChange(
|
|
60
|
-
|
|
97
|
+
if (isAllOptionsSelected) onChange(null);else onChange(flatOptionsForSelectAll.map(_ref2 => {
|
|
98
|
+
let {
|
|
99
|
+
value
|
|
100
|
+
} = _ref2;
|
|
101
|
+
return value;
|
|
102
|
+
}).filter(optionValue => optionValue !== null && !(value != null && value.includes(optionValue))));
|
|
103
|
+
}, [isAllOptionsSelected, onChange, flatOptionsForSelectAll, value]);
|
|
61
104
|
const handleClearAll = useCallback(event => {
|
|
62
105
|
event.stopPropagation();
|
|
63
106
|
onChange(null);
|
|
64
107
|
}, [onChange]);
|
|
108
|
+
const handleOptionPress = useCallback(newValue => {
|
|
109
|
+
onChange(newValue);
|
|
110
|
+
if (!isMultiSelect) setOpen(false);
|
|
111
|
+
}, [onChange, isMultiSelect, setOpen]);
|
|
65
112
|
const indeterminate = !isAllOptionsSelected && isSomeOptionsSelected ? true : false;
|
|
66
113
|
const SelectAllOption = useMemo(() => /*#__PURE__*/_jsx(SelectAllOptionComponent, {
|
|
67
114
|
accessibilityRole: accessibilityRoles == null ? void 0 : accessibilityRoles.option,
|
|
@@ -83,10 +130,11 @@ const DefaultSelectDropdownComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef
|
|
|
83
130
|
children: clearAllLabel
|
|
84
131
|
}),
|
|
85
132
|
indeterminate: indeterminate,
|
|
86
|
-
label: selectAllLabel + " (" +
|
|
133
|
+
label: selectAllLabel + " (" + flatOptionsForSelectAll.filter(o => o.value !== null).length + ")",
|
|
87
134
|
media: media != null ? media : /*#__PURE__*/_jsx(Checkbox, {
|
|
88
135
|
checked: isAllOptionsSelected,
|
|
89
136
|
indeterminate: indeterminate,
|
|
137
|
+
onPress: toggleSelectAll,
|
|
90
138
|
tabIndex: -1
|
|
91
139
|
}),
|
|
92
140
|
onPress: toggleSelectAll,
|
|
@@ -95,7 +143,7 @@ const DefaultSelectDropdownComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef
|
|
|
95
143
|
styles: optionStyles,
|
|
96
144
|
type: type,
|
|
97
145
|
value: 'select-all'
|
|
98
|
-
}, "select-all"), [SelectAllOptionComponent, accessibilityRoles == null ? void 0 : accessibilityRoles.option, accessory, styles == null ? void 0 : styles.optionBlendStyles, styles == null ? void 0 : styles.option, compact, end, handleClearAll, clearAllLabel,
|
|
146
|
+
}, "select-all"), [SelectAllOptionComponent, accessibilityRoles == null ? void 0 : accessibilityRoles.option, accessory, styles == null ? void 0 : styles.optionBlendStyles, styles == null ? void 0 : styles.option, compact, disabled, end, handleClearAll, clearAllLabel, indeterminate, selectAllLabel, flatOptionsForSelectAll, media, isAllOptionsSelected, toggleSelectAll, optionStyles, type]);
|
|
99
147
|
if (!open) return null;
|
|
100
148
|
return /*#__PURE__*/_jsx(Tray, {
|
|
101
149
|
ref: ref,
|
|
@@ -109,51 +157,72 @@ const DefaultSelectDropdownComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef
|
|
|
109
157
|
children: /*#__PURE__*/_jsx(ScrollView, {
|
|
110
158
|
showsVerticalScrollIndicator: true,
|
|
111
159
|
children: /*#__PURE__*/_jsxs(VStack, {
|
|
112
|
-
children: [!hideSelectAll && isMultiSelect && options.length > 0 && SelectAllOption, options.length > 0 ? options.map(
|
|
113
|
-
var _ref3;
|
|
114
|
-
|
|
115
|
-
|
|
160
|
+
children: [!hideSelectAll && isMultiSelect && options.length > 0 && SelectAllOption, options.length > 0 ? options.map(optionOrGroup => {
|
|
161
|
+
var _optionProps$value, _optionProps$value2, _ref3;
|
|
162
|
+
// Check if it's a group (has 'options' property and 'label')
|
|
163
|
+
if (isSelectOptionGroup(optionOrGroup)) {
|
|
164
|
+
var _group$disabled;
|
|
165
|
+
const group = optionOrGroup;
|
|
166
|
+
return /*#__PURE__*/_jsx(SelectOptionGroupComponent, {
|
|
167
|
+
SelectOptionComponent: SelectOptionComponent,
|
|
168
|
+
accessibilityRole: accessibilityRoles == null ? void 0 : accessibilityRoles.option,
|
|
169
|
+
accessory: accessory,
|
|
170
|
+
compact: compact,
|
|
171
|
+
disabled: (_group$disabled = group.disabled) != null ? _group$disabled : disabled,
|
|
172
|
+
end: end,
|
|
173
|
+
label: group.label,
|
|
174
|
+
media: media,
|
|
175
|
+
onChange: onChange,
|
|
176
|
+
options: group.options,
|
|
177
|
+
setOpen: setOpen,
|
|
178
|
+
styles: optionGroupStyles,
|
|
179
|
+
type: type,
|
|
180
|
+
value: value
|
|
181
|
+
}, "group-" + group.label);
|
|
182
|
+
}
|
|
183
|
+
const option = optionOrGroup;
|
|
184
|
+
const {
|
|
185
|
+
Component: optionComponent,
|
|
116
186
|
media: optionMedia,
|
|
117
187
|
accessory: optionAccessory,
|
|
118
|
-
end: optionEnd
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const
|
|
188
|
+
end: optionEnd,
|
|
189
|
+
disabled: optionDisabled
|
|
190
|
+
} = option,
|
|
191
|
+
optionProps = _objectWithoutPropertiesLoose(option, _excluded2);
|
|
192
|
+
const RenderedComponent = optionComponent != null ? optionComponent : SelectOptionComponent;
|
|
193
|
+
const selected = optionProps.value !== null && isMultiSelect ? value.includes(optionProps.value) : value === optionProps.value;
|
|
123
194
|
/** onPress handlers are passed so that when the media is pressed,
|
|
124
195
|
* the onChange handler is called. Since the <RenderedSelectOption>
|
|
125
196
|
* has an accessibilityRole, the inner media won't be detected by a screen reader
|
|
126
197
|
* so this behavior matches web
|
|
127
198
|
* */
|
|
128
199
|
const defaultMedia = isMultiSelect ? /*#__PURE__*/_jsx(Checkbox, {
|
|
200
|
+
"aria-hidden": true,
|
|
129
201
|
checked: selected,
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
202
|
+
onChange: () => handleOptionPress(optionProps.value),
|
|
203
|
+
tabIndex: -1,
|
|
204
|
+
value: (_optionProps$value = optionProps.value) == null ? void 0 : _optionProps$value.toString()
|
|
133
205
|
}) : /*#__PURE__*/_jsx(Radio, {
|
|
206
|
+
"aria-hidden": true,
|
|
134
207
|
checked: selected,
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
208
|
+
onChange: () => handleOptionPress(optionProps.value),
|
|
209
|
+
tabIndex: -1,
|
|
210
|
+
value: (_optionProps$value2 = optionProps.value) == null ? void 0 : _optionProps$value2.toString()
|
|
139
211
|
});
|
|
140
|
-
return /*#__PURE__*/_jsx(
|
|
212
|
+
return /*#__PURE__*/_jsx(RenderedComponent, _extends({
|
|
141
213
|
accessibilityRole: accessibilityRoles == null ? void 0 : accessibilityRoles.option,
|
|
142
214
|
accessory: optionAccessory != null ? optionAccessory : accessory,
|
|
143
215
|
blendStyles: styles == null ? void 0 : styles.optionBlendStyles,
|
|
144
216
|
compact: compact,
|
|
145
|
-
disabled:
|
|
217
|
+
disabled: optionDisabled || disabled,
|
|
146
218
|
end: optionEnd != null ? optionEnd : end,
|
|
147
219
|
media: (_ref3 = optionMedia != null ? optionMedia : media) != null ? _ref3 : defaultMedia,
|
|
148
|
-
onPress:
|
|
149
|
-
onChange(newValue);
|
|
150
|
-
if (!isMultiSelect) setOpen(false);
|
|
151
|
-
},
|
|
220
|
+
onPress: handleOptionPress,
|
|
152
221
|
selected: selected,
|
|
153
222
|
style: styles == null ? void 0 : styles.option,
|
|
154
223
|
styles: optionStyles,
|
|
155
224
|
type: type
|
|
156
|
-
},
|
|
225
|
+
}, optionProps), optionProps.value);
|
|
157
226
|
}) : /*#__PURE__*/_jsx(SelectEmptyDropdownContentsComponent, {
|
|
158
227
|
label: emptyOptionsLabel,
|
|
159
228
|
styles: emptyDropdownContentsStyles
|
|
@@ -21,7 +21,7 @@ const DefaultSelectOptionComponent = (_ref, ref) => {
|
|
|
21
21
|
styles,
|
|
22
22
|
type,
|
|
23
23
|
accessibilityRole,
|
|
24
|
-
background =
|
|
24
|
+
background = 'transparent'
|
|
25
25
|
} = _ref,
|
|
26
26
|
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
27
27
|
const labelNode = useMemo(() => typeof label === 'string' ? /*#__PURE__*/_jsx(Text, {
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const _excluded = ["Component", "media", "accessory", "end", "disabled"];
|
|
2
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
3
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
4
|
+
import { memo, useCallback, useMemo } from 'react';
|
|
5
|
+
import { Checkbox } from '../../controls/Checkbox';
|
|
6
|
+
import { Radio } from '../../controls/Radio';
|
|
7
|
+
import { VStack } from '../../layout/VStack';
|
|
8
|
+
import { Text } from '../../typography/Text';
|
|
9
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
+
const DefaultSelectOptionGroupComponent = /*#__PURE__*/memo(_ref => {
|
|
11
|
+
let {
|
|
12
|
+
label,
|
|
13
|
+
options,
|
|
14
|
+
SelectOptionComponent,
|
|
15
|
+
value,
|
|
16
|
+
onChange,
|
|
17
|
+
setOpen,
|
|
18
|
+
type,
|
|
19
|
+
accessibilityRole,
|
|
20
|
+
accessory,
|
|
21
|
+
media,
|
|
22
|
+
end,
|
|
23
|
+
disabled,
|
|
24
|
+
compact,
|
|
25
|
+
styles
|
|
26
|
+
} = _ref;
|
|
27
|
+
const optionStyles = useMemo(() => ({
|
|
28
|
+
optionCell: styles == null ? void 0 : styles.optionCell,
|
|
29
|
+
optionContent: styles == null ? void 0 : styles.optionContent,
|
|
30
|
+
optionLabel: styles == null ? void 0 : styles.optionLabel,
|
|
31
|
+
optionDescription: styles == null ? void 0 : styles.optionDescription,
|
|
32
|
+
selectAllDivider: styles == null ? void 0 : styles.selectAllDivider
|
|
33
|
+
}), [styles == null ? void 0 : styles.optionCell, styles == null ? void 0 : styles.optionContent, styles == null ? void 0 : styles.optionLabel, styles == null ? void 0 : styles.optionDescription, styles == null ? void 0 : styles.selectAllDivider]);
|
|
34
|
+
const isMultiSelect = type === 'multi';
|
|
35
|
+
const handleOptionPress = useCallback(newValue => {
|
|
36
|
+
onChange(newValue);
|
|
37
|
+
if (!isMultiSelect) setOpen(false);
|
|
38
|
+
}, [onChange, isMultiSelect, setOpen]);
|
|
39
|
+
if (options.length === 0) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
return /*#__PURE__*/_jsxs(VStack, {
|
|
43
|
+
role: "group",
|
|
44
|
+
style: styles == null ? void 0 : styles.optionGroup,
|
|
45
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
46
|
+
color: "fgMuted",
|
|
47
|
+
font: "caption",
|
|
48
|
+
paddingX: 2,
|
|
49
|
+
paddingY: 2,
|
|
50
|
+
children: label
|
|
51
|
+
}), options.map(option => {
|
|
52
|
+
var _ref2;
|
|
53
|
+
const {
|
|
54
|
+
Component: optionComponent,
|
|
55
|
+
media: optionMedia,
|
|
56
|
+
accessory: optionAccessory,
|
|
57
|
+
end: optionEnd,
|
|
58
|
+
disabled: optionDisabled
|
|
59
|
+
} = option,
|
|
60
|
+
optionProps = _objectWithoutPropertiesLoose(option, _excluded);
|
|
61
|
+
const RenderedComponent = optionComponent != null ? optionComponent : SelectOptionComponent;
|
|
62
|
+
const selected = optionProps.value !== null && isMultiSelect ? value.includes(optionProps.value) : value === optionProps.value;
|
|
63
|
+
const defaultMedia = isMultiSelect ? /*#__PURE__*/_jsx(Checkbox, {
|
|
64
|
+
checked: selected,
|
|
65
|
+
onChange: () => handleOptionPress(optionProps.value),
|
|
66
|
+
tabIndex: -1
|
|
67
|
+
}) : /*#__PURE__*/_jsx(Radio, {
|
|
68
|
+
checked: selected,
|
|
69
|
+
onChange: () => handleOptionPress(optionProps.value),
|
|
70
|
+
tabIndex: -1
|
|
71
|
+
});
|
|
72
|
+
return /*#__PURE__*/_jsx(RenderedComponent, _extends({
|
|
73
|
+
accessibilityRole: accessibilityRole,
|
|
74
|
+
accessory: optionAccessory != null ? optionAccessory : accessory,
|
|
75
|
+
blendStyles: styles == null ? void 0 : styles.optionBlendStyles,
|
|
76
|
+
compact: compact,
|
|
77
|
+
disabled: optionDisabled || disabled,
|
|
78
|
+
end: optionEnd != null ? optionEnd : end,
|
|
79
|
+
media: (_ref2 = optionMedia != null ? optionMedia : media) != null ? _ref2 : defaultMedia,
|
|
80
|
+
onPress: handleOptionPress,
|
|
81
|
+
selected: selected,
|
|
82
|
+
style: styles == null ? void 0 : styles.option,
|
|
83
|
+
styles: optionStyles,
|
|
84
|
+
type: type
|
|
85
|
+
}, optionProps), optionProps.value);
|
|
86
|
+
})]
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
DefaultSelectOptionGroupComponent.displayName = 'DefaultSelectOptionGroup';
|
|
90
|
+
export const DefaultSelectOptionGroup = DefaultSelectOptionGroupComponent;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const _excluded = ["value", "type", "options", "onChange", "open", "setOpen", "disabled", "disableClickOutsideClose", "placeholder", "helperText", "compact", "label", "labelVariant", "accessibilityLabel", "accessibilityHint", "accessibilityRoles", "selectAllLabel", "emptyOptionsLabel", "clearAllLabel", "hideSelectAll", "defaultOpen", "startNode", "endNode", "variant", "maxSelectedOptionsToShow", "hiddenSelectedOptionsLabel", "removeSelectedOptionAccessibilityLabel", "accessory", "media", "end", "SelectOptionComponent", "SelectAllOptionComponent", "SelectDropdownComponent", "SelectControlComponent", "SelectEmptyDropdownContentsComponent", "style", "styles", "testID"];
|
|
1
|
+
const _excluded = ["value", "type", "options", "onChange", "open", "setOpen", "disabled", "disableClickOutsideClose", "placeholder", "helperText", "compact", "label", "labelVariant", "accessibilityLabel", "accessibilityHint", "accessibilityRoles", "selectAllLabel", "emptyOptionsLabel", "clearAllLabel", "hideSelectAll", "defaultOpen", "startNode", "endNode", "variant", "maxSelectedOptionsToShow", "hiddenSelectedOptionsLabel", "removeSelectedOptionAccessibilityLabel", "accessory", "media", "end", "SelectOptionComponent", "SelectAllOptionComponent", "SelectDropdownComponent", "SelectControlComponent", "SelectEmptyDropdownContentsComponent", "SelectOptionGroupComponent", "style", "styles", "testID"];
|
|
2
2
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
3
3
|
import React, { forwardRef, memo, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { View } from 'react-native';
|
|
@@ -7,35 +7,16 @@ import { DefaultSelectControl } from './DefaultSelectControl';
|
|
|
7
7
|
import { DefaultSelectDropdown } from './DefaultSelectDropdown';
|
|
8
8
|
import { DefaultSelectEmptyDropdownContents } from './DefaultSelectEmptyDropdownContents';
|
|
9
9
|
import { DefaultSelectOption } from './DefaultSelectOption';
|
|
10
|
+
import { DefaultSelectOptionGroup } from './DefaultSelectOptionGroup';
|
|
11
|
+
import { isSelectOptionGroup } from './types';
|
|
10
12
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
13
|
export const defaultAccessibilityRoles = {
|
|
12
14
|
option: 'menuitem'
|
|
13
15
|
};
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
* Configuration for a single option in the Select component
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Props for individual option components within the Select dropdown
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Custom UI to render for an option in the Select component options array
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Props for the select control component (the clickable input that opens the dropdown)
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Props for the dropdown component that contains the list of options
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Props for the Select component
|
|
37
|
-
*/
|
|
17
|
+
// Re-export all types for backward compatibility
|
|
38
18
|
|
|
19
|
+
export { isSelectOptionGroup };
|
|
39
20
|
const SelectBase = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
40
21
|
let {
|
|
41
22
|
value,
|
|
@@ -72,6 +53,7 @@ const SelectBase = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
72
53
|
SelectDropdownComponent = DefaultSelectDropdown,
|
|
73
54
|
SelectControlComponent = DefaultSelectControl,
|
|
74
55
|
SelectEmptyDropdownContentsComponent = DefaultSelectEmptyDropdownContents,
|
|
56
|
+
SelectOptionGroupComponent = DefaultSelectOptionGroup,
|
|
75
57
|
style,
|
|
76
58
|
styles,
|
|
77
59
|
testID
|
|
@@ -102,8 +84,9 @@ const SelectBase = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
102
84
|
optionDescription: styles == null ? void 0 : styles.optionDescription,
|
|
103
85
|
selectAllDivider: styles == null ? void 0 : styles.selectAllDivider,
|
|
104
86
|
emptyContentsContainer: styles == null ? void 0 : styles.emptyContentsContainer,
|
|
105
|
-
emptyContentsText: styles == null ? void 0 : styles.emptyContentsText
|
|
106
|
-
|
|
87
|
+
emptyContentsText: styles == null ? void 0 : styles.emptyContentsText,
|
|
88
|
+
optionGroup: styles == null ? void 0 : styles.optionGroup
|
|
89
|
+
}), [styles == null ? void 0 : styles.dropdown, styles == null ? void 0 : styles.option, styles == null ? void 0 : styles.optionBlendStyles, styles == null ? void 0 : styles.optionCell, styles == null ? void 0 : styles.optionContent, styles == null ? void 0 : styles.optionLabel, styles == null ? void 0 : styles.optionDescription, styles == null ? void 0 : styles.selectAllDivider, styles == null ? void 0 : styles.emptyContentsContainer, styles == null ? void 0 : styles.emptyContentsText, styles == null ? void 0 : styles.optionGroup]);
|
|
107
90
|
const containerRef = useRef(null);
|
|
108
91
|
useImperativeHandle(ref, () => Object.assign(containerRef.current, {
|
|
109
92
|
open,
|
|
@@ -145,6 +128,7 @@ const SelectBase = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
145
128
|
SelectAllOptionComponent: SelectAllOptionComponent,
|
|
146
129
|
SelectEmptyDropdownContentsComponent: SelectEmptyDropdownContentsComponent,
|
|
147
130
|
SelectOptionComponent: SelectOptionComponent,
|
|
131
|
+
SelectOptionGroupComponent: SelectOptionGroupComponent,
|
|
148
132
|
accessibilityRoles: accessibilityRoles,
|
|
149
133
|
accessory: accessory,
|
|
150
134
|
clearAllLabel: clearAllLabel,
|
|
@@ -3,4 +3,6 @@ export * from './DefaultSelectControl';
|
|
|
3
3
|
export * from './DefaultSelectDropdown';
|
|
4
4
|
export * from './DefaultSelectEmptyDropdownContents';
|
|
5
5
|
export * from './DefaultSelectOption';
|
|
6
|
-
export * from './
|
|
6
|
+
export * from './DefaultSelectOptionGroup';
|
|
7
|
+
export * from './Select';
|
|
8
|
+
export * from './types';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for a single option in the Select component
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Props for individual option components within the Select dropdown
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Custom UI to render for an option in the Select component options array
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Configuration for a group of options in the Select component
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Props for the option group component in the Select dropdown
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Custom UI to render for an option group in the Select component options array
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Array of options for the Select component. Can be individual options or groups with `label` and `options`
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Type guard to check if an option is a group
|
|
31
|
+
*/
|
|
32
|
+
export function isSelectOptionGroup(option) {
|
|
33
|
+
return 'options' in option && Array.isArray(option.options) && 'label' in option;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Props for the select control component (the clickable input that opens the dropdown)
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Props for the dropdown component that contains the list of options
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Props for the Select component
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Type for the Select component function signature
|
|
50
|
+
*/
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const _excluded = ["invertColorScheme", "numberOfLines"];
|
|
2
|
+
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
3
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
4
|
+
import React, { forwardRef, memo, useCallback } from 'react';
|
|
5
|
+
import { Select } from '../select/Select';
|
|
6
|
+
import { SelectChipControl } from './SelectChipControl';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Chip-styled Select control built on top of the Alpha Select.
|
|
10
|
+
* Supports both single and multi selection via Select's `type` prop.
|
|
11
|
+
*/
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
const SelectChipComponent = /*#__PURE__*/memo(/*#__PURE__*/forwardRef((_ref, ref) => {
|
|
14
|
+
let {
|
|
15
|
+
invertColorScheme,
|
|
16
|
+
numberOfLines
|
|
17
|
+
} = _ref,
|
|
18
|
+
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
19
|
+
const SelectChipControlComponent = useCallback(props => {
|
|
20
|
+
return /*#__PURE__*/_jsx(SelectChipControl, _extends({
|
|
21
|
+
invertColorScheme: invertColorScheme,
|
|
22
|
+
numberOfLines: numberOfLines
|
|
23
|
+
}, props));
|
|
24
|
+
}, [invertColorScheme, numberOfLines]);
|
|
25
|
+
return /*#__PURE__*/_jsx(Select, _extends({
|
|
26
|
+
ref: ref,
|
|
27
|
+
SelectControlComponent: SelectChipControlComponent
|
|
28
|
+
}, props));
|
|
29
|
+
}));
|
|
30
|
+
SelectChipComponent.displayName = 'SelectChip';
|
|
31
|
+
export const SelectChip = SelectChipComponent;
|