#import "./custom_html.typ" as chtml // Need inline svg for css color control, so no `image` element :( #let menu-icon = html.elem( "svg", attrs: ( //width: "24", //height: "24", style: "width: 2em; height: 2em;", fill: "currentcolor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" ), html.elem("path", attrs: ( clip-rule: "evenodd", fill-rule: "evenodd", d: "M3 6.75A.75.75.0 013.75 6h16.5a.75.75.0 010 1.5H3.75A.75.75.0 013 6.75zM3 12a.75.75.0 01.75-.75h16.5a.75.75.0 010 1.5H3.75A.75.75.0 013 12zm0 5.25a.75.75.0 01.75-.75h16.5a.75.75.0 010 1.5H3.75A.75.75.0 013 17.25z" )) ) #let close-icon = html.elem( "svg", attrs: ( //width: "24", //height: "24", style: "width: 2em; height: 2em;", fill: "currentcolor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" ), html.elem("path", attrs: ( clip-rule: "evenodd", fill-rule: "evenodd", d: "M5.47 5.47a.75.75.0 011.06.0L12 10.94l5.47-5.47a.75.75.0 111.06 1.06L13.06 12l5.47 5.47a.75.75.0 11-1.06 1.06L12 13.06l-5.47 5.47a.75.75.0 01-1.06-1.06L10.94 12 5.47 6.53a.75.75.0 010-1.06z" )) ) /// Buttons to toggle the navigation menu. /// aria-label is the accessibility label for the toggle. /// menu-icon and close-icon are the content of the toggle deppending on /// its state. Be carefull to keep it compatible with both light and dark /// theme. #let nav-menu-toggle( aria-label: "Menu Toggle", menu-icon: menu-icon, close-icon: close-icon, ) = { ```raw-css body:has(#nav-menu-toggle:checked) #icon-nav-menu { display: none; } body:has(#nav-menu-toggle:checked) #icon-nav-menu-close { display: flex; } body:has(#nav-menu-toggle:not(:checked)) #icon-nav-menu { display: flex; } body:has(#nav-menu-toggle:not(:checked)) #icon-nav-menu-close { display: none; } #nav-menu-toggle-label { display: flex; justify-content: center; align-items: center; &:has(input:focus-visible) icon-container { outline: 2px solid var(--color-button-focus); } &:hover icon-container { box-shadow: inset 0px 0px 0.4em 0px var(--color-button-shadow); cursor: pointer; } icon-container { padding: 0.2em; border-radius: 0.5em; justify-content: center; align-items: center; } input { opacity: 0; position: absolute; pointer-event: none; } } ``` html.label(id: "nav-menu-toggle-label", aria-label: aria-label, { html.input(type: "checkbox", name: "nav-menu-toggle", id: "nav-menu-toggle") chtml.icon-container(id: "icon-nav-menu", menu-icon) chtml.icon-container(id: "icon-nav-menu-close", close-icon) }) /* */ } #let nav-menu(body) = { ```raw-css body:has(#nav-menu-toggle:not(:checked)) nav-menu { /*display: none;*/ /* visibility: hidden + max-height: 0 ~= display: none */ visibility: hidden; opacity: 0; max-height: 0; } nav-menu { border-top: solid 1px var(--color-border); border-bottom: solid 1px var(--color-border); text-align: center; font-size: 1.25em; padding-left: 2rem; padding-right: 2rem; max-height: 100%; visibility: visible; @starting-style { opacity: 0; max-height: 0; } /* Uses visibility instead of diplay for animation because Firefox * preferes making slopeware instead of fixing this bug: * https://bugzilla.mozilla.org/show_bug.cgi?id=1882408 */ transition: opacity 0.5s ease-in, /*display 0.5s,*/ visibility 0.5s, max-height 0.5s ease-out; transition-behavior: allow-discrete; ul { list-style: none; padding: 0px; margin-top: 0.5em; margin-bottom: 0.5em; } li { padding-top: 0.5rem; padding-bottom: 0.5rem; a { /* If a list item is considered only of a link, expend link to * the whole item. */ margin: 0px; display: block; width: 100%; height: 100%; /* Unstyle link */ color: inherit; text-decoration: inherit; /* cursor: inherit; // we want to keep the clickable cursor */ } } li:hover { border-top: solid 1px var(--color-border); border-bottom: solid 1px var(--color-border); } } ``` chtml.nav-menu(body) }