Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/josefaidt/svelte-themer

A theming engine for your Svelte apps using CSS Variables, persisted.
https://github.com/josefaidt/svelte-themer

css-variables svelte theme theming

Last synced: 6 days ago
JSON representation

A theming engine for your Svelte apps using CSS Variables, persisted.

Awesome Lists containing this project

README

        

# svelte-themer

A theming engine for your Svelte apps using CSS Variables, persisted.

```html

import { ThemeWrapper, ThemeToggle } from 'svelte-themer'


svelte themer



:global(html) {
background-color: var(--theme-colors-background, initial);
color: var(--theme-colors-text, initial);
}

```

## CSS Variables

CSS variables are created for app-wide consumption using the nomenclature `--[prefix]-[property!]`

For example:

- `--theme-text` by default where `property = 'text'`
- `--base-text` where `prefix = 'base'` and `property = 'text'`
- `--text` where `prefix = null || undefined` and `property = 'text'`

Now supports adding _all_ theme colors as theme-specific CSS variables:

```js
const lightTheme = {
light: {
colors: {
text: '#282230',
background: {
_: '#f1f1f1',
contrast: '#b1b1b1',
},
primary: '#01796f',
primary_dark: '#016159',
secondary: '#562931',
},
},
}
```

Turns into

```css
:root {
--theme-light-colors-text: #282230;
--theme-light-colors-background: #f1f1f1;
--theme-light-colors-background-contrast: #b1b1b1;
--theme-light-colors-primary: #01796f;
--theme-light-colors-primary_dark: #016159;
--theme-light-colors-secondary: #562931;
}

[theme='light'],
.theme--light {
--theme-colors-text: var(--theme-light-colors-text);
--theme-colors-background: var(--theme-light-colors-background);
--theme-colors-background-contrast: --var(
theme-light-colors-background-contrast
);
--theme-colors-primary: var(--theme-light-colors-primary);
--theme-colors-primary_dark: var(--theme-light-colors-primary_dark);
--theme-colors-secondary: var(--theme-light-colors-secondary);
}
```

## Getting Started

Use the preset themes supplied by svelte-themer or create your own! Theme names are specified by the key, and all properties are transformed into CSS Variables.

**NOTE**: svelte-themer is preset with 3 themes to showcase the flexible functionality of `toggle()`

```js
// src/themes.js
export const themes = {
light: {
colors: {
text: '#282230',
background: {
_: '#f1f1f1',
contrast: '#b1b1b1',
},
primary: '#01796f',
primary_dark: '#016159',
secondary: '#562931',
},
},
dark: {
colors: {
text: '#f1f1f1',
background: {
_: '#27323a',
contrast: '#0d1215',
},
primary: '#01978b',
primary_dark: '#00887c',
secondary: '#fe8690',
},
},
}
```

## Components

With svelte-themer there are two components: a wrapper component, and a button for toggling themes. The provided button is more for convenience as the function used to toggle themes is exposed to the theme context.

### ThemeWrapper

```html

import { ThemeWrapper } from 'svelte-themer'
import themes from './themes.js'


My Svelte App


```

This allows any components nested to access the theme [Context](https://svelte.dev/tutorial/context-api) which wraps a writeable `theme` [store](https://svelte.dev/tutorial/writable-stores)

#### Theme Persistence

By default svelte-themer persists the chosen theme with `localStorage`, and can be modified via the `key` prop. To disabled persistence, provide `key={null}`.

```html

```

#### Theme Loading Order

`ThemeWrapper` will load a theme on first visit based on the following order:

1. User-provided - The value specified in the `theme` prop.
2. Saved - User's stored choice (from `localStorage`)
3. Prefers - User's Operating System settings (via `prefers-color-scheme`)
4. Fallback - First theme in `themes` specified (from presets, `light`)

By default, the "prefers" step will choose a theme based on OS settings, however this can be modified to directly choose "light" or "dark" by leveraging the `mode` prop:

```html

```

### Accessing Theme Context

Described below is the pattern used for accessing `theme` context to create your own toggle button.

```html

import { getContext } from 'svelte'
let { toggle, current, theme } = getContext('theme')

{$current}

```

### Provided Theme Toggle

```html

import { ThemeWrapper, ThemeToggle } from 'svelte-themer'
import themes from './themes.js'


My Svelte App



```

## Actions

### use:theme

```svelte

import { theme } from 'svelte-themer/use'
export let myTheme = {
text: 'red',
}


Hello, World!


p {
color: var(--text);
}

```

### use:stylesheet

```svelte

import { stylesheet } from 'svelte-themer/use'
export let myTheme = {
text: 'red',
}


Hello, World!


p {
color: var(--text);
}

```

## Contributing

Refer to the [contributing guidelines](CONTRIBUTING.md).

## License

[MIT](LICENSE)