LoadingOverlay
Covers its content with a spinner and a message while something is busy, keeping the content in place but out of reach.
Demo
Saved 0 times.
Loading invoices
A chart that is on its way
Loading the chart
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/loading_overlay.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/loading_overlay.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/loading_overlay.qwe
component LoadingOverlayDemoLive() { state busy = false state saved = 0 <div.demo-stack> <LoadingOverlay id="loading-overlay-demo-form" busy={busy} label="Saving your changes"> <div.demo-stack style="padding: 16px; border: 1px solid var(--ui-border); border-radius: var(--ui-radius)"> <TextField name="title" label="Title" value="Quarterly report"/> <div.demo-row> <Button id="loading-overlay-demo-save" on_click={() => { busy = true }}>Save</Button> <Button variant="outline">Cancel</Button> </div> </div> </LoadingOverlay> <div.demo-row> <Button id="loading-overlay-demo-done" variant="outline" size="sm" disabled={!busy} on_click={() => { busy = false; saved += 1 }}>Pretend it saved</Button> <span.demo-note>Saved {saved} {saved == 1 ? "time" : "times"}.</span> </div> </div>}view LoadingOverlayDemo() = <div.demo-stack> <LoadingOverlayDemoLive/> <div.demo-row> <LoadingOverlay id="loading-overlay-demo-empty" label="Loading invoices" min_height="140px" class="demo-wide"/> </div> <LoadingOverlay id="loading-overlay-demo-quiet" show_label={false} blur={false} label="Loading the chart"> <div style="height: 100px; display: grid; place-items: center; border: 1px dashed var(--ui-border); border-radius: var(--ui-radius)"> A chart that is on its way </div> </LoadingOverlay> </div>Source
ui/loading_overlay.qwe
// LoadingOverlay: covers what it wraps with a spinner and a message while// something is busy, so the content stays in place (and keeps its size) but// cannot be used until it is back.//// <LoadingOverlay busy={saving} label="Saving your changes">// <form>...</form>// </LoadingOverlay>// <LoadingOverlay busy={true} show_label={false} min_height="200px"/>//// busy: covers the content while true (true by default, for a box that is loading// from the start). label: what is happening ("Loading"), shown under the spinner// and read by screen readers (role="status"); show_label: false keeps it for// screen readers only. blur: softens the content underneath (true). min_height:// a CSS length, for a box with nothing in it yet. While busy the content is inert// (no clicks, no Tab stops) and the box says aria-busy. The spinner pulses instead// of turning with reduced motion.import ui/theme.qwe use ui_clslet loading_overlay_css = css`.ui-lo { position: relative; min-width: 0; }.ui-lo-content { transition: filter .2s, opacity .2s; }.ui-lo-busy > .ui-lo-content { opacity: .6; }.ui-lo-busy.ui-lo-blur > .ui-lo-content { filter: blur(2px); }.ui-lo-cover { position: absolute; inset: 0; z-index: 5; display: grid; place-content: center; justify-items: center; gap: 10px; padding: 16px; border-radius: inherit; background: color-mix(in srgb, var(--ui-bg) 55%, transparent); font: 500 14px/1.4 var(--ui-font); color: var(--ui-fg); text-align: center;}.ui-lo-spin { width: 28px; height: 28px; border-radius: 50%; border: 3px solid color-mix(in srgb, var(--ui-accent) 20%, transparent); border-top-color: var(--ui-accent); animation: ui-lo-turn .75s linear infinite;}@keyframes ui-lo-turn { to { transform: rotate(360deg); } }@keyframes ui-lo-pulse { 50% { opacity: .35; } }@media (prefers-reduced-motion: reduce) { .ui-lo-spin { animation: ui-lo-pulse 2s ease-in-out infinite; border-color: var(--ui-accent); } .ui-lo-content { transition: none; }}`view LoadingOverlay(busy: bool = true, label: str = "Loading", show_label: bool = true, blur: bool = true, min_height: str? = null, id: str? = null, class: str? = null, children) { style global loading_overlay_css <div class={ui_cls(["ui-lo", busy && "ui-lo-busy", blur && "ui-lo-blur", class])} id={id} aria-busy={busy ? "true" : null} style={min_height != null ? `min-height: ${min_height}` : null}> <div.ui-lo-content inert={busy}>{children}</div> {busy && <div.ui-lo-cover role="status"> <span.ui-lo-spin aria-hidden="true"></span> <span class={show_label ? "ui-lo-label" : "ui-sr"}>{label}</span> </div>} </div>}Related
LoadingDotsThree dots bouncing in turn, inline, for something short that is on its way; screen readers hear the label.5 views · 6 downloadsAlertA message in the page in six tones and three variants, with an icon, announced to screen readers, and dismissable.5 views · 9 downloadsBadgeA small pill for a status or a count: six tones, soft, solid or outline, a status dot, and 99+.8 views · 6 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 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 downloadsInlineMessageA small one-line message with an icon for its tone (info, success, warning, error), to sit in a form or beside a control.5 views · 7 downloads
Thread
Thread 0 posts
On LoadingOverlay: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.