Skip to content

Commit c668529

Browse files
authored
ComboBox bug fixes (#1449)
1 parent f68e64b commit c668529

File tree

4 files changed

+417
-39
lines changed

4 files changed

+417
-39
lines changed

packages/@react-spectrum/combobox/src/MobileComboBox.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import AlertMedium from '@spectrum-icons/ui/AlertMedium';
1414
import {AriaButtonProps} from '@react-types/button';
1515
import buttonStyles from '@adobe/spectrum-css-temp/components/button/vars.css';
16+
import {chain, mergeProps, useId} from '@react-aria/utils';
1617
import CheckmarkMedium from '@spectrum-icons/ui/CheckmarkMedium';
1718
import ChevronDownMedium from '@spectrum-icons/ui/ChevronDownMedium';
1819
import {classNames, unwrapDOMRef} from '@react-spectrum/utils';
@@ -28,7 +29,6 @@ import {focusSafely} from '@react-aria/focus';
2829
import intlMessages from '../intl/*.json';
2930
import labelStyles from '@adobe/spectrum-css-temp/components/fieldlabel/vars.css';
3031
import {ListBoxBase, useListBoxLayout} from '@react-spectrum/listbox';
31-
import {mergeProps, useId} from '@react-aria/utils';
3232
import {ProgressCircle} from '@react-spectrum/progress';
3333
import React, {HTMLAttributes, ReactElement, ReactNode, RefObject, useCallback, useRef} from 'react';
3434
import searchStyles from '@adobe/spectrum-css-temp/components/search/vars.css';
@@ -55,6 +55,7 @@ export const MobileComboBox = React.forwardRef(function MobileComboBox<T extends
5555
isQuiet,
5656
isDisabled,
5757
validationState,
58+
isReadOnly,
5859
loadingState
5960
} = props;
6061

@@ -114,13 +115,13 @@ export const MobileComboBox = React.forwardRef(function MobileComboBox<T extends
114115
isDisabled={isDisabled}
115116
isPlaceholder={!state.inputValue}
116117
validationState={validationState}
117-
onPress={() => state.open()}
118+
onPress={() => !isReadOnly && state.open()}
118119
isLoading={loadingState === 'loading' || loadingState === 'filtering'}
119120
loadingIndicator={loadingState != null && loadingCircle}>
120121
{state.inputValue || props.placeholder || ''}
121122
</ComboBoxButton>
122123
</Field>
123-
<Tray isOpen={state.isOpen} onClose={state.commit} isFixedHeight isNonModal {...overlayProps}>
124+
<Tray isOpen={state.isOpen} onClose={chain(state.commit, state.close)} isFixedHeight isNonModal {...overlayProps}>
124125
<ComboBoxTray
125126
{...props}
126127
overlayProps={overlayProps}
@@ -408,7 +409,7 @@ function ComboBoxTray(props: ComboBoxTrayProps) {
408409
'tray-dialog'
409410
)
410411
}>
411-
<DismissButton onDismiss={() => state.commit()} />
412+
<DismissButton onDismiss={chain(state.commit, state.close)} />
412413
<TextFieldBase
413414
label={label}
414415
labelProps={labelProps}
@@ -477,7 +478,7 @@ function ComboBoxTray(props: ComboBoxTrayProps) {
477478
onScroll={onScroll}
478479
onLoadMore={onLoadMore}
479480
isLoading={loadingState === 'loading' || loadingState === 'loadingMore'} />
480-
<DismissButton onDismiss={() => state.commit()} />
481+
<DismissButton onDismiss={chain(state.commit, state.close)} />
481482
</div>
482483
</FocusScope>
483484
);

packages/@react-spectrum/combobox/stories/ComboBox.stories.tsx

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {ComboBox, Item, Section} from '../';
2020
import Copy from '@spectrum-icons/workflow/Copy';
2121
import Draw from '@spectrum-icons/workflow/Draw';
2222
import {Flex} from '@react-spectrum/layout';
23+
import {mergeProps} from '@react-aria/utils';
2324
import React, {useState} from 'react';
2425
import {storiesOf} from '@storybook/react';
2526
import {Text} from '@react-spectrum/text';
@@ -179,7 +180,7 @@ storiesOf('ComboBox', module)
179180
)
180181
.add(
181182
'isOpen',
182-
() => <ControlledOpenCombobox isOpen />,
183+
() => <ControlledOpenCombobox isOpen allowsCustomValue defaultSelectedKey="two" />,
183184
{note: 'Combobox needs focus to show dropdown.'}
184185
)
185186
.add(
@@ -419,6 +420,12 @@ storiesOf('ComboBox', module)
419420
<AllControlledOpenComboBox selectedKey="2" inputValue="Kangaroo" disabledKeys={['2', '6']} />
420421
)
421422
)
423+
.add(
424+
'inputValue, selectedKey, isOpen, allowsCustomValue (controlled)',
425+
() => (
426+
<AllControlledOpenComboBox selectedKey="2" inputValue="Kangaroo" disabledKeys={['2', '6']} allowsCustomValue />
427+
)
428+
)
422429
.add(
423430
'custom filter',
424431
() => (
@@ -540,8 +547,7 @@ let CustomFilterComboBox = (props) => {
540547

541548
return (
542549
<ComboBox
543-
{...actions}
544-
{...props}
550+
{...mergeProps(props, actions)}
545551
label="Combobox"
546552
items={filteredItems}
547553
inputValue={filterValue}
@@ -642,7 +648,7 @@ let ControlledKeyComboBox = (props) => {
642648
<Text>Clear key</Text>
643649
</Button>
644650
</ButtonGroup>
645-
<ComboBox {...props} selectedKey={selectedKey} defaultItems={withSection} label="Combobox" onOpenChange={action('onOpenChange')} onInputChange={action('onInputChange')} onSelectionChange={onSelectionChange} onBlur={action('onBlur')} onFocus={action('onFocus')}>
651+
<ComboBox {...mergeProps(props, actions)} selectedKey={selectedKey} defaultItems={withSection} label="Combobox" onSelectionChange={onSelectionChange}>
646652
{(item: any) => (
647653
<Section items={item.children} title={item.name}>
648654
{(item: any) => <Item>{item.name}</Item>}
@@ -674,7 +680,7 @@ let ControlledValueComboBox = (props) => {
674680
<Text>Clear field</Text>
675681
</Button>
676682
</ButtonGroup>
677-
<ComboBox {...props} inputValue={value} defaultItems={withSection} label="Combobox" onOpenChange={action('onOpenChange')} onInputChange={onValueChange} onSelectionChange={action('onSelectionChange')} onBlur={action('onBlur')} onFocus={action('onFocus')}>
683+
<ComboBox {...mergeProps(props, actions)} inputValue={value} defaultItems={withSection} label="Combobox" onInputChange={onValueChange}>
678684
{(item: any) => (
679685
<Section items={item.children} title={item.name}>
680686
{(item: any) => <Item>{item.name}</Item>}
@@ -695,7 +701,7 @@ let CustomValueComboBox = (props) => {
695701
return (
696702
<div>
697703
<div>Selected Key: {selectedKey}</div>
698-
<ComboBox {...props} selectedKey={selectedKey} defaultItems={withSection} label="Combobox" onOpenChange={action('onOpenChange')} onInputChange={action('onInputChange')} onSelectionChange={onSelectionChange} onBlur={action('onBlur')} onFocus={action('onFocus')} marginTop={20}>
704+
<ComboBox {...mergeProps(props, actions)} selectedKey={selectedKey} defaultItems={withSection} label="Combobox" onSelectionChange={onSelectionChange} marginTop={20}>
699705
{(item: any) => (
700706
<Section items={item.children} title={item.name}>
701707
{(item: any) => <Item>{item.name}</Item>}
@@ -712,7 +718,7 @@ let ControlledOpenCombobox = (props) => {
712718
return (
713719
<Flex direction="column">
714720
<TextField label="Email" />
715-
<ComboBox label="Combobox" isOpen={isOpen} {...actions} onOpenChange={setOpen}>
721+
<ComboBox label="Combobox" {...mergeProps(props, actions)} isOpen={isOpen} onOpenChange={setOpen}>
716722
<Item key="one">Item One</Item>
717723
<Item key="two" textValue="Item Two">
718724
<Copy size="S" />
@@ -737,11 +743,11 @@ function AllControlledOpenComboBox(props) {
737743
});
738744

739745
let onSelectionChange = (key: React.Key) => {
740-
setFieldState({
746+
setFieldState(prevState => ({
741747
isOpen: false,
742-
inputValue: list.getItem(key)?.value.name ?? '',
748+
inputValue: list.getItem(key)?.value.name ?? (props.allowsCustomValue ? prevState.inputValue : ''),
743749
selectedKey: key
744-
});
750+
}));
745751
};
746752

747753
let onInputChange = (value: string) => {
@@ -762,7 +768,7 @@ function AllControlledOpenComboBox(props) {
762768

763769
return (
764770
<div>
765-
<ComboBox disabledKeys={props.disabledKeys} selectedKey={fieldState.selectedKey} inputValue={fieldState.inputValue} defaultItems={list.items} label="Combobox" isOpen={fieldState.isOpen} onOpenChange={onOpenChange} onInputChange={onInputChange} onSelectionChange={onSelectionChange} onBlur={action('onBlur')} onFocus={action('onFocus')}>
771+
<ComboBox allowsCustomValue={props.allowsCustomValue} disabledKeys={props.disabledKeys} selectedKey={fieldState.selectedKey} inputValue={fieldState.inputValue} defaultItems={list.items} label="Combobox" isOpen={fieldState.isOpen} onOpenChange={onOpenChange} onInputChange={onInputChange} onSelectionChange={onSelectionChange} onBlur={action('onBlur')} onFocus={action('onFocus')}>
766772
{item => (
767773
<Section items={item.children} title={item.value.name}>
768774
{item => <Item>{item.value.name}</Item>}
@@ -795,7 +801,7 @@ function ResizeCombobox() {
795801

796802
function render(props = {}) {
797803
return (
798-
<ComboBox label="Combobox" onOpenChange={action('onOpenChange')} onInputChange={action('onInputChange')} onSelectionChange={action('onSelectionChange')} onBlur={action('onBlur')} onFocus={action('onFocus')} {...props}>
804+
<ComboBox label="Combobox" {...mergeProps(props, actions)}>
799805
<Item key="one">Item One</Item>
800806
<Item key="two" textValue="Item Two">
801807
<Copy size="S" />

0 commit comments

Comments
 (0)