Skip to content

Themes

Vanilla Tweakpane provides a robust theming system based on CSS variables.

Svelte Tweakpane UI provides abstractions over the underlying CSS variables with some additional conveniences, most notably:

  • Easy access to a collection of bundled preset themes.
  • Abstractions around scoping to simplify using different themes on the same page.
  • Type safety / autocompletion when defining custom themes or overriding existing ones.

Theme-related helpers are exposed on the ThemeUtils object, and a Theme type is also available to provide auto-completion and type safety when defining or overriding themes.


Using preset themes

🔗

ThemeUtils.presets provides default dark and light themes, plus all of the themes defined in the Panepaint theme building tool on the Tweakpane site.

Every Svelte Tweakpane UI component includes an optional theme prop, into which you can pass a Theme object. The Theme object can be a bundled preset, a completely new theme of of your own creation, an extension of a bundled preset, or a partial override of the global default theme (standard) by default.

Applying presets

🔗

Pass a ThemeUtils.presets value to the theme prop of your Tweakpane component:

SvelteTweakpaneThemeBasic.svelte
<script lang="ts">
import { Button, ThemeUtils } from 'svelte-tweakpane-ui';
</script>
<Button label="Jet Black Button" theme={ThemeUtils.presets.jetblack} />

This applies the theme to a single component or pane on the page:

Creating a theme picker

🔗

A quick example of using a <List> to browse and select from all the available preset themes:

SvelteTweakpaneThemePicker.svelte
<script lang="ts">
import { List, Pane, ThemeUtils } from 'svelte-tweakpane-ui';
let themeKey: keyof typeof ThemeUtils.presets = 'standard';
</script>
<Pane
position="inline"
theme={ThemeUtils.presets[themeKey]}
title="Theme Picker"
>
<List
bind:value={themeKey}
label="Theme"
options={Object.keys(ThemeUtils.presets)}
/>
</Pane>

Scoping

🔗

Svelte Tweakpane UI manages setting CSS variables at the right points in the DOM to ensure that themes are rationally scoped, and to allow for multiple themes to be used on the same page.

Themes are scoped either to a pane via its theme prop, to a standalone component via its theme prop, or to the entire window via the setGlobalDefaultTheme() utility function.

In the case of standalone Svelte Tweakpane UI components, the theme is still technically scoped to a <Pane>, because it is applied to the implicit pane that’s created to contain the standalone element.

Panes

🔗

Each pane on the page can have its own theme:

<Pane theme={ThemeUtils.presets.jetblack}>
<Button />
</Pane>
<Pane theme={ThemeUtils.presets.standard}>
<Button />
</Pane>

Standalone components

🔗

Standalone components can also have their own themes:

<Button label="I'm jet black" theme={ThemeUtils.presets.jetblack} />
<Button label="I'm standard" theme={ThemeUtils.presets.standard} />

Global default theme

🔗

You can set a global default theme for all Tweakpane components on the page using the setGlobalDefaultTheme() utility function.

Individual panes or standalone components can still override the global default theme via their theme prop.

<script lang="ts">
import { Button, ThemeUtils } from 'svelte-tweakpane-ui';
ThemeUtils.setGlobalDefaultTheme(ThemeUtils.presets.jetblack);
</script>
<Button label="I'm jet black, the custom global default" />
<Button label="I'm light" theme={ThemeUtils.presets.light} />

Customization

🔗

Creating a new theme

🔗

Themes are plain old JavaScript objects with a key for each CSS variable that Tweakpane uses. Define all theme keys to ensure complete control over the output.

SvelteTweakpaneThemeCustom.svelte
<script lang="ts">
import { Button, type Theme } from 'svelte-tweakpane-ui';
const customTheme: Theme = {
baseBackgroundColor: 'hsl(230, 70%, 27%)',
baseBorderRadius: '6px',
baseFontFamily: 'sans-serif',
baseShadowColor: 'rgba(0, 0, 0, 0.2)',
bladeBorderRadius: '2px',
bladeHorizontalPadding: '4px',
bladeValueWidth: '180px',
buttonBackgroundColor: 'hsl(230, 7%, 70%)',
buttonBackgroundColorActive: '#d6d7db',
buttonBackgroundColorFocus: '#c8cad0',
buttonBackgroundColorHover: '#bbbcc4',
buttonForegroundColor: 'hsl(230, 7%, 17%)',
containerBackgroundColor: 'rgba(187, 188, 196, 0.1)',
containerBackgroundColorActive: 'rgba(187, 188, 196, 0.25)',
containerBackgroundColorFocus: 'rgba(187, 188, 196, 0.2)',
containerBackgroundColorHover: 'rgba(187, 188, 196, 0.15)',
containerForegroundColor: 'hsl(230, 7%, 75%)',
containerHorizontalPadding: '4px',
containerUnitSize: '20px',
containerUnitSpacing: '4px',
containerVerticalPadding: '4px',
grooveForegroundColor: 'rgba(187, 188, 196, 0.1)',
inputBackgroundColor: 'rgba(187, 188, 196, 0.1)',
inputBackgroundColorActive: 'rgba(187, 188, 196, 0.25)',
inputBackgroundColorFocus: 'rgba(187, 188, 196, 0.2)',
inputBackgroundColorHover: 'rgba(187, 188, 196, 0.15)',
inputForegroundColor: 'hsl(230, 7%, 75%)',
labelForegroundColor: 'rgba(187, 188, 196, 0.7)',
monitorBackgroundColor: 'rgba(0, 0, 0, 0.2)',
monitorForegroundColor: 'rgba(187, 188, 196, 0.7)',
pluginImageDraggingColor: 'hsla(230, 100%, 66%, 1)'
};
</script>
<Button label="I'm custom" theme={customTheme} />

Customizing existing themes

🔗

If you only want to override a few values, you can extend a preset theme. This approach ensures that none of the global default theme’s values can reach your custom theme.

SvelteTweakpaneThemeExtend.svelte
<script lang="ts">
import { Button, type Theme, ThemeUtils } from 'svelte-tweakpane-ui';
const customizedTheme: Theme = {
...ThemeUtils.presets.iceberg,
baseBackgroundColor: 'hsla(230, 20%, 11%, 0.5)',
labelForegroundColor: 'hsla(230, 12%, 88%, 1.00)'
};
</script>
<Button label="I'm customized" theme={customizedTheme} />

Overriding default values

🔗

If you don’t mind inheriting from the global default theme, then passing partial theme objects to the theme prop is a quick way to override a few keys of the global default theme.

For example, to restore the rounded look to specific inline components, you can pass a specific baseBorderRadius value:

SvelteTweakpaneThemeOverride.svelte
<script lang="ts">
import { Button } from 'svelte-tweakpane-ui';
</script>
<Button
label="Rounded Parent Button"
theme={{ baseBorderRadius: '6px' }}
/>

Defaults

🔗

By default, all components will use the ThemeUtils.presets.standard theme, which is a dark theme.

Svelte Tweakpane UI introduces one exception for inline panes and standalone components. “Inline” components include those created inside a <Pane position="inline"> component, and “standalone” components that are not the child of a <Pane>.

To better integrate with other inline elements on the page, and especially to avoid a strange scalloped aesthetic when stacking multiple standalone components, rounding is removed by default from inline and standalone the component backgrounds.

If you want to restore the rounded look to specific inline components, you can pass a specific baseBorderRadius value to the theme prop of the component — or explicitly set the ThemeUtils.presets.standard theme.