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

fix: make the icons and indicators in the select accessible #1462

Merged
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
24 changes: 12 additions & 12 deletions cypress/e2e/components/AsyncSelect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,41 @@ describe("AsyncSelect", () => {
it("can select multiple values", () => {
getMultiselect().click();

cy.focused().type("cana");
assertDropDownIsOpen().contains("Canada");
cy.focused().type("on");
assertDropDownIsOpen().contains("Ontario");
cy.focused().type("{enter}");

cy.focused().type("mex");
assertDropDownIsOpen().contains("Mexico");
cy.focused().type("qu");
assertDropDownIsOpen().contains("Quebec");
cy.focused().type("{enter}");

getMultiselect().contains("Canada");
getMultiselect().contains("Mexico");
getMultiselect().contains("Ontario");
getMultiselect().contains("Quebec");
});

describe("clears selected values", () => {
it("clears all multiselect values", () => {
getMultiselect().click();

cy.focused().type("cana");
assertDropDownIsOpen().contains("Canada");
cy.focused().type("on");
assertDropDownIsOpen().contains("Ontario");
cy.focused().type("{enter}");

getClearButton().click();

getMultiselect().contains("Select countries");
getMultiselect().contains("Enter a province");
});

it("clears single-select values", () => {
getSelectComponent().click();

cy.focused().type("cana");
assertDropDownIsOpen().contains("Canada");
cy.focused().type("on");
assertDropDownIsOpen().contains("Ontario");
cy.focused().type("{enter}");

getClearButton().click();

getMultiselect().contains("Select countries");
getMultiselect().contains("Enter a province");
});
});

Expand Down
91 changes: 37 additions & 54 deletions src/AsyncSelect/AsyncSelect.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,13 @@ import React, { useRef } from "react";
import { action } from "@storybook/addon-actions";
import { useState } from "react";
import { AsyncSelect, Button } from "../index";
import simulatedAPIRequest from "../utils/story/simulatedAPIRequest";

const northAmericanCountries = [
{
value: "Canada",
label: "Canada",
},
{
value: "United States",
label: "United States",
},
{
value: "Mexico",
label: "Mexico",
},
];

const loadMatchingCountries = async (inputValue: string) => {
const data = await simulatedAPIRequest(inputValue, northAmericanCountries);
const results = await data.json();

return results.map(({ name }) => ({
label: name,
value: name,
}));
import { filterOptions } from "../utils/story/simulatedAPIRequests";
import { provinces } from "./fixtures";
import { Flex } from "../Flex";

const loadMatchingProvinces = async (inputValue: string) => {
const data = await filterOptions(inputValue, provinces);
return await data.json();
};

export default {
Expand All @@ -35,14 +17,14 @@ export default {

export const Default = () => (
<AsyncSelect
placeholder="Please select a country"
placeholder="Enter a province"
onChange={action("selection changed")}
onBlur={action("blurred")}
className="Select"
classNamePrefix="SelectTest"
labelText="Country"
labelText="Province"
onInputChange={action("typed input value changed")}
loadOptions={loadMatchingCountries}
loadOptions={loadMatchingProvinces}
/>
);

Expand All @@ -52,25 +34,25 @@ Default.story = {

export const WithDefaultOptions = () => (
<AsyncSelect
placeholder="Filter Countries"
placeholder="Enter a province"
onChange={action("selection changed")}
onBlur={action("blurred")}
className="Select"
classNamePrefix="SelectTest"
labelText="Country"
labelText="Province"
onInputChange={action("typed input value changed")}
isClearable
defaultOptions={[
{
value: "Canada",
label: "Canada",
value: "ON",
label: "Ontario",
},
{
value: "United States",
label: "United States",
value: "QC",
label: "Quebec",
},
]}
loadOptions={loadMatchingCountries}
loadOptions={loadMatchingProvinces}
/>
);

Expand All @@ -80,15 +62,15 @@ WithDefaultOptions.story = {

export const WithADefaultValue = () => (
<AsyncSelect
placeholder="Please select a country"
placeholder="Enter a province"
onChange={action("selection changed")}
onBlur={action("blurred")}
className="Select"
classNamePrefix="SelectTest"
labelText="Country"
defaultValue="Can"
labelText="Province"
defaultValue="Ontario"
onInputChange={action("typed input value changed")}
loadOptions={loadMatchingCountries}
loadOptions={loadMatchingProvinces}
/>
);

Expand All @@ -98,29 +80,29 @@ WithADefaultValue.story = {

export const Multiselect = () => (
<AsyncSelect
placeholder="Select countries"
placeholder="Enter a province"
onChange={action("selection changed")}
onBlur={action("blurred")}
className="Select"
classNamePrefix="SelectTest"
labelText="Countries"
labelText="Provinces"
multiselect
onInputChange={action("typed input value changed")}
loadOptions={loadMatchingCountries}
loadOptions={loadMatchingProvinces}
/>
);

export const WithAClearButton = () => (
<AsyncSelect
placeholder="Select countries"
placeholder="Enter a province"
onChange={action("selection changed")}
onBlur={action("blurred")}
className="Select"
classNamePrefix="SelectTest"
labelText="Countries"
labelText="Provinces"
isClearable
onInputChange={action("typed input value changed")}
loadOptions={loadMatchingCountries}
loadOptions={loadMatchingProvinces}
/>
);

Expand All @@ -131,21 +113,21 @@ export const UsingRefToControlFocus = () => {
};

return (
<>
<Flex gap="x2" flexDirection="column">
<AsyncSelect
ref={ref}
placeholder="Please select a country"
placeholder="Enter a province"
onChange={action("selection changed")}
onBlur={action("blurred")}
className="Select"
classNamePrefix="SelectTest"
labelText="Country"
defaultValue="Can"
labelText="Province"
defaultValue="Ontario"
onInputChange={action("typed input value changed")}
loadOptions={loadMatchingCountries}
loadOptions={loadMatchingProvinces}
/>
<Button onClick={handleClick}>Focus the Input</Button>
</>
</Flex>
);
};

Expand All @@ -164,12 +146,13 @@ export const Controlled = () => {
};

return (
<>
<AsyncSelect onChange={handleChange} value={value} labelText="Country" loadOptions={loadMatchingCountries} />
<Flex gap="x2" flexDirection="column">
<AsyncSelect onChange={handleChange} value={value} labelText="Province" loadOptions={loadMatchingProvinces} />
<Button onClick={handleClear}>Clear</Button>
</>
</Flex>
);
};

Controlled.story = {
name: "controlled",
};
54 changes: 54 additions & 0 deletions src/AsyncSelect/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
export const provinces = [
{
label: "Alberta",
value: "AB",
},
{
label: "British Columbia",
value: "BC",
},
{
label: "Manitoba",
value: "MB",
},
{
label: "New Brunswick",
value: "NB",
},
{
label: "Newfoundland and Labrador",
value: "NL",
},
{
label: "Northwest Territories",
value: "NT",
},
{
label: "Nova Scotia",
value: "NS",
},
{
label: "Nunavut",
value: "NU",
},
{
label: "Ontario",
value: "ON",
},
{
label: "Prince Edward Island",
value: "PE",
},
{
label: "Quebec",
value: "QC",
},
{
label: "Saskatchewan",
value: "SK",
},
{
label: "Yukon Territory",
value: "YT",
},
];
12 changes: 6 additions & 6 deletions src/Select/Select.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ WithCloseMenuOnSelectTurnedOff.story = {
};

export const TestMultiselectOverflow = () => (
<>
<Flex gap="x2" flexDirection="column">
<Select
defaultValue={["accepted", "assigned"]}
noOptionsMessage={() => "No options"}
Expand Down Expand Up @@ -517,7 +517,7 @@ export const TestMultiselectOverflow = () => (
onInputChange={action("typed input value changed")}
/>
</Box>
</>
</Flex>
);

TestMultiselectOverflow.story = {
Expand Down Expand Up @@ -551,10 +551,10 @@ WithFixedPositioning.story = {
};

export const WithFetchedOptions = () => (
<Box style={{ width: "300px" }}>
<Flex flexDirection="column" gap="x2" width="300px">
<SelectWithManyOptions labelText="Select from many options:" />
<SelectWithManyOptions multiselect labelText="Multiselect many options:" />
</Box>
</Flex>
);

export const WithCustomOptionComponent = () => {
Expand Down Expand Up @@ -609,7 +609,7 @@ export const UsingRefToControlFocus = () => {
};

return (
<>
<Flex flexDirection="column" gap="x2">
<Select
defaultValue={["accepted"]}
noOptionsMessage={() => "No options"}
Expand All @@ -621,7 +621,7 @@ export const UsingRefToControlFocus = () => {
menuPosition="fixed"
/>
<Button onClick={handleClick}>Focus the Input</Button>
</>
</Flex>
);
};

Expand Down
33 changes: 17 additions & 16 deletions src/Select/customReactSelectStyles.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,23 @@ import { getControlBorderRadius, getMenuBorderRadius, showIndicatorSeparator } f

describe("custom react-select styles", () => {
describe("showIndicatorSeparator", () => {
test.each`
isMulti | hasValue | hasDefaultOptions | expected
${true} | ${true} | ${true} | ${true}
${true} | ${false} | ${false} | ${false}
${false} | ${true} | ${false} | ${false}
${false} | ${false} | ${true} | ${false}
${true} | ${true} | ${false} | ${false}
${false} | ${true} | ${true} | ${false}
${true} | ${false} | ${true} | ${false}
${false} | ${false} | ${false} | ${false}
`(
"returns $expected when isMulti is $isMulti, hasValue is $hasValue, and hasDefaultOptions is $hasDefaultOptions",
({ isMulti, hasValue, hasDefaultOptions, expected }) => {
expect(showIndicatorSeparator({ isMulti, hasValue, hasDefaultOptions })).toBe(expected);
}
);
it("should not show the indicator separator when the select has no value", () => {
const result = showIndicatorSeparator({ hasValue: false, isClearable: true, isMulti: true });

expect(result).toEqual(false);
});

it("should show the indicator separator when the select allows multiple selections", () => {
const result = showIndicatorSeparator({ hasValue: true, isClearable: false, isMulti: true });

expect(result).toEqual(true);
});

it("should show the indicator separator when the select is clearable", () => {
const result = showIndicatorSeparator({ hasValue: true, isClearable: false, isMulti: true });

expect(result).toEqual(true);
});
});

describe("getControlBorderRadius", () => {
Expand Down
Loading
Loading