Composables
Reactive state helpers and DOM behaviours. A factory is called and returns a controller built on runes; an action is attached to an element; a transition is handed to Svelte. The class behind a factory never leaves its module — call the factory, never new.
createMediaQuery
factoryCall it — createMediaQuery(query)
Reactive matchMedia, for layout that has to branch on a breakpoint in markup rather than in CSS. matches is seeded false and filled by an effect, so anything that must be decided before the first paint — prefers-reduced-motion inside a DOM action, say — has to call matchMedia directly instead, or it will act on the seed.
Parameters
| Prop | Type | Default | Description |
|---|---|---|---|
query required | string | A CSS media query, e.g. |
MediaQueryController
| Prop | Type | Default | Description |
|---|---|---|---|
matches required | boolean | Whether the query matches right now. |
Import from ground/composables/use-media-query, or from the barrel.
createTextScale
factoryCall it — createTextScale()
Reader-controlled text size, applied as the --text-scale multiplier on the document element so popovers and dialogs rendered outside the shell scale with it. AppShell owns one and passes it to DisplayControls — an app needs its own only for a shell it built itself.
TextScaleController
| Prop | Type | Default | Description |
|---|---|---|---|
level required | number | Index of the current step, | |
steps required | number | How many steps exist, for labelling the control. | |
next required | () => void | Advances one step, wrapping back to the default past the last. |
Import from ground/composables/use-text-scale, or from the barrel.
createTheme
factoryCall it — createTheme(fallback?)
Colour-scheme controller for an app shell: reads the visitor's stored choice, falls back to the OS, and keeps .dark/.light on the document element in sync. Create one per app and hand it to AppShell, which forwards it to DisplayControls.
Parameters
| Prop | Type | Default | Description |
|---|---|---|---|
fallback | 'system'|'light'|'dark' | Scheme to use on a first visit only — once anything is stored, the visitor's own choice outranks it. An app with no dark design yet can pass |
ThemeController
| Prop | Type | Default | Description |
|---|---|---|---|
mode required | 'system'|'light'|'dark' | The stored preference. | |
resolved required | 'light'|'dark' | The scheme actually in effect, with | |
set required | (mode: 'system'|'light'|'dark') => void | Pins a preference and persists it. | |
toggle required | () => void | Flips between light and dark, pinning the result. |
Import from ground/composables/use-theme, or from the barrel.
countUp
actionAttach it with use: — use:countUp={{ options? }}
use: action that counts every number inside an element up to the value already rendered, the first time it scrolls into view. The finished text is the target, so the real figure survives with no JS and under reduced motion; thousands separators and the copy around them ($, %, M+) stay exactly where they were. Eases out on --ease-entrance, because a linear count reads as a spinner still loading.
Parameters
| Prop | Type | Default | Description |
|---|---|---|---|
node required | HTMLElement | ||
options | CountUpOptions |
CountUpOptions
| Prop | Type | Default | Description |
|---|---|---|---|
duration | number | How long the climb takes, in milliseconds. | |
delay | number | Delay in milliseconds, for staggering a row of figures. |
Import from ground/composables/use-count-up, or from the barrel.
lightSource
actionAttach it with use: — use:lightSource={{ options? }}
use: action that aims the theme's single light source at the pointer. It listens on window and writes --light-x on the document element rather than on the node, so every surface-sheen surface leans the same way — dialogs and popovers rendered outside this tree included. AppShell already applies it; an app needs it only for a shell of its own. Idle under reduced motion.
Parameters
| Prop | Type | Default | Description |
|---|---|---|---|
node required | HTMLElement | ||
options | LightSourceOptions |
LightSourceOptions
| Prop | Type | Default | Description |
|---|---|---|---|
swing | number | Total travel of the hot spot across the full viewport width, in percentage points — a lean toward the pointer, not the lamp being dragged. |
Import from ground/composables/use-light-source, or from the barrel.
scrollFade
actionAttach it with use: — use:scrollFade={{ options? }}
use: action that fades a scrolling box's clipped edges, so a cut-off list reads as "there is more" instead of as its own end. Required on any box that clips its content. Each edge is sized by its distance from the end, so it grows and shrinks with the scroll and is simply absent when the content fits — nothing to transition, nothing to tune.
Parameters
| Prop | Type | Default | Description |
|---|---|---|---|
node required | HTMLElement | ||
options | ScrollFadeOptions |
ScrollFadeOptions
| Prop | Type | Default | Description |
|---|---|---|---|
size | number | Height of a fade at full strength, in pixels. | |
top | boolean | Fade the top edge. Pass | |
bottom | boolean | Fade the bottom edge. |
Import from ground/composables/use-scroll-fade, or from the barrel.
scrollReveal
actionAttach it with use: — use:scrollReveal={{ options? }}
use: action that fades and lifts an element into place the first time it scrolls into view. Does nothing at all when the visitor asked for reduced motion, and never hides anything without JS — the hidden state is written from script, so a crawler or a script-off render gets the finished page rather than an empty one.
Parameters
| Prop | Type | Default | Description |
|---|---|---|---|
node required | HTMLElement | ||
options | ScrollRevealOptions |
ScrollRevealOptions
| Prop | Type | Default | Description |
|---|---|---|---|
y | number | Distance in pixels the element rises from. | |
duration | number | Transition duration in milliseconds. | |
delay | number | Delay in milliseconds, for staggering neighbours. |
Import from ground/composables/use-scroll-reveal, or from the barrel.
flyAndScale
transitionPass it to transition: — transition:flyAndScale={{ options? }}
Svelte transition for something that appears over the page — the small rise-and-settle a popover or menu panel uses. Pass it to transition:/in:, not use:; it is a transition, not an action.
Parameters
| Prop | Type | Default | Description |
|---|---|---|---|
node required | HTMLElement | ||
options | FlyAndScaleOptions |
FlyAndScaleOptions
| Prop | Type | Default | Description |
|---|---|---|---|
y | number | Distance in pixels the element travels as it settles. | |
start | number | Scale it grows from. | |
duration | number | Duration in milliseconds. |
Import from ground/composables/use-transition, or from the barrel.