Navigation

AlphabetIndex

A to Z links into a list sorted by name; letters with nothing under them stay in place, disabled.

#navigation#link#list#no-js

Demo

Preview

Showing names starting with C.

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/alphabet_index.qwe
main.qwe
import ui/theme.qwe use theme_cssuse ui/alphabet_index.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>

Example

The code of the preview above.

demos/alphabet_index.qwe
component AlphabetIndexDemoLive() {    state at = "C"    <div.demo-stack>        <AlphabetIndex id="alphabet-index-demo-live" present={["A", "B", "C", "E", "G", "L", "M", "P", "S", "T", "W"]} current={at}                       hash={false} on_select={(l) => { at = l }}/>        <p.demo-note>Showing names starting with {at}.</p>    </div>}view AlphabetIndexDemo() =    <div.demo-stack style="gap: 20px">        <AlphabetIndex id="alphabet-index-demo" present={["a", "b", "d", "f", "h", "k", "m", "n", "r", "s", "#"]} href="#alpha-{letter}"/>        <AlphabetIndexDemoLive/>        <AlphabetIndex label="Greek" letters="ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ" hash={false} href="#greek-{letter}"/>    </div>

Source

ui/alphabet_index.qwe
// AlphabetIndex: the letters A to Z (and # for the rest) as links into a long list// sorted by name: a glossary, a directory, a list of artists. Letters that have// nothing under them are shown but cannot be followed, so the row keeps its shape.////   <AlphabetIndex present={["A", "B", "D", "M"]} href="#letter-{letter}"/>//   <AlphabetIndex present={letters} current="D" on_select={(l) => { at = l }}/>//// present: the letters that have entries (any case); the others are disabled.// Leave it out to make every letter a link. href: each link's address, with// "{letter}" standing for the letter ("#{letter}"); "#" becomes "other" in it.// current: the letter marked (aria-current="true"). hash: show "#" at the end for// names that start with a digit or a symbol (true). letters: another alphabet, as a// string ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"). label: what screen readers call it// ("Index"). id: the nav's id. on_select(letter): inside one of your components, called with the// letter clicked instead of following its link.import ui/theme.qwe use ui_clslet alphabet_index_css = css`.ui-alpha ul { display: flex; flex-wrap: wrap; gap: 2px; margin: 0; padding: 0; list-style: none; font: 13px/1 var(--ui-font); }.ui-alpha-letter {  display: inline-flex; align-items: center; justify-content: center; min-width: 28px; height: 28px; padding: 0 4px;  border-radius: var(--ui-radius-sm); color: var(--ui-fg); font-weight: 600; text-decoration: none; transition: background .12s, color .12s;}a.ui-alpha-letter:hover { background: var(--ui-subtle); color: var(--ui-accent); }.ui-alpha-letter:focus-visible { outline: none; box-shadow: var(--ui-focus); }.ui-alpha-letter[aria-current] { background: var(--ui-accent); color: var(--ui-accent-fg); }.ui-alpha-off { color: var(--ui-strong); cursor: default; }@media (prefers-reduced-motion: reduce) { .ui-alpha-letter { transition: none; } }`view AlphabetIndex(present: list? = null, href: str = "#{letter}", current: str? = null, hash: bool = true,                   letters: str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", label: str = "Index", id: str? = null, on_select = null, class: str? = null) {    style global alphabet_index_css    let have = present != null ? present | map((l) => upper(str(l))) : null    let all = (for i in range(0, len(letters)) => slice(letters, i, i + 1)) + (hash ? ["#"] : [])    <nav class={ui_cls(["ui-alpha", class])} id={id} aria-label={label}>        <ul>            {for l in all => {                let there = have == null || contains(have, l)                let at = current != null && upper(current) == l                <li>{there                    ? <a.ui-alpha-letter href={replace(href, "{letter}", l == "#" ? "other" : l)}                         aria-current={at ? "true" : null} aria-label={l == "#" ? "Other" : null}                         @click={(e) => { if on_select != null { e.preventDefault(); on_select(l) } }}>{l}</a>                    : <span.ui-alpha-letter.ui-alpha-off aria-disabled="true" aria-label={l == "#" ? "Other, nothing" : `${l}, nothing`}>{l}</span>}                </li>            }}        </ul>    </nav>}
Thread
46Useful? Like it, or add to its thread below.

Thread 0 posts

On AlphabetIndex: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.