Skip to content

Commit

Permalink
feat(Select): add onClear argument to renderControl method (#1022)
Browse files Browse the repository at this point in the history
  • Loading branch information
korvin89 authored Sep 20, 2023
1 parent 0ba6abd commit d3af988
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 12 deletions.
19 changes: 18 additions & 1 deletion src/components/Select/__tests__/Select.clear.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import userEvent from '@testing-library/user-event';
import {SelectQa} from '../constants';
import type {SelectProps} from '../types';

import {DEFAULT_OPTIONS, setup} from './utils';
import {DEFAULT_OPTIONS, renderControl, setup} from './utils';

afterEach(() => {
cleanup();
Expand Down Expand Up @@ -73,4 +73,21 @@ describe('Select clear', () => {
await user.keyboard('[Enter]');
expect(onUpdate).toHaveBeenCalledWith([]);
});

test.each([[{multiple: false}], [{multiple: true}]])(
'check for correct onClear invocation in case of using renderControl without basic clear button (args: %j)',
async (props) => {
const {getByText} = setup({
...props,
options: DEFAULT_OPTIONS,
value: [DEFAULT_OPTIONS[0].value],
renderControl,
onUpdate,
});
const user = userEvent.setup();
const clearButton = getByText('Clear');
await user.click(clearButton);
expect(onUpdate).toHaveBeenCalledWith([]);
},
);
});
30 changes: 22 additions & 8 deletions src/components/Select/__tests__/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {act, render} from '@testing-library/react';
import range from 'lodash/range';

import {Select} from '..';
import type {SelectOption, SelectOptionGroup, SelectProps} from '..';
import type {SelectOption, SelectOptionGroup, SelectProps, SelectRenderControlProps} from '..';
import {MobileProvider} from '../../mobile';
import {selectControlBlock, selectControlButtonBlock, selectListBlock} from '../constants';

Expand Down Expand Up @@ -51,24 +51,24 @@ export const ControlledSelect = (props: Partial<SelectProps>) => {
);
};

export function setup(props: Partial<SelectProps> = {}, mobile?: boolean) {
export const setup = (props: Partial<SelectProps> = {}, mobile?: boolean) => {
const utils = render(
<MobileProvider mobile={Boolean(mobile)}>
<ControlledSelect {...props} />
</MobileProvider>,
);
return utils;
}
};

export function timeout(ms: number) {
export const timeout = (ms: number) => {
// https://testing-library.com/docs/react-testing-library/api/#act
// https://reactjs.org/docs/test-utils.html#act
return act(async () => {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
});
}
};

export function generateOptions(args: number | [string, string][]): SelectOption[] {
if (typeof args === 'number') {
Expand All @@ -81,12 +81,26 @@ export function generateOptions(args: number | [string, string][]): SelectOption
return args.map(([value, content]) => ({value, content}));
}

export function generateOptionsGroups(
export const generateOptionsGroups = (
groupsCount: number,
optionsCount: number,
): SelectOptionGroup[] {
): SelectOptionGroup[] => {
return range(0, groupsCount).map((i) => ({
label: `Group ${i + 1}`,
options: generateOptions(optionsCount),
}));
}
};

export const renderControl = (args: SelectRenderControlProps) => {
const {onClear, onClick, onKeyDown, ref} = args;
return (
<div>
<button
ref={ref as React.RefObject<HTMLButtonElement>}
onClick={onClick}
onKeyDown={onKeyDown}
></button>
<button onClick={onClear}>Clear</button>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type ControlProps = {
value: SelectProps['value'];
clearValue: () => void;
hasClear?: boolean;
} & Omit<SelectRenderControlProps, 'onClick'>;
} & Omit<SelectRenderControlProps, 'onClick' | 'onClear'>;

export const SelectControl = React.forwardRef<HTMLButtonElement, ControlProps>((props, ref) => {
const {
Expand Down Expand Up @@ -117,10 +117,11 @@ export const SelectControl = React.forwardRef<HTMLButtonElement, ControlProps>((
return renderControl(
{
onKeyDown,
onClear: clearValue,
onClick: toggleOpen,
renderClear: (arg) => renderClearIcon(arg),
ref,
open: Boolean(open),
renderClear: (arg) => renderClearIcon(arg),
popupId,
selectId,
activeIndex,
Expand Down
3 changes: 2 additions & 1 deletion src/components/Select/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ export type SelectRenderClearArgs = {
};

export type SelectRenderControlProps = {
onClear: () => void;
onClick: (e: React.MouseEvent<HTMLElement>) => void;
onKeyDown: (e: React.KeyboardEvent<HTMLElement>) => void;
renderClear?: (args: SelectRenderClearArgs) => React.ReactNode;
ref: React.Ref<HTMLElement>;
open: boolean;
renderClear?: (args: SelectRenderClearArgs) => React.ReactNode;
popupId: string;
selectId: string;
activeIndex?: number;
Expand Down

0 comments on commit d3af988

Please sign in to comment.