Skip to content
Open
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
12 changes: 12 additions & 0 deletions .changeset/fix-select-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@clickhouse/click-ui": patch
---

Fix a few bugs by changing the way Select works with its options: instead of imperative rebuilding of several service entities,
derive them in-flow, “you might not need an effect”.

Bugs fixed:
- search now always works in Selects and matches any text that is rendered in items, including options that arrive while the menu is open
- disabled items can no longer be selected via keyboard navigation

Note: filtered-out items now stay mounted (hidden) instead of unmounting, so their rendered text stays available to search.
56 changes: 28 additions & 28 deletions src/components/CheckboxMultiSelect/CheckboxMultiSelect.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,11 @@ describe('CheckboxCheckboxMultiSelect', () => {
const selectTrigger = getByTestId('select-trigger');
selectTrigger && fireEvent.click(selectTrigger);

expect(queryByText('Content0')).toBeInTheDocument();
expect(queryByText('Content1 long text content')).toBeInTheDocument();
expect(queryByText('Content2')).toBeInTheDocument();
expect(queryByText('Content3')).toBeInTheDocument();
expect(queryByText('Content4')).toBeInTheDocument();
expect(queryByText('Content0')).toBeVisible();
expect(queryByText('Content1 long text content')).toBeVisible();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content3')).toBeVisible();
expect(queryByText('Content4')).toBeVisible();
});

