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 <noreply@anthropic.com>
This commit is contained in:
@@ -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(
|
||||
<Wrapper>
|
||||
<Sidebar>
|
||||
<Sidebar.Section
|
||||
icon={<span>ic</span>}
|
||||
label="Apps"
|
||||
open
|
||||
onToggle={vi.fn()}
|
||||
maxHeight="200px"
|
||||
>
|
||||
<div>child</div>
|
||||
</Sidebar.Section>
|
||||
</Sidebar>
|
||||
</Wrapper>,
|
||||
)
|
||||
|
||||
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(
|
||||
<Wrapper>
|
||||
<Sidebar>
|
||||
<Sidebar.Section
|
||||
icon={<span>ic</span>}
|
||||
label="Apps"
|
||||
open
|
||||
onToggle={vi.fn()}
|
||||
>
|
||||
<div>child</div>
|
||||
</Sidebar.Section>
|
||||
</Sidebar>
|
||||
</Wrapper>,
|
||||
)
|
||||
|
||||
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(
|
||||
<Wrapper>
|
||||
<Sidebar>
|
||||
<Sidebar.Section
|
||||
icon={<span>ic</span>}
|
||||
label="Apps"
|
||||
open={false}
|
||||
onToggle={vi.fn()}
|
||||
maxHeight="200px"
|
||||
>
|
||||
<div>child</div>
|
||||
</Sidebar.Section>
|
||||
</Sidebar>
|
||||
</Wrapper>,
|
||||
)
|
||||
|
||||
const contentWrapper = container.querySelector('.sectionContent')
|
||||
expect(contentWrapper).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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 && <span className={styles.sectionIcon}>{icon}</span>}
|
||||
<span className={styles.treeSectionLabel}>{label}</span>
|
||||
</div>
|
||||
{open && children}
|
||||
{open && (
|
||||
<div
|
||||
className={styles.sectionContent}
|
||||
style={maxHeight ? { maxHeight } : undefined}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user