svelte-styled-system Svelte Themes

Svelte Styled System

using styled-system with svelte in ~1kb

Attention! POC only!

POC for bringing the principles of https://styled-system.com/ to svelte.

This is for demo purposes only and not meant to be used yet! May change / be abandoned any time.

Demo: https://svelte.dev/repl/fd2a1151c14c4c2685ee55f661665204?version=3.17.1

Examples (with REPLs):

Using styled-system with svelte

Defining your theme:

The theme definition is nothing more than a plain JS-Object wrapped in a writable store, that should contain an attribute breakpoints: string[] at the top level as a minimum config (if you want to use responsive attributes).

Besides that you can define all of your design variables just as you like.

Example:

// theme.js
import { writable } from "svelte/store";

export const theme = writable({
  // demo: 560px, 768px, 1024px at base 16
  breakpoints: ["35rem", "48rem", "64rem"],
  color: {
    primary: "dodgerblue",
    secondary: "papayawhip",
    grey: "#eee"
  },
  space: {
    s: "0.5rem",
    m: "1rem",
    l: "2rem"
  }
});

Using your theme

Using your theme is pretty straight forward, too. styled from svelte-styled-system is a regular svelte action so you can use it with use:styled. It expects an array in the form [$$props, $theme] note the $ sign in front of your imported theme to (automatically subscribe / unsubscribe to changes automatically!)

// Box.svelte
<script>
  import { styled } from 'svelte-styled-system';
  import { theme } from './theme.js';
</script>

<div use:styled={[$$props, $theme]}>
  <slot></slot>
</div>

That's all! Your are ready to use all css property names + shorthand props as attribute on your component! See https://styled-system.com/api for more documentation.

// App.svelte
<script>
  import Box from './Box.svelte';
</script>

<Box
  p={["space.s", "space.m", "space.l"]}
  bg="color.primary" color="color.secondary"
  textAlign="center"
>
  <h3>Using styled-system in svelte!</h3>
  <p>Resize me to see my responsive padding in action</p>
</Box>

How does the value resolution work?

  1. The attribute name will get mapped to the css property name. You can specify it either in camelCase (textAlign) or kebab-case (text-align). So, if you know css by heart, you already know 99% of your component's props.

  2. if the value is a string, svelte-styled-system first assumes it might be a keypath to your theme object. It uses (dlv) under the hood. If the path can not be resolved, the the resolution will fallback to the input value. (input: textAlign="center" => center can not be found in the theme so the output is just text-align: center;)

{
  color: {
    primary: "dodgerblue", // path: color.primary
  },
  // path: scale.0 => 0
  // path: scale.1 => 0.5rem
  // path: scale.2 => 1rem
  scale: ["0", "0.5rem", "1rem"]
}
  1. if the value is an array then svelte-styled-system will create a media query for each breakpoint and will resolve the separate values just as described before. padding: [0, "space.m", "space.l"]:
  • will create padding: 0; (raw value) for theme.breakpoints[0]
  • will create padding: 1rem; (space.m) for theme.breakpoints[1]
  • will create padding: 2rem; (space.l) for theme.breakpoints[2]

Currently available shorthand properties:

For commonly used css properties there are shortcuts to make your code even less verbose.

Example: my="space.m" => margin-top: 1rem; margin-bottom: 1rem;

As with all other properties you can use the responsive Array notation as well! A complete list of shorthand props is available in the (chakra-ui docs)[https://chakra-ui.com/style-props] or at (src/constants.js)[src/constants.js]

Note: Shorthand path resolutions ("theme keys") are not supported yet. So you always have to specify the full object path:

// react styled-system:
<MyComponent bg="primary" />

// svelte-styled-system:
<MyComponent bg="color.primary" />

Top categories

Loading Svelte Themes