it('filters items by search text', () => {
Expand All @@ -275,16 +275,16 @@ describe('CheckboxCheckboxMultiSelect', () => {
selectTrigger && fireEvent.click(selectTrigger);

expect(queryByText('Group label')).toBeVisible();
expect(queryByText('Content0')).toBeInTheDocument();
expect(queryByText('Content1 long text content')).toBeInTheDocument();
expect(queryByText('Content2')).toBeInTheDocument();
expect(queryByText('Content3')).toBeInTheDocument();
expect(queryByText('Content4')).toBeInTheDocument();
expect(queryByText('Content0')).toBeVisible();
expect(queryByText('Content1 long text content')).toBeVisible();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content3')).toBeVisible();
expect(queryByText('Content4')).toBeVisible();
fireEvent.change(getByTestId('select-search-input'), {
target: { value: 'content2' },
});
expect(queryByText('Content2')).toBeInTheDocument();
expect(queryByText('Content1 long text content')).not.toBeInTheDocument();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content1 long text content')).not.toBeVisible();
expect(queryByText('Group label')).not.toBeVisible();
});

Expand All @@ -299,16 +299,16 @@ describe('CheckboxCheckboxMultiSelect', () => {
selectTrigger && fireEvent.click(selectTrigger);

expect(queryByText('Group label')).toBeVisible();
expect(queryByText('Content0')).toBeInTheDocument();
expect(queryByText('Content1 long text content')).toBeInTheDocument();
expect(queryByText('Content2')).toBeInTheDocument();
expect(queryByText('Content3')).toBeInTheDocument();
expect(queryByText('Content4')).toBeInTheDocument();
expect(queryByText('Content0')).toBeVisible();
expect(queryByText('Content1 long text content')).toBeVisible();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content3')).toBeVisible();
expect(queryByText('Content4')).toBeVisible();
fireEvent.change(getByTestId('select-search-input'), {
target: { value: 'content2' },
});
expect(queryByText('Content2')).toBeInTheDocument();
expect(queryByText('Content1 long text content')).not.toBeInTheDocument();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content1 long text content')).not.toBeVisible();
expect(queryByText('Group label')).not.toBeVisible();
});

Expand All @@ -325,16 +325,16 @@ describe('CheckboxCheckboxMultiSelect', () => {
fireEvent.change(selectInput, {
target: { value: 'content2' },
});
expect(queryByText('Content2')).toBeInTheDocument();
expect(queryByText('Content1 long text content')).not.toBeInTheDocument();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content1 long text content')).not.toBeVisible();
expect(queryByText('Group label')).not.toBeVisible();
fireEvent.click(getByTestId('select-search-close'));
expect(queryByText('Group label')).toBeVisible();
expect(queryByText('Content0')).toBeInTheDocument();
expect(queryByText('Content1 long text content')).toBeInTheDocument();
expect(queryByText('Content2')).toBeInTheDocument();
expect(queryByText('Content3')).toBeInTheDocument();
expect(queryByText('Content4')).toBeInTheDocument();
expect(queryByText('Content0')).toBeVisible();
expect(queryByText('Content1 long text content')).toBeVisible();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content3')).toBeVisible();
expect(queryByText('Content4')).toBeVisible();
expect(document.activeElement).toBe(selectInput);
});

Expand All @@ -350,8 +350,8 @@ describe('CheckboxCheckboxMultiSelect', () => {
fireEvent.change(getByTestId('select-search-input'), {
target: { value: 'nodata' },
});
expect(queryByText('Content2')).not.toBeInTheDocument();
expect(queryByText('Content1 long text content')).not.toBeInTheDocument();
expect(queryByText('Content2')).not.toBeVisible();
expect(queryByText('Content1 long text content')).not.toBeVisible();
expect(queryByText('Group label')).not.toBeVisible();
const btn = queryByText(/No Options found/i);
expect(btn).toBeInTheDocument();
Expand Down
60 changes: 30 additions & 30 deletions src/components/MultiSelect/MultiSelect.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,11 @@ describe('MultiSelect', () => {
expect(selectTrigger).not.toBeNull();
selectTrigger && fireEvent.click(selectTrigger);

expect(queryByText('Content0')).not.toBeNull();
expect(queryByText('Content1 long text content')).not.toBeNull();
expect(queryByText('Content2')).not.toBeNull();
expect(queryByText('Content3')).not.toBeNull();
expect(queryByText('Content4')).not.toBeNull();
expect(queryByText('Content0')).toBeVisible();
expect(queryByText('Content1 long text content')).toBeVisible();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content3')).toBeVisible();
expect(queryByText('Content4')).toBeVisible();
});

it('filter by text', () => {
Expand All @@ -239,16 +239,16 @@ describe('MultiSelect', () => {
selectTrigger && fireEvent.click(selectTrigger);

expect(queryByText('Group label')).toBeVisible();
expect(queryByText('Content0')).not.toBeNull();
expect(queryByText('Content1 long text content')).not.toBeNull();
expect(queryByText('Content2')).not.toBeNull();
expect(queryByText('Content3')).not.toBeNull();
expect(queryByText('Content4')).not.toBeNull();
expect(queryByText('Content0')).toBeVisible();
expect(queryByText('Content1 long text content')).toBeVisible();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content3')).toBeVisible();
expect(queryByText('Content4')).toBeVisible();
fireEvent.change(getByTestId('select-search-input'), {
target: { value: 'content2' },
});
expect(queryByText('Content2')).not.toBeNull();
expect(queryByText('Content1 long text content')).toBeNull();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content1 long text content')).not.toBeVisible();
expect(queryByText('Group label')).not.toBeVisible();
});

Expand All @@ -262,16 +262,16 @@ describe('MultiSelect', () => {
selectTrigger && fireEvent.click(selectTrigger);

expect(queryByText('Group label')).toBeVisible();
expect(queryByText('Content0')).not.toBeNull();
expect(queryByText('Content1 long text content')).not.toBeNull();
expect(queryByText('Content2')).not.toBeNull();
expect(queryByText('Content3')).not.toBeNull();
expect(queryByText('Content4')).not.toBeNull();
expect(queryByText('Content0')).toBeVisible();
expect(queryByText('Content1 long text content')).toBeVisible();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content3')).toBeVisible();
expect(queryByText('Content4')).toBeVisible();
fireEvent.change(getByTestId('select-search-input'), {
target: { value: 'content2' },
});
expect(queryByText('Content2')).not.toBeNull();
expect(queryByText('Content1 long text content')).toBeNull();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content1 long text content')).not.toBeVisible();
expect(queryByText('Group label')).not.toBeVisible();
});

Expand All @@ -287,16 +287,16 @@ describe('MultiSelect', () => {
fireEvent.change(selectInput, {
target: { value: 'content2' },
});
expect(queryByText('Content2')).not.toBeNull();
expect(queryByText('Content1 long text content')).toBeNull();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content1 long text content')).not.toBeVisible();
expect(queryByText('Group label')).not.toBeVisible();
fireEvent.click(getByTestId('select-search-close'));
expect(queryByText('Group label')).toBeVisible();
expect(queryByText('Content0')).not.toBeNull();
expect(queryByText('Content1 long text content')).not.toBeNull();
expect(queryByText('Content2')).not.toBeNull();
expect(queryByText('Content3')).not.toBeNull();
expect(queryByText('Content4')).not.toBeNull();
expect(queryByText('Content0')).toBeVisible();
expect(queryByText('Content1 long text content')).toBeVisible();
expect(queryByText('Content2')).toBeVisible();
expect(queryByText('Content3')).toBeVisible();
expect(queryByText('Content4')).toBeVisible();
expect(document.activeElement).toBe(selectInput);
});
it('on no options available show no data', () => {
Expand All @@ -310,8 +310,8 @@ describe('MultiSelect', () => {
fireEvent.change(getByTestId('select-search-input'), {
target: { value: 'nodata' },
});
expect(queryByText('Content2')).toBeNull();
expect(queryByText('Content1 long text content')).toBeNull();
expect(queryByText('Content2')).not.toBeVisible();
expect(queryByText('Content1 long text content')).not.toBeVisible();
expect(queryByText('Group label')).not.toBeVisible();
const btn = queryByText(/No Options found/i);
expect(btn).not.toBeNull();
Expand All @@ -333,8 +333,8 @@ describe('MultiSelect', () => {
fireEvent.change(getByTestId('select-search-input'), {
target: { value: 'nodata' },
});
expect(queryByText('Content2')).toBeNull();
expect(queryByText('Content1 long text content')).toBeNull();
expect(queryByText('Content2')).not.toBeVisible();
expect(queryByText('Content1 long text content')).not.toBeVisible();
expect(queryByText('Group label')).not.toBeVisible();
const btn = queryByText(/No Field found/i);
expect(btn).not.toBeNull();
Expand Down
Loading
Loading