Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clear methods to work with custom components #54

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
48 changes: 45 additions & 3 deletions src/__tests__/select-event.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import "@testing-library/jest-dom/extend-expect";
import { fireEvent, render } from "@testing-library/react";

import React from "react";
import Select from "react-select";
import Select, { components } from "react-select";
import selectEvent from "..";

let Async: any;
Expand Down Expand Up @@ -232,7 +232,7 @@ describe("The select event helpers", () => {
<Select {...defaultProps} defaultValue={OPTIONS[0]} isClearable />
);
expect(form).toHaveFormValues({ food: "chocolate" });
await selectEvent.clearFirst(input);
await selectEvent.clearAll(input);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you revert this change? This test case tests the clearFirst utility.

expect(form).toHaveFormValues({ food: "" });
});

Expand All @@ -241,7 +241,7 @@ describe("The select event helpers", () => {
<Select {...defaultProps} defaultValue={OPTIONS[0]} isClearable />
);
expect(form).toHaveFormValues({ food: "chocolate" });
await selectEvent.clearFirst(input);
await selectEvent.clearAll(input);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, let’s leave the clearFirst

expect(form).toHaveFormValues({ food: "" });
await selectEvent.select(input, "Chocolate");
expect(form).toHaveFormValues({ food: "chocolate" });
Expand Down Expand Up @@ -420,3 +420,45 @@ describe("The select event helpers", () => {
});
});
});

describe("Custom components", () => {
const MultiValueRemove = (props: any) => <components.MultiValueRemove {...props}><span>X</span></components.MultiValueRemove>
const ClearIndicator = (props: any) => <components.ClearIndicator {...props}><span>X</span></components.ClearIndicator>

it('clears all the items', async () => {
const { form, input } = renderForm(
<Creatable
{...defaultProps}
isMulti
defaultValue={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
components={{
ClearIndicator,
}}
/>
);
expect(form).toHaveFormValues({
food: ["chocolate", "vanilla", "strawberry"],
});

await selectEvent.clearAll(input);
expect(form).toHaveFormValues({ food: "" });
})
it('clears the first item', async () => {
const { form, input } = renderForm(
<Creatable
{...defaultProps}
isMulti
defaultValue={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
components={{
MultiValueRemove,
}}
/>
);
expect(form).toHaveFormValues({
food: ["chocolate", "vanilla", "strawberry"],
});

await selectEvent.clearFirst(input);
expect(form).toHaveFormValues({ food: ["vanilla", "strawberry"] });
})
})
12 changes: 6 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@ export const create = async (
*/
export const clearFirst = async (input: HTMLElement) => {
const container = getReactSelectContainerFromInput(input);
// The "clear" button is the first svg element that is hidden to screen readers
const clearButton = container.querySelector('svg[aria-hidden="true"]')!;
// The "clear" button is constructed from the user-defined `${classNamePrefix}__multi-value__remove`.
// This is built from the internal util `cx` of react-select, so we take advantage of the attribute selector here.
const clearButton = container.querySelector('[class*="multi-value__remove"]')!;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to keep backwards compatibility with older react-select versions.

What would be the best way to achieve this?
Do we need to default to the svg selector of the new one doesn’t match anything?

await clear(input, clearButton);
};

Expand All @@ -138,10 +139,9 @@ export const clearFirst = async (input: HTMLElement) => {
*/
export const clearAll = async (input: HTMLElement) => {
const container = getReactSelectContainerFromInput(input);
// The "clear all" button is the penultimate svg element that is hidden to screen readers
// (the last one is the dropdown arrow)
const elements = container.querySelectorAll('svg[aria-hidden="true"]');
const clearAllButton = elements[elements.length - 2];
// The "clear all" button is constructed from the user-defined `${classNamePrefix}__multi-value__remove`.
// This is built from the internal util `cx` of react-select, so we take advantage of the attribute selector here.
const clearAllButton = container.querySelector('[class*="clear-indicator"]')!;
await clear(input, clearAllButton);
};

Expand Down