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, [])