Skip to content

[clang-doc] Make sidebar sections collapsible#174531

Merged
evelez7 merged 1 commit intomainfrom
users/evelez7/clang-doc-collapsible-sidebar-lists
Jan 6, 2026
Merged

[clang-doc] Make sidebar sections collapsible#174531
evelez7 merged 1 commit intomainfrom
users/evelez7/clang-doc-collapsible-sidebar-lists

Conversation

@evelez7
Copy link
Member

@evelez7 evelez7 commented Jan 6, 2026

Collapsible lists are achieved via <details> and their child
<summary> tags. <details> tags allow for a section to be designated
as collapsible, while the <summary> tag is used as the sidebar
section's header. This approach was chosen over making the lists
stateful through various CSS properties.

This patch also refactors the <li> tag structure of sidebar sections.
Previously, the section header and list items were in separate <li>
tags without sharing a parent. Now, the header and items are under a
single <li> tag which makes more sense semantically.

Collapsible lists are achieved via `<details>` and their child
`<summary>` tags. `<details>` tags allow for a section to be designated
as collapsible, while the `<summary>` tag is used as the sidebar
section's header. This approach was chosen over making the lists
stateful through various CSS properties.

This patch also refactors the `<li>` tag structure of sidebar sections.
Previously, the section header and list items were in separate `<li>`
tags without sharing a parent. Now, the header and items are under a
single `<li>` tag which makes more sense semantically.
Copy link
Member Author

evelez7 commented Jan 6, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@evelez7 evelez7 requested review from ilovepi and petrhosek January 6, 2026 06:26
@evelez7 evelez7 marked this pull request as ready for review January 6, 2026 06:26
@llvmbot
Copy link
Member

llvmbot commented Jan 6, 2026

@llvm/pr-subscribers-clang-tools-extra

Author: Erick Velez (evelez7)

Changes

Collapsible lists are achieved via &lt;details&gt; and their child
&lt;summary&gt; tags. &lt;details&gt; tags allow for a section to be designated
as collapsible, while the &lt;summary&gt; tag is used as the sidebar
section's header. This approach was chosen over making the lists
stateful through various CSS properties.

This patch also refactors the &lt;li&gt; tag structure of sidebar sections.
Previously, the section header and list items were in separate &lt;li&gt;
tags without sharing a parent. Now, the header and items are under a
single &lt;li&gt; tag which makes more sense semantically.


Patch is 49.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/174531.diff

11 Files Affected:

  • (modified) clang-tools-extra/clang-doc/assets/clang-doc-mustache.css (+2-4)
  • (modified) clang-tools-extra/clang-doc/assets/class-template.mustache (+96-80)
  • (modified) clang-tools-extra/clang-doc/assets/index-template.mustache (+12-10)
  • (modified) clang-tools-extra/clang-doc/assets/namespace-template.mustache (+72-60)
  • (modified) clang-tools-extra/test/clang-doc/basic-project.mustache.test (+88-68)
  • (modified) clang-tools-extra/test/clang-doc/index.cpp (+13-11)
  • (modified) clang-tools-extra/test/clang-doc/json/class.cpp (+17-19)
  • (modified) clang-tools-extra/test/clang-doc/json/compound-constraints.cpp (+19-21)
  • (modified) clang-tools-extra/test/clang-doc/mustache-index.cpp (+14-16)
  • (modified) clang-tools-extra/test/clang-doc/mustache-separate-namespace.cpp (+10-8)
  • (modified) clang-tools-extra/test/clang-doc/typedef-alias.cpp (+20-25)
diff --git a/clang-tools-extra/clang-doc/assets/clang-doc-mustache.css b/clang-tools-extra/clang-doc/assets/clang-doc-mustache.css
index 67f11f77eae61..0181e255f4d9f 100644
--- a/clang-tools-extra/clang-doc/assets/clang-doc-mustache.css
+++ b/clang-tools-extra/clang-doc/assets/clang-doc-mustache.css
@@ -421,8 +421,7 @@ body, html {
 }
 
 .sidebar ul li {
-    padding-right: 1rem;
-    padding-left: 2rem;
+    padding-left: 1rem;
     padding-top: 0.25rem;
     padding-bottom: 0.25rem;
 }
