Skip to content

Commit

Permalink
fix(TreeView): Fix undefined problem (#1587)
Browse files Browse the repository at this point in the history
  • Loading branch information
silvalaura authored Nov 21, 2024
1 parent 22226aa commit c54190d
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/treeview-undefined4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'react-magma-dom': patch
---

fix(TreeView): Fix undefined problem
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ export const TreeItem = React.forwardRef<HTMLLIElement, TreeItemProps>(
{React.Children.map(
children,
(child: React.ReactElement<any>, index) => {
return child.type === TreeItem ? (
return child?.type === TreeItem ? (
<Transition isOpen={expanded} collapse unmountOnExit>
<ul role="group">
{React.cloneElement(child, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,7 @@ export const InvalidTreeItems = (args: Partial<TreeViewProps>) => {
<em>
This is an example of a tree with badly structured tree items. Expect
only the following items to be expandable: Node 1, Child 1, Node 2,
Child 2, Grandchild 2.
Child 2, Grandchild 2, Node 6.
</em>
</p>
<TreeView {...args}>
Expand All @@ -1058,25 +1058,35 @@ export const InvalidTreeItems = (args: Partial<TreeViewProps>) => {
</TreeItem>
<TreeItem label="Node 1" itemId="item1" testId="item1">
<TreeItem label="Child 1" itemId="item-child1">
<TreeItem label="Grandchild 1" itemId="item-gchild1">
<TreeItem label="Grandchild 1 - has tag content" itemId="item-gchild1">
<Tag>This is a tag as a child of Grandchild 1</Tag>
</TreeItem>
</TreeItem>
</TreeItem>
<TreeItem label="Node 2" itemId="item2">
<TreeItem label="Child 2" itemId="item-child2">
<TreeItem label="Grandchild 2" itemId="item-gchild2">
<TreeItem label="Grandchild 2 - has valid and invalid children" itemId="item-gchild2">
<TreeItem label="Great-grandchild 2" itemId="item-ggchild2" />
<TreeItem label="Great-grandchild 3" itemId="item-ggchild3">
<>Invalid child</>
</TreeItem>
</TreeItem>
</TreeItem>
</TreeItem>
<TreeItem label="Node 3" itemId="item3"></TreeItem>
<TreeItem label="Node 4" itemId="item4">
<TreeItem label="Node 3 - has empty content" itemId="item3"></TreeItem>
<TreeItem label="Node 4 - has child with only text" itemId="item4">
Child of node 4 is just text
</TreeItem>
<TreeItem label="Node 5 - has null content" itemId="item5">
{null}
</TreeItem>
<TreeItem label="Node 6 - has undefined and valid children" itemId="item6">
{undefined}
<TreeItem label="Node 7" itemId="item7" />
<TreeItem label="Node 8 - has undefined content" itemId="item8">
{undefined}
</TreeItem>
</TreeItem>
</TreeView>
</>
);
Expand Down
51 changes: 51 additions & 0 deletions packages/react-magma-dom/src/components/TreeView/TreeView.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2492,6 +2492,29 @@ describe('TreeView', () => {
expect(getByTestId('item-child2-expand')).toBeInTheDocument();
});

it('when multiple TreeViews are passed as a child and at least one is valid and the other is undefined, the tree item is expandable', () => {
const { getByTestId } = render(
<TreeView>
<TreeItem label="Node 1" itemId="item1" testId="item1">
<TreeItem label="Child 1" itemId="item-child1" testId="item-child1">
{undefined}
</TreeItem>
{undefined}
<TreeItem label="Child 2" itemId="item-child2" testId="item-child2">
<TreeItem
label="Child 2.1"
itemId="item-child2.1"
testId="item-child2.1"
/>
</TreeItem>
</TreeItem>
</TreeView>
);

expect(getByTestId('item1-expand')).toBeInTheDocument();
userEvent.click(getByTestId('item1-expand'));
expect(getByTestId('item-child2-expand')).toBeInTheDocument();
});

it('when a fragment is passed as a child, the tree item is not expandable', () => {
const { queryByTestId } = render(
Expand Down Expand Up @@ -2535,6 +2558,34 @@ describe('TreeView', () => {
expect(queryByTestId('item1-expand')).not.toBeInTheDocument();
});

it('when undefined is passed as a child, the tree item is not expandable', () => {
const { queryByTestId } = render(
<TreeView>
<TreeItem label="Node 1" itemId="item1" testId="item1">
{undefined}
</TreeItem>
<TreeItem label="Node 2" itemId="item2" testId="item2"></TreeItem>
</TreeView>
);

expect(queryByTestId('item1-expand')).not.toBeInTheDocument();
expect(queryByTestId('item2-expand')).not.toBeInTheDocument();
});

it('when null is passed as a child, the tree item is not expandable', () => {
const { queryByTestId } = render(
<TreeView>
<TreeItem label="Node 1" itemId="item1" testId="item1">
{null}
</TreeItem>
<TreeItem label="Node 2" itemId="item2" testId="item2"></TreeItem>
</TreeView>
);

expect(queryByTestId('item1-expand')).not.toBeInTheDocument();
expect(queryByTestId('item2-expand')).not.toBeInTheDocument();
});

it('when a TreeView does not have a child, the tree item is not expandable', () => {
const { queryByTestId } = render(
<TreeView>
Expand Down
9 changes: 4 additions & 5 deletions packages/react-magma-dom/src/components/TreeView/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ const areChildrenValid = children => {
return false; // Return false if a child is a string
}

if (child.type !== TreeItem) {
if (child?.type !== TreeItem) {
return hasValidChild;
}
// Recursively check the validity of nested children
Expand Down Expand Up @@ -575,13 +575,12 @@ const processParentsSelection = ({
checkedStatus: TreeViewItemInterface['checkedStatus'];
}) => {
const item = items.find(item => item.itemId === itemId);
const { parentId } = item;

if (parentId === null) {
if (item?.parentId === null) {
return items;
}

const siblings = items.filter(item => item?.parentId === parentId);
const siblings = items.filter(i => i.parentId === item?.parentId);
const isAllSiblingsHasTheSameStatus = siblings.every(
item =>
(item.checkedStatus || IndeterminateCheckboxStatus.unchecked) ===
Expand All @@ -591,7 +590,7 @@ const processParentsSelection = ({
? checkedStatus
: IndeterminateCheckboxStatus.indeterminate;

const parent = items.find(item => item.itemId === parentId);
const parent = items.find(i => i.itemId === item?.parentId);

const nextItems = items.map(item =>
item.itemId === parent.itemId
Expand Down

2 comments on commit c54190d

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

Please sign in to comment.