From 57d60bf2edbe6654155b5881e539e08f4496cc7c Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Wed, 15 Apr 2026 20:57:43 +0200 Subject: [PATCH] feat: add maxHeight prop with sectionContent wrapper to SidebarSection Adds position and maxHeight to SidebarSectionProps and wraps children in a .sectionContent div when the section is open, enabling scrollable constrained height via inline style. Co-Authored-By: Claude Sonnet 4.6 --- .../layout/Sidebar/Sidebar.test.tsx | 69 +++++++++++++++++++ src/design-system/layout/Sidebar/Sidebar.tsx | 13 +++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/design-system/layout/Sidebar/Sidebar.test.tsx b/src/design-system/layout/Sidebar/Sidebar.test.tsx index 21c8f52..b308ae3 100644 --- a/src/design-system/layout/Sidebar/Sidebar.test.tsx +++ b/src/design-system/layout/Sidebar/Sidebar.test.tsx @@ -324,4 +324,73 @@ describe('Sidebar compound component', () => { const item = screen.getByText('Admin').closest('[role="button"]')! expect(item.className).toMatch(/bottomItemActive/) }) + + // 17. renders sectionContent wrapper with maxHeight when open + it('renders section content wrapper with maxHeight style when open', () => { + const { container } = render( + + + ic} + label="Apps" + open + onToggle={vi.fn()} + maxHeight="200px" + > +
child
+
+
+
, + ) + + const contentWrapper = container.querySelector('.sectionContent') + expect(contentWrapper).toBeInTheDocument() + expect(contentWrapper).toHaveStyle({ maxHeight: '200px' }) + expect(screen.getByText('child')).toBeInTheDocument() + }) + + // 18. renders sectionContent wrapper without maxHeight when not provided + it('renders section content wrapper without inline maxHeight when maxHeight is not provided', () => { + const { container } = render( + + + ic} + label="Apps" + open + onToggle={vi.fn()} + > +
child
+
+
+
, + ) + + const contentWrapper = container.querySelector('.sectionContent') + expect(contentWrapper).toBeInTheDocument() + expect(contentWrapper).not.toHaveStyle({ maxHeight: '200px' }) + expect(screen.getByText('child')).toBeInTheDocument() + }) + + // 19. does not render sectionContent wrapper when section is closed + it('does not render section content wrapper when section is closed', () => { + const { container } = render( + + + ic} + label="Apps" + open={false} + onToggle={vi.fn()} + maxHeight="200px" + > +
child
+
+
+
, + ) + + const contentWrapper = container.querySelector('.sectionContent') + expect(contentWrapper).not.toBeInTheDocument() + }) }) diff --git a/src/design-system/layout/Sidebar/Sidebar.tsx b/src/design-system/layout/Sidebar/Sidebar.tsx index f154c9f..8dddcc3 100644 --- a/src/design-system/layout/Sidebar/Sidebar.tsx +++ b/src/design-system/layout/Sidebar/Sidebar.tsx @@ -26,6 +26,8 @@ interface SidebarSectionProps { active?: boolean children: ReactNode className?: string + position?: 'top' | 'bottom' + maxHeight?: string } interface SidebarFooterProps { @@ -83,6 +85,8 @@ function SidebarSection({ active, children, className, + position: _position, + maxHeight, }: SidebarSectionProps) { const { collapsed, onCollapseToggle } = useSidebarContext() @@ -125,7 +129,14 @@ function SidebarSection({ {icon && {icon}} {label} - {open && children} + {open && ( +
+ {children} +
+ )} ) }