@@ -430,8 +429,7 @@ body, html {
 .sidebar-section {
     font-size:1.5rem;
     font-weight: bold;
-    margin-bottom: 1rem;
-    padding: 3rem;
+    padding-left: 1rem;
 }
 .sidebar-section a {
     color: var(--brand)
diff --git a/clang-tools-extra/clang-doc/assets/class-template.mustache b/clang-tools-extra/clang-doc/assets/class-template.mustache
index 20510b6fd4d10..0b29ad23129c6 100644
--- a/clang-tools-extra/clang-doc/assets/class-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/class-template.mustache
@@ -16,115 +16,131 @@
                 <h2>{{TagType}} {{Name}}</h2>
                 <ul>
                     {{#HasPublicMembers}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#PublicMembers">Public Members</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#PublicMembers}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{Name}}">{{Name}}</a>
-                            </li>
-                            {{/PublicMembers}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                              <a class="sidebar-item" href="#PublicMembers">Public Members</a>
+                            </summary>
+                            <ul>
+                                {{#PublicMembers}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{Name}}">{{Name}}</a>
+                                </li>
+                                {{/PublicMembers}}
+                            </ul>
+                        </details>
                     </li>
                     {{/HasPublicMembers}}
                     {{#ProtectedMembers}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#PublicMethods">Protected Members</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Obj}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{Name}}">{{Name}}</a>
-                            </li>
-                            {{/Obj}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#PublicMethods">Protected Members</a>
+                            </summary>
+                            <ul>
+                                {{#Obj}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{Name}}">{{Name}}</a>
+                                </li>
+                                {{/Obj}}
+                            </ul>
+                        </details>
                     </li>
                     {{/ProtectedMembers}}
                     {{#HasPublicFunctions}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#PublicMethods">Public Method</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#PublicFunctions}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
-                            </li>
-                            {{/PublicFunctions}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#PublicMethods">Public Method</a>
+                            </summary>
+                            <ul>
+                                {{#PublicFunctions}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
+                                </li>
+                                {{/PublicFunctions}}
+                            </ul>
+                        </details>
                     </li>
                     {{/HasPublicFunctions}}
                     {{#ProtectedFunction}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#ProtectedFunction">Protected Method</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Obj}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{ID}}">{{Name}}</a>
-                            </li>
-                            {{/Obj}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#ProtectedFunction">Protected Method</a>
+                            </summary>
+                            <ul>
+                                {{#Obj}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{ID}}">{{Name}}</a>
+                                </li>
+                                {{/Obj}}
+                            </ul>
+                        </details>
                     </li>
                     {{/ProtectedFunction}}
                     {{#HasEnums}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#Enums">Enums</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Enums}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
-                            </li>
-                            {{/Enums}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#Enums">Enums</a>
+                            </summary>
+                            <ul>
+                                {{#Enums}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
+                                </li>
+                                {{/Enums}}
+                            </ul>
+                        </details>
                     </li>
                     {{/HasEnums}}
                     {{#HasTypedefs}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#Typedefs">Typedefs</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Typedefs}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
-                            </li>
-                            {{/Typedefs}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#Typedefs">Typedefs</a>
+                            </summary>
+                            <ul>
+                                {{#Typedefs}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
+                                </li>
+                                {{/Typedefs}}
+                            </ul>
+                        </details>
                     </li>
                     {{/HasTypedefs}}
                     {{#HasRecords}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#Classes">Inner Classes</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Records}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
-                            </li>
-                            {{/Records}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#Classes">Inner Classes</a>
+                            </summary>
+                            <ul>
+                                {{#Records}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
+                                </li>
+                                {{/Records}}
+                            </ul>
+                        </details>
                     </li>
                     {{/HasRecords}}
                     {{#HasFriends}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#Friends">Friends</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Friends}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{Reference.USR}}">{{Reference.Name}}</a>
-                            </li>
-                            {{/Friends}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#Friends">Friends</a>
+                            </summary>
+                            <ul>
+                                {{#Friends}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{Reference.USR}}">{{Reference.Name}}</a>
+                                </li>
+                                {{/Friends}}
+                            </ul>
+                        </details>
                     </li>
                     {{/HasRecords}}
                 </ul>
diff --git a/clang-tools-extra/clang-doc/assets/index-template.mustache b/clang-tools-extra/clang-doc/assets/index-template.mustache
index de64da4d709ee..cee7df872a0e8 100644
--- a/clang-tools-extra/clang-doc/assets/index-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/index-template.mustache
@@ -8,17 +8,19 @@
             <div class="sidebar">
                 <h2>{{ProjectName}}</h2>
                 <ul>
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#Namespaces">Namespaces</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Index}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{Name}}">{{Name}}</a>
-                            </li>
-                            {{/Index}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#Namespaces">Namespaces</a>
+                            </summary>
+                            <ul>
+                                {{#Index}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{Name}}">{{Name}}</a>
+                                </li>
+                                {{/Index}}
+                            </ul>
+                        </details>
                     </li>
                 </ul>
             </div>
diff --git a/clang-tools-extra/clang-doc/assets/namespace-template.mustache b/clang-tools-extra/clang-doc/assets/namespace-template.mustache
index 2d8381a9ea6e3..567af626714ef 100644
--- a/clang-tools-extra/clang-doc/assets/namespace-template.mustache
+++ b/clang-tools-extra/clang-doc/assets/namespace-template.mustache
@@ -16,87 +16,99 @@
                 <h2>{{#RecordType}}{{RecordType}} {{/RecordType}}{{Name}}</h2>
                 <ul>
                     {{#HasEnums}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#Enums">Enums</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Enums}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
-                            </li>
-                            {{/Enums}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#Enums">Enums</a>
+                            </summary>
+                            <ul>
+                                {{#Enums}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
+                                </li>
+                                {{/Enums}}
+                            </ul>
+                        </details>
                     </li>
                     {{/HasEnums}}
                     {{#HasRecords}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#Classes">Inner Classes</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Records}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
-                            </li>
-                            {{/Records}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#Classes">Inner Classes</a>
+                            </summary>
+                            <ul>
+                                {{#Records}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
+                                </li>
+                                {{/Records}}
+                            </ul>
+                        </details>
                     </li>
                     {{/HasRecords}}
                     {{#HasFunctions}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#Functions">Functions</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Functions}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{USR}}">{{Name}}{{#Template}}{{#Specialization}}&lt;{{#Parameters}}{{Param}}{{^End}}, {{/End}}{{/Parameters}}&gt;{{/Specialization}}{{/Template}}</a>
-                            </li>
-                            {{/Functions}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#Functions">Functions</a>
+                            </summary>
+                            <ul>
+                                {{#Functions}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{USR}}">{{Name}}{{#Template}}{{#Specialization}}&lt;{{#Parameters}}{{Param}}{{^End}}, {{/End}}{{/Parameters}}&gt;{{/Specialization}}{{/Template}}</a>
+                                </li>
+                                {{/Functions}}
+                            </ul>
+                        </details>
                     </li>
                     {{/HasFunctions}}
                     {{#HasNamespaces}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#Namespaces">Namespaces</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Namespaces}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
-                            </li>
-                            {{/Namespaces}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#Namespaces">Namespaces</a>
+                            </summary>
+                            <ul>
+                                {{#Namespaces}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
+                                </li>
+                                {{/Namespaces}}
+                            </ul>
+                        </details>
                     </li>
                     {{/HasNamespaces}}
                     {{#HasConcepts}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#Concepts">Concepts</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Concepts}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
-                            </li>
-                            {{/Concepts}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+                                <a class="sidebar-item" href="#Concepts">Concepts</a>
+                            </summary>
+                            <ul>
+                                {{#Concepts}}
+                                <li class="sidebar-item-container">
+                                    <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
+                                </li>
+                                {{/Concepts}}
+                            </ul>
+                        </details>
                     </li>
                     {{/HasConcepts}}
                     {{#HasTypedefs}}
-                    <li class="sidebar-section">
-                        <a class="sidebar-item" href="#Typedefs">Typedefs</a>
-                    </li>
                     <li>
-                        <ul>
-                            {{#Typedefs}}
-                            <li class="sidebar-item-container">
-                                <a class="sidebar-item" href="#{{USR}}">{{Name}}</a>
-                            </li>
-                            {{/Typedefs}}
-                        </ul>
+                        <details open>
+                            <summary class="sidebar-section">
+          ...
[truncated]

Copy link
Member Author

evelez7 commented Jan 6, 2026

Copy link
Member Author

evelez7 commented Jan 6, 2026

Merge activity

  • Jan 6, 9:41 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jan 6, 9:42 PM UTC: @evelez7 merged this pull request with Graphite.

@evelez7 evelez7 merged commit 8ed9a40 into main Jan 6, 2026
14 checks passed
@evelez7 evelez7 deleted the users/evelez7/clang-doc-collapsible-sidebar-lists branch January 6, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants