NavLink
A link marked current when the page's URL is where it goes, or under it; as text, a pill or underlined.
Demo
With no `current`, the page's own path is compared: this gallery is at /.
Get it
It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.
$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/nav_link.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/nav_link.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/nav_link.qwe
view NavLinkDemo() = <div.demo-stack> <div.demo-row id="nav-link-demo-page"> <NavLink href="/" exact={true}>Home</NavLink> <NavLink href="/docs">Docs</NavLink> <NavLink href="/blog">Blog</NavLink> </div> <p.demo-note>With no `current`, the page's own path is compared: this gallery is at /.</p> <div.demo-row id="nav-link-demo-pill"> <NavLink href="/inbox" current="/inbox/42" variant="pill" icon="M4 4h16v16H4zM4 13h5l1.5 2h3L15 13h5" badge={3}>Inbox</NavLink> <NavLink href="/sent" current="/inbox/42" variant="pill" icon="M3 12 21 3l-4 18-5-7zM12 14l9-11">Sent</NavLink> <NavLink href="/drafts" current="/inbox/42" variant="pill" icon="✎">Drafts</NavLink> </div> <div.demo-row id="nav-link-demo-underline" style="gap: 20px"> <NavLink href="/settings" current="/settings" exact={true} variant="underline">General</NavLink> <NavLink href="/settings/team" current="/settings" variant="underline">Team</NavLink> <NavLink href="/settings/billing" current="/settings" variant="underline">Billing</NavLink> </div> </div>Source
ui/nav_link.qwe
// NavLink: a link that is marked current (aria-current="page") when the page's URL// is the one it goes to, or starts with it. For a site's own navigation, where the// mark says where the visitor is.//// <NavLink href="/docs">Docs</NavLink>// <NavLink href="/" exact={true} variant="pill">Home</NavLink>// <NavLink href="/inbox" current={request.path} badge={3}>Inbox</NavLink>//// href: where it goes. current: the page's path to compare with (the request's path,// from url(), when not given). It is current when the path is `href`, or is under it// ("/docs/start" under "/docs"); exact: only when it is `href` itself. "/" is only// ever exact. variant: "text" (default: coloured when current), "pill" (a soft// background when current) or "underline" (a line under it when current).// icon: a character or an emoji, or an SVG path (24x24, stroked) when it starts with "M".// badge: a count after the text. label: what screen readers hear instead of the text.// on_click(): inside one of your components, what a click does besides following.import ui/theme.qwe use ui_clslet nav_link_css = css`.ui-navlink { display: inline-flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: var(--ui-radius-sm); color: var(--ui-muted); font: 500 14px/1.3 var(--ui-font); text-decoration: none; white-space: nowrap; transition: color .12s, background .12s;}.ui-navlink:hover { color: var(--ui-fg); }.ui-navlink:focus-visible { outline: none; box-shadow: var(--ui-focus); }.ui-navlink[aria-current="page"] { color: var(--ui-accent); }.ui-navlink-pill:hover { background: var(--ui-subtle); }.ui-navlink-pill[aria-current="page"] { background: var(--ui-accent-soft); }.ui-navlink-underline { border-radius: 0; padding: 8px 2px; box-shadow: inset 0 -2px 0 transparent; }.ui-navlink-underline[aria-current="page"] { color: var(--ui-fg); box-shadow: inset 0 -2px 0 var(--ui-accent); }.ui-navlink-icon { display: inline-grid; place-items: center; flex: none; width: 18px; height: 18px; font-size: 15px; line-height: 1; }.ui-navlink-icon svg { width: 18px; height: 18px; }.ui-navlink-badge { min-width: 18px; padding: 0 6px; border-radius: 999px; background: var(--ui-accent); color: var(--ui-accent-fg); font-size: 11px; font-weight: 600; line-height: 18px; text-align: center; font-variant-numeric: tabular-nums;}@media (prefers-reduced-motion: reduce) { .ui-navlink { transition: none; } }`// Whether `here` (a path, with or without a query) is at `href` or under it.fn nav_link_matches(href: str, here: str, exact: bool) -> bool { let path = re.replace(here, "[?#].*$", "") let base = len(href) > 1 && ends_with(href, "/") ? slice(href, 0, len(href) - 1) : href path == base || path == base + "/" || (!exact && base != "/" && starts_with(path, base + "/"))}view NavLink(href: str, current: str? = null, exact: bool = false, variant: str = "text", icon: str? = null, badge = null, label: str? = null, id: str? = null, on_click = null, class: str? = null, children) { style global nav_link_css let here = current ?? url().path let on = nav_link_matches(href, here, exact) <a class={ui_cls(["ui-navlink", variant != "text" && `ui-navlink-${variant}`, class])} id={id} href={href} aria-current={on ? "page" : null} aria-label={label} @click={() => { on_click && on_click() }}> {icon != null && <span.ui-navlink-icon aria-hidden="true">{starts_with(icon, "M") && len(icon) > 2 ? <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d={icon}/></svg> : icon}</span>} <span>{children}</span> {badge != null && <span.ui-navlink-badge>{badge}</span>} </a>}Related
AlphabetIndexA to Z links into a list sorted by name; letters with nothing under them stay in place, disabled.4 views · 6 downloadsBreadcrumbsWhere this page sits: a trail of links up to the home page, the last one marked as this page.5 views · 6 downloadsCollapsibleNavSide navigation in groups that fold under their titles, the browser remembering which are open.6 views · 7 downloadsDirectoryNavA long list of names grouped under sticky letter headers, with a row of letters at the top that jumps to each group.5 views · 5 downloadsFooterNavColumns of grouped links for a site's footer, each under its title, wrapping on narrow screens.5 views · 7 downloadsJumpLinksA row of links to the sections of the page, scrolling sideways when narrow and sticking to the top if asked.6 views · 6 downloads
Thread
Thread 0 posts
On NavLink: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.