diff --git a/docs/_template.html b/docs/_template.html
index 9b6ac0aa..5a6b9c3e 100644
--- a/docs/_template.html
+++ b/docs/_template.html
@@ -22,6 +22,7 @@
+
{{fsdocs-head-extra}}
@@ -93,6 +94,7 @@
+
{{fsdocs-body-extra}}
diff --git a/docs/content/fsdocs-default.css b/docs/content/fsdocs-default.css
index e2063f56..210117eb 100644
--- a/docs/content/fsdocs-default.css
+++ b/docs/content/fsdocs-default.css
@@ -1000,6 +1000,13 @@ span[onmouseout] {
margin-top: 0;
}
+.fsdocs-description-heading {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: flex-start;
+}
+
.fsdocs-xmldoc {
& pre {
overflow-x: auto;
diff --git a/docs/content/fsdocs-details-set-expanded.js b/docs/content/fsdocs-details-set-expanded.js
new file mode 100644
index 00000000..f1518cd1
--- /dev/null
+++ b/docs/content/fsdocs-details-set-expanded.js
@@ -0,0 +1,9 @@
+const expandDetails = !!JSON.parse(localStorage.getItem('details-expanded'));
+
+addEventListener('load', _ => {
+ if (expandDetails) {
+ for (const details of document.getElementsByTagName('details')) {
+ details.setAttribute('open', 'true');
+ }
+ }
+});
diff --git a/docs/content/fsdocs-details-toggle.js b/docs/content/fsdocs-details-toggle.js
new file mode 100644
index 00000000..9ef6ab39
--- /dev/null
+++ b/docs/content/fsdocs-details-toggle.js
@@ -0,0 +1,50 @@
+import { LitElement, html, css } from 'https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js';
+
+const detailsExpanded = !!JSON.parse(localStorage.getItem('details-expanded'));
+
+export class DetailsToggle extends LitElement {
+ static properties = {
+ _detailsExpanded: { state: true, type: Boolean },
+ };
+
+ constructor() {
+ super();
+ this._detailsExpanded = detailsExpanded;
+ document.addEventListener('detailstoggled', e => {
+ this._detailsExpanded = !!e?.detail?.expanding;
+ this.render();
+ });
+ }
+
+ static styles = css`
+ :host {
+ cursor: pointer;
+ transform: translateY(3px);
+ }
+ `;
+
+ toggleDetails() {
+ this._detailsExpanded = !this._detailsExpanded;
+ localStorage.setItem('details-expanded', JSON.stringify(this._detailsExpanded));
+ if (this._detailsExpanded) {
+ for (const details of document.getElementsByTagName('details')) {
+ details.setAttribute('open', 'true');
+ }
+ } else {
+ for (const details of document.getElementsByTagName('details')) {
+ details.removeAttribute('open');
+ }
+ }
+ document.dispatchEvent(new CustomEvent('detailstoggled', { detail: { expanding: this._detailsExpanded } }));
+ }
+
+ render() {
+ const icon = this._detailsExpanded ? 'carbon:collapse-categories' : 'carbon:expand-categories';
+ const title = this._detailsExpanded ? 'Collapse details' : 'Expand details';
+ return html`
+
+ `;
+ }
+}
+
+customElements.define('fsdocs-details-toggle', DetailsToggle);
diff --git a/src/FSharp.Formatting.ApiDocs/GenerateHtml.fs b/src/FSharp.Formatting.ApiDocs/GenerateHtml.fs
index 5190acaf..34c5d5e6 100644
--- a/src/FSharp.Formatting.ApiDocs/GenerateHtml.fs
+++ b/src/FSharp.Formatting.ApiDocs/GenerateHtml.fs
@@ -109,7 +109,9 @@ type HtmlRender(model: ApiDocModel, ?menuTemplateFolder: string) =
thead [] [
tr [] [
td [ Class "fsdocs-member-list-header" ] [ !!tableHeader ]
- td [ Class "fsdocs-member-list-header" ] [ !! "Description" ]
+ td [ Class "fsdocs-member-list-header" ] [
+ div [ Class "fsdocs-description-heading" ] [ !! "Description"; fsdocsDetailsToggle [] ]
+ ]
]
]
tbody [] [
diff --git a/src/FSharp.Formatting.Common/HtmlModel.fs b/src/FSharp.Formatting.Common/HtmlModel.fs
index 0ffea852..3f25c765 100644
--- a/src/FSharp.Formatting.Common/HtmlModel.fs
+++ b/src/FSharp.Formatting.Common/HtmlModel.fs
@@ -750,3 +750,6 @@ module internal Html =
/// Web component from https://iconify.design/docs/
let iconifyIcon (props: HtmlProperties list) =
HtmlElement.CustomElement("iconify-icon", props, [])
+
+ let fsdocsDetailsToggle (props: HtmlProperties list) =
+ HtmlElement.CustomElement("fsdocs-details-toggle", props, [])