Skip to content

Commit

Permalink
Merge pull request #149 from Ke1sy/fix-previous-half-selection-on-upd…
Browse files Browse the repository at this point in the history
…ate-selectedIds

fix half-selection after manual manipulations with nodes and updating…
  • Loading branch information
mellis481 authored Aug 24, 2023
2 parents dddeef6 + 1c0a981 commit e3aa7d9
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/TreeView/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ export const propagateSelectChange = (
const some = enabledChildren.some(
(x) =>
selectedIds.has(x) ||
changes.some.has(x) ||
(changes.some.has(x) && !changes.none.has(x)) ||
(halfSelectedIds.has(x) && !changes.none.has(x))
);
if (!some) {
Expand Down
81 changes: 81 additions & 0 deletions src/__tests__/ControlledTree.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ const folder = {
{ name: "Onions" },
],
},
{
name: "Deserts",
children: [
{ name: "Cookies" },
{
name: "Cakes",
children: [
{
name: "Cheesecake",
children: [{ name: "Classic" }, { name: "Chocolate" }],
},
{ name: "Vanilla" },
],
},
],
},
],
};

Expand Down Expand Up @@ -171,6 +187,7 @@ function MultiSelectCheckboxControlledWithStateInside() {
<MultiSelectCheckboxControlled
selectedIds={selectedIds}
data={dataWithoutIds}
defaultExpandedIds={[1, 7, 11, 16, 22, 24, 25]}
/>
</div>
);
Expand Down Expand Up @@ -372,6 +389,70 @@ describe("Data without ids", () => {
expect(nodes[6]).toHaveAttribute("aria-checked", "false");
});

test("SelectedIds should clear selection and half-selection after manual selection of top level parent and deselection of low level child", () => {
const { queryAllByRole, queryAllByTestId } = render(
<MultiSelectCheckboxControlledWithStateInside />
);

const nodes = queryAllByRole("treeitem");

expect(nodes[11]).toHaveAttribute("aria-checked", "true");

fireEvent.click(queryAllByTestId("clear-selected-nodes")[0]);

expect(nodes[11]).toHaveAttribute("aria-checked", "false");

fireEvent.click(queryAllByTestId("select-only-vegetables")[0]);

expect(nodes[15]).toHaveAttribute("aria-checked", "true");
expect(nodes[16]).toHaveAttribute("aria-checked", "true");
expect(nodes[17]).toHaveAttribute("aria-checked", "true");
expect(nodes[18]).toHaveAttribute("aria-checked", "true");
expect(nodes[19]).toHaveAttribute("aria-checked", "true");
expect(nodes[20]).toHaveAttribute("aria-checked", "true");

nodes[21].focus();
if (document.activeElement == null)
throw new Error(
`Expected to find an active element on the document (after focusing the second element with role["treeitem"]), but did not.`
);
fireEvent.click(nodes[21].getElementsByClassName("checkbox-icon")[0]); // select Deserts

expect(nodes[21]).toHaveAttribute("aria-checked", "true"); // Deserts
expect(nodes[22]).toHaveAttribute("aria-checked", "true"); // Cookies
expect(nodes[23]).toHaveAttribute("aria-checked", "true"); // Cakes
expect(nodes[24]).toHaveAttribute("aria-checked", "true"); // Cheesecake
expect(nodes[25]).toHaveAttribute("aria-checked", "true"); // Classic cheesecake
expect(nodes[26]).toHaveAttribute("aria-checked", "true"); // Chocolate cheesecake
expect(nodes[27]).toHaveAttribute("aria-checked", "true"); // Vanilla

nodes[26].focus();
if (document.activeElement == null)
throw new Error(
`Expected to find an active element on the document (after focusing the second element with role["treeitem"]), but did not.`
);
fireEvent.click(nodes[26].getElementsByClassName("checkbox-icon")[0]); // deselect Chocolate cheesecake

expect(nodes[21]).toHaveAttribute("aria-checked", "mixed"); // Deserts
expect(nodes[22]).toHaveAttribute("aria-checked", "true"); // Cookies
expect(nodes[23]).toHaveAttribute("aria-checked", "mixed"); // Cakes
expect(nodes[24]).toHaveAttribute("aria-checked", "mixed"); // Cheesecake
expect(nodes[25]).toHaveAttribute("aria-checked", "true"); // Classic cheesecake
expect(nodes[26]).toHaveAttribute("aria-checked", "false"); // Chocolate cheesecake
expect(nodes[27]).toHaveAttribute("aria-checked", "true"); // Vanilla

fireEvent.click(queryAllByTestId("select-only-vegetables")[0]);

expect(nodes[21]).toHaveAttribute("aria-checked", "false"); // Deserts
expect(nodes[22]).toHaveAttribute("aria-checked", "false"); // Cookies
expect(nodes[23]).toHaveAttribute("aria-checked", "false"); // Cakes
expect(nodes[24]).toHaveAttribute("aria-checked", "false"); // Cheesecake
expect(nodes[25]).toHaveAttribute("aria-checked", "false"); // Classic cheesecake
expect(nodes[26]).toHaveAttribute("aria-checked", "false"); // Chocolate cheesecake
expect(nodes[27]).toHaveAttribute("aria-checked", "false"); // Vanilla
expect(nodes[15]).toHaveAttribute("aria-checked", "true");
});

test("SelectedIds should select all children if parent node selected", () => {
const { queryAllByRole } = render(
<MultiSelectCheckboxControlled selectedIds={[16]} data={dataWithoutIds} />
Expand Down

0 comments on commit e3aa7d9

Please sign in to comment.