Feedback

Skeleton

Grey shapes where content will be while it loads: text lines, boxes, circles, and a card.

#feedback#loading#no-js

Demo

Preview

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

Example

The code of the preview above.

demos/skeleton.qwe
view SkeletonDemo() =    <div.demo-stack>        <div.demo-row>            <Skeleton shape="circle" width="48px"/>            <div style="flex: 1; min-width: 200px"><Skeleton lines={3}/></div>        </div>        <div.demo-row>            <Skeleton shape="rect" width="120px" height="80px"/>            <Skeleton shape="rect" width="120px" height="80px"/>            <Skeleton shape="text" width="160px"/>        </div>        <div.demo-narrow><SkeletonCard/></div>    </div>

Source

ui/skeleton.qwe
// Skeleton: grey shapes where content will be, while it loads. Hidden from screen// readers (aria-hidden): say what is loading elsewhere, with a Spinner's label or// aria-busy on the region.////   <Skeleton lines={3}/>//   <Skeleton shape="circle" width="48px"/>//   <Skeleton shape="rect" height="160px"/>//   <SkeletonCard/>//// shape: "text" (default), "rect" or "circle". lines: rows of text, the last one// shorter. width and height: any CSS length; text is as wide as its container,// a rect 100% by 120px, a circle 40px across (height defaults to width).// The shimmer stops with reduced motion. SkeletonCard: an avatar, two lines and a// picture, the shape of a typical card.import ui/theme.qwe use ui_clslet skeleton_css = css`.ui-skeleton { display: block; border-radius: var(--ui-radius-sm);  background: linear-gradient(90deg, var(--ui-subtle) 0%, color-mix(in srgb, var(--ui-subtle) 55%, var(--ui-strong)) 50%, var(--ui-subtle) 100%);  background-size: 200% 100%; animation: ui-skeleton-shine 1.4s ease-in-out infinite; }.ui-skeleton-lines { display: grid; gap: 8px; }.ui-skeleton-line { height: .8em; border-radius: 4px; font-size: 15px; }.ui-skeleton-line:last-child:not(:first-child) { width: 62%; }.ui-skeleton-rect { width: 100%; height: 120px; }.ui-skeleton-circle { width: 40px; height: 40px; border-radius: 50%; flex: none; }.ui-skeleton-card { display: grid; gap: 14px; padding: 16px; border: 1px solid var(--ui-border);  border-radius: var(--ui-radius); background: var(--ui-surface); }.ui-skeleton-card-head { display: flex; align-items: center; gap: 12px; }.ui-skeleton-card-head > :last-child { flex: 1; }@keyframes ui-skeleton-shine { from { background-position: 100% 0; } to { background-position: -100% 0; } }@media (prefers-reduced-motion: reduce) { .ui-skeleton { animation: none; background: var(--ui-subtle); } }`view Skeleton(shape: str = "text", lines: int = 1, width: str? = null, height: str? = null,              class: str? = null) {    style global skeleton_css    let tall = height ?? (shape == "circle" ? width : null)    let size = ui_cls([width != null && `width: ${width};`, tall != null && `height: ${tall};`])    let style = size != "" ? size : null    shape == "text"        ? <div class={ui_cls(["ui-skeleton-lines", class])} style={style} aria-hidden="true">              {for i in range(lines < 1 ? 1 : lines) => <span.ui-skeleton.ui-skeleton-line></span>}          </div>        : <span class={ui_cls(["ui-skeleton", `ui-skeleton-${shape}`, class])} style={style} aria-hidden="true"></span>}view SkeletonCard(class: str? = null) {    style global skeleton_css    <div class={ui_cls(["ui-skeleton-card", class])} aria-hidden="true">        <div.ui-skeleton-card-head>            <Skeleton shape="circle"/>            <Skeleton lines={2}/>        </div>        <Skeleton shape="rect" height="96px"/>        <Skeleton lines={3}/>    </div>}
Thread
66Useful? Like it, or add to its thread below.

Thread 0 posts

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

No posts yet. The first one opens the thread.