Skip to content

Commit 492bd60

Browse files
Merge branch 'main' into 19228-controlled-tag
2 parents 74819d8 + 75b4831 commit 492bd60

File tree

3 files changed

+106
-1
lines changed

3 files changed

+106
-1
lines changed

packages/react/src/components/TreeView/TreeNode.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,13 @@ const TreeNode = React.forwardRef<HTMLElement, TreeNodeProps>(
287287
}
288288
if (matches(event, [keys.Enter, keys.Space])) {
289289
event.preventDefault();
290+
if (match(event, keys.Enter) && children) {
291+
// Toggle expansion state for parent nodes
292+
if (!enableTreeviewControllable) {
293+
onToggle?.(event, { id, isExpanded: !expanded, label, value });
294+
}
295+
setExpanded(!expanded);
296+
}
290297
if (href) {
291298
currentNode.current?.click();
292299
}

packages/react/src/components/TreeView/TreeView-test.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,4 +564,100 @@ describe('TreeView', () => {
564564
expect(node2).toHaveClass(`${prefix}--tree-node--selected`);
565565
expect(node3).toHaveClass(`${prefix}--tree-node--selected`);
566566
});
567+
568+
it('should expand a collapsed parent node when Enter key is pressed', async () => {
569+
const user = userEvent.setup();
570+
571+
render(
572+
<TreeView label="Tree View">
573+
<TreeNode
574+
data-testid="parent-node"
575+
label="Parent Node"
576+
isExpanded={false}>
577+
<TreeNode data-testid="child-node" label="Child Node" />
578+
</TreeNode>
579+
</TreeView>
580+
);
581+
582+
const parentNode = screen.getByTestId('parent-node');
583+
584+
// Initially, the parent node should not be expanded
585+
expect(parentNode).not.toHaveAttribute('aria-expanded', 'true');
586+
587+
// Focus on the parent node
588+
parentNode.focus();
589+
expect(parentNode).toHaveFocus();
590+
591+
// Press the Enter key
592+
await user.keyboard('[Enter]');
593+
594+
// The parent node should now be expanded
595+
expect(parentNode).toHaveAttribute('aria-expanded', 'true');
596+
597+
// Child node should be visible
598+
const childNode = screen.getByTestId('child-node');
599+
expect(childNode).toBeInTheDocument();
600+
});
601+
602+
it('should collapse an expanded parent node when Enter key is pressed', async () => {
603+
const user = userEvent.setup();
604+
605+
render(
606+
<TreeView label="Tree View">
607+
<TreeNode
608+
data-testid="parent-node"
609+
label="Parent Node"
610+
isExpanded={true}>
611+
<TreeNode data-testid="child-node" label="Child Node" />
612+
</TreeNode>
613+
</TreeView>
614+
);
615+
616+
const parentNode = screen.getByTestId('parent-node');
617+
618+
// Initially, the parent node should be expanded
619+
expect(parentNode).toHaveAttribute('aria-expanded', 'true');
620+
621+
// Focus on the parent node
622+
parentNode.focus();
623+
expect(parentNode).toHaveFocus();
624+
625+
// Press the Enter key
626+
await user.keyboard('[Enter]');
627+
628+
// The parent node should now be collapsed
629+
expect(parentNode).toHaveAttribute('aria-expanded', 'false');
630+
});
631+
632+
it('should expand/collapse nodes with Enter key while maintaining selection', async () => {
633+
const user = userEvent.setup();
634+
635+
render(
636+
<TreeView label="Tree View">
637+
<TreeNode
638+
data-testid="parent-node"
639+
label="Parent Node"
640+
isExpanded={false}>
641+
<TreeNode data-testid="child-node" label="Child Node" />
642+
</TreeNode>
643+
</TreeView>
644+
);
645+
646+
const parentNode = screen.getByTestId('parent-node');
647+
648+
// Focus and select the parent node
649+
parentNode.focus();
650+
await user.click(parentNode);
651+
expect(parentNode).toHaveClass(`${prefix}--tree-node--selected`);
652+
653+
// Press Enter to expand
654+
await user.keyboard('[Enter]');
655+
expect(parentNode).toHaveAttribute('aria-expanded', 'true');
656+
expect(parentNode).toHaveClass(`${prefix}--tree-node--selected`); // Should still be selected
657+
658+
// Press Enter again to collapse
659+
await user.keyboard('[Enter]');
660+
expect(parentNode).toHaveAttribute('aria-expanded', 'false');
661+
expect(parentNode).toHaveClass(`${prefix}--tree-node--selected`); // Should still be selected
662+
});
567663
});

packages/web-components/src/components/tabs/tabs.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,9 @@ export default class CDSTabs extends HostListenerMixin(CDSContentSwitcher) {
202202

203203
// Specifies child `<cds-tab>` to hide its divider instead of using CSS,
204204
// until `:host-context()` gets supported in all major browsers
205-
(nextItem as CDSTab).hideDivider = true;
205+
if (nextItem) {
206+
(nextItem as CDSTab).hideDivider = true;
207+
}
206208
}
207209

208210
protected _selectionDidChange(itemToSelect: CDSTab) {

0 commit comments

Comments
 (0)