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
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 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>
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.
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"]
}
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"]
:padding: 0;
(raw value) for theme.breakpoints[0]
padding: 1rem;
(space.m
) for theme.breakpoints[1]
padding: 2rem;
(space.l
) for theme.breakpoints[2]
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" />