@@ -4,12 +4,12 @@ import React, { useRef } from 'react';
44import type { ItemInnerProps , SidebarMenuItem } from './common' ;
55import { NavHeader , NavSection } from './common' ;
66import { SidebarItem } from './SidebarItem' ;
7- import { Button , ButtonSize , ButtonVariant } from '../buttons/Button' ;
8- import { ArrowIcon } from '../icons' ;
7+ import { ArrowIcon , PlusIcon } from '../icons' ;
98import type { SettingsFlags } from '../../graphql/settings' ;
109import { useSettingsContext } from '../../contexts/SettingsContext' ;
1110import { isNullOrUndefined } from '../../lib/func' ;
1211import useSidebarRendered from '../../hooks/useSidebarRendered' ;
12+ import Link from '../utilities/Link' ;
1313
1414export interface SectionCommonProps
1515 extends Pick < ItemInnerProps , 'shouldShowLabel' > {
@@ -24,6 +24,8 @@ interface SectionProps extends SectionCommonProps {
2424 items : SidebarMenuItem [ ] ;
2525 isItemsButton : boolean ;
2626 isAlwaysOpenOnMobile ?: boolean ;
27+ onAdd ?: ( ) => void ;
28+ addHref ?: string ;
2729}
2830
2931export function Section ( {
@@ -36,6 +38,8 @@ export function Section({
3638 className,
3739 flag,
3840 isAlwaysOpenOnMobile,
41+ onAdd,
42+ addHref,
3943} : SectionProps ) : ReactElement {
4044 const { flags, updateFlag } = useSettingsContext ( ) ;
4145 const { sidebarRendered } = useSidebarRendered ( ) ;
@@ -49,30 +53,79 @@ export function Section({
4953 } ;
5054
5155 return (
52- < NavSection className = { className } >
56+ < NavSection className = { classNames ( 'mt-1' , className ) } >
5357 { title && (
54- < NavHeader
55- className = { classNames (
56- 'hidden justify-between laptop:flex' ,
57- sidebarExpanded ? 'px-3 opacity-100' : 'px-0 opacity-0' ,
58- ) }
59- >
60- { title }
61- < Button
62- variant = { ButtonVariant . Tertiary }
63- onClick = { toggleFlag }
64- size = { ButtonSize . XSmall }
65- aria-label = { `Toggle ${ title } ` }
66- icon = {
58+ < NavHeader className = "relative hidden laptop:flex" >
59+ { /* Divider shown when sidebar is collapsed */ }
60+ < div
61+ className = { classNames (
62+ 'absolute inset-x-0 flex items-center justify-center px-2 transition-opacity duration-300' ,
63+ sidebarExpanded ? 'opacity-0' : 'opacity-100' ,
64+ ) }
65+ >
66+ < hr className = "w-full border-t border-border-subtlest-tertiary" />
67+ </ div >
68+ { /* Header content shown when sidebar is expanded */ }
69+ < div
70+ className = { classNames (
71+ 'group/section flex min-h-9 w-full items-center justify-between px-2 py-1.5 transition-opacity duration-300' ,
72+ sidebarExpanded ? 'opacity-100' : 'pointer-events-none opacity-0' ,
73+ ) }
74+ >
75+ < button
76+ type = "button"
77+ onClick = { toggleFlag }
78+ aria-label = { `Toggle ${ title } ` }
79+ aria-expanded = { ! ! isVisible . current }
80+ className = "flex items-center gap-1 rounded-6 transition-colors hover:text-text-primary"
81+ >
82+ < span
83+ className = { classNames (
84+ 'text-text-quaternary typo-callout' ,
85+ ! sidebarExpanded && 'opacity-0' ,
86+ ) }
87+ >
88+ { title }
89+ </ span >
6790 < ArrowIcon
68- className = { isVisible . current ? 'rotate-360' : 'rotate-180' }
91+ className = { classNames (
92+ 'h-2.5 w-2.5 text-text-quaternary transition-transform duration-200' ,
93+ isVisible . current ? 'rotate-180' : 'rotate-90' ,
94+ ) }
6995 />
70- }
71- />
96+ </ button >
97+ { addHref && (
98+ < Link href = { addHref } >
99+ < a
100+ aria-label = { `Add to ${ title } ` }
101+ className = "flex h-6 w-6 items-center justify-center rounded-6 text-text-tertiary transition-all hover:bg-surface-hover hover:text-text-primary"
102+ >
103+ < PlusIcon className = "h-4 w-4" />
104+ </ a >
105+ </ Link >
106+ ) }
107+ { ! addHref && onAdd && (
108+ < button
109+ type = "button"
110+ onClick = { onAdd }
111+ aria-label = { `Add to ${ title } ` }
112+ className = "flex h-6 w-6 items-center justify-center rounded-6 text-text-tertiary transition-all hover:bg-surface-hover hover:text-text-primary"
113+ >
114+ < PlusIcon className = "h-4 w-4" />
115+ </ button >
116+ ) }
117+ </ div >
72118 </ NavHeader >
73119 ) }
74- { ( isVisible . current || shouldAlwaysBeVisible ) &&
75- items . map ( ( item ) => (
120+ < div
121+ className = { classNames (
122+ 'flex flex-col overflow-hidden transition-all duration-300' ,
123+ isVisible . current || shouldAlwaysBeVisible
124+ ? 'max-h-[2000px] opacity-100' // Using large max-height for CSS transition animation
125+ : 'max-h-0 opacity-0' ,
126+ ) }
127+ >
128+ { items . map ( ( item ) => (
76129 < SidebarItem
77130 key = { `${ item . title } -${ item . path } ` }
78131 item = { item }
@@ -81,6 +134,7 @@ export function Section({
81134 shouldShowLabel = { shouldShowLabel }
82135 />
83136 ) ) }
137+ </ div >
84138 </ NavSection >
85139 ) ;
86140}
0 commit comments