implement css logic for nav menu

This commit is contained in:
Jean-Marie 'Histausse' Mineau 2026-03-18 01:21:55 +01:00
parent 7e0235fb88
commit e7a8cf8a8e
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
6 changed files with 65 additions and 6 deletions

View file

@ -12,3 +12,7 @@
html.elem("theme-picker", attrs: (aria-label: label, role: "radiogroup"), body)
}
#let code-block = html.elem.with("code-block")
#let icon-container(..args, body) = {
html.elem("icon-container", attrs: args.named(), body)
}
#let nav-menu = html.elem.with("nav-menu")

View file

@ -1,6 +1,7 @@
#import "./custom_html.typ" as chtml
#import "./theme_picker.typ": theme_picker
#import "./theme_colors.typ": theme_colors_css
#import "./theme_picker.typ": theme-picker
#import "./theme_colors.typ": theme-colors-css
#import "./nav_menu.typ": nav-menu, nav-menu-toggle
/// Make the body of the webpage
#let html_body(
@ -10,9 +11,11 @@
logo,
/// Logo alt-text
logo_alt,
/// Navigation menu content, css style expect a list
menu: none,
body
) = {
theme_colors_css
theme-colors-css
```raw-css
site-wrapper {
display: flex;
@ -61,8 +64,12 @@
chtml.site-wrapper({
chtml.site-container({
html.nav({
theme_picker()
theme-picker()
if menu != none { nav-menu-toggle() }
})
if menu != none {
nav-menu(menu)
}
html.header(style: "display: flex; flex-wrap: wrap-reverse;", {
html.hgroup({
header

View file

@ -31,6 +31,8 @@
/// List of related sites for metadata
me-links: (),
//-- Body --
/// Navigation menu content, css style expect a list
menu: none,
/// Body of the page
body
) = {
@ -51,6 +53,7 @@
logo,
logo-alt,
header: header,
menu: menu,
body
)
})

45
lib/nav_menu.typ Normal file
View file

@ -0,0 +1,45 @@
#import "./custom_html.typ" as chtml
/// Buttons to toggle the navigation menu.
#let nav-menu-toggle(
) = {
```raw-css
body:has(#nav-menu-toggle:checked) #icon-nav-menu { display: none; }
body:has(#nav-menu-toggle:checked) #icon-nav-menu-close { display: block; }
body:has(#nav-menu-toggle:not(:checked)) #icon-nav-menu { display: block; }
body:has(#nav-menu-toggle:not(:checked)) #icon-nav-menu-close { display: none; }
#nav-menu-toggle-label {
input {
opacity: 0;
position: absolute;
pointer-event: none;
}
}
```
html.label(id: "nav-menu-toggle-label", {
html.input(type: "checkbox", name: "nav-menu-toggle", id: "nav-menu-toggle")
chtml.icon-container(id: "icon-nav-menu", sym.eq.triple)
chtml.icon-container(id: "icon-nav-menu-close")[X]
})
/*
<button class="btn btn-square" id="menu-toggle" aria-expanded="true" type="button" title="Menu">
<svg class="icon-menu" width="24" height="24" fill="currentcolor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path 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"></path>
</svg>
<svg class="icon-close hidden" width="24" height="24" fill="currentcolor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
<path 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"></path>
</svg>
</button>
*/
}
#let nav-menu(body) = {
```raw-css
body:has(#nav-menu-toggle:not(:checked)) nav-menu {
display: none;
}
nav-menu {
}
```
chtml.nav-menu(body)
}

View file

@ -1,5 +1,5 @@
#let theme_colors_css = ```raw-css
#let theme-colors-css = ```raw-css
:root {
color-scheme: light dark;
&:has(#theme-light:checked) {

View file

@ -3,7 +3,7 @@
/// Buttons to chose the theme to use (Light/Dark)
/// label is the aria-label of the html element (for screenreader).
/// label-auto, label-light and label-dark are the content of each button.
#let theme_picker(
#let theme-picker(
label: "Theme Picker",
label-auto: [Auto],
label-light: [Light],