Skip to content

UI State Reading Preferences

Three persistent stores in a global scope are the whole preferences layer. The toolbar writes them and the article reads them, and neither one knows the other exists. persistent keeps the choice across reloads, and setting color-scheme on the article is enough for its light-dark() colors to repaint.

Declare the stores once near the top of the page and anything below can read the same settings.

Rain on the ridge

The trail turned to run-off an hour before the pass, and the map stopped agreeing with the ground somewhere after the second creek.

We waited it out under a slab of granite and watched the valley fill with cloud from the top down.

Code

The following example assumes that you have imported the component and set up the theme.

Reading Preferences
<sv-ui-state id="reading-prefs" global>
3 collapsed lines
<sv-store name="$scheme" persistent value="light"></sv-store>
<sv-store type="number" name="$scale" persistent value="100"></sv-store>
<sv-store type="number" name="$measure" persistent value="30"></sv-store>
</sv-ui-state>
<div class="reader">
39 collapsed lines
<div class="reader-bar">
<div class="reader-schemes">
<button type="button" bind-class-toggle="is-active:$scheme === 'light'" bind-event="click:$scheme('light')">Light</button>
<button type="button" bind-class-toggle="is-active:$scheme === 'dark'" bind-event="click:$scheme('dark')">Dark</button>
</div>
<label class="reader-knob">
Text
<input
type="range"
bind-event="input.passive:$scale(+EVENT.target.value)"
bind-prop="value:$scale"
max="130"
min="90"
step="10"
/>
</label>
<label class="reader-knob">
Width
<input
type="range"
bind-event="input.passive:$measure(+EVENT.target.value)"
bind-prop="value:$measure"
max="42"
min="22"
step="2"
/>
</label>
</div>
<article class="reader-article" bind-style="color-scheme:$scheme; font-size:$scale + '%'; max-inline-size:$measure + 'rem'">
<h4>Rain on the ridge</h4>
<p>
The trail turned to run-off an hour before the pass, and the map stopped agreeing with the ground somewhere after the second
creek.
</p>
<p>We waited it out under a slab of granite and watched the valley fill with cloud from the top down.</p>
</article>
</div>
<style>
69 collapsed lines
.reader {
display: grid;
gap: 1em;
justify-items: center;
padding-block: 1em;
.reader-bar {
display: flex;
flex-wrap: wrap;
gap: 1em;
align-items: center;
justify-content: center;
}
.reader-schemes {
display: flex;
gap: 0.3em;
button {
padding: 0.35em 0.8em;
font: inherit;
font-size: 0.85em;
color: var(--sv-gray-3);
cursor: pointer;
background-color: var(--sv-gray-6);
border: var(--sv-bdr-sz-sm) solid transparent;
border-radius: var(--sv-bdr-rad-sm);
&.is-active {
color: var(--sv-gray-0);
border-color: var(--sv-accent);
}
}
}
.reader-knob {
display: flex;
gap: 0.5em;
align-items: center;
font-size: 0.85em;
color: var(--sv-gray-3);
input {
inline-size: 7rem;
accent-color: var(--sv-accent);
}
}
.reader-article {
padding: 1.2em 1.4em;
color: light-dark(#22222a, #e6e6ea);
background-color: light-dark(#fcfcfe, #16161a);
border-radius: var(--sv-bdr-rad-md);
h4 {
margin: 0 0 0.6em;
font-size: 1.1em;
}
p {
margin: 0 0 0.6em;
line-height: 1.6;
}
p:last-child {
margin-block-end: 0;
}
}
}
</style>