• Stars
    star
    140
  • Rank 261,473 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 4 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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

svelte-themer

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

<script>
  import { ThemeWrapper, ThemeToggle } from 'svelte-themer'
</script>

<ThemeWrapper>
  <main>
    <h1>svelte themer</h1>
    <ThemeToggle />
  </main>
</ThemeWrapper>

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

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:

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

Turns into

: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()

// 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

<!-- src/App.svelte -->
<script>
  import { ThemeWrapper } from 'svelte-themer'
  import themes from './themes.js'
</script>

<ThemeWrapper themes="{themes}">
  <main>
    <h1>My Svelte App</h1>
  </main>
</ThemeWrapper>

This allows any components nested to access the theme Context which wraps a writeable theme store

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}.

<ThemeWrapper key="my-svelte-app__theme">
  <!--  -->
</ThemeWrapper>

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:

<ThemeWrapper mode="auto|light|dark">
  <!--  -->
</ThemeWrapper>

Accessing Theme Context

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

<!-- src/MyToggleButton.svelte -->
<script>
  import { getContext } from 'svelte'
  let { toggle, current, theme } = getContext('theme')
</script>

<button on:click="{toggle}">
  <slot>{$current}</slot>
</button>

Provided Theme Toggle

<!-- src/App.svelte -->
<script>
  import { ThemeWrapper, ThemeToggle } from 'svelte-themer'
  import themes from './themes.js'
</script>

<ThemeWrapper themes="{themes}">
  <main>
    <h1>My Svelte App</h1>
    <ThemeToggle />
  </main>
</ThemeWrapper>

Actions

use:theme

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

<div use:theme="{myTheme}">
  <p>Hello, World!</p>
</div>

<style>
  p {
    color: var(--text);
  }
</style>

use:stylesheet

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

<div use:stylesheet="{myTheme}">
  <p>Hello, World!</p>
</div>

<style>
  p {
    color: var(--text);
  }
</style>

Contributing

Refer to the contributing guidelines.

License

MIT

More Repositories

1

rouge-theme

VSCode theme created for a dark, material feel with a flushed color palette
JavaScript
38
star
2

express-fs-router

Straightforward filesystem routing utility for Express.js
JavaScript
10
star
3

josef.dev

Personal website built with Svelte-Kit
Astro
9
star
4

svelte-routify-mdsvex-demo

Sample application using Svelte, Routify, and MDsveX
JavaScript
6
star
5

vite-vitest-ts

TypeScript
5
star
6

sveltekit-chrome-extension

Demo showcasing using SvelteKit to build a Chrome Extension
TypeScript
5
star
7

a-links

a/links is an extension for short, composable bookmarks
Svelte
5
star
8

josefaidt.github.io

professional portfolio
JavaScript
5
star
9

gatsby-theme-weather

A weather dashboard Gatsby theme powered by weather.gov
JavaScript
5
star
10

mdx-deck-theme-garlic

garlic theme for mdx-deck
JavaScript
4
star
11

amplify-gen2-admin-actions

TypeScript
3
star
12

pnpm-biome-monorepo-template

personal template repo for pnpm+biome
3
star
13

amplify-svelte-kit-workaround

JavaScript
3
star
14

svelte-cachedb

HTML
3
star
15

deploy-aws-cdk-with-github-actions

Deploy AWS CDK apps with GitHub Actions
TypeScript
2
star
16

7dtd-map

Live Map implementation for 7 Days to Die
JavaScript
2
star
17

psecrets

Utility for managing project secrets and parameters with AWS SSM Parameter Store
TypeScript
2
star
18

resume

Personal resume created with Next.js, CSS Modules, and a GitHub Action to create a PDF copy of the printed site
JavaScript
2
star
19

go-fakecompany-api

Go
2
star
20

avm

TypeScript
1
star
21

viteconf-amplify

CSS
1
star
22

sviny

For your tiny Svelte apps
JavaScript
1
star
23

amplify-storage-demo

Demo using Next.js and AWS Amplify with Auth and Storage
JavaScript
1
star
24

twin-pines

Find National Parks' history near you!
HTML
1
star
25

amplify-gen2-workaround-cognito-domain

TypeScript
1
star
26

aws-amplify-2

TypeScript
1
star
27

gen2-starter

My Amplify Gen 2 starter application
TypeScript
1
star
28

amplify-gen2-google-recaptcha

TypeScript
1
star
29

serverless-nextjs-fauna-demo

Getting started with serverless Next.js and Fauna - Jed's Supply Co.
CSS
1
star
30

amplify-secrets-using-hooks

JavaScript
1
star
31

redirects-from-paths

generate Vercel and Netlify redirects
JavaScript
1
star
32

demo-sveltekit-mdsvex

Svelte
1
star