When a customer builds a tasting box, they move teas from a list of what's available to a list of what they've chosen. Build App: it takes left and right, the starting lists of tea names (strings, unique across both lists). When they aren't given, as in the Preview, use a few names of your own.
Show two lists side by side: a <section> titled by an <h2> reading Available (the left list) and one titled Chosen (the right list), each section labelled by its heading through aria-labelledby. Each tea is an <li> with a <label> holding a checkbox and the tea's name. Every checkbox starts unchecked. A list with no teas shows No teas instead.
Between the lists are four buttons, named with aria-label: Move all right, Move selected right, Move selected left, and Move all left (their text can be », ›, ‹, «). The selected buttons move the checked teas on their side; the all buttons move every tea on their side. Moved teas go to the end of the other list, in the order they were in, and arrive unchecked. Checks on the other side stay as they were.
A button that would move nothing is disabled: Move selected right while no tea in Available is checked, Move all right while Available is empty, and the same for the left buttons with Chosen. Don't change the arrays you're given.
<App left={["Sencha", "Assam", "Oolong"]} right={["Chai"]} />
// check Oolong and Sencha, then press Move selected right:
// Available: Assam
// Chosen: Chai, Sencha, Oolong
const left = ["Sencha", "Assam", "Oolong", "Rooibos"];
const right = ["Chai"];
const teasIn = (name) => within(screen.getByRole("region", { name })).queryAllByRole("listitem").map((li) => li.textContent.trim());
const button = (name) => screen.getByRole("button", { name });
render(<App left={left} right={right} />);
expect(teasIn("Available")).toEqual(["Sencha", "Assam", "Oolong", "Rooibos"]);
expect(teasIn("Chosen")).toEqual(["Chai"]);
expect(screen.getAllByRole("checkbox").some((input) => input.checked)).toBe(false);
const left = ["Sencha", "Assam", "Oolong", "Rooibos"];
const right = ["Chai"];
const teasIn = (name) => within(screen.getByRole("region", { name })).queryAllByRole("listitem").map((li) => li.textContent.trim());
const button = (name) => screen.getByRole("button", { name });
render(<App left={left} right={right} />);
expect(button("Move selected right")).toBeDisabled();
expect(button("Move selected left")).toBeDisabled();
await user.click(screen.getByRole("checkbox", { name: "Chai" }));
expect(button("Move selected left")).toBeEnabled();
expect(button("Move selected right")).toBeDisabled();
await user.click(screen.getByRole("checkbox", { name: "Chai" }));
await user.click(screen.getByRole("checkbox", { name: "Assam" }));
expect(button("Move selected right")).toBeEnabled();
expect(button("Move selected left")).toBeDisabled();
const left = ["Sencha", "Assam", "Oolong", "Rooibos"];
const right = ["Chai"];
const teasIn = (name) => within(screen.getByRole("region", { name })).queryAllByRole("listitem").map((li) => li.textContent.trim());
const button = (name) => screen.getByRole("button", { name });
render(<App left={left} right={right} />);
await user.click(screen.getByRole("checkbox", { name: "Oolong" }));
await user.click(screen.getByRole("checkbox", { name: "Sencha" }));
await user.click(button("Move selected right"));
expect(teasIn("Available")).toEqual(["Assam", "Rooibos"]);
expect(teasIn("Chosen")).toEqual(["Chai", "Sencha", "Oolong"]);
expect(screen.getByRole("checkbox", { name: "Sencha" })).not.toBeChecked();
expect(screen.getByRole("checkbox", { name: "Oolong" })).not.toBeChecked();
expect(button("Move selected right")).toBeDisabled();
expect(button("Move selected left")).toBeDisabled();
const left = ["Sencha", "Assam", "Oolong", "Rooibos"];
const right = ["Chai"];
const teasIn = (name) => within(screen.getByRole("region", { name })).queryAllByRole("listitem").map((li) => li.textContent.trim());
const button = (name) => screen.getByRole("button", { name });
render(<App left={left} right={["Chai", "Mint", "Earl Grey"]} />);
await user.click(screen.getByRole("checkbox", { name: "Earl Grey" }));
await user.click(screen.getByRole("checkbox", { name: "Chai" }));
await user.click(button("Move selected left"));
expect(teasIn("Available")).toEqual(["Sencha", "Assam", "Oolong", "Rooibos", "Chai", "Earl Grey"]);
expect(teasIn("Chosen")).toEqual(["Mint"]);
const left = ["Sencha", "Assam", "Oolong", "Rooibos"];
const right = ["Chai"];
const teasIn = (name) => within(screen.getByRole("region", { name })).queryAllByRole("listitem").map((li) => li.textContent.trim());
const button = (name) => screen.getByRole("button", { name });
render(<App left={left} right={right} />);
await user.click(screen.getByRole("checkbox", { name: "Chai" }));
await user.click(screen.getByRole("checkbox", { name: "Assam" }));
await user.click(button("Move selected right"));
expect(screen.getByRole("checkbox", { name: "Chai" })).toBeChecked();
expect(screen.getByRole("checkbox", { name: "Assam" })).not.toBeChecked();
await user.click(button("Move selected left"));
expect(teasIn("Available")).toEqual(["Sencha", "Oolong", "Rooibos", "Chai"]);
expect(teasIn("Chosen")).toEqual(["Assam"]);
const left = ["Sencha", "Assam", "Oolong", "Rooibos"];
const right = ["Chai"];
const teasIn = (name) => within(screen.getByRole("region", { name })).queryAllByRole("listitem").map((li) => li.textContent.trim());
const button = (name) => screen.getByRole("button", { name });
render(<App left={left} right={right} />);
await user.click(screen.getByRole("checkbox", { name: "Rooibos" }));
await user.click(button("Move all right"));
expect(teasIn("Chosen")).toEqual(["Chai", "Sencha", "Assam", "Oolong", "Rooibos"]);
expect(screen.getByRole("checkbox", { name: "Rooibos" })).not.toBeChecked();
expect(button("Move all right")).toBeDisabled();
expect(button("Move selected right")).toBeDisabled();
await user.click(button("Move all left"));
expect(teasIn("Available")).toEqual(["Chai", "Sencha", "Assam", "Oolong", "Rooibos"]);
expect(teasIn("Chosen")).toEqual([]);
expect(button("Move all left")).toBeDisabled();
const left = ["Sencha", "Assam", "Oolong", "Rooibos"];
const right = ["Chai"];
const teasIn = (name) => within(screen.getByRole("region", { name })).queryAllByRole("listitem").map((li) => li.textContent.trim());
const button = (name) => screen.getByRole("button", { name });
render(<App left={left} right={[]} />);
expect(within(screen.getByRole("region", { name: "Chosen" })).getByText("No teas")).toBeInTheDocument();
expect(button("Move all left")).toBeDisabled();
expect(button("Move all right")).toBeEnabled();
await user.click(button("Move all right"));
expect(within(screen.getByRole("region", { name: "Available" })).getByText("No teas")).toBeInTheDocument();
expect(within(screen.getByRole("region", { name: "Chosen" })).queryByText("No teas")).not.toBeInTheDocument();
const left = ["Sencha", "Assam", "Oolong", "Rooibos"];
const right = ["Chai"];
const teasIn = (name) => within(screen.getByRole("region", { name })).queryAllByRole("listitem").map((li) => li.textContent.trim());
const button = (name) => screen.getByRole("button", { name });
const frozenLeft = Object.freeze([...left]);
const frozenRight = Object.freeze([...right]);
render(<App left={frozenLeft} right={frozenRight} />);
await user.click(screen.getByRole("checkbox", { name: "Assam" }));
await user.click(button("Move selected right"));
await user.click(button("Move all left"));
expect(teasIn("Available")).toEqual(["Sencha", "Oolong", "Rooibos", "Chai", "Assam"]);
expect(frozenLeft).toEqual(["Sencha", "Assam", "Oolong", "Rooibos"]);
expect(frozenRight).toEqual(["Chai"]);
Run tests runs every test on your code, here in your browser. The problem is solved when they all pass.
Ctrl + Enter runs the tests (⌘ + Enter on a Mac).
I'm here to help with Transfer list. I give hints, never the solution, so you get to solve it yourself. Ask for a hint, select code to ask about it, or press Ask Tuto why on a failing test.
Your first 3 answers need no account. for free to keep asking.