feat: Add oneLine mode to AsyncSelect (#22379)

This commit is contained in:
Kamil Gabryjelski
2022-12-12 16:01:29 +01:00
committed by GitHub
parent 85c9480791
commit a5a0cf9ffb
3 changed files with 73 additions and 1 deletions

View File

@@ -123,6 +123,15 @@ const ARG_TYPES = {
By default label and value.
`,
},
oneLine: {
defaultValue: false,
description: `Sets maxTagCount to 1. The overflow tag is always displayed in
the same line, line wrapping is disabled.
When the dropdown is open, sets maxTagCount to 0,
displays only the overflow tag.
Requires '"mode=multiple"'.
`,
},
};
const USERS = [

View File

@@ -756,6 +756,54 @@ test('finds an element with a numeric value and does not duplicate the options',
expect(await querySelectOption('11')).not.toBeInTheDocument();
});
test('Renders only 1 tag and an overflow tag in oneLine mode', () => {
render(
<AsyncSelect
{...defaultProps}
value={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
mode="multiple"
oneLine
/>,
);
expect(screen.getByText(OPTIONS[0].label)).toBeVisible();
expect(screen.queryByText(OPTIONS[1].label)).not.toBeInTheDocument();
expect(screen.queryByText(OPTIONS[2].label)).not.toBeInTheDocument();
expect(screen.getByText('+ 2 ...')).toBeVisible();
});
test('Renders only an overflow tag if dropdown is open in oneLine mode', async () => {
render(
<AsyncSelect
{...defaultProps}
value={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
mode="multiple"
oneLine
/>,
);
await open();
const withinSelector = within(getElementByClassName('.ant-select-selector'));
await waitFor(() => {
expect(
withinSelector.queryByText(OPTIONS[0].label),
).not.toBeInTheDocument();
expect(
withinSelector.queryByText(OPTIONS[1].label),
).not.toBeInTheDocument();
expect(
withinSelector.queryByText(OPTIONS[2].label),
).not.toBeInTheDocument();
expect(withinSelector.getByText('+ 3 ...')).toBeVisible();
});
await type('{esc}');
expect(await withinSelector.findByText(OPTIONS[0].label)).toBeVisible();
expect(withinSelector.queryByText(OPTIONS[1].label)).not.toBeInTheDocument();
expect(withinSelector.queryByText(OPTIONS[2].label)).not.toBeInTheDocument();
expect(withinSelector.getByText('+ 2 ...')).toBeVisible();
});
/*
TODO: Add tests that require scroll interaction. Needs further investigation.
- Fetches more data when scrolling and more data is available

View File

@@ -71,6 +71,7 @@ import {
TOKEN_SEPARATORS,
DEFAULT_SORT_COMPARATOR,
} from './constants';
import { oneLineTagRender } from './CustomTag';
const Error = ({ error }: { error: string }) => (
<StyledError>
@@ -125,6 +126,8 @@ const AsyncSelect = forwardRef(
tokenSeparators,
value,
getPopupContainer,
oneLine,
maxTagCount: propsMaxTagCount,
...props
}: AsyncSelectProps,
ref: RefObject<AsyncSelectRef>,
@@ -148,6 +151,16 @@ const AsyncSelect = forwardRef(
: 'multiple';
const allowFetch = !fetchOnlyOnSearch || inputValue;
const [maxTagCount, setMaxTagCount] = useState(
propsMaxTagCount ?? MAX_TAG_COUNT,
);
useEffect(() => {
if (oneLine) {
setMaxTagCount(isDropdownVisible ? 0 : 1);
}
}, [isDropdownVisible, oneLine]);
useEffect(() => {
selectValueRef.current = selectValue;
}, [selectValue]);
@@ -487,7 +500,7 @@ const AsyncSelect = forwardRef(
}
headerPosition={headerPosition}
labelInValue
maxTagCount={MAX_TAG_COUNT}
maxTagCount={maxTagCount}
mode={mappedMode}
notFoundContent={isLoading ? t('Loading...') : notFoundContent}
onDeselect={handleOnDeselect}
@@ -513,6 +526,8 @@ const AsyncSelect = forwardRef(
<StyledCheckOutlined iconSize="m" />
)
}
oneLine={oneLine}
tagRender={oneLine ? oneLineTagRender : undefined}
{...props}
ref={ref}
>