Theming

Is always hard to chose the right style for your application. This library has some basic concepts that helps you do that.

Class attribute

Every components will have a class attribute, that will let you specify all the classes you want to apply to the root element of the components.

In case the components has more than one root elements, or want to let you specify more element classes, then the class attribute will be an object

Components style props

Some components (many of them) will have style props you can apply to them. Those props will begin with -- and svelte will convert them to CSS variable. The variable you define will overwrite the component default. Something like that:

<script lang="ts">
  import { Button } from '@likable-hair/svelte'
</script>

<Button
  --button-background-color="green"
>my background will be green</Button>

Themes store

The library comes with a themes store, where are stored all the color needed by the app. This store has this type of object:

type Shades = {
  50: string
  100: string
  200: string
  300: string
  400: string
  500: string
  600: string
  700: string
  800: string
  900: string
  950: string
}

type Theme = string // should be a custom name, usually 'light' or 'dark'

type Colors = Record<Theme, {
  light?: {
    background?: Shades,
    contrast?: Shades,
    primary?: Shades,
    secondary?: Shades,
    error?: Shades,
    warning?: Shades,
  },
  dark?: {
    background?: Shades,
    contrast?: Shades,
    primary?: Shades,
    secondary?: Shades,
    error?: Shades,
    warning?: Shades,
  }
}>

type ThemeStore = {
  colors: Colors,
  active: Theme,
  disabled: boolean,
  inherit?: string
}

The color specified for the current theme will be used as default for components. The default theme will be light, but you can always choose another one, like explained below.

The colors key of the store is initially empty. If you want to change it import the store from the library and then set the value:

import { theme } from '@likable-hair/svelte'

theme.update((currentTheme) => {
  const activeTheme = currentTheme.active

  if(!currentTheme.colors[activeTheme]) currentTheme.colors[activeTheme] = {}
  if(!currentTheme.colors[activeTheme].light) currentTheme.colors[activeTheme].light = {}
  currentTheme.colors[activeTheme].light.background = {
    50: #eff6ff
  }

  return currentTheme
})

Color CSS Variables

The theme store is useful if you want to change colors or theme at runtime, but when you load the page you can see that the page has to execute the javascript in order to setting the right colors.

To avoid the side effect you can set the default colors with CSS variables, then when the javascript will run the store will take over.

Those are the CSS variables:

:root {
  /* light theme */
  --global-color-light-background-50: #eff6ff;
  --global-color-light-background-100: #dbeafe;
  --global-color-light-background-200: #bfdbfe;
  --global-color-light-background-300: #93c5fd;
  --global-color-light-background-400: #60a5fa;
  --global-color-light-background-500: #3b82f6;
  --global-color-light-background-600: #2563eb;
  --global-color-light-background-700: #1d4ed8;
  --global-color-light-background-800: #1e40af;
  --global-color-light-background-900: #1e3a8a;
  --global-color-light-background-950: #1e3a8a;

  --global-color-light-contrast-50: #eff6ff;
  --global-color-light-contrast-100: #dbeafe;
  --global-color-light-contrast-200: #bfdbfe;
  /* ... */

  --global-color-light-primary-50: #eff6ff;
  --global-color-light-primary-100: #dbeafe;
  --global-color-light-primary-200: #bfdbfe;
  /* ... */

  --global-color-light-secondary-50: #eff6ff;
  --global-color-light-secondary-100: #dbeafe;
  --global-color-light-secondary-200: #bfdbfe;
  /* ... */

  --global-color-light-error-50: #eff6ff;
  --global-color-light-error-100: #dbeafe;
  --global-color-light-error-200: #bfdbfe;
  /* ... */

  --global-color-light-warning-50: #eff6ff;
  --global-color-light-warning-100: #dbeafe;
  --global-color-light-warning-200: #bfdbfe;
  /* ... */


  /* dark theme */
  --global-color-dark-background-50: #eff6ff;
  --global-color-dark-background-100: #dbeafe;
  --global-color-dark-background-200: #bfdbfe;
  --global-color-dark-background-300: #93c5fd;
  --global-color-dark-background-400: #60a5fa;
  --global-color-dark-background-500: #3b82f6;
  --global-color-dark-background-600: #2563eb;
  --global-color-dark-background-700: #1d4ed8;
  --global-color-dark-background-800: #1e40af;
  --global-color-dark-background-900: #1e3a8a;
  --global-color-dark-background-950: #1e3a8a;

  --global-color-dark-contrast-50: #eff6ff;
  --global-color-dark-contrast-100: #dbeafe;
  --global-color-dark-contrast-200: #bfdbfe;
  /* ... */

  --global-color-dark-primary-50: #eff6ff;
  --global-color-dark-primary-100: #dbeafe;
  --global-color-dark-primary-200: #bfdbfe;
  /* ... */

  --global-color-dark-secondary-50: #eff6ff;
  --global-color-dark-secondary-100: #dbeafe;
  --global-color-dark-secondary-200: #bfdbfe;
  /* ... */

  --global-color-dark-error-50: #eff6ff;
  --global-color-dark-error-100: #dbeafe;
  --global-color-dark-error-200: #bfdbfe;
  /* ... */

  --global-color-dark-warning-50: #eff6ff;
  --global-color-dark-warning-100: #dbeafe;
  --global-color-dark-warning-200: #bfdbfe;
  /* ... */
}

Setting the variable is not mandatory. Neither using the store is: you can choose to use only css variables for example. In that case could be useful to deactivate the store like that:

import { theme } from '@likable-hair/svelte'

theme.update((currentTheme) => {
  currentTheme.disabled = true
  return currentTheme
})

Either way if the store is empty CSS variables will remain untouched.

Setting the active theme

As you can see in the theme store there is an attribute called active. This attribute contains the value light by default, if you have set multiple colors in the theme you can set the active to one of those and colors will switch.

This way you will be able to specify not only a dark theme but also whatever color scheme you need.

Tailwind Integration

Thanks to the class attribute you can use all the available tailwind classes. So if you prefer to use tailwind as a theming engine you're free to choose.
Previous
Next