Skeleton
Grey shapes where content will be while it loads: text lines, boxes, circles, and a card.
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/skeleton.qwemain.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>}Related
LoadingDotsThree dots bouncing in turn, inline, for something short that is on its way; screen readers hear the label.5 views · 6 downloadsLoadingOverlayCovers its content with a spinner and a message while something is busy, keeping the content in place but out of reach.5 views · 5 downloadsProgressHow far along something is, as a bar or a ring, with its percentage, or indeterminate.5 views · 6 downloadsSkeletonTableA table of grey bars in rows and columns, with a header row, while a table's data loads.4 views · 7 downloadsSkeletonTextGrey lines in the shape of a paragraph, with a heading and several paragraphs if asked, while text loads.5 views · 5 downloadsSpinnerA loading spinner with a label for screen readers; it pulses instead of turning with reduced motion.6 views · 7 downloads
Thread
Thread 0 posts
On Skeleton: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.