Skip to content

Commit

Permalink
fix: remove reach dependencies, refactor InputSearch
Browse files Browse the repository at this point in the history
  • Loading branch information
wp-aberg committed Jun 18, 2024
1 parent 0b669d6 commit 4423ca7
Show file tree
Hide file tree
Showing 20 changed files with 2,349 additions and 279 deletions.
5 changes: 2 additions & 3 deletions build.washingtonpost.com/docs/components/input-search.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,14 @@ export default function Example() {
/>
))}
{results2.length > 3 && (
<>
<InputSearch.ListHeading>Group</InputSearch.ListHeading>
<InputSearch.ListHeading title="Group">
{results2.slice(3).map((city) => (
<InputSearch.ListItem
key={`${city.name.toLowerCase()}, ${city.state.toLowerCase()}`}
value={`${city.name}, ${city.state}`}
/>
))}
</>
</InputSearch.ListHeading>
)}
</InputSearch.List>
) : (
Expand Down
1,577 changes: 1,575 additions & 2 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions packages/kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,16 @@
"@radix-ui/react-tabs": "latest",
"@radix-ui/react-tooltip": "^1.0.0",
"@radix-ui/react-use-controllable-state": "^1.0.1",
"@reach/combobox": "^0.18.0",
"@reach/popover": "^0.18.0",
"@react-types/combobox": "^3.11.1",
"@react-types/shared": "^3.23.1",
"@stitches/react": "^1.2.8",
"@washingtonpost/wpds-assets": "2.0.0",
"match-sorter": "6.3.1",
"nanoid": "^3.3.4",
"popper-max-size-modifier": "^0.2.0",
"react-popper": "^2.2.5",
"react-aria": "^3.33.1",
"react-stately": "^3.31.1",
"react-swipeable": "^7.0.0",
"react-transition-group": "^4.4.5"
},
Expand Down
220 changes: 176 additions & 44 deletions packages/kit/src/input-search/InputSearchInput.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { render, screen } from "@testing-library/react";
// eslint-disable-next-line import/no-named-as-default
import userEvent from "@testing-library/user-event";
import { InputSearchInput } from "./InputSearchInput";
import { InputSearchRoot } from "./InputSearchRoot";
import { InputSearchPopover } from "./InputSearchPopover";
import { Icon } from "../icon";
import { Settings } from "@washingtonpost/wpds-assets";
import { InputSearchList } from "./InputSearchList";
import { InputSearchListItem } from "./InputSearchListItem";
import { theme } from "../theme";

describe("InputSearchInput", () => {
Expand All @@ -16,63 +18,193 @@ describe("InputSearchInput", () => {
}}
>
{ui}
<InputSearchPopover {...contextProps} />
<InputSearchPopover {...contextProps}>
<InputSearchList>
<InputSearchListItem value="Test item" />
</InputSearchList>
</InputSearchPopover>
</InputSearchRoot>
);
};

test("renders visibly into the document", () => {
customRender(<InputSearchInput name="test" id="test" label="Test" />, {});
expect(screen.getByLabelText("Test")).toBeInTheDocument();
customRender(<InputSearchInput name="test" id="test" />, {});
expect(screen.getByRole("combobox")).toBeInTheDocument();
});

