AlphabetIndex
A to Z links into a list sorted by name; letters with nothing under them stay in place, disabled.
Demo
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.qwemain.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>}Related
DirectoryNavA 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 downloadsLinkListA plain list of links, each with a line saying where it leads, an icon and a short note at the right.5 views · 6 downloadsMenuA vertical list of links and actions in titled sections, with icons, shortcuts, counts, disabled items and the active one marked.6 views · 6 downloadsSitemapListA site's pages as a nested list of links, as deep as the site goes, flowing into columns on wide screens.4 views · 5 downloadsAccordionSections that open under their titles, on the browser's own <details>: exclusive with a group.5 views · 7 downloadsBreadcrumbsWhere this page sits: a trail of links up to the home page, the last one marked as this page.5 views · 6 downloads
Thread
Thread 0 posts
On AlphabetIndex: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.