Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,35 @@ test('do not count unselected disabled options in "Select all"', async () => {
).toBeInTheDocument();
});

test('"Select all" does not count null-valued options', async () => {
// A falsy-valued option (e.g. <NULL>, value: null) is skipped by
// handleSelectAll, so it must not be counted in the "Select all" badge or
// the count overstates the selection. Regression test for #40228. Uses a
// local options array to stay isolated from tests that mutate OPTIONS.
const localOptions = [
{ label: 'Alpha', value: 1 },
{ label: 'Bravo', value: 2 },
];
render(
<Select
{...defaultProps}
options={[...localOptions, NULL_OPTION]}
mode="multiple"
maxTagCount={0}
/>,
);
await open();
// Three options are visible, but the <NULL> option is not bulk-selectable,
// so the badge must count only the two real options (would be 3 before fix).
await userEvent.click(
await screen.findByText(selectAllButtonText(localOptions.length)),
);
// And Select all selects exactly those two — the null option is skipped.
const values = await findAllSelectValues();
expect(values.length).toBe(1);
expect(values[0]).toHaveTextContent(`+ ${localOptions.length} ...`);
});

test('"Deselect all" counts all selected options', async () => {
render(<Select {...defaultProps} allowNewOptions mode="multiple" />);
await open();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,12 @@ const Select = forwardRef(
const isDisabled = option.disabled;
const isNew = option.isNewOption;

// Mirror handleSelectAll, which skips falsy-valued options (e.g. the
// <NULL> option whose value is null): they are not bulk-selectable,
// so counting them here makes the "Select all" badge overstate what
// gets selected.
if (
option.value &&
(!isDisabled || isSelected) &&
((isNew && isSelected) || !isNew)
) {
Expand Down
Loading