From 487b78a1049dd2c74ef3450babd1c459a30aea5f Mon Sep 17 00:00:00 2001 From: Xander Leatherwood <44583237+xman343@users.noreply.github.com> Date: Fri, 28 Jul 2023 16:03:43 -0400 Subject: [PATCH 01/11] initial commit From a1d1b38538f7568787f7431c7557a7623958a0c1 Mon Sep 17 00:00:00 2001 From: Xander Leatherwood <44583237+xman343@users.noreply.github.com> Date: Fri, 28 Jul 2023 16:15:42 -0400 Subject: [PATCH 02/11] sideNav, sideNavContent, sideNavTop, sideNavBottom --- .../core/SideNavigation/SideNavigation.tsx | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx index 2f6696c514e..bdea4fb824a 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx @@ -57,6 +57,22 @@ type SideNavigationProps = { * @default false */ isSubmenuOpen?: boolean; + /** + * Passes props for SideNav. + */ + sideNavProps?: React.ComponentProps<'div'>; + /** + * Passes props for SideNav content. + */ + sideNavContentProps?: React.ComponentProps<'div'>; + /** + * Passes props for SideNav top. + */ + sideNavTopProps?: React.ComponentProps<'div'>; + /** + * Passes props for SideNav bottom. + */ + sideNavBottomProps?: React.ComponentProps<'div'>; }; /** @@ -83,6 +99,10 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { onExpanderClick, submenu, isSubmenuOpen = false, + sideNavProps, + sideNavContentProps, + sideNavTopProps, + sideNavBottomProps, ...rest } = props; @@ -110,14 +130,28 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { {...rest} > {expanderPlacement === 'top' && ExpandButton} - - + + {items.map((sidenavButton: JSX.Element, index) => !_isExpanded ? ( { ), )} - + {secondaryItems?.map((sidenavButton: JSX.Element, index) => !_isExpanded ? ( Date: Mon, 31 Jul 2023 13:49:19 -0400 Subject: [PATCH 03/11] unit tests --- .../SideNavigation/SideNavigation.test.tsx | 49 +++++++++++++++++++ .../core/SideNavigation/SideNavigation.tsx | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx index 3d927d9f3ae..e02e876db33 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx @@ -274,3 +274,52 @@ it('should not show submenu if isSubmenuOpen is false', () => { expect(wrapper.querySelector('.iui-side-navigation-submenu')).toBeFalsy(); expect(screen.queryByText('submenu content')).toBeFalsy(); }); + +it('passes custom props to subcomponents', () => { + const { container } = renderComponent({ + sideNavProps: { + className: 'custom-sidenav-class', + style: { width: 70 }, + }, + sideNavContentProps: { + className: 'custom-sidenav-content-class', + style: { width: 80 }, + }, + sideNavTopProps: { + className: 'custom-sidenav-top-class', + style: { width: 90 }, + }, + sideNavBottomProps: { + className: 'custom-sidenav-bottom-class', + style: { width: 100 }, + }, + }); + + // sideNav props test + const sideNavElement = container.querySelector( + '.iui-side-navigation.iui-collapsed.custom-sidenav-class', + ) as HTMLElement; + expect(sideNavElement).toBeTruthy(); + expect(sideNavElement.style.width).toBe('70px'); + + // content props test + const contentElement = container.querySelector( + '.iui-sidenav-content.custom-sidenav-content-class', + ) as HTMLElement; + expect(contentElement).toBeTruthy(); + expect(contentElement.style.width).toBe('80px'); + + // top props test + const topElement = container.querySelector( + '.iui-top.custom-sidenav-top-class', + ) as HTMLElement; + expect(topElement).toBeTruthy(); + expect(topElement.style.width).toBe('90px'); + + // bottom props test + const bottomElement = container.querySelector( + '.iui-bottom.custom-sidenav-bottom-class', + ) as HTMLElement; + expect(bottomElement).toBeTruthy(); + expect(bottomElement.style.width).toBe('100px'); +}); diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx index bdea4fb824a..08cc961eb6c 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx @@ -169,7 +169,7 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { {secondaryItems?.map((sidenavButton: JSX.Element, index) => !_isExpanded ? ( From 6c78a535ee12ce0762c51e04832b471ebae70494 Mon Sep 17 00:00:00 2001 From: Xander Leatherwood <44583237+xman343@users.noreply.github.com> Date: Mon, 31 Jul 2023 14:11:15 -0400 Subject: [PATCH 04/11] node modules From e8d878f768597dfed583589504c375c4a8964104 Mon Sep 17 00:00:00 2001 From: Xander Leatherwood <44583237+xman343@users.noreply.github.com> Date: Mon, 31 Jul 2023 14:23:08 -0400 Subject: [PATCH 05/11] yarn lockfile fix From fe9611b5dc2ad4da8285d9076cb342354f053851 Mon Sep 17 00:00:00 2001 From: Xander Leatherwood <44583237+xman343@users.noreply.github.com> Date: Wed, 2 Aug 2023 14:23:31 -0400 Subject: [PATCH 06/11] prop names edited --- .../SideNavigation/SideNavigation.test.tsx | 8 ++--- .../core/SideNavigation/SideNavigation.tsx | 32 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx index f046a8dee86..627a461312e 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx @@ -277,19 +277,19 @@ it('should not show submenu if isSubmenuOpen is false', () => { it('passes custom props to subcomponents', () => { const { container } = renderComponent({ - sideNavProps: { + innerProps: { className: 'custom-sidenav-class', style: { width: 70 }, }, - sideNavContentProps: { + contentProps: { className: 'custom-sidenav-content-class', style: { width: 80 }, }, - sideNavTopProps: { + topProps: { className: 'custom-sidenav-top-class', style: { width: 90 }, }, - sideNavBottomProps: { + bottomProps: { className: 'custom-sidenav-bottom-class', style: { width: 100 }, }, diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx index 08cc961eb6c..5e8a69d0d55 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx @@ -60,19 +60,19 @@ type SideNavigationProps = { /** * Passes props for SideNav. */ - sideNavProps?: React.ComponentProps<'div'>; + innerProps?: React.ComponentProps<'div'>; /** * Passes props for SideNav content. */ - sideNavContentProps?: React.ComponentProps<'div'>; + contentProps?: React.ComponentProps<'div'>; /** * Passes props for SideNav top. */ - sideNavTopProps?: React.ComponentProps<'div'>; + topProps?: React.ComponentProps<'div'>; /** * Passes props for SideNav bottom. */ - sideNavBottomProps?: React.ComponentProps<'div'>; + bottomProps?: React.ComponentProps<'div'>; }; /** @@ -99,10 +99,10 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { onExpanderClick, submenu, isSubmenuOpen = false, - sideNavProps, - sideNavContentProps, - sideNavTopProps, - sideNavBottomProps, + innerProps, + contentProps, + topProps, + bottomProps, ...rest } = props; @@ -131,26 +131,26 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { > {expanderPlacement === 'top' && ExpandButton} {items.map((sidenavButton: JSX.Element, index) => !_isExpanded ? ( @@ -168,8 +168,8 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { {secondaryItems?.map((sidenavButton: JSX.Element, index) => !_isExpanded ? ( From 495e6eec382fe5b4a6ebfc9e6e42a10b733ae1d2 Mon Sep 17 00:00:00 2001 From: Xander Leatherwood <44583237+xman343@users.noreply.github.com> Date: Thu, 10 Aug 2023 10:43:46 -0400 Subject: [PATCH 07/11] wrapperProps implemented --- .../core/SideNavigation/SideNavigation.test.tsx | 14 +++++++------- .../src/core/SideNavigation/SideNavigation.tsx | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx index 627a461312e..4e89f0b803f 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx @@ -229,7 +229,7 @@ it('should handle custom class and style', () => { }); const sidebar = container.querySelector( - '.iui-side-navigation-wrapper', + '.iui-side-navigation', ) as HTMLElement; expect(sidebar).toHaveClass('test-class'); @@ -277,8 +277,8 @@ it('should not show submenu if isSubmenuOpen is false', () => { it('passes custom props to subcomponents', () => { const { container } = renderComponent({ - innerProps: { - className: 'custom-sidenav-class', + wrapperProps: { + className: 'custom-wrapper-class', style: { width: 70 }, }, contentProps: { @@ -296,11 +296,11 @@ it('passes custom props to subcomponents', () => { }); // sideNav props test - const sideNavElement = container.querySelector( - '.iui-side-navigation.iui-collapsed.custom-sidenav-class', + const wrapperElement = container.querySelector( + '.iui-side-navigation-wrapper.custom-wrapper-class', ) as HTMLElement; - expect(sideNavElement).toBeTruthy(); - expect(sideNavElement.style.width).toBe('70px'); + expect(wrapperElement).toBeTruthy(); + expect(wrapperElement.style.width).toBe('70px'); // content props test const contentElement = container.querySelector( diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx index 5e8a69d0d55..f9b3da8eab5 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx @@ -58,9 +58,9 @@ type SideNavigationProps = { */ isSubmenuOpen?: boolean; /** - * Passes props for SideNav. + * Passes props for SideNav wrapper. */ - innerProps?: React.ComponentProps<'div'>; + wrapperProps?: React.ComponentProps<'div'>; /** * Passes props for SideNav content. */ @@ -99,7 +99,7 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { onExpanderClick, submenu, isSubmenuOpen = false, - innerProps, + wrapperProps, contentProps, topProps, bottomProps, @@ -125,21 +125,21 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { return ( {expanderPlacement === 'top' && ExpandButton} Date: Thu, 10 Aug 2023 11:57:44 -0400 Subject: [PATCH 08/11] props moved to button --- .../SideNavigation/SideNavigation.test.tsx | 25 ++++++++----------- .../core/SideNavigation/SideNavigation.tsx | 20 +++++++-------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx index 4e89f0b803f..318c88484fc 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx @@ -222,20 +222,6 @@ it('should render active and disabled sidebar buttons', () => { expect(mainItems[2]).toHaveClass('iui-submenu-open'); }); -it('should handle custom class and style', () => { - const { container } = renderComponent({ - className: 'test-class', - style: { height: 200 }, - }); - - const sidebar = container.querySelector( - '.iui-side-navigation', - ) as HTMLElement; - - expect(sidebar).toHaveClass('test-class'); - expect(sidebar).toHaveStyle('height: 200px'); -}); - it('should render with submenu', () => { const { container } = renderComponent({ submenu: submenu content, @@ -277,6 +263,8 @@ it('should not show submenu if isSubmenuOpen is false', () => { it('passes custom props to subcomponents', () => { const { container } = renderComponent({ + className: 'custom-class', + style: { width: 60 }, wrapperProps: { className: 'custom-wrapper-class', style: { width: 70 }, @@ -295,13 +283,20 @@ it('passes custom props to subcomponents', () => { }, }); - // sideNav props test + // wrapper props test const wrapperElement = container.querySelector( '.iui-side-navigation-wrapper.custom-wrapper-class', ) as HTMLElement; expect(wrapperElement).toBeTruthy(); expect(wrapperElement.style.width).toBe('70px'); + // button props test + const buttonElement = container.querySelector( + '.iui-button-base.iui-button.iui-sidenav-button.iui-expand.custom-class', + ) as HTMLElement; + expect(buttonElement).toBeTruthy(); + expect(buttonElement.style.width).toBe('60px'); + // content props test const contentElement = container.querySelector( '.iui-sidenav-content.custom-sidenav-content-class', diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx index f9b3da8eab5..9a1a53e2bcc 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx @@ -113,11 +113,14 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { const ExpandButton = ( { _setIsExpanded((expanded) => !expanded); onExpanderClick?.(); }, [onExpanderClick])} + ref={forwardedRef} + {...rest} > @@ -125,21 +128,16 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { return ( {expanderPlacement === 'top' && ExpandButton} Date: Thu, 10 Aug 2023 13:21:52 -0400 Subject: [PATCH 09/11] Revert "props moved to button" This reverts commit 2eae953238c6a0ed577da54374e1211b24fea72c. --- .../SideNavigation/SideNavigation.test.tsx | 25 +++++++++++-------- .../core/SideNavigation/SideNavigation.tsx | 20 ++++++++------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx index 318c88484fc..4e89f0b803f 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx @@ -222,6 +222,20 @@ it('should render active and disabled sidebar buttons', () => { expect(mainItems[2]).toHaveClass('iui-submenu-open'); }); +it('should handle custom class and style', () => { + const { container } = renderComponent({ + className: 'test-class', + style: { height: 200 }, + }); + + const sidebar = container.querySelector( + '.iui-side-navigation', + ) as HTMLElement; + + expect(sidebar).toHaveClass('test-class'); + expect(sidebar).toHaveStyle('height: 200px'); +}); + it('should render with submenu', () => { const { container } = renderComponent({ submenu: submenu content, @@ -263,8 +277,6 @@ it('should not show submenu if isSubmenuOpen is false', () => { it('passes custom props to subcomponents', () => { const { container } = renderComponent({ - className: 'custom-class', - style: { width: 60 }, wrapperProps: { className: 'custom-wrapper-class', style: { width: 70 }, @@ -283,20 +295,13 @@ it('passes custom props to subcomponents', () => { }, }); - // wrapper props test + // sideNav props test const wrapperElement = container.querySelector( '.iui-side-navigation-wrapper.custom-wrapper-class', ) as HTMLElement; expect(wrapperElement).toBeTruthy(); expect(wrapperElement.style.width).toBe('70px'); - // button props test - const buttonElement = container.querySelector( - '.iui-button-base.iui-button.iui-sidenav-button.iui-expand.custom-class', - ) as HTMLElement; - expect(buttonElement).toBeTruthy(); - expect(buttonElement.style.width).toBe('60px'); - // content props test const contentElement = container.querySelector( '.iui-sidenav-content.custom-sidenav-content-class', diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx index 9a1a53e2bcc..f9b3da8eab5 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.tsx @@ -113,14 +113,11 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { const ExpandButton = ( { _setIsExpanded((expanded) => !expanded); onExpanderClick?.(); }, [onExpanderClick])} - ref={forwardedRef} - {...rest} > @@ -128,16 +125,21 @@ export const SideNavigation = React.forwardRef((props, forwardedRef) => { return ( {expanderPlacement === 'top' && ExpandButton} Date: Mon, 14 Aug 2023 10:57:38 -0400 Subject: [PATCH 10/11] changeset added --- .changeset/old-swans-love.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/old-swans-love.md diff --git a/.changeset/old-swans-love.md b/.changeset/old-swans-love.md new file mode 100644 index 00000000000..e57938673b4 --- /dev/null +++ b/.changeset/old-swans-love.md @@ -0,0 +1,5 @@ +--- +'@itwin/itwinui-react': major +--- + +Added wrapperProps, contentProps, topProps, and bottomProps to Side Navigation component to improve customization. Top-level props (className, styling, etc) now passed to SideNav button instead of to the wrapper. From 29e7a2ec04072dbd033b0b57b1bce9a6a1ba44b1 Mon Sep 17 00:00:00 2001 From: Xander Leatherwood <44583237+xman343@users.noreply.github.com> Date: Mon, 14 Aug 2023 11:06:41 -0400 Subject: [PATCH 11/11] updated unit test --- .../src/core/SideNavigation/SideNavigation.test.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx index 4e89f0b803f..e853984548d 100644 --- a/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx +++ b/packages/itwinui-react/src/core/SideNavigation/SideNavigation.test.tsx @@ -277,6 +277,8 @@ it('should not show submenu if isSubmenuOpen is false', () => { it('passes custom props to subcomponents', () => { const { container } = renderComponent({ + className: 'custom-class', + style: { width: 60 }, wrapperProps: { className: 'custom-wrapper-class', style: { width: 70 }, @@ -295,7 +297,14 @@ it('passes custom props to subcomponents', () => { }, }); - // sideNav props test + // sidenav props test + const sidenavElement = container.querySelector( + '.iui-side-navigation.iui-collapsed.custom-class', + ) as HTMLElement; + expect(sidenavElement).toBeTruthy(); + expect(sidenavElement.style.width).toBe('60px'); + + // wrapper props test const wrapperElement = container.querySelector( '.iui-side-navigation-wrapper.custom-wrapper-class', ) as HTMLElement;