styled-svelte v1.2.0
styled-svelte
styled-svelte is a way to create Svelte components that have styles attached to them. It's available from styled-svelte. styled was heavily inspired by @emotion/styled and styled-components
Table of Contents
- Quick Start
- API
- Styles with html tag —
styled - Styled with component tag —
styled - Styled with props —
styledprops - Styles with props in component —
build in - Styles with styledSystem —
styledSystembuild in - Forwarding Refs Events —
build in - Action Events —
build inaction props - Theme —
ThemeProviderprops.themeuseTheme - Global Styles —
injectGlobal - Color Utility —
alphadarkerlightenand more - Other Api —
csscxcacheand more
- Styles with html tag —
- Example App
- Thanks
Quick Start
Get up and running with a single import.
npm install --save styled-svelteimport styled from 'styled-svelte';
const Div = styled.div`
padding: 10px 20px;
`;
const Button = styled.button`
color: #333;
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
backgroundcolor: #e8e8e8;
&:hover {
backgroundcolor: #d8d8d8;
}
`;Use them like any other Svelte component – except they're styled!
<Div>
<Button>Click</Button>
</Div>API
styled
The styled function accepts tag and styles as a object or template string and returns a svelte component.
Styles with html tag
styled with html tag or component. and used object styles.
import styled from 'styled-svelte';
const Button = styled('button', {
color: '#333',
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
});styled with object styles. except you call it with an html tag
const Button = styled.button({
color: '#333',
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
});styled with css styles, except you call it with an html tag
import styled from 'styled-svelte';
const Button = styled.button`
color: #333;
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
backgroundcolor: #e8e8e8;
&:hover: {
backgroundcolor: #d8d8d8;
}
`;Styled with Component tag
import styled from 'styled-svelte';
const Button = styled('button', {
color: '#333',
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
});
const NewButton = styled(Button, {
color: '#fff',
padding: '10px 32px',
backgroundColor: '#333',
'&:hover': {
backgroundColor: '#444',
},
});Styles with props
Object Styles
import styled, { type AnyProperties } from 'styled-svelte';
// Object Styles function return object
const Button = styled('button', (props: AnyProperties) => ({
color: props.color,
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
}));
// OR
const Button = styled.button((props: AnyProperties) => ({
color: props.color,
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
}));
// Object Styles function return string (look like css)
const Button = styled(
'button',
(props: AnyProperties) => `
color: ${props.color};
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
background-color: #e8e8e8;
&:hover {
background-color: #d8d8d8;
}
`
);
// OR
const Button = styled.button(
(props: AnyProperties) => `
color: ${props.color};
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
background-color: #e8e8e8;
&:hover {
background-color: #d8d8d8;
}
`
);CSS Styles
import styled, { type AnyProperties } from 'styled-svelte';
// Css Styles with Props (function return props)
const Button = styled.button`
color: ${(props: AnyProperties) => props.color};
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
backgroundcolor: #e8e8e8;
&:hover: {
backgroundcolor: #d8d8d8;
}
`;Use
<Button color="#333">Click</Button>Output in HTML
<button class="styled-1hfd8np">Click</button>Styles with props in Component
*Overide styled API
*Build in props for every component
*Padding and Margin multiply by 8
Padding Props
p props p={2} eq. padding: 16px;
p={[2]} eq. padding: 16px;
p={[2,4]} eq. padding: 16px 32px;
p={[2,4,1]} eq. padding: 16px 32px 8px;
p={[2,4,1,0]} eq. padding: 16px 32px 8px 0px;
pt props pt={2} eq. padding-top: 16px;
pr props pr={2} eq. padding-right: 16px;
pb props pb={2} eq. padding-bottom: 16px;
pl props pl={2} eq. padding-left: 16px;
px props px={2} eq. padding-left: 16px; padding-right: 16px;
py props py={2} eq. padding-top: 16px; padding-bottom: 16px;
Margin Props
m props m={2} eq. margin: 16px;
m={[2]} eq. margin: 16px;
m={[2,4]} eq. margin: 16px 32px;
m={[2,4,1]} eq. margin: 16px 32px 8px;
m={[2,4,1,0]} eq. margin: 16px 32px 8px 0px;
mt props mt={2} eq. margin-top: 16px;
mr props mr={2} eq. margin-right: 16px;
mb props mb={2} eq. margin-bottom: 16px;
ml props ml={2} eq. margin-left: 16px;
mx props mx={2} eq. margin-left: 16px; margin-right: 16px;
my props my={2} eq. margin-top: 16px; margin-bottom: 16px;
className Props
className props className="btn"
Sx Props js-in-css
*(Styles Object OR Styles Object with Props)
sx props sx={{color:'#333',padding:'16px'}} eq. color: #333; padding: '16px';
sx props sx={(props)=>({color:props.theme[props.theme.mode].color.primary,padding:'16px'})} eq. color: #1976d2; padding: '16px';
Remark: props.theme work with ThemeProvider only
Example Styles with props in Componenent
<script lang="ts">
import styled from 'styled-svelte';
const Button = styled('button', {
color: '#333',
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: '#e8e8e8',
'&:hover': {
backgroundColor: '#d8d8d8',
},
});
</script>
<!-- Default use-->
<Button>Click<Button>
<!-- You can do this: Styles in Component -->
<Button p={[2,4]} m={0.5} sx={{color:'#fff',backgroundColor:'#333',
'&:hover':{backgroundColor:'#555'}}}>Click Me</Button>
<!-- OR Sx with Props -->
<Button p={[2,4]} m={0.5} sx={(props)=>({color:props.theme[props.theme.mode].color.primary,backgroundColor:'#333',
'&:hover':{backgroundColor:'#555'}})}>Click Me</Button>Add subffix
<Button subffix="mybtn">Click</Button>Output in HTML
<button class="styled-1hfd8np-mybtn">Click</button>Combining class names
<Button className="btn">Click</Button>Output in HTML
<button class="btn styled-1hfd8np">Click</button>Remark: btn class from other css library (if you want to overide)
Styles with styledSystem
<Button
styledSystem
color="#333"
border="none"
outline="none"
padding="10px 20px"
cursor="pointer"
backgroundColor="#e8e8e8">Click
</Button>The other props you can used theme. please see Other props in Component
Other props in Component
*If styledSystem={true}, the other props you can used. build in, require string
alignItems alignSelf background backgroundColor backgroundImage backgroundPosition backgroundRepeat border borderColor borderWidth borderStyle borderRadius bottom boxShadow boxSizing color columns columnGap columnSpan cursor direction display flexBasis flexDirection flexGrow flexShrink flexWrap float font fontFamily fontStyle fontWeight gap grid gridArea gridAutoColumns gridAutoFlow gridAutoRows gridGap gridRow gridTemplateAreas gridTemplateColumns gridTemplateRows height justifyContent justifyItems justifySelf left letterSpacing listStyle lineHeight margin marginTop marginRight marginBottom marginLeft maxHeight maxWidth minHeight minWidth objectFit objectPosition opacity outline overflow overflowX overflowY padding paddingTop paddingRight paddingBottom paddingLeft position pointerEvents right rotate rowGap scale scrollBehavior textAlign textDecoration textIndent textJustify textOverflow textShadow textTransform top transform transition translate verticalAlign visibility whiteSpace width wordBreak wordSpacing zIndex
Forwarding Refs Events
Build in forwordRefEvents for every component created by styled api
Action Events
Build in action events props for every component created by styled api
<MyComponent action={myAction}/>Theme
Wrapped component with <ThemeProvider {theme}></ThemeProvider>
<script lang="ts">
// src/Main.svelte
import { ThemeProvider } from 'styled-svelte';
import App from './App.svelte';
import { themePallete } from './theme/themePallete';
</script>
<ThemeProvider theme={themePallete}>
<App />
</ThemeProvider>// src/main.ts
import Main from './Main.svelte';
const main = new Main({
target: document.getElementById('app'), // vite
// target: document.body, // rollup
});
export default main;// src/theme/themePallete.ts
// Example theme pallete
export type ThemePallete = {
light: Pallete;
dark: Pallete;
mode: string;
};
type Pallete = {
color: {
primary: string;
secondary: string;
error: string;
warning: string;
info: string;
success: string;
};
background: {
primary: string;
secondary: string;
};
text: {
primary: string;
secondary: string;
disable: string;
};
};
export const themePallete: ThemePallete = {
light: {
color: {
primary: '#1976d2',
secondary: '#9c27b0',
error: '#df2f2f',
warning: '#ed6c02',
info: '#0288d1',
success: '#2e7d36',
},
background: {
primary: '#fff',
secondary: '#f8f8f8',
},
text: {
primary: '#000000de',
secondary: '#00000099',
disable: '#00000061',
},
},
dark: {
color: {
primary: '#90caf9',
secondary: '#ce93d8',
error: '#f44336',
warning: '#ffa726',
info: '#29b6f6',
success: '#66bb6a',
},
background: {
primary: '#121212',
secondary: '#1f1f1f',
},
text: {
primary: '#fff',
secondary: '#ffffffb3',
disable: '#ffffff80',
},
},
mode: 'light',
};Use in components by props.theme or useTheme()
<script lang="ts">
import styled, { type Props, useTheme, alpha } from 'styled-svelte';
import type { ThemePallate } from './theme/themePallete';
// Object Styles, access theme from Props and assign Types on styled
const Button = styled<ThemePallete>('button', (props) => ({
color: props.theme[props.theme.mode].color.primary,
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: alpha(props.theme[props.theme.mode].color.primary, 0.6),
'&:hover': {
backgroundColor: alpha(props.theme[props.theme.mode].color.primary, 0.5),
},
}));
// OR Access theme from Props and assign Types on props
const Button = styled('button', (props: Props<ThemePallete>) => ({
//
}));
// Css Styles, access theme from Props and assign Types on props
const Button = styled.button`
color: ${(props:Props<ThemePallete>) => props.theme[props.theme.mode].color.primary};
border: none;
outline: none;
padding: 10px 20px;
cursor: pointer;
backgroundColor: ${(props/*:Props<ThemePallete>*/) => alpha(props.theme[props.theme.mode].color.primary, 0.6)};
&:hover {
backgroundColor: ${(props/*:Props<ThemePallete>*/) => alpha(props.theme[props.theme.mode].color.primary, 0.5)};
}
}`;
// OR useTheme() API
const theme = useTheme();
const Button = styled('button', {
color: $theme[$theme.mode].color.primary,
border: 'none',
outline: 'none',
padding: '10px 20px',
cursor: 'pointer',
backgroundColor: $theme[$theme.mode].color.primary,
'&:hover': {
backgroundColor: alpha($theme[$theme.mode].color.primary, 0.2),
},
});
</script>Remark: props.theme work with ThemeProvider only
Toggle Dark Mode
<script lang="ts">
const theme = useTheme();
const toggleMode = () => {
theme.update((t) => {
t.mode = t.mode === 'light' ? 'dark' : 'light';
return t;
});
};
</script>
<Button on:click={toggleMode}>Toggle dark mode</Button>;Global Styles
injectGlobal injects styles into the global scope and is useful for applications such as css resets or font faces.
import { injectGlobal } from 'styled-svelte';
injectGlobal({
'*': {
padding: 0,
margin: 0,
boxSizing: 'border-box',
},
});Color Utility
import {
alpha,
darker,
lighten,
lightness,
saturate,
grayscale,
whiten,
blacken,
fade,
opaquer,
} from 'styled-svelte';
alpha('#1976d2', 0.8); // #1976d2cc
darker('#1976d2', 0.2); // #145EA8
lighten('#1976d2', 0.2); // #338DE7
lightness('#1976d2', 0.2); // ##000101
saturate('#1976d2', 0.5); // ##0076FF
grayscale('#1976d2'); // #646464
whiten('#1976d2', 0.8); // #2D80D2
blacken('#1976d2', 0.8); // #1964AE
fade('#1976d2', 0.2); // #0576d2cc
opaquer('#1976d2', 0.8); // #1976d2Other Api
such as css cx injectGlobal flush hydrate merge getRegisteredStyles keyframes sheet cache can read from @emotion/css
import {
flush,
hydrate,
cx,
merge,
getRegisteredStyles,
injectGlobal,
keyframes,
css,
sheet,
cache
} = from 'styled-svelte';