({
title,
items,
sidebarExpanded,
shouldShowLabel,
activePage,
isItemsButton,
className,
flag,
isAlwaysOpenOnMobile,
onAdd,
addHref,
compact = false,
}: SectionProps)
| 34 | } |
| 35 | |
| 36 | export function Section({ |
| 37 | title, |
| 38 | items, |
| 39 | sidebarExpanded, |
| 40 | shouldShowLabel, |
| 41 | activePage, |
| 42 | isItemsButton, |
| 43 | className, |
| 44 | flag, |
| 45 | isAlwaysOpenOnMobile, |
| 46 | onAdd, |
| 47 | addHref, |
| 48 | compact = false, |
| 49 | }: SectionProps): ReactElement { |
| 50 | const { flags, updateFlag } = useSettingsContext(); |
| 51 | const { sidebarRendered } = useSidebarRendered(); |
| 52 | const shouldAlwaysBeVisible = isAlwaysOpenOnMobile && !sidebarRendered; |
| 53 | const currentFlagValue = flag ? flags?.[flag] : undefined; |
| 54 | // The collapse toggle only renders alongside a section `title`. Without a |
| 55 | // title (e.g. the V2 sidebar's category panels) there is no way to |
| 56 | // re-expand, so a persisted `false` flag set from a layout that did show the |
| 57 | // toggle would strand the section permanently closed. Titleless sections are |
| 58 | // always expanded. |
| 59 | const initialIsVisible = |
| 60 | !title || isNullOrUndefined(currentFlagValue) ? true : currentFlagValue; |
| 61 | // State (not a ref) so toggling re-renders even for sections without a |
| 62 | // persisted `flag` (e.g. the settings panel groups) — otherwise the |
| 63 | // collapse never visibly happens. |
| 64 | const [isVisible, setIsVisible] = useState(initialIsVisible); |
| 65 | |
| 66 | const toggleFlag = () => { |
| 67 | const nextIsVisible = !isVisible; |
| 68 | |
| 69 | if (flag) { |
| 70 | updateFlag(flag, nextIsVisible); |
| 71 | } |
| 72 | |
| 73 | setIsVisible(nextIsVisible); |
| 74 | }; |
| 75 | |
| 76 | return ( |
| 77 | <NavSection className={classNames('group/section mt-1', className)}> |
| 78 | {title && ( |
| 79 | <NavHeader className="relative hidden laptop:flex"> |
| 80 | {/* Divider shown when a collapsible (titled) section is collapsed */} |
| 81 | <div |
| 82 | className={classNames( |
| 83 | 'absolute inset-x-0 flex items-center justify-center px-2 transition-opacity duration-300', |
| 84 | sidebarExpanded ? 'opacity-0' : 'opacity-100', |
| 85 | )} |
| 86 | > |
| 87 | <hr className="w-full border-t border-border-subtlest-tertiary" /> |
| 88 | </div> |
| 89 | {/* Header content shown when sidebar is expanded */} |
| 90 | <div |
| 91 | className={classNames( |
| 92 | // `ml-3 mr-2 ... pl-1` aligns the section title's left edge |
| 93 | // with the items below it (items have `mx-3`), so "Feeds v" |
nothing calls this directly
no test coverage detected