--- title: "Ui: coverLayouts" description: "smabar plugin reference: Ui: coverLayouts" canonical: "https://smabar.com/docs/plugin-ref-ui-cover-layouts/" lang: en --- # Ui: coverLayouts > smabar plugin reference: Ui: coverLayouts Canonical HTML version: https://smabar.com/docs/plugin-ref-ui-cover-layouts/ · Language: en · Publisher: smabar (https://smabar.com) --- [Build my plugin](https://smabar.com/build-my-plugin.md) · [All references](https://smabar.com/docs/plugin-ref-index.md) · [Install the ZIP](https://smabar.com/docs/install-plugin-zip.md) Source: smabar 1.5.0, revision `a019f2563965edc37a5e8d84742ea1ff2fa6f824`. [Export metadata and checksums](https://smabar.com/plugin-reference/export.json). This is an offline reference. MCP calls quoted below describe the connected workflow; use the linked documents and create local files instead. Live state, installed plugins, available providers and the user's active theme are unknown. Never claim a live check. Read with [styling](https://smabar.com/docs/plugin-ref-styling.md) and [examples](https://smabar.com/docs/plugin-ref-examples.md). ## what ```json "Nine named cover recipes for the bar tile — the tile's face inside the bar. Pick ONE per tile and fill it with your data; every recipe fits the hard height budget (var(--sb-tile-content-h), see tileSizing.height) and scales with the bar on its own." ``` ## settingsConvention ```json "Let the USER pick the cover: declare a settingsSchema property named coverLayout as a string enum of the layout ids you implement (with a default). The settings UI renders enums as a choice grid automatically; the value arrives via on_settings_changed — branch your tile render on it." ``` ## animationNote ```json "The tile DOM is rebuilt whenever your pushed HTML string changes, which restarts CSS animations and transitions. Keep the tile HTML stable per state — no per-second data in the markup — and push only on real changes; the shell's value memory (donut fill, progress width, data-sb-tween numbers) then animates the differences for you. When one surface contains multiple remembered values, put the same unique data-sb-key on each logical value across renders (on the data-chart element, data-sb-tween element, or sb-progress fill child). Without stable keys, multiple values deliberately update without cross-render animation so insert/reorder cannot borrow a neighbor's state." ``` ## layouts ```json [ { "id": "basic", "name": "Basis", "purpose": "One icon and one core value — the calm default.", "whenToUse": "A single fact that speaks for itself: a state, a temperature, a count.", "markup": "
Energy high
", "animation": "None needed. For a live status accent, color the icon (sb-ok/sb-warn/sb-crit) or add an sb-badge.", "sizing": "One line, fits every bar. The icon reads at 1.4em automatically; any tileScale." }, { "id": "basicPlus", "name": "Basis Plus", "purpose": "Icon plus a title with one sub line.", "whenToUse": "A fact that needs a label or context line: next meeting, current song, city + condition.", "markup": "
Team Syncin 18 min
", "animation": "None. Growing text belongs on data-marquee with a max-width, not in a wider tile.", "sizing": "The stack's hero/sub lines follow the bar height; tileScale m or l for a roomier hero." }, { "id": "dualText", "name": "Dual Text", "purpose": "Two stacked texts with strong hierarchy — big value over small context, no icon.", "whenToUse": "Time over date, value over unit, headline over source.", "markup": "
09:42Fri, Aug 30
", "animation": "For clocks let the shell tick via data-clock-text (see conventions) — never re-render per second. A changing hero number can carry data-sb-tween to count instead of jump.", "sizing": "Exactly the sb-tile-stack budget: hero ~60%, sub ~25% of the tile height, clamped into the type scale — tileScale picks the steps." }, { "id": "headlineMotion", "name": "Headline + Motion", "purpose": "Compact info on the left, a living signal on the right: a tiny CSS equalizer.", "whenToUse": "Anything 'currently running': playback, focus session, recording, an active job.", "markup": "
48 minFocus
", "animation": "The equalizer runs purely in CSS — push the tile ONCE per state change, never per tick: a changed HTML string rebuilds the DOM and restarts the loop. Add is-paused on sb-eq to freeze it dimmed (paused playback); reduced motion falls back to the static staggered bars.", "sizing": "The glyph is 1em tall and sits inline. Keep the text side stable (sb-mono numbers, data-marquee titles with a max-width)." }, { "id": "segmentHeader", "name": "Segment Header", "purpose": "A secondary label in the muted step, the primary value beneath it; the same hierarchy as a stack with the label first.", "whenToUse": "Categorized values where the label matters: WEATHER / 18° cloudy, CPU / 51%, FOCUS / 48 min.", "markup": "
Weather18° Partly cloudy
", "animation": "The header is static; a changing value line can carry data-sb-tween.", "sizing": "The label and value use the same themed type steps and spacing as sb-tile-stack, including tileScale. The optional sb-tile-seg--fill accent pill adds padding; prefer the plain label in a compact bar." }, { "id": "progressRing", "name": "Progress Ring", "purpose": "Title and current value on the left, a circular progress indicator on the right.", "whenToUse": "One bounded 0-100 metric: battery, hydration goal, download, storage, timer progress. Not for unbounded numbers — use statSplit for those.", "markup": "
1.8 LHydration72
", "animation": "Value changes glide: the shell remembers the previous value per tile and transitions the ring fill (--sb-dur-slow, honors prefers-reduced-motion). Pair the center number with data-sb-tween so it counts along. Push a render only when the value actually changed.", "sizing": "The ring fills the tile height automatically and grows with the bar. The center label fits ~3 characters at default bar height — render the bare number in sb-mono, put the unit in title. tileScale: any." }, { "id": "statSplit", "name": "Stat Split", "purpose": "A main KPI on the left, its comparison/trend on the right, divided by a hairline.", "whenToUse": "Statistics with context: value vs. yesterday, price + change, count + trend — fitness, productivity, finance, system numbers.", "markup": "
48 minFocus+12%
", "animation": "data-sb-tween counts the KPI to its new value; the sparkline redraws statically (no morphing). sb-stat__delta--up/--down color the trend.", "sizing": "Two sb-tile-stack columns with a hairline divider — keep each side to two short lines. The sparkline renders as a small 3.5em inline glyph inside tiles." }, { "id": "checklist", "name": "Checklist", "purpose": "A very compact task list with done markers.", "whenToUse": "Routines, daily goals, short todo snapshots — the tile shows the state, the flyout manages it.", "markup": "
", "animation": "The done circle fills via is-done; the swap is instant on re-render (the DOM is replaced) — treat the fill as the signal, not a transition.", "sizing": "TWO entries fit every bar. Three need ~38px content height, four ~50px (taller bar or labels below icons) — overflow clips silently, so render only what fits and keep the full list in the flyout." }, { "id": "nextEvent", "name": "Timeline / Next Event", "purpose": "The next time-based thing: time and title over a slim progress track.", "whenToUse": "Calendar, timers, deadlines, travel, downloads, workflows — anything approaching on a time axis.", "markup": "
14:00Design Review
", "animation": "The track is the plain sb-progress bar: its width glides between renders (shell value memory). For live remaining time render data-sb-countdown parts in the text line — the shell ticks every second, you push once.", "sizing": "One text line plus the 4px track (~21px) — fits every bar. Give the title data-marquee with a max-width so the tile keeps a stable width." } ] ```