':''}))}close(){const t=this.querySelector("#menu-content"),e=this.querySelector(".toggle-icon"),n=this.querySelector(".toggle-btn");if(!t||!e||!n)return;t.classList.contains("show")&&(n.setAttribute("aria-label","open menu"),t.classList.remove("show"),e.innerHTML='')}getStyle(){const t=document.createElement("style");t.textContent=" flyout-menu { touch-action: manipulation; display: flex;} #menu-content { position: absolute; right: 0px; bottom: 100%; display: flex; transform: translateY(10px); transform-origin: bottom; background-color: var(--contents-bg); box-shadow: 0 8px 16px rgba(var(--box-shadow-color), var(--box-shadow-opacity)); border: 2px solid var(--accent-color); border-radius: 10px; padding: 10px; margin: 10px; max-width: 100%; visibility: hidden; opacity: 0; z-index: 10; transition: opacity 1s, transform 1s; gap: 0.35rem; touch-action: manipulation; box-sizing: border-box;} #menu-content.enabled { transition: opacity 0.3s, transform 0.3s, visibility 0s 0.3s; } #menu-content.show { visibility: visible; opacity: 1; transform: translateY(0px); transition: opacity 0.3s, transform 0.3s, visibility 0s 0s; } .home-icon { height: 50px; width: 50px; color: var(--accent-color) } .garden-icon { height: 50px; width: 50px; color: var(--accent-color); } .icon-container { display: flex; justify-content: center; align-items: center; flex-direction: column; } .toggle-btn { cursor: pointer; border: none; background: none; outline: none; } .toggle-icon { display: block; } .toggle-svg { color: var(--text-color) } .toggle-btn:focus-visible { outline: 2px solid #4D90FE; outline-offset: 2px; } ",this.appendChild(t)}render(){this.innerHTML=' '}}class e extends HTMLElement{_current=null;minH;maxH;observer;constructor(){super(),this.minH=parseInt(this.dataset.minH||"2",10),this.maxH=parseInt(this.dataset.maxH||"3",10)}connectedCallback(){this.cloneTemplate(),this.maybeInitDOMDependentFeatures()}cloneTemplate(){const t=document.getElementById("desktopToc"),e=document.importNode(t.content,!0);this.appendChild(e)}initDOMDependentFeatures(){this._current=this.querySelector('a[aria-current="true"]');const t=[...this.querySelectorAll("a")];this.setupIntersectionObserver(t)}maybeInitDOMDependentFeatures(){"interactive"===document.readyState||"complete"===document.readyState?this.initDOMDependentFeatures():document.addEventListener("DOMContentLoaded",(()=>this.initDOMDependentFeatures()),{once:!0})}set current(t){t!==this._current&&(this._current&&this._current.removeAttribute("aria-current"),this._current&&this._current.parentElement&&this._current.parentElement.classList.remove("current"),t.setAttribute("aria-current","true"),t.parentElement&&t.parentElement.classList.add("current"),this._current=t)}setupIntersectionObserver(t){const e=document.querySelectorAll("main [id], main [id] ~ *, main .content > *");this.observer&&this.observer.disconnect(),this.observer=new IntersectionObserver((e=>{for(const{isIntersecting:n,target:o}of e){if(!n)continue;const e=this.getElementHeading(o);if(!e)continue;const i=t.find((t=>t.hash==="#"+encodeURIComponent(e.id)));if(i){this.current=i;break}}}),{rootMargin:this.getRootMargin()}),e.forEach((t=>this.observer.observe(t)))}getRootMargin(){const t=(this.querySelector("summary")?.getBoundingClientRect().height||0)+32;return`-${t}px 0% ${t+53-document.documentElement.clientHeight}px`}getElementHeading(t){if(!t)return null;const e=new Set;for(;t&&!e.has(t);){if(t instanceof HTMLHeadingElement){if("_top"===t.id)return t;const e=t.tagName[1];if(e&&parseInt(e,10)>=this.minH&&parseInt(e,10)<=this.maxH)return t}e.add(t),t=t.parentElement}return null}}class n extends e{constructor(){super()}connectedCallback(){this.cloneTemplate(),super.maybeInitDOMDependentFeatures(),this.setupToggle(),this.getStyle()}cloneTemplate(){const t=document.getElementById("mobileToc");if(t){const e=document.importNode(t.content,!0);this.appendChild(e)}}set current(t){super.current=t;const e=this.querySelector("#display-current");e&&(e.textContent=t.textContent)}setupToggle(){const t=this.querySelector("#toc-toggle"),e=this.querySelector("#toc-content"),n=this.querySelector("#button-title");t&&e&&n&&t.addEventListener("click",(()=>{const o=this.getRootNode();if(o instanceof ShadowRoot){const t=o.host;if(t.shadowRoot){const e=t.shadowRoot.querySelector("flyout-menu");e&&e.close()}}const i=e.classList.contains("show");i?t.setAttribute("aria-label","open table of contents"):t.setAttribute("aria-label","close table of contents"),e.classList.toggle("show",!i),n.classList.toggle("show",!i),e.classList.add("enabled");const s=this.querySelector("#caret");s&&(s.style.transform=`rotateZ(${i?"0deg":"-90deg"})`)}))}close(){const t=this.querySelector("#toc-content"),e=this.querySelector("#toc-toggle"),n=this.querySelector("#button-title"),o=this.querySelector("#caret");e&&e.setAttribute("aria-label","open table of contents"),t&&t.classList.toggle("show",!1),n&&n.classList.toggle("show",!1),o&&(o.style.transform="rotateZ(0deg)")}getStyle(){const t=document.createElement("style");t.textContent='\n\t\t\t\t\t\t\tmobile-toc {\n\t\t\t\t\t\t\t\tdisplay: flex;\n\t\t\t\t\t\t\t\toverflow: hidden;\n\t\t\t\t\t\t\t\ttouch-action: manipulation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content {\n\t\t\t\t\t\t\t\tposition: absolute;\n\t\t\t\t\t\t\t\tleft: 0px;\n\t\t\t\t\t\t\t\tright: 0px;\n\t\t\t\t\t\t\t\tbottom: 100%;\n\t\t\t\t\t\t\t\ttransform: translateY(10px);\n\t\t\t\t\t\t\t\tz-index: 10;\n\t\t\t\t\t\t\t\tbackground-color: var(--contents-bg);\n\t\t\t\t\t\t\t\tcolor: var(--text-color);\n\t\t\t\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\t\t\t\tbox-shadow: 0 8px 16px rgba(var(--box-shadow-color), var(--box-shadow-opacity));\n\t\t\t\t\t\t\t\tborder: 2px solid var(--accent-color);\n\t\t\t\t\t\t\t\tborder-radius: 10px;\n\t\t\t\t\t\t\t\tpadding: 10px;\n\t\t\t\t\t\t\t\tmargin: 10px;\n\t\t\t\t\t\t\t\tmax-width: 17rem;\n\t\t\t\t\t\t\t\tvisibility: hidden;\n\t\t\t\t\t\t\t\topacity: 0;\n\t\t\t\t\t\t\t\toverflow: hidden;\n\t\t\t\t\t\t\t\tdisplay: flex;\n\t\t\t\t\t\t\t\tjustify-content: center;\n\t\t\t\t\t\t\t\talign-items: center;\n\t\t\t\t\t\t\t\ttouch-action: manipulation;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content-wrapper {\n\t\t\t\t\t\t\t\twidth: 95%;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content ul {\n\t\t\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\t\t\tpadding: 0;\n\t\t\t\t\t\t\t\tlist-style: none;\n\t\t\t\t\t\t\t\tmargin: 0;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content li {\n\t\t\t\t\t\t\t\tdisplay: flex;\n\t\t\t\t\t\t\t\tflex-direction: column;\n\t\t\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\t\t\tpadding: 0;\n\t\t\t\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\t\t\t\tborder-top: 1px solid #565656;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content ul ul li.current {\n\t\t\t\t\t\t\t\tbackground-color: var(--contents-accent);\n\t\t\t\t\t\t\t\tborder-radius: 2px;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content a[aria-current="true"] {\n\t\t\t\t\t\t\t\tbackground-color: var(--contents-accent);\n\t\t\t\t\t\t\t\tborder-radius: 2px;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content > #toc-content-wrapper > ul > li:first-child {\n\t\t\t\t\t\t\t\tborder-top: none;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content ul ul li {\n\t\t\t\t\t\t\t\tpadding-left: 20px;\n\t\t\t\t\t\t\t\tpadding-right: 0;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content li,\n\t\t\t\t\t\t\t#toc-content a {\n\t\t\t\t\t\t\t\twhite-space: nowrap;\n\t\t\t\t\t\t\t\toverflow: hidden;\n\t\t\t\t\t\t\t\ttext-overflow: ellipsis;\n\t\t\t\t\t\t\t\tdisplay: block;\n\t\t\t\t\t\t\t\tpadding-top: 0.05rem;\n\t\t\t\t\t\t\t\tpadding-bottom: 0.05rem;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content a {\n\t\t\t\t\t\t\t\tpadding-left: 0.35rem;\n\t\t\t\t\t\t\t\ttext-decoration: none;\n\t\t\t\t\t\t\t\tfont-weight: 500;\n\t\t\t\t\t\t\t\tcolor: var(--accent-color);\n\t\t\t\t\t\t\t\ttransition: color 0.15s;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content a:focus-visible {\n\t\t\t\t\t\t\t\tcolor: var(--text-color-opposite);\n\t\t\t\t\t\t\t\tbackground-color: var(--accent-color);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content a:hover {\n\t\t\t\t\t\t\t\ttext-decoration: underline;\n\t\t\t\t\t\t\t\ttext-underline-position: from-font;\n\t\t\t\t\t\t\t\ttext-decoration-thickness: 2px;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content.enabled {\n\t\t\t\t\t\t\t\ttransition:\n\t\t\t\t\t\t\t\t\topacity 0.3s,\n\t\t\t\t\t\t\t\t\ttransform 0.3s,\n\t\t\t\t\t\t\t\t\tvisibility 0s 0.3s;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-content.show {\n\t\t\t\t\t\t\t\tvisibility: visible;\n\t\t\t\t\t\t\t\topacity: 1;\n\t\t\t\t\t\t\t\ttransform: translate3d(0, 0px, 0);\n\t\t\t\t\t\t\t\ttransition:\n\t\t\t\t\t\t\t\t\topacity 0.3s,\n\t\t\t\t\t\t\t\t\ttransform 0.3s,\n\t\t\t\t\t\t\t\t\tvisibility 0s 0s;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#caret {\n\t\t\t\t\t\t\t\ttransform: rotateZ(var(--caret-rotation));\n\t\t\t\t\t\t\t\ttransition: transform 0.3s ease-in-out;\n\t\t\t\t\t\t\t\tmargin-top: 0.15rem;\n\t\t\t\t\t\t\t\twidth: 1.25rem;\n\t\t\t\t\t\t\t\theight: 1.25rem;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#display-current {\n\t\t\t\t\t\t\t\twhite-space: nowrap;\n\t\t\t\t\t\t\t\ttext-overflow: ellipsis;\n\t\t\t\t\t\t\t\toverflow: hidden;\n\t\t\t\t\t\t\t\tmin-width: 10rem;\n\t\t\t\t\t\t\t\ttext-align: left;\n\t\t\t\t\t\t\t\tmargin-left: 0.35rem;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#button-title {\n\t\t\t\t\t\t\t\tdisplay: flex;\n\t\t\t\t\t\t\t\tpadding: 0.25rem;\n\t\t\t\t\t\t\t\tbackground-color: var(--contents-accent);\n\t\t\t\t\t\t\t\tjustify-content: space-between;\n\t\t\t\t\t\t\t\tborder: 1px solid grey;\n\t\t\t\t\t\t\t\tborder-radius: 0.5rem;\n\t\t\t\t\t\t\t\tgap: 0.25rem;\n\t\t\t\t\t\t\t\tfont-weight: 500;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#button-title.show {\n\t\t\t\t\t\t\t\tbackground-color: var(--accent-color);\n\t\t\t\t\t\t\t\tcolor: var(--text-color-opposite);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#toc-toggle {\n\t\t\t\t\t\t\t\tbackground: transparent;\n\t\t\t\t\t\t\t\tcolor: inherit;\n\t\t\t\t\t\t\t\tfont: inherit;\n\t\t\t\t\t\t\t\tborder: none;\n\t\t\t\t\t\t\t\tmargin: 0;\n\t\t\t\t\t\t\t\tpadding: 0;\n\t\t\t\t\t\t\t\talign-items: center;\n\t\t\t\t\t\t\t\tdisplay: flex;\n\t\t\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\t\t\t-webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n\t\t\t\t\t\t\t\tmax-width: 45%;\n\t\t\t\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t#btn-pad {\n\t\t\t\t\t\t\t\tpadding: 0.2rem;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t',this.appendChild(t)}}class o extends HTMLElement{lastScrollTop=0;shadow;ignoreScrollUpdate=!1;constructor(){super(),this.shadow=this.attachShadow({mode:"open",delegatesFocus:!0}),this.timeoutId=null}connectedCallback(){this.createContent(),this.handleInitialHashScroll(),this.lastScrollPos=window.scrollY||document.documentElement.scrollTop,window.addEventListener("scroll",this.handleScroll),this.addEventListeners()}disconnectedCallback(){window.removeEventListener("scroll",this.handleScroll),this.removeLinkClickListener()}handleInitialHashScroll(){window.location.hash&&(this.ignoreScrollUpdate=!0,setTimeout((()=>{this.ignoreScrollUpdate=!1}),1e3))}createContent(){if(window.location.hash){const t=document.createElement("style");t.textContent=this.getStyle(),this.shadow.appendChild(t);const e=document.createElement("nav"),n=document.createElement("mobile-toc"),o=document.createElement("flyout-menu");o.setAttribute("data-theme-icon-size","60px"),e.appendChild(n),e.appendChild(o),this.shadow.appendChild(e)}else setTimeout((()=>{const t=document.createElement("style");t.textContent=this.getStyle(),this.shadow.appendChild(t);const e=document.createElement("nav"),n=document.createElement("mobile-toc"),o=document.createElement("flyout-menu");o.setAttribute("data-theme-icon-size","60px"),e.appendChild(n),e.appendChild(o),this.shadow.appendChild(e)}),450)}addEventListeners(){if(window.location.hash){this.shadow.querySelectorAll("a").forEach((t=>t.addEventListener("click",this.handleLinkClick))),this.addEventListener("focus",this.handleFocus,!0)}else setTimeout((()=>{this.shadow.querySelectorAll("a").forEach((t=>t.addEventListener("click",this.handleLinkClick))),this.addEventListener("focus",this.handleFocus,!0)}),450)}removeLinkClickListener(){this.shadow.querySelectorAll("a").forEach((t=>t.removeEventListener("click",this.handleLinkClick)))}handleLinkClick=()=>{clearTimeout(this.timeoutId),this.ignoreScrollUpdate=!0;this.shadow.querySelector("mobile-toc").close(),this.timeoutId=setTimeout((()=>{this.ignoreScrollUpdate=!1,this.lastScrollPos=window.scrollY||document.documentElement.scrollTop}),1e3)};handleFocus=()=>{this.style.transform="translateY(0)"};handleScroll=()=>{if(this.ignoreScrollUpdate)return;const t=Math.max(0,window.scrollY||document.documentElement.scrollTop);if(t>=document.documentElement.scrollHeight-window.innerHeight)return this.style.transform="translateY(0)",void(this.lastScrollPos=t);if(Math.abs(t-this.lastScrollPos)<5)return;const e=this.shadow.querySelector("mobile-toc"),n=this.shadow.querySelector("flyout-menu");if(!e||!n)return;const o=e.querySelector("section")?.classList.contains("show"),i=n.querySelector("#menu-content")?.classList.contains("show");t>this.lastScrollPos?(o&&e.close(),i&&n.close(),this.style.transform="translateY(100%)"):this.style.transform="translateY(0)",this.lastScrollPos=t};getStyle(){return" :host { position: fixed; bottom: 0; left: 0; right: 0; color: var(--text-color); background-color: var(--contents-bg); border-top: 1px solid black; padding: 0.625rem; transform: translateY(0); transition: transform 0.3s ease-in-out; z-index: 20; max-width: 100%; touch-action: manipulation; } nav { display: flex; justify-content: space-between; width: 100%; }"}}customElements.get("visible-on-scroll-up")||customElements.define("visible-on-scroll-up",o),customElements.get("mobile-toc")||customElements.define("mobile-toc",n),customElements.get("flyout-menu")||customElements.define("flyout-menu",t),customElements.get("aside-toc")||customElements.define("aside-toc",e)}()
Updated: 11 months ago Published: May 2024 1 min read
Images of variations and thoughts about basic UI elements that I like
- Drop downs
- More clicks, but more clear what’s happening
- Switches
- Clear what’s happening but missing the system default option
- Toggle buttons
- Not always clear whats happening
- Does the icon represent the current theme or the theme that it will go to?
- Does it toggle between three states?
- Google Flights

- Nextjs Docs

- Nodejs Docs
