Skip to content

Commit

Permalink
feat(combobox): add flag to disable autocomplete (uber#3391)
Browse files Browse the repository at this point in the history
* feat(combobox): add flag to disable autocomplete

* test(vrt): update visual snapshots for 70a320d [skip ci] (uber#3392)

Co-authored-by: UberOpenSourceBot <[email protected]>

Co-authored-by: UberOpenSourceBot <[email protected]>
Co-authored-by: UberOpenSourceBot <[email protected]>
  • Loading branch information
3 people authored Jun 3, 2020
1 parent b232e26 commit c59394f
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 8 deletions.
7 changes: 7 additions & 0 deletions documentation-site/components/yard/config/combobox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ const ComboboxConfig: TConfig = {
type: PropTypes.Function,
description: 'Transforms option to custom node in listbox.',
},
autocomplete: {
value: true,
defaultValue: true,
type: PropTypes.Boolean,
description:
'Controls if keyboard navigation should temporarily update input value.',
},
disabled: {
value: false,
type: PropTypes.Boolean,
Expand Down
43 changes: 43 additions & 0 deletions src/combobox/__tests__/combobox-autocomplete-false.scenario.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Copyright (c) 2018-2020 Uber Technologies, Inc.
This source code is licensed under the MIT license found in the
LICENSE file in the root directory of this source tree.
*/
// @flow

import * as React from 'react';

import {FormControl} from '../../form-control/index.js';
import {useStyletron} from '../../styles/index.js';
import {Combobox} from '../index.js';

type OptionT = {label: string, id: string};
const options: OptionT[] = [
{label: 'AliceBlue', id: '#F0F8FF'},
{label: 'AntiqueWhite', id: '#FAEBD7'},
{label: 'Aqua', id: '#00FFFF'},
{label: 'Aquamarine', id: '#7FFFD4'},
{label: 'Azure', id: '#F0FFFF'},
{label: 'Beige', id: '#F5F5DC'},
];

function Example() {
const [css] = useStyletron();
const [value, setValue] = React.useState('');
return (
<div className={css({width: '375px', padding: '12px 48px'})}>
<FormControl label="label" caption="caption">
<Combobox
autocomplete={false}
value={value}
onChange={setValue}
mapOptionToString={o => o.label}
options={options}
/>
</FormControl>
</div>
);
}

export default Example;
16 changes: 16 additions & 0 deletions src/combobox/__tests__/combobox.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,20 @@ describe('combobox', () => {
fireEvent.click(button);
expect(input.getAttribute('value')).toBe(updateValue);
});

it('does not change input value while keyboard nav if autocomplete is false', () => {
const {container} = render(
<Combobox
autocomplete={false}
mapOptionToString={o => o}
onChange={() => {}}
options={options}
value={''}
/>,
{container: document.body},
);
const input = container.querySelector('input');
fireEvent.keyDown(input, {keyCode: 40});
expect(input.getAttribute('value')).toBe('');
});
});
12 changes: 6 additions & 6 deletions src/combobox/combobox.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const ARROW_DOWN = 40;
// aria 1.2 spec: https://www.w3.org/TR/wai-aria-practices-1.2/#combobox
function Combobox<OptionT>(props: PropsT<OptionT>) {
const {
autocomplete = true,
disabled = false,
error = false,
onChange,
Expand Down Expand Up @@ -73,12 +74,11 @@ function Combobox<OptionT>(props: PropsT<OptionT>) {
// option and selection index is not in option bounds, reset it to default.
setSelectionIndex(-1);
} else {
// NOTE(chase): May want to consider adding an option to _not_ autocomplete the
// temporary value in the input element. If a feature request comes up, this is
// where it would go.
let selectedOption = options[selectionIndex];
if (selectedOption) {
setTempValue(mapOptionToString(selectedOption));
if (autocomplete) {
let selectedOption = options[selectionIndex];
if (selectedOption) {
setTempValue(mapOptionToString(selectedOption));
}
}
}
}, [options, selectionIndex]);
Expand Down
1 change: 1 addition & 0 deletions src/combobox/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface SIZE {
}

export type PropsT<OptionT = unknown> = {
autocomplete?: boolean;
disabled?: boolean;
mapOptionToNode?: ({isSelected: boolean, option: OptionT}) => React.ReactNode;
mapOptionToString: (OptionT) => string;
Expand Down
4 changes: 2 additions & 2 deletions src/combobox/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import * as React from 'react';

import type {OverrideT} from '../helpers/overrides.js';
import {SIZE} from '../input/index.js';
// import type {InputPropsT} from '../input/index.js';
// import type {PopoverPropsT} from '../popover/index.js';

export type PropsT<OptionT = mixed> = {|
// Controls if the input value will be updated while keyboard navigating. Defaults to true.
autocomplete?: boolean,
// Disallows text input and listbox opening.
disabled?: boolean,
// Proxies value through to Input component.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c59394f

Please sign in to comment.