Themed #
Fuz provides UI components that use Moss' theming system for dark mode and custom themes.
Themed
adds global support for both the browser's color-scheme and custom themes based on Moss style variables, which use CSS custom properties . Themed
is a singleton component that's mounted at the top-level of the page:
import Themed from '@ryanatkn/fuz/Themed.svelte';
<!-- +layout.svelte -->
<Themed>
{@render children()}
</Themed>
Why the singleton?
Why nested children?
Color scheme #
Themed
defaults to automatic color-scheme detection with prefers-color-scheme , and users can also set it directly:
import Color_Scheme_Input from '@ryanatkn/fuz/Color_Scheme_Input.svelte';
<Color_Scheme_Input />
Pass props to override the default:
<Color_Scheme_Input
value={{color_scheme: 'auto'}}
onchange={...}
/>
The builtin themes support both dark and light color schemes. Custom themes may support one or both color schemes.
More about Color_Scheme_Input
Builtin themes #
A theme is a simple JSON collection of Moss style variables that can be transformed into CSS that set custom properties. Each variable can have values for light and/or dark color schemes. In other words, "dark" isn't a theme, it's a mode that any theme can implement.
Example usage #
Themes are plain CSS that can be sourced in a variety of ways.
To use Fuz's base theme:
<!-- +layout.svelte -->
<script>
import '@ryanatkn/moss/style.css';
import '@ryanatkn/moss/theme.css';
import Themed from '@ryanatkn/fuz/Themed.svelte';
import type {Snippet} from 'svelte';
interface Props {
children: Snippet;
}
const {children}: Props = $props();
</script>
<!-- enable theme and color-scheme support -->
<Themed>
{@render children()}
</Themed>
Themed
can be customized with the the nonreactive prop themer
:
import {Themer} from '@ryanatkn/fuz/theme.svelte.js';
const themer = new Themer(...);
<Themed {themer}>
{@render children()}
</Themed>
Themed
sets the themer
in the Svelte context:
// get values from the Svelte context provided by
// the nearest `Themed` ancestor:
import {themer_context} from '@ryanatkn/fuz/theme.svelte.js';
const themer = themer_context.get();
themer.theme.name; // 'base'
themer.color_scheme; // 'auto'
For a more complete example, see fuz_template.
More details #
Themed
initializes the system's theme support. Without it, the page will not
reflect the user's system color-scheme
. By default, Themed
applies the base theme to the root
of the page via create_theme_setup_script
. It uses JS to add the .dark
CSS class to the :root
element.
This strategy enables color scheme and theme support with minimal CSS and optimal performance for most use cases. The system supports plain CSS usage that can be static or dynamic, or imported at buildtime or runtime. It also allows runtime access to the underlying data like the style variables if you want to pay the performance costs. Scoped theming to one part of the page is planned.
The theme setup script interacts with sync_color_scheme
to save the user's
preference to localStorage
. See also Color_Scheme_Input
.
The setup script avoids flash-on-load due to color scheme, but currently themes flash in after loading. We'll try to fix this when the system stabilizes.