From 74734251d2a08cc6cce14457278667c1a18f515b Mon Sep 17 00:00:00 2001
From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com>
Date: Tue, 22 Jul 2025 10:54:56 -0700
Subject: [PATCH 1/2] fix(unity-react-core): sidebar menu should auto-expand if
it contains an active page item
---
.../SidebarMenu/SidebarMenu.stories.tsx | 30 ++++++++---
.../SidebarMenu/SidebarMenu.test.tsx | 34 +++++++++----
.../components/SidebarMenu/SidebarMenu.tsx | 51 ++++++++++---------
3 files changed, 76 insertions(+), 39 deletions(-)
diff --git a/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.stories.tsx b/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.stories.tsx
index b02c1d9d8d..1e344c90a2 100644
--- a/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.stories.tsx
+++ b/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.stories.tsx
@@ -20,6 +20,7 @@ const defaultProps = {
{
href: "https://example.com",
text: "Link 2.1",
+ isActive: false,
},
{
href: "https://example.com",
@@ -56,18 +57,33 @@ const defaultProps = {
text: "Link 5.2",
},
],
- }
- ]
-}
+ },
+ ],
+};
-const sidebarMenuTemplate = args =>
-
-
;
+const sidebarMenuTemplate = args => (
+
+
+
+);
export const Overview = {
render: sidebarMenuTemplate.bind({}),
name: "Sidebar",
args: {
...defaultProps,
- }
+ },
+};
+
+const defaultProps2 = JSON.parse(JSON.stringify(defaultProps));
+defaultProps2.links[0].text = "Link 1";
+defaultProps2.links[0].isActive = false;
+defaultProps2.links[1].items[0].isActive = true;
+defaultProps2.links[1].items[0].text = "Active Link";
+
+export const WithNestedActivePage = {
+ render: sidebarMenuTemplate.bind({}),
+ args: {
+ ...defaultProps2,
+ },
};
diff --git a/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.test.tsx b/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.test.tsx
index d1743fc28f..6bb1eb40f6 100644
--- a/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.test.tsx
+++ b/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.test.tsx
@@ -10,6 +10,7 @@ const defaultProps: SidebarProps = {
{
href: "https://example.com",
text: "Link 1",
+ isActive: true,
},
{
text: "Link 2 dropdown",
@@ -23,24 +24,39 @@ const defaultProps: SidebarProps = {
text: "Link 2.2",
},
],
- }
- ]
+ },
+ ],
};
-const renderComponent = (props:SidebarProps) => {
+const defaultProps2 = JSON.parse(JSON.stringify(defaultProps));
+delete defaultProps2.links[0].isActive;
+defaultProps2.links[1].items[0].isActive = true;
+
+const renderComponent = (props: SidebarProps) => {
return render();
};
describe("SidebarMenu tests", () => {
- let component:RenderResult;
+ let component: RenderResult;
+
+ afterEach(cleanup);
- beforeEach(() => {
+ it("should have top level active link", () => {
component = renderComponent(defaultProps);
+ expect(component.getByText("Link 1")).toHaveClass("is-active");
+ expect(component.queryByText("Link 2 dropdown")).toHaveAttribute(
+ "aria-expanded",
+ "false"
+ );
});
- afterEach(cleanup);
-
- it("should define component", () => {
- expect(component).toBeDefined();
+ it("should have nested level active link", () => {
+ component = renderComponent(defaultProps2);
+ expect(component.getByText("Link 2.1")).toBeVisible();
+ expect(component.getByText("Link 2.1")).toHaveClass("is-active");
+ expect(component.queryByText("Link 2 dropdown")).toHaveAttribute(
+ "aria-expanded",
+ "true"
+ );
});
});
diff --git a/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.tsx b/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.tsx
index ae7d326397..82cdd58adf 100644
--- a/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.tsx
+++ b/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.tsx
@@ -1,16 +1,18 @@
import React from "react";
import { GaEventWrapper } from "../GaEventWrapper/GaEventWrapper";
+interface SidebarItemProps {
+ href: string;
+ text: string;
+ isActive?: boolean;
+}
+
export interface Link {
href?: string;
text: string;
isActive?: boolean;
- items?: Array<{
- href: string;
- text: string;
- isActive?: boolean;
- }>;
-};
+ items?: SidebarItemProps[];
+}
const defaultGaProps = {
name: "onclick",
@@ -24,6 +26,16 @@ export interface SidebarProps {
links: Link[];
}
+const SidebarItem: React.FC = ({
+ href,
+ text,
+ isActive,
+}) => (
+
+ {text}
+
+);
+
export const SidebarMenu: React.FC = ({ title, links }) => {
return (
@@ -46,9 +58,10 @@ export const SidebarMenu: React.FC
= ({ title, links }) => {
>
{links.map((link, index) => {
if (link.items) {
+ const isExpanded = link.items.some(({ isActive }) => isActive);
// Render dropdown card
return (
-
+
= ({ title, links }) => {
href={`#cardBody${index}`}
data-bs-toggle="collapse"
data-bs-target={`#cardBody${index}`}
- aria-expanded="false"
+ aria-expanded={isExpanded}
aria-controls={`cardBody${index}`}
>
{link.text}
@@ -69,18 +82,12 @@ export const SidebarMenu: React.FC = ({ title, links }) => {
{link.items.map(item => (
-
- {item.text}
-
+
))}
@@ -88,13 +95,11 @@ export const SidebarMenu: React.FC
= ({ title, links }) => {
} else {
// Render regular link
return (
-
-
- {link.text}
-
+
+
);
}
From b020a5519a03e6a1c33141f8edfe00c6b11f652b Mon Sep 17 00:00:00 2001
From: Scott Williams <5209283+scott-williams-az@users.noreply.github.com>
Date: Tue, 22 Jul 2025 14:21:48 -0700
Subject: [PATCH 2/2] fix(unity-react-core): sidebar menu should auto-expand if
it contains an active page item
---
.../SidebarMenu/SidebarMenu.test.tsx | 2 +-
.../components/SidebarMenu/SidebarMenu.tsx | 31 ++++++++++---------
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.test.tsx b/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.test.tsx
index 6bb1eb40f6..6830e37202 100644
--- a/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.test.tsx
+++ b/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.test.tsx
@@ -53,7 +53,7 @@ describe("SidebarMenu tests", () => {
it("should have nested level active link", () => {
component = renderComponent(defaultProps2);
expect(component.getByText("Link 2.1")).toBeVisible();
- expect(component.getByText("Link 2.1")).toHaveClass("is-active");
+ expect(component.getByText("Link 2 dropdown")).toHaveClass("is-active");
expect(component.queryByText("Link 2 dropdown")).toHaveAttribute(
"aria-expanded",
"true"
diff --git a/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.tsx b/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.tsx
index 82cdd58adf..6383c31fe3 100644
--- a/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.tsx
+++ b/packages/unity-react-core/src/components/SidebarMenu/SidebarMenu.tsx
@@ -26,16 +26,6 @@ export interface SidebarProps {
links: Link[];
}
-const SidebarItem: React.FC
= ({
- href,
- text,
- isActive,
-}) => (
-
- {text}
-
-);
-
export const SidebarMenu: React.FC = ({ title, links }) => {
return (
@@ -58,8 +48,8 @@ export const SidebarMenu: React.FC
= ({ title, links }) => {
>
{links.map((link, index) => {
if (link.items) {
- const isExpanded = link.items.some(({ isActive }) => isActive);
// Render dropdown card
+ const isExpanded = link.items.some(({ isActive }) => isActive);
return (
@@ -99,7 +97,12 @@ export const SidebarMenu: React.FC = ({ title, links }) => {
key={`${link.text}${link.href}`}
className="nav-link-container"
>
-
+
+ {link.text}
+
);
}