88 useState ,
99 type ComponentType ,
1010 type KeyboardEvent ,
11- type ReactNode ,
1211} from "react" ;
1312import {
1413 ArchiveIcon ,
@@ -24,32 +23,22 @@ import {
2423 Settings2Icon ,
2524 XIcon ,
2625} from "lucide-react" ;
27- import { useLocation , useNavigate , useRouterState } from "@tanstack/react-router" ;
26+ import { useLocation , useNavigate } from "@tanstack/react-router" ;
2827
2928import { Button } from "../ui/button" ;
30- import { Collapsible , CollapsiblePanel } from "../ui/collapsible" ;
3129import { Input } from "../ui/input" ;
3230import { Kbd } from "../ui/kbd" ;
33- import { cn } from "../../lib/utils" ;
3431import {
3532 SidebarContent ,
3633 SidebarFooter ,
3734 SidebarGroup ,
3835 SidebarMenu ,
3936 SidebarMenuButton ,
4037 SidebarMenuItem ,
41- SidebarMenuSub ,
42- SidebarMenuSubButton ,
43- SidebarMenuSubItem ,
4438 useSidebar ,
4539} from "../ui/sidebar" ;
4640import { SidebarUtilityMenu } from "../sidebar/SidebarChrome" ;
4741import { scrollToSettingsTarget } from "./settingsLayout" ;
48- import {
49- getVisibleSettingsSectionIds ,
50- observeSettingsSectionVisibility ,
51- type SettingsSectionVisibilityState ,
52- } from "./settingsSectionVisibility" ;
5342import {
5443 searchSettings ,
5544 SETTINGS_SECTION_LABELS ,
@@ -106,102 +95,22 @@ const SETTINGS_NAV_ITEMS: ReadonlyArray<{
10695 icon : SETTINGS_SECTION_ICONS [ to ] ,
10796} ) ) ;
10897
109- const SETTINGS_PAGE_SECTIONS : Partial <
110- Readonly < Record < SettingsPath , ReadonlyArray < { label : string ; targetId : string } > > >
111- > = {
112- "/settings/general" : [
113- { label : "Organization" , targetId : "organization" } ,
114- { label : "Behavior" , targetId : "behavior" } ,
115- { label : "Projects & threads" , targetId : "projects-and-threads" } ,
116- { label : "Confirmations" , targetId : "confirmations" } ,
117- { label : "Text generation" , targetId : "text-generation" } ,
118- { label : "About" , targetId : "about" } ,
119- { label : "Legacy features" , targetId : "legacy-features" } ,
120- ] ,
121- "/settings/appearance" : [
122- { label : "Colors & themes" , targetId : "appearance" } ,
123- { label : "Interface" , targetId : "appearance-interface" } ,
124- { label : "Motion" , targetId : "motion" } ,
125- { label : "Typography" , targetId : "typography" } ,
126- ] ,
127- "/settings/source-control" : [
128- { label : "Version control" , targetId : "source-control" } ,
129- { label : "Text generation" , targetId : "source-control-text-generation" } ,
130- ] ,
131- "/settings/connections" : [
132- { label : "This environment" , targetId : "connections-environment" } ,
133- { label : "Remote environments" , targetId : "remote-environments" } ,
134- ] ,
135- } ;
136-
13798function SettingsSectionIcon ( { to } : { to : SettingsPath } ) {
13899 const Icon = SETTINGS_SECTION_ICONS [ to ] ;
139100 return < Icon className = "mt-0.5 size-3.5 shrink-0 text-sidebar-muted-foreground/60" /> ;
140101}
141102
142- function SettingsSubmenuCollapse ( {
143- open,
144- children,
145- } : {
146- readonly open : boolean ;
147- readonly children : ReactNode ;
148- } ) {
149- return (
150- < Collapsible open = { open } >
151- < CollapsiblePanel className = "duration-150 ease-out motion-reduce:transition-none" >
152- { children }
153- </ CollapsiblePanel >
154- </ Collapsible >
155- ) ;
156- }
157-
158103export function SettingsSidebarNav ( { pathname } : { pathname : string } ) {
159104 const navigate = useNavigate ( ) ;
160105 const currentHash = useLocation ( { select : ( location ) => location . hash } ) ;
161- const resolvedPathname = useRouterState ( {
162- select : ( state ) => state . resolvedLocation ?. pathname ,
163- } ) ;
164106 const { isMobile, setOpenMobile, open, setOpen } = useSidebar ( ) ;
165107 const searchInputRef = useRef < HTMLInputElement > ( null ) ;
166108 const [ query , setQuery ] = useState ( "" ) ;
167109 const [ activeResultIndex , setActiveResultIndex ] = useState ( 0 ) ;
168- const [ sectionVisibility , setSectionVisibility ] = useState < SettingsSectionVisibilityState | null > (
169- null ,
170- ) ;
171110 const searchableItems = useAvailableSettingsSearchItems ( ) ;
172111 const results = useMemo ( ( ) => searchSettings ( query , searchableItems ) , [ query , searchableItems ] ) ;
173112 const isSearching = query . trim ( ) . length > 0 ;
174113 const hasResults = results . length > 0 ;
175- const activeSettingsPath = SETTINGS_NAV_ITEMS . find (
176- ( item ) => pathname === item . to || pathname . startsWith ( `${ item . to } /` ) ,
177- ) ?. to ;
178- const observedVisibilityScope = useMemo ( ( ) => {
179- const path = SETTINGS_NAV_ITEMS . find (
180- ( item ) =>
181- resolvedPathname === item . to || resolvedPathname ?. startsWith ( `${ item . to } /` ) === true ,
182- ) ?. to ;
183- const pageSections = path ? SETTINGS_PAGE_SECTIONS [ path ] : undefined ;
184- return path && pageSections ? { path, pageSections } : null ;
185- } , [ resolvedPathname ] ) ;
186- const visiblePageSectionIds = getVisibleSettingsSectionIds ( {
187- activePath : activeSettingsPath ,
188- scope : observedVisibilityScope ,
189- visibility : sectionVisibility ,
190- } ) ;
191-
192- useEffect ( ( ) => {
193- if ( ! observedVisibilityScope ) return ;
194- const container = document . querySelector < HTMLElement > ( "[data-settings-page-layout]" ) ;
195- if ( ! container ) return ;
196-
197- return observeSettingsSectionVisibility ( {
198- container,
199- targetIds : observedVisibilityScope . pageSections . map ( ( section ) => section . targetId ) ,
200- onChange ( targetIds ) {
201- setSectionVisibility ( { scope : observedVisibilityScope , targetIds : new Set ( targetIds ) } ) ;
202- } ,
203- } ) ;
204- } , [ observedVisibilityScope ] ) ;
205114
206115 useEffect ( ( ) => {
207116 setActiveResultIndex ( ( index ) => Math . min ( index , Math . max ( results . length - 1 , 0 ) ) ) ;
@@ -261,24 +170,6 @@ export function SettingsSidebarNav({ pathname }: { pathname: string }) {
261170 } ,
262171 [ isMobile , navigate , setOpenMobile ] ,
263172 ) ;
264- const handlePageSectionClick = useCallback (
265- ( to : SettingsPath , targetId : string ) => {
266- if ( isMobile ) {
267- setOpenMobile ( false ) ;
268- }
269- if ( pathname === to && scrollToSettingsTarget ( targetId , { highlight : false } ) ) {
270- return ;
271- }
272- void navigate ( {
273- to,
274- hash : targetId ,
275- replace : true ,
276- hashScrollIntoView : false ,
277- state : { settingsTargetHighlight : false } ,
278- } ) ;
279- } ,
280- [ isMobile , navigate , pathname , setOpenMobile ] ,
281- ) ;
282173 const clearSearch = useCallback ( ( ) => {
283174 setQuery ( "" ) ;
284175 setActiveResultIndex ( 0 ) ;
@@ -430,8 +321,7 @@ export function SettingsSidebarNav({ pathname }: { pathname: string }) {
430321 < SidebarMenu className = "ps-px" >
431322 { SETTINGS_NAV_ITEMS . map ( ( item ) => {
432323 const Icon = item . icon ;
433- const pageSections = SETTINGS_PAGE_SECTIONS [ item . to ] ;
434- const isActive = activeSettingsPath === item . to ;
324+ const isActive = pathname === item . to || pathname . startsWith ( `${ item . to } /` ) ;
435325 return (
436326 < SidebarMenuItem key = { item . to } >
437327 < SidebarMenuButton
@@ -441,29 +331,6 @@ export function SettingsSidebarNav({ pathname }: { pathname: string }) {
441331 < Icon />
442332 < span className = "truncate" > { item . label } </ span >
443333 </ SidebarMenuButton >
444- { pageSections ? (
445- < SettingsSubmenuCollapse open = { isActive } >
446- < SidebarMenuSub className = "border-l-0" >
447- { pageSections . map ( ( section ) => (
448- < SidebarMenuSubItem key = { section . targetId } >
449- < SidebarMenuSubButton
450- render = { < button type = "button" /> }
451- size = "sm"
452- data-visible = { visiblePageSectionIds . has ( section . targetId ) }
453- className = { cn (
454- "w-full text-sidebar-muted-foreground/65" ,
455- visiblePageSectionIds . has ( section . targetId ) &&
456- "font-medium text-sidebar-foreground" ,
457- ) }
458- onClick = { ( ) => handlePageSectionClick ( item . to , section . targetId ) }
459- >
460- < span className = "ms-0.5" > { section . label } </ span >
461- </ SidebarMenuSubButton >
462- </ SidebarMenuSubItem >
463- ) ) }
464- </ SidebarMenuSub >
465- </ SettingsSubmenuCollapse >
466- ) : null }
467334 </ SidebarMenuItem >
468335 ) ;
469336 } ) }
0 commit comments