11< h3 > < a href ="{{ pathto(root_doc)|e }} "> {{ project|title }}</ a > </ h3 >
22< div id ="salt-globaltoc ">
3- {{ toctree(includehidden=True, collapse=False, maxdepth=1 ) }}
3+ {{ toctree(includehidden=True, collapse=False, maxdepth=2 ) }}
44</ div >
55
66< style >
@@ -14,6 +14,13 @@ <h3><a href="{{ pathto(root_doc)|e }}">{{ project|title }}</a></h3>
1414 margin : 0 0 0.25rem 0 ;
1515}
1616
17+ /* Indent nested levels */
18+ # salt-globaltoc ul ul {
19+ padding-left : 0.75rem ;
20+ margin : 0 ;
21+ width : 100% ;
22+ }
23+
1724# salt-globaltoc p .caption {
1825 display : flex;
1926 align-items : center;
@@ -33,7 +40,7 @@ <h3><a href="{{ pathto(root_doc)|e }}">{{ project|title }}</a></h3>
3340 color : var (--pst-color-text-base , inherit);
3441}
3542
36- /* Triangle arrow indicator */
43+ /* Triangle arrow indicator on captions */
3744# salt-globaltoc p .caption ::before {
3845 content : "" ;
3946 display : inline-block;
@@ -50,7 +57,56 @@ <h3><a href="{{ pathto(root_doc)|e }}">{{ project|title }}</a></h3>
5057 transform : rotate (90deg );
5158}
5259
53- # salt-globaltoc .toctree-l1 > a {
60+ /* Flex layout for li items that have children, so link + toggle button sit on one row */
61+ # salt-globaltoc li .has-children {
62+ display : flex;
63+ flex-wrap : wrap;
64+ align-items : flex-start;
65+ }
66+
67+ # salt-globaltoc li .has-children > a {
68+ flex : 1 ;
69+ min-width : 0 ;
70+ }
71+
72+ # salt-globaltoc li .has-children > ul {
73+ width : 100% ;
74+ }
75+
76+ /* Toggle button injected next to links that have children */
77+ # salt-globaltoc .toc-toggle {
78+ flex-shrink : 0 ;
79+ background : none;
80+ border : none;
81+ cursor : pointer;
82+ padding : 0.25rem 0.35rem ;
83+ color : var (--pst-color-text-muted , # 6c757d );
84+ line-height : 1 ;
85+ border-radius : 4px ;
86+ }
87+
88+ # salt-globaltoc .toc-toggle : hover {
89+ color : var (--pst-color-text-base , inherit);
90+ background-color : var (--pst-color-surface , rgba (0 , 0 , 0 , 0.06 ));
91+ }
92+
93+ # salt-globaltoc .toc-toggle ::before {
94+ content : "" ;
95+ display : inline-block;
96+ width : 0 ;
97+ height : 0 ;
98+ border-style : solid;
99+ border-width : 4px 0 4px 6px ;
100+ border-color : transparent transparent transparent currentColor;
101+ transition : transform 0.15s ease;
102+ }
103+
104+ # salt-globaltoc .toc-toggle .expanded ::before {
105+ transform : rotate (90deg );
106+ }
107+
108+ /* Link styles for all toctree levels */
109+ # salt-globaltoc li > a {
54110 display : block;
55111 padding : 0.25rem 0.5rem ;
56112 color : var (--pst-color-text-base , inherit);
@@ -59,40 +115,96 @@ <h3><a href="{{ pathto(root_doc)|e }}">{{ project|title }}</a></h3>
59115 line-height : 1.4 ;
60116}
61117
62- # salt-globaltoc . toctree-l1 > a : hover {
118+ # salt-globaltoc li > a : hover {
63119 background-color : var (--pst-color-surface , rgba (0 , 0 , 0 , 0.06 ));
64120}
65121
66- # salt-globaltoc . toctree-l1 .current > a ,
67- # salt-globaltoc . toctree-l1 .current > a : hover {
122+ # salt-globaltoc li .current > a ,
123+ # salt-globaltoc li .current > a : hover {
68124 font-weight : 600 ;
69125 background-color : var (--pst-color-surface , rgba (0 , 0 , 0 , 0.06 ));
70126 color : var (--pst-color-primary , # 0099cd );
71127}
128+
129+ /* Slightly smaller text for deeper levels */
130+ # salt-globaltoc .toctree-l2 > a ,
131+ # salt-globaltoc .toctree-l3 > a ,
132+ # salt-globaltoc .toctree-l4 > a {
133+ font-size : 0.85rem ;
134+ padding : 0.18rem 0.5rem ;
135+ }
72136</ style >
73137
74138< script >
75139( function ( ) {
140+ function hasCurrentDescendant ( ul ) {
141+ return ! ! ul . querySelector ( "li.current" ) ;
142+ }
143+
76144 function initCollapsible ( ) {
77145 var container = document . getElementById ( "salt-globaltoc" ) ;
78146 if ( ! container ) return ;
79147
148+ // Caption-level collapsing (start expanded by default)
80149 container . querySelectorAll ( "p.caption" ) . forEach ( function ( caption ) {
81150 var ul = caption . nextElementSibling ;
82151 if ( ! ul || ul . tagName !== "UL" ) return ;
83152
84- if ( ul . querySelector ( "li.current" ) ) {
85- caption . classList . add ( "expanded" ) ;
86- } else {
87- ul . style . display = "none" ;
88- }
153+ caption . classList . add ( "expanded" ) ;
89154
90155 caption . addEventListener ( "click" , function ( ) {
91156 var isCollapsed = ul . style . display === "none" ;
92157 ul . style . display = isCollapsed ? "" : "none" ;
93158 caption . classList . toggle ( "expanded" , isCollapsed ) ;
94159 } ) ;
95160 } ) ;
161+
162+ // Nested li collapsing: any li that directly contains a ul
163+ container . querySelectorAll ( "li" ) . forEach ( function ( li ) {
164+ var childUl = li . querySelector ( ":scope > ul" ) ;
165+ if ( ! childUl ) return ;
166+
167+ var link = li . querySelector ( ":scope > a" ) ;
168+ if ( ! link ) return ;
169+
170+ // Distinguish sub-pages (no # in href) from intra-page section headers (# in href)
171+ var childLinks = childUl . querySelectorAll ( ":scope > li > a" ) ;
172+ var hasSubPages = false ;
173+ childLinks . forEach ( function ( childLink ) {
174+ var href = childLink . getAttribute ( "href" ) || "" ;
175+ if ( href . indexOf ( "#" ) === - 1 ) {
176+ hasSubPages = true ;
177+ }
178+ } ) ;
179+
180+ if ( ! hasSubPages ) {
181+ // Children are section headers of this page — hide them entirely
182+ childUl . style . display = "none" ;
183+ return ;
184+ }
185+
186+ li . classList . add ( "has-children" ) ;
187+
188+ var btn = document . createElement ( "button" ) ;
189+ btn . className = "toc-toggle" ;
190+ btn . setAttribute ( "aria-label" , "Toggle section" ) ;
191+
192+ var expanded = li . classList . contains ( "current" ) || hasCurrentDescendant ( childUl ) ;
193+ if ( expanded ) {
194+ btn . classList . add ( "expanded" ) ;
195+ } else {
196+ childUl . style . display = "none" ;
197+ }
198+
199+ link . insertAdjacentElement ( "afterend" , btn ) ;
200+
201+ btn . addEventListener ( "click" , function ( e ) {
202+ e . stopPropagation ( ) ;
203+ var isCollapsed = childUl . style . display === "none" ;
204+ childUl . style . display = isCollapsed ? "" : "none" ;
205+ btn . classList . toggle ( "expanded" , isCollapsed ) ;
206+ } ) ;
207+ } ) ;
96208 }
97209
98210 if ( document . readyState === "loading" ) {
0 commit comments