Skip to content

Commit

Permalink
fix(Picker): fixing Picker filtering logic (#1286)
Browse files Browse the repository at this point in the history
  • Loading branch information
VadymBezpalko authored Aug 13, 2024
1 parent 3f54c75 commit 8e0c4bd
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 46 deletions.
4 changes: 4 additions & 0 deletions packages/react-components/src/components/Picker/Picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const Picker: React.FC<IPickerProps> = ({
const [triggerFocus, setTriggerFocus] = React.useState(false);
const isControlled = isVisible !== undefined;
const isOpen = isControlled ? isVisible : open;
const inputRef = React.useRef<HTMLInputElement>(null);

const handleVisibilityChange = (newValue: boolean, event?: Event) => {
if (newValue) {
Expand All @@ -74,6 +75,8 @@ export const Picker: React.FC<IPickerProps> = ({
selectAllOptionText,
onSelect,
setOpen: handleVisibilityChange,
clearSearchAfterSelection,
inputRef,
});

const {
Expand Down Expand Up @@ -131,6 +134,7 @@ export const Picker: React.FC<IPickerProps> = ({
type={type}
size={size}
clearSearchAfterSelection={clearSearchAfterSelection}
inputRef={inputRef}
onItemRemove={handleItemRemove}
onSelect={handleSelect}
onFilter={handleOnFilter}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,34 +146,4 @@ describe('<PickerTriggerBody> component', () => {
expect(queryByText('Selected custom one')).toBeVisible();
expect(queryByText('Selected custom two')).toBeVisible();
});

it('should clear search input after item selection if clearSearchAfterSelection is passed', () => {
const onFilter = vi.fn();
const { getByRole, rerender } = renderComponent({
...defaultProps,
isOpen: true,
onFilter,
clearSearchAfterSelection: true,
});

userEvent.type(getByRole('textbox'), 'Option one');
expect(onFilter).toBeCalledWith('Option one');

rerender(
<PickerTriggerBody
{...defaultProps}
isOpen
clearSearchAfterSelection
selectedItems={[
{
key: 'one',
name: 'Option one',
},
]}
/>
);

expect(onFilter).toHaveBeenCalledWith('');
expect(getByRole('textbox')).toHaveValue('');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface ITriggerBodyProps {
onClear: () => void;
virtualItemRef: React.MutableRefObject<HTMLElement | null>;
isTriggerFocused: boolean;
inputRef?: React.RefObject<HTMLInputElement>;
}

export const PickerTriggerBody: React.FC<ITriggerBodyProps> = ({
Expand All @@ -45,16 +46,13 @@ export const PickerTriggerBody: React.FC<ITriggerBodyProps> = ({
searchPhrase,
virtualItemRef,
isTriggerFocused,
inputRef,
}) => {
const shouldDisplaySearch = isOpen && !isSearchDisabled;
const inputRef = React.useRef<HTMLInputElement>(null);

React.useEffect(() => {
if (clearSearchAfterSelection) {
onFilter('');

if (inputRef.current) {
inputRef.current.value = '';
if (inputRef?.current) {
inputRef.current.focus();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ interface UsePickerItemsProps {
selectAllOptionText?: string;
onSelect: (items: IPickerListItem[] | null) => void;
setOpen: (isOpen: boolean) => void;
clearSearchAfterSelection: boolean;
inputRef: React.RefObject<HTMLInputElement>;
}

interface IUsePickerItems {
Expand All @@ -34,6 +36,8 @@ export const usePickerItems = ({
selectAllOptionText,
onSelect,
setOpen,
clearSearchAfterSelection,
inputRef,
}: UsePickerItemsProps): IUsePickerItems => {
const [_selectedKeys, setSelectedKeys] = React.useState<string[]>(
() => selected?.map(getPickerListItemKey) || []
Expand All @@ -45,6 +49,25 @@ export const usePickerItems = ({

const [searchPhrase, setSearchPhrase] = React.useState<string>('');

const handleOnFilter = (text: string) => setSearchPhrase(text);

const handleItemRemove = (itemKey: string) => handleSelect(itemKey);

const handleClear = () => {
!isDataControlled && setSelectedKeys([]);
onSelect(null);
setSearchPhrase('');
setOpen(false);
};

const clearInput = () => {
handleOnFilter('');

if (inputRef.current) {
inputRef.current.value = '';
}
};

const items = React.useMemo<IPickerListItem[]>(() => {
const shouldShowSelectAll = type === 'multi' && selectAllOptionText;
let items = options;
Expand Down Expand Up @@ -118,21 +141,14 @@ export const usePickerItems = ({
return newIndexes;
});
}

if (clearSearchAfterSelection) {
clearInput();
}
}
}
};

const handleOnFilter = (text: string) => setSearchPhrase(text);

const handleItemRemove = (itemKey: string) => handleSelect(itemKey);

const handleClear = () => {
!isDataControlled && setSelectedKeys([]);
onSelect(null);
setSearchPhrase('');
setOpen(false);
};

return {
selectedKeys,
items,
Expand Down

0 comments on commit 8e0c4bd

Please sign in to comment.