Banner
An announcement across the top of the page in six tones, with a link, closed for the session once dismissed.
Demo
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/banner.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/banner.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/banner.qwe
view BannerDemo() = <div.demo-stack> <Banner href="#banner" link="See what's new">Quillo 1.0 is out: live queries, typed records and a debugger.</Banner> <Banner tone="warning" title="Maintenance" remember="demo-maintenance">Sunday 02:00–03:00 UTC: the dashboard will be read-only.</Banner> <Banner tone="success" variant="soft" href="#banner" link="Read the report">Your data export is ready.</Banner> <Banner tone="danger" dismissable={false}>Payments are delayed by up to an hour. We're on it.</Banner> <Banner tone="neutral" variant="soft" title="Heads up">This is a preview environment; data resets every night.</Banner> </div>Source
ui/banner.qwe
// Banner: an announcement across the top of the page, with a link and a close// button. It hides itself when closed, so it works placed straight in a page.//// <Banner href="/changelog" link="See what's new">Quillo 1.0 is out.</Banner>// <Banner tone="warning" title="Maintenance" remember="maint-0412">Sunday 02:00–03:00 UTC.</Banner>// <Banner tone="danger" dismissable={false} sticky={true}>Payments are delayed. We're on it.</Banner>//// The message is its children. tone: "accent" (default), "neutral", "info",// "success", "warning" or "danger". variant: "solid" (default), filled with the// tone, or "soft", tinted with a line under it. title: a bold start to the message.// href and link: a link after the message ("Learn more" by default). dismissable:// the close button (true). remember: a name for this announcement; once closed it// stays closed for the rest of the browser session (in sessionStorage), on every// page that shows it, until the name changes. Without it, it shows again on the// next page. sticky: it stays at the top of the window as the page scrolls.// label: its name for screen readers ("Announcement"); it is a region they can// jump to. on_dismiss: called with nothing when it is closed, inside one of your// components.import ui/theme.qwe use ui_clslet banner_css = css`.ui-banner-host { display: contents; }.ui-banner { display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 8px 16px; font: 14px/1.45 var(--ui-font); --t: var(--ui-accent); --ts: var(--ui-accent-soft); --tf: var(--ui-accent-fg); }.ui-banner-neutral { --t: var(--ui-fg); --ts: var(--ui-subtle); --tf: var(--ui-bg); }.ui-banner-info { --t: var(--ui-info); --ts: var(--ui-info-soft); --tf: var(--ui-bg); }.ui-banner-success { --t: var(--ui-success); --ts: var(--ui-success-soft); --tf: var(--ui-bg); }.ui-banner-warning { --t: var(--ui-warning); --ts: var(--ui-warning-soft); --tf: var(--ui-bg); }.ui-banner-danger { --t: var(--ui-danger); --ts: var(--ui-danger-soft); --tf: var(--ui-bg); }.ui-banner-solid { background: var(--t); color: var(--tf); }.ui-banner-soft { background: var(--ts); color: var(--ui-fg); border-bottom: 1px solid color-mix(in srgb, var(--t) 25%, transparent); }.ui-banner-sticky { position: sticky; top: 0; z-index: 40; }.ui-banner-body { display: flex; flex: 1; flex-wrap: wrap; align-items: baseline; justify-content: center; gap: 2px 14px; min-width: 0; text-align: center; }.ui-banner-text { margin: 0; }.ui-banner-text strong { margin-right: 6px; font-weight: 650; }.ui-banner-link { flex: none; color: inherit; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; white-space: nowrap; border-radius: 3px; }.ui-banner-soft .ui-banner-link { color: var(--t); }.ui-banner-neutral.ui-banner-soft .ui-banner-link { color: var(--ui-fg); }.ui-banner-link:hover { text-decoration-thickness: 2px; }.ui-banner-link:focus-visible, .ui-banner-x:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }.ui-banner-x { flex: none; display: grid; place-items: center; width: 28px; height: 28px; margin: -4px -6px -4px 0; border: 0; border-radius: var(--ui-radius-sm); background: transparent; color: inherit; font-size: 20px; line-height: 1; opacity: .75; cursor: pointer; }.ui-banner-x:hover { opacity: 1; background: color-mix(in srgb, currentColor 14%, transparent); }.ui-banner-pad { flex: none; width: 22px; }`component Banner(tone: str = "accent", variant: str = "solid", title: str? = null, href: str? = null, link: str = "Learn more", dismissable: bool = true, remember: str? = null, sticky: bool = false, label: str = "Announcement", on_dismiss = null, class: str? = null, children) { style global banner_css state shown = true let key = remember != null ? `ui-banner:${remember}` : null let close = () => { shown = false if key != null { js("sessionStorage.setItem", key, "1") } if on_dismiss != null { on_dismiss() } } <div class="ui-banner-host" @mount={(_el) => { if key != null && js("sessionStorage.getItem", key) == "1" { shown = false } }}> {shown && <div class={ui_cls(["ui-banner", `ui-banner-${tone}`, `ui-banner-${variant}`, sticky && "ui-banner-sticky", class])} role="region" aria-label={label}> {dismissable && <span.ui-banner-pad></span>} <div.ui-banner-body> <p.ui-banner-text>{title != null && <strong>{title}</strong>}{children}</p> {href != null && <a.ui-banner-link href={href}>{link} →</a>} </div> {dismissable && <button.ui-banner-x type="button" aria-label="Dismiss" @click={close}>×</button>} </div>} </div>}Related
CoachmarkA small callout pointing at an element by id, explaining it once, dismissed with Got it; several make a tour.6 views · 8 downloadsConnectionStatusSays when the browser goes offline, as a bar across the top or a pill, and that it is back online for a moment.6 views · 7 downloadsCookieConsentA cookie banner with accept, reject and settings by category, remembering the choice in localStorage.6 views · 7 downloadsEmptyStateWhat a list or page shows when there is nothing in it yet, with an icon and what to do next.6 views · 6 downloadsErrorPageA 404 or 500 page: the code large, what it means, a search box if wanted, and links to go on from.5 views · 6 downloadsNotificationDotA small dot or a count on the corner of anything, in tones and four positions, with a label for screen readers.5 views · 7 downloads
Thread
Thread 0 posts
On Banner: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.