test("uses contexts portal prop", () => {
customRender(<InputSearchInput name="test" id="test" label="Test" />, {
portal: false,
});
expect(screen.getByTestId("border-style-override")).toHaveStyle(
"--wpds-colors-signal: var(--wpds-colors-subtle)"
test("renders with custom CSS class", () => {
customRender(
<InputSearchInput name="test" id="test" css={{ color: "red" }} />,
{}
);
expect(screen.getByRole("combobox")).toHaveClass(/wpds-.*-css/);
});

test("uses the error prop", () => {
customRender(<InputSearchInput name="test" id="test" error />, {});
expect(screen.getByTestId("input-text-container")).toHaveClass(
/wpds-.*-isInvalid-true/
);
});

test("uses the success prop", () => {
customRender(<InputSearchInput name="test" id="test" success />, {});
expect(screen.getByTestId("input-text-container")).toHaveClass(
/wpds-.*-isSuccessful-true/
);
});

test("uses the disabled prop", () => {
customRender(<InputSearchInput name="test" id="test" disabled />, {});
expect(screen.getByRole("combobox")).toBeDisabled();
});

test("uses the label", () => {
const labelText = "Test";
customRender(
<InputSearchInput name="test" id="test" label="Test" error />,
<InputSearchInput name="test" id="test" label={labelText} />,
{}
);
expect(screen.getByTestId("input-text-container")).toHaveClass(
/wpds-.*-isInvalid-true/
expect(screen.getByLabelText(labelText)).toBeInTheDocument();
});

/** must be managed by react-stately / react-aria */
test.skip("uses id", () => {
customRender(<InputSearchInput name="test" id="test" />, {});
expect(screen.getByRole("combobox")).toHaveAttribute("id", "test");
});

test("uses name", () => {
customRender(<InputSearchInput name="test" id="test" />, {});
expect(screen.getByRole("combobox")).toHaveAttribute("name", "test");
});

test("uses name", () => {
customRender(<InputSearchInput name="test" id="test" />, {});
expect(screen.getByRole("combobox")).toHaveAttribute("name", "test");
});

test("uses placeholder", () => {
customRender(
<InputSearchInput name="test" id="test" placeholder="Test" />,
{}
);
expect(screen.getByRole("combobox")).toHaveAttribute("placeholder", "Test");
});

test("renders with custom CSS class", () => {
customRender(
<InputSearchInput name="test" id="test" css={{ color: "red" }} />,
{}
);
expect(screen.getByRole("combobox")).toHaveClass(/wpds-.*-css/);
});

test("shows as required", () => {
customRender(<InputSearchInput name="test" id="test" required />, {});
expect(screen.getByText("*")).toBeInTheDocument();
});

test("uses the value prop", () => {
customRender(<InputSearchInput name="test" id="test" value="Test" />, {});
expect(screen.getByRole("combobox")).toHaveValue("Test");
});

test("uses the buttonIconText prop", () => {
const buttonIconText = "Click to search";
customRender(
<InputSearchInput
name="test"
id="test"
buttonIconText={buttonIconText}
/>,
{}
);
expect(screen.getByText(buttonIconText)).toBeInTheDocument();
});

/*
success
disabled
label
as
defaultValue
id
placeholder
onFocus
onBlur
onChange
css
required
name
type
value
selectOnClick
autocomplete
buttonIconText
buttonIconType
errorMessage
helperText
onButtonIconClick
*/

/*
OMIT
icon
children
*/
test("uses the buttonIconType prop", () => {
customRender(
<InputSearchInput name="test" id="test" buttonIconType="submit" />,
{}
);
expect(screen.getByRole("button")).toHaveAttribute("type", "submit");
});

test("uses the errorMessage prop", () => {
customRender(
<InputSearchInput name="test" id="test" errorMessage="Error" />,
{}
);
expect(screen.getByText("Error")).toBeInTheDocument();
});

test("uses the helperText prop", () => {
customRender(
<InputSearchInput name="test" id="test" helperText="Help" />,
{}
);
expect(screen.getByText("Help")).toBeInTheDocument();
});

test("uses the onFocus event handler", () => {
const onFocus = jest.fn();
customRender(
<InputSearchInput name="test" id="test" onFocus={onFocus} />,
{}
);
screen.getByRole("combobox").focus();
expect(onFocus).toHaveBeenCalled();
});

test("uses the onBlur event handler", () => {
const onBlur = jest.fn();
customRender(
<InputSearchInput name="test" id="test" onBlur={onBlur} />,
{}
);
const input = screen.getByRole("combobox");
input.focus();
input.blur();

expect(onBlur).toHaveBeenCalled();
});

test("uses the onChange event handler", async () => {
const user = userEvent.setup();
const onChange = jest.fn();
customRender(
<InputSearchInput name="test" id="test" onChange={onChange} />,
{}
);

await user.keyboard("Test");

expect(onChange).toHaveBeenCalled;
});

test("uses the onButtonIconClick event handler", async () => {
const user = userEvent.setup();
const onButtonIconClick = jest.fn();
customRender(
<InputSearchInput
name="test"
id="test"
onButtonIconClick={onButtonIconClick}
/>,
{}
);
await user.click(screen.getByRole("button"));
expect(onButtonIconClick).toHaveBeenCalled();
});

test("updates the value when an item is highlighted", async () => {
const user = userEvent.setup();
customRender(<InputSearchInput name="test" id="test" />, {});
const inputElement = screen.getByRole("combobox");
await user.click(inputElement);
await user.keyboard("T");
await user.keyboard("[ArrowDown]");
expect(inputElement).toHaveValue("Test item");
});
});
Loading

0 comments on commit 4423ca7

Please sign in to comment.