Skip to content

Commit

Permalink
[@mantine/core] Add option to display nothingFoundMessage when data…
Browse files Browse the repository at this point in the history
… is empty in Select and MultiSelect components (#6477)

* [@mantine/core] MultiSelect: Show not found message when not searchable

* [@mantine/core] Select: Show not found message when not searchable

* [mantine.dev] update the notFoundMessage prop information
  • Loading branch information
AustinWildgrube authored Jul 2, 2024
1 parent 508991c commit a8404e9
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 14 deletions.
5 changes: 2 additions & 3 deletions apps/mantine.dev/src/pages/core/multi-select.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,8 @@ function Demo() {

## Nothing found

Set `nothingFoundMessage` prop to display given message when no options match search query.
If `nothingFoundMessage` is not set, `MultiSelect` dropdown will be hidden when no options match search query.
The message is not displayed when trimmed search query is empty.
Set the `nothingFoundMessage` prop to display a given message when no options match the search query
or there is no data available. If the `nothingFoundMessage` prop is not set, the `MultiSelect` dropdown will be hidden.

<Demo data={MultiSelectDemos.nothingFound} />

Expand Down
5 changes: 2 additions & 3 deletions apps/mantine.dev/src/pages/core/select.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,8 @@ function Demo() {

## Nothing found

Set `nothingFoundMessage` prop to display given message when no options match search query.
If `nothingFoundMessage` is not set, `Select` dropdown will be hidden when no options match search query.
The message is not displayed when trimmed search query is empty.
Set the `nothingFoundMessage` prop to display a given message when no options match the search query
or there is no data available. If the `nothingFoundMessage` prop is not set, the `Select` dropdown will be hidden.

<Demo data={SelectDemos.nothingFound} />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,17 @@ describe('@mantine/core/MultiSelect', () => {
await userEvent.click(screen.getByRole('textbox'));
expect(screen.queryByRole('listbox')).toBe(null);
});

it('displays the nothing found message if no options matched the search query', async () => {
render(<MultiSelect {...defaultProps} searchable nothingFoundMessage="Nothing found" />);
await userEvent.click(screen.getByRole('textbox'));
await userEvent.type(screen.getByRole('textbox'), 'test-3');
expect(screen.getByText('Nothing found')).toBeVisible();
});

it('displays the nothing found message if there is no data', async () => {
render(<MultiSelect {...defaultProps} data={[]} nothingFoundMessage="No data" />);
await userEvent.click(screen.getByRole('textbox'));
expect(screen.getByText('No data')).toBeVisible();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export interface MultiSelectProps
/** Determines whether the select should be searchable, `false` by default */
searchable?: boolean;

/** Message displayed when no option matched current search query, only applicable when `searchable` prop is set */
/** Message displayed when no option matches the current search query while the `searchable` prop is set or there is no data */
nothingFoundMessage?: React.ReactNode;

/** Determines whether check icon should be displayed near the selected option label, `true` by default */
Expand Down Expand Up @@ -408,11 +408,7 @@ export const MultiSelect = factory<MultiSelectFactory>((_props, ref) => {
filter={filter}
search={_searchValue}
limit={limit}
hiddenWhenEmpty={
!searchable ||
!nothingFoundMessage ||
(hidePickedOptions && filteredData.length === 0 && _searchValue.trim().length === 0)
}
hiddenWhenEmpty={!nothingFoundMessage}
withScrollArea={withScrollArea}
maxDropdownHeight={maxDropdownHeight}
filterOptions={searchable}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,18 @@ export function Searchable() {
);
}

export function NoDataProvidedMessage() {
return (
<div style={{ padding: 40 }}>
<MultiSelect
data={[]}
placeholder="MultiSelect something"
nothingFoundMessage="Try adding some data..."
/>
</div>
);
}

export function SearchableHidePicked() {
return (
<div style={{ padding: 40 }}>
Expand Down
12 changes: 12 additions & 0 deletions packages/@mantine/core/src/components/Select/Select.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,18 @@ export function Searchable() {
);
}

export function NoDataProvidedMessage() {
return (
<div style={{ padding: 40 }}>
<Select
data={[]}
placeholder="Select something"
nothingFoundMessage="Try adding some data..."
/>
</div>
);
}

export function HiddenDropdown() {
return (
<div style={{ padding: 40 }}>
Expand Down
6 changes: 6 additions & 0 deletions packages/@mantine/core/src/components/Select/Select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ describe('@mantine/core/Select', () => {
expect(screen.getByText('Nothing found')).toBeVisible();
});

it('displays the nothing found message if there is no data', async () => {
render(<Select {...defaultProps} data={[]} nothingFoundMessage="No data" />);
await userEvent.click(screen.getByRole('textbox'));
expect(screen.getByText('No data')).toBeVisible();
});

it('allows controlling search value with searchValue prop', async () => {
render(<Select {...defaultProps} searchable searchValue="test-1" />);
await userEvent.click(screen.getByRole('textbox'));
Expand Down
4 changes: 2 additions & 2 deletions packages/@mantine/core/src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export interface SelectProps
/** Position of the check icon relative to the option label, `'left'` by default */
checkIconPosition?: 'left' | 'right';

/** Message displayed when no option matched current search query, only applicable when `searchable` prop is set */
/** Message displayed when no option matches the current search query while the `searchable` prop is set or there is no data */
nothingFoundMessage?: React.ReactNode;

/** Controlled search value */
Expand Down Expand Up @@ -296,7 +296,7 @@ export const Select = factory<SelectFactory>((_props, ref) => {
filter={filter}
search={search}
limit={limit}
hiddenWhenEmpty={!searchable || !nothingFoundMessage}
hiddenWhenEmpty={!nothingFoundMessage}
withScrollArea={withScrollArea}
maxDropdownHeight={maxDropdownHeight}
filterOptions={searchable && selectedOption?.label !== search}
Expand Down

0 comments on commit a8404e9

Please sign in to comment.