Skip to content

Commit 640e002

Browse files
authored
feat: ComboBox - @deephaven/components (#2067)
* New `ComboBox` component in @deephaven/components * Split out some shared logic from `Picker` since `ComboBox` is basically a subclass * Deleted old `ComboBox` component and replaced usage (condition column + row formatting. Also tested to make sure it still works as before) * Updated Styleguide resolves #2065 BREAKING CHANGE: ComboBox component has been replaced. To migrate to new version: - Passing children is used instead of `options` prop to define dropdown items. For cases where option value and display are the same, passing an array of values as `children` will work. For cases where value and display differ, `Item` elements must be passed as children. e.g. `<Item key={value}>{display}</Item>` e.g. ```typescript // values will be used for display + value const items = useMemo( () => ['Aaa', 'Bbb', 'Ccc'], [] ) <ComboBox>{items}</ComboBox> ``` ```typescript <ComboBox> <Item key="aaa">Aaa</Item> <Item key="bbb">Bbb</Item> <Item key="ccc">Ccc</Item> </ComboBox> ``` - The `spellcheck=false` prop is no longer supported or needed - `searchPlaceholder` and `inputPlaceholder` props are no longer supported and should be omitted. There is an optional `description` prop for cases where a descriptive label is desired. There is also a `label` prop for the primary component label.
1 parent 3e52242 commit 640e002

59 files changed

Lines changed: 719 additions & 830 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/code-studio/src/styleguide/Inputs.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
UISwitch,
1515
Select,
1616
Option,
17+
Item,
1718
} from '@deephaven/components';
1819
import SampleSection from './SampleSection';
1920

@@ -33,6 +34,10 @@ const EXAMPLES = [
3334
{ title: 'Title 12', value: 'Value 12' },
3435
];
3536

37+
const items = EXAMPLES.map(({ title, value }) => (
38+
<Item key={value}>{title}</Item>
39+
));
40+
3641
const TIMEOUTS = [
3742
{ title: '1 minute', value: 1 * 60 * 1000 },
3843
{ title: '5 minutes', value: 5 * 60 * 1000 },
@@ -283,20 +288,15 @@ function Inputs(): React.ReactElement {
283288
<div className="form-group">
284289
<h5>Input with Select</h5>
285290
<div className="input-group">
286-
<ComboBox
287-
options={EXAMPLES}
288-
inputPlaceholder="10.128.0.8"
289-
searchPlaceholder="Search actions here"
290-
/>
291+
<ComboBox aria-label="ComboBox" width="100%">
292+
{items}
293+
</ComboBox>
291294
</div>
292295
<br />
293296
<div className="input-group">
294-
<ComboBox
295-
options={EXAMPLES}
296-
inputPlaceholder="10.128.0.8"
297-
searchPlaceholder="Search actions here"
298-
disabled
299-
/>
297+
<ComboBox aria-label="Disabled ComboBox" isDisabled width="100%">
298+
{items}
299+
</ComboBox>
300300
</div>
301301
</div>
302302

packages/code-studio/src/styleguide/Pickers.tsx

Lines changed: 63 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
Text,
99
PickerNormalized,
1010
Checkbox,
11+
ComboBox,
1112
} from '@deephaven/components';
1213
import { vsPerson } from '@deephaven/icons';
1314
import { Icon } from '@adobe/react-spectrum';
@@ -75,7 +76,7 @@ export function Pickers(): JSX.Element {
7576
[selectedKey]
7677
);
7778

78-
const onChange = useCallback((key: ItemKey): void => {
79+
const onChange = useCallback((key: ItemKey | null): void => {
7980
setSelectedKey(key);
8081
}, []);
8182

@@ -85,53 +86,66 @@ export function Pickers(): JSX.Element {
8586
<h2 className="ui-title">Pickers</h2>
8687

8788
<Flex gap={14} direction="column">
88-
<Flex direction="row" gap={14}>
89-
<Picker label="Single Child" tooltip={{ placement: 'bottom-end' }}>
90-
<Item textValue="Aaa">Aaa</Item>
91-
</Picker>
92-
93-
<Picker label="Mixed Children Types" defaultSelectedKey="999" tooltip>
94-
{mixedItemsWithIconsNoDescriptions}
95-
</Picker>
96-
97-
<Picker label="Sections" tooltip>
98-
{/* eslint-disable react/jsx-curly-brace-presence */}
99-
{'String 1'}
100-
{'String 2'}
101-
{'String 3'}
102-
<Section title="Section">
103-
<Item textValue="Item Aaa">Item Aaa</Item>
104-
<Item textValue="Item Bbb">Item Bbb</Item>
105-
<Item textValue="Complex Ccc">
106-
<PersonIcon />
107-
<Text>Complex Ccc</Text>
108-
</Item>
109-
</Section>
110-
<Section key="Key B">
111-
<Item textValue="Item Ddd">Item Ddd</Item>
112-
<Item textValue="Item Eee">Item Eee</Item>
113-
<Item textValue="Complex Fff">
114-
<PersonIcon />
115-
<Text>Complex Fff</Text>
116-
</Item>
117-
<Item textValue="Ggg">
118-
<PersonIcon />
119-
<Text>Label</Text>
120-
<Text slot="description">Description</Text>
121-
</Item>
122-
<Item textValue="Hhh">
123-
<PersonIcon />
124-
<Text>Label that causes overflow</Text>
125-
<Text slot="description">Description that causes overflow</Text>
126-
</Item>
127-
</Section>
128-
<Section title="Section A">{itemElementsA}</Section>
129-
<Section title="Section B">{itemElementsB}</Section>
130-
<Section key="Section C">{itemElementsC}</Section>
131-
<Section key="Section D">{itemElementsD}</Section>
132-
<Section title="Section E">{itemElementsE}</Section>
133-
</Picker>
134-
</Flex>
89+
{[Picker, ComboBox].map(Component => {
90+
const label = (suffix: string) =>
91+
`${Component === Picker ? 'Picker' : 'ComboBox'} (${suffix})`;
92+
return (
93+
<Flex key={Component.name} direction="row" gap={14}>
94+
<Component
95+
label={label('Single Child')}
96+
tooltip={{ placement: 'bottom-end' }}
97+
>
98+
<Item textValue="Aaa">Aaa</Item>
99+
</Component>
100+
<Component
101+
label={label('Mixed Children Types')}
102+
defaultSelectedKey="999"
103+
tooltip
104+
>
105+
{mixedItemsWithIconsNoDescriptions}
106+
</Component>
107+
<Component label={label('Sections')} tooltip>
108+
{/* eslint-disable react/jsx-curly-brace-presence */}
109+
{'String 1'}
110+
{'String 2'}
111+
{'String 3'}
112+
<Section title="Section">
113+
<Item textValue="Item Aaa">Item Aaa</Item>
114+
<Item textValue="Item Bbb">Item Bbb</Item>
115+
<Item textValue="Complex Ccc">
116+
<PersonIcon />
117+
<Text>Complex Ccc</Text>
118+
</Item>
119+
</Section>
120+
<Section key="Key B">
121+
<Item textValue="Item Ddd">Item Ddd</Item>
122+
<Item textValue="Item Eee">Item Eee</Item>
123+
<Item textValue="Complex Fff">
124+
<PersonIcon />
125+
<Text>Complex Fff</Text>
126+
</Item>
127+
<Item textValue="Ggg">
128+
<PersonIcon />
129+
<Text>Label</Text>
130+
<Text slot="description">Description</Text>
131+
</Item>
132+
<Item textValue="Hhh">
133+
<PersonIcon />
134+
<Text>Label that causes overflow</Text>
135+
<Text slot="description">
136+
Description that causes overflow
137+
</Text>
138+
</Item>
139+
</Section>
140+
<Section title="Section A">{itemElementsA}</Section>
141+
<Section title="Section B">{itemElementsB}</Section>
142+
<Section key="Section C">{itemElementsC}</Section>
143+
<Section key="Section D">{itemElementsD}</Section>
144+
<Section title="Section E">{itemElementsE}</Section>
145+
</Component>
146+
</Flex>
147+
);
148+
})}
135149

136150
<Checkbox
137151
checked={showIcons}
@@ -142,7 +156,7 @@ export function Pickers(): JSX.Element {
142156

143157
<Flex direction="row" gap={14}>
144158
<PickerNormalized
145-
label="Controlled"
159+
label="Picker (Controlled)"
146160
getInitialScrollPosition={getInitialScrollPosition}
147161
normalizedItems={itemsWithIcons}
148162
selectedKey={selectedKey}

packages/code-studio/src/styleguide/SpectrumComparison.tsx

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
ActionButton,
55
Button,
66
Checkbox,
7-
ComboBox,
87
Flex,
98
Grid,
109
Icon,
@@ -16,7 +15,6 @@ import {
1615
import {
1716
Button as BootstrapButtonOld,
1817
Checkbox as CheckboxOld,
19-
ComboBox as ComboBoxOld,
2018
Select,
2119
View,
2220
Text,
@@ -38,12 +36,6 @@ const buttons: [BootstrapLevel, SpectrumButtonProps['variant']][] = [
3836
['danger', 'negative'],
3937
];
4038

41-
const options = [
42-
{ title: 'One', value: '1' },
43-
{ title: 'Two', value: '2' },
44-
{ title: 'Three', value: '3' },
45-
];
46-
4739
export function SpectrumComparison(): JSX.Element {
4840
const [isChecked, setIsChecked] = useState(false);
4941

@@ -155,31 +147,6 @@ export function SpectrumComparison(): JSX.Element {
155147
<label>Bootstrap</label>
156148
<label>Spectrum</label>
157149

158-
{[false, true].map(isDisabled => (
159-
<Fragment key={String(isDisabled)}>
160-
<div>
161-
<label className="input-label">
162-
{isDisabled ? 'Disabled ' : ''}Combobox
163-
</label>
164-
<ComboBoxOld
165-
disabled={isDisabled}
166-
options={options}
167-
defaultValue="One"
168-
/>
169-
</div>
170-
171-
<ComboBox
172-
isDisabled={isDisabled}
173-
label={isDisabled ? 'Disabled Combobox' : 'Combobox'}
174-
inputValue="One"
175-
>
176-
<Item key="1">One</Item>
177-
<Item key="2">Two</Item>
178-
<Item key="3">Three</Item>
179-
</ComboBox>
180-
</Fragment>
181-
))}
182-
183150
{[false, true].map(isDisabled => (
184151
<Fragment key={String(isDisabled)}>
185152
<div>

packages/components/src/ComboBox.test.tsx

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)