Skip to content

Commit

Permalink
fix(dropdowns): compose onKeyDown handler for multiselect (#1277)
Browse files Browse the repository at this point in the history
  • Loading branch information
hzhu committed Jan 25, 2022
1 parent 63d4d12 commit 1664050
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 11 deletions.
16 changes: 8 additions & 8 deletions packages/dropdowns/.size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{
"index.cjs.js": {
"bundled": 90488,
"minified": 55054,
"gzipped": 11734
"bundled": 90578,
"minified": 55125,
"gzipped": 11739
},
"index.esm.js": {
"bundled": 84138,
"minified": 49609,
"gzipped": 11371,
"bundled": 84209,
"minified": 49661,
"gzipped": 11380,
"treeshaked": {
"rollup": {
"code": 32969,
"code": 33010,
"import_statements": 794
},
"webpack": {
"code": 43980
"code": 44045
}
}
}
Expand Down
66 changes: 65 additions & 1 deletion packages/dropdowns/src/elements/Multiselect/Multiselect.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* found at http://www.apache.org/licenses/LICENSE-2.0.
*/

import React from 'react';
import React, { useState, useEffect } from 'react';
import userEvent from '@testing-library/user-event';
import { render, fireEvent, renderRtl, act } from 'garden-test-utils';
import { Dropdown, Multiselect, Field, Menu, Item, Label, PreviousItem } from '../..';
Expand Down Expand Up @@ -186,6 +186,70 @@ describe('Multiselect', () => {
expect(icon).toHaveStyleRule('height', '16px');
});

it('composes onKeyDown handler', () => {
const onKeyDown = jest.fn();
const EVERLASTING_WINGED = 'Everlasting winged';
const options = ['Celosia', 'Dusty miller', EVERLASTING_WINGED];

const Example = () => {
const [inputValue, setInputValue] = useState('');
const [matchingOptions, setMatchingOptions] = useState(options);
const [selectedItems, setSelectedItems] = useState([options[0], options[1]]);

useEffect(() => {
const matchedOptions = options.filter(
option => option.trim().toLowerCase().indexOf(inputValue.trim().toLowerCase()) !== -1
);

setMatchingOptions(matchedOptions);
}, [inputValue]);

return (
<Dropdown
inputValue={inputValue}
selectedItems={selectedItems}
onSelect={setSelectedItems}
onInputValueChange={setInputValue}
>
<Field>
<Label>Seeds</Label>
<Multiselect
onKeyDown={onKeyDown}
renderItem={({ value, removeValue }) => (
<div>
{value}
<button onClick={removeValue} tabIndex={-1}>
Remove
</button>
</div>
)}
/>
</Field>
<Menu>
{matchingOptions.map((option: string) => (
<Item key={option} value={option}>
<span>{option}</span>
</Item>
))}
</Menu>
</Dropdown>
);
};

const { getByRole, queryByRole, queryAllByLabelText } = render(<Example />);
const combobox = getByRole('combobox');
const multiselect = queryAllByLabelText('Seeds')[0];
const addedOption = () => queryByRole('option', { name: new RegExp(EVERLASTING_WINGED, 'u') });

expect(addedOption()).not.toBeInTheDocument();

userEvent.type(multiselect, EVERLASTING_WINGED);
userEvent.type(combobox, '{enter}');

expect(addedOption()).toBeInTheDocument();
expect(onKeyDown).toHaveBeenCalledTimes(EVERLASTING_WINGED.length + 1);
});

describe('Interaction', () => {
it('opens on click', () => {
const { getByTestId } = render(
Expand Down
5 changes: 3 additions & 2 deletions packages/dropdowns/src/elements/Multiselect/Multiselect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export const Multiselect = React.forwardRef<HTMLDivElement, IMultiselectProps>(
renderShowMore,
inputRef: externalInputRef = null,
start,
onKeyDown,
...props
},
ref
Expand Down Expand Up @@ -164,14 +165,14 @@ export const Multiselect = React.forwardRef<HTMLDivElement, IMultiselectProps>(
const { type, ...selectProps } = getToggleButtonProps(
getRootProps({
tabIndex: props.disabled ? undefined : -1,
onKeyDown: (e: React.KeyboardEvent<HTMLElement>) => {
onKeyDown: composeEventHandlers(onKeyDown, (e: React.KeyboardEvent<HTMLElement>) => {
if (isOpen) {
(e.nativeEvent as any).preventDownshiftDefault = true;
} else if (!inputValue && e.keyCode === KEY_CODES.HOME) {
setFocusedItem(selectedItems[0]);
e.preventDefault();
}
},
}),
onFocus: () => {
setIsFocused(true);
},
Expand Down

0 comments on commit 1664050

Please sign in to comment.