Created
March 26, 2021 10:13
-
-
Save mattcompiles/2e7c77fb17746034c3f732308b91f8a1 to your computer and use it in GitHub Desktop.
vanilla-extract - Stitches style API demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { stitch } from './vanilla-stitches-runtime'; | |
import { stackPattern, buttonPattern } from './styles.css'; | |
const button = stitch(buttonPattern); | |
const stack = stitch(stackPattern); | |
document.body.innerHTML = ` | |
<div class="${stack({ space: 'xlarge' })}"> | |
<div class="${stack({ space: 'small' })}"> | |
<button class="${button()}">Button</button> | |
<button class="${button({ variant: 'purple' })}">Purple button</button> | |
</div> | |
<div class="${stack()}"> | |
<button class="${button({ size: 'large' })}">Large Button</button> | |
<button class="${button({ | |
variant: 'purple', | |
size: 'large', | |
})}">Large Purple button</button> | |
</div> | |
<div> | |
`; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import mapValues from 'lodash/mapValues'; | |
import { createGlobalTheme } from '@vanilla-extract/css'; | |
import { createPattern } from './vanilla-stitches-style'; | |
const gray800 = '#888'; | |
const vars = createGlobalTheme(':root', { | |
color: { | |
gray400: 'gainsboro', | |
gray500: 'lightgray', | |
gray800: gray800, | |
purple400: 'blueviolet', | |
purple500: 'darkviolet', | |
}, | |
space: { | |
xsmall: '4px', | |
small: '8px', | |
medium: '20px', | |
large: '28px', | |
xlarge: '40px', | |
}, | |
shadows: { | |
small: [ | |
`0 2px 4px 0px ${gray800}`, | |
`0 2px 2px -2px ${gray800}`, | |
`0 4px 4px -4px ${gray800}`, | |
].join(', '), | |
medium: [ | |
`0 2px 4px 0px ${gray800}`, | |
`0 8px 8px -4px ${gray800}`, | |
`0 12px 12px -8px ${gray800}`, | |
].join(', '), | |
large: [ | |
`0 2px 4px 0px ${gray800}`, | |
`0 12px 12px -4px ${gray800}`, | |
`0 20px 20px -12px ${gray800}`, | |
].join(', '), | |
}, | |
}); | |
export const buttonPattern = createPattern({ | |
appearance: 'none', | |
border: 'none', | |
borderRadius: 99999, | |
lineHeight: 1, | |
variants: { | |
variant: { | |
gray: { | |
backgroundColor: vars.color.gray400, | |
':hover': { | |
backgroundColor: vars.color.gray500, | |
}, | |
}, | |
purple: { | |
backgroundColor: vars.color.purple400, | |
color: 'white', | |
':hover': { | |
backgroundColor: vars.color.purple500, | |
}, | |
}, | |
}, | |
size: { | |
standard: { | |
fontSize: 13, | |
height: 25, | |
paddingLeft: vars.space.small, | |
paddingRight: vars.space.small, | |
}, | |
large: { | |
fontSize: 16, | |
height: vars.space.xlarge, | |
paddingLeft: vars.space.medium, | |
paddingRight: vars.space.medium, | |
}, | |
}, | |
}, | |
compoundVariants: [ | |
{ | |
size: 'large', | |
variant: 'purple', | |
css: { | |
boxShadow: vars.shadows.large, | |
}, | |
}, | |
], | |
defaultVariants: { | |
variant: 'gray', | |
size: 'standard', | |
}, | |
}); | |
export const stackPattern = createPattern({ | |
display: 'flex', | |
flexDirection: 'column', | |
alignItems: 'flex-start', | |
variants: { | |
space: mapValues(vars.space, (spaceValue) => ({ | |
gap: spaceValue, | |
})), | |
}, | |
defaultVariants: { | |
space: 'medium', | |
}, | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import mapValues from 'lodash/mapValues'; | |
import { style, mapToStyles } from '@vanilla-extract/css'; | |
import { StitchesOptions, StitchesResult, VariantGroups } from './vanilla-stitches-types'; | |
export function createPattern<Variants extends VariantGroups>( | |
options: StitchesOptions<Variants>, | |
): StitchesResult<Variants> { | |
const { variants, defaultVariants, compoundVariants = [], ...rest } = options; | |
const defaultClassName = style(rest); | |
const variantClassNames = mapValues(variants, (variantGroup) => | |
mapToStyles(variantGroup), | |
) as StitchesResult<Variants>['variantClassNames']; | |
const compoundVariantsValues = compoundVariants.map((cp) => { | |
const { css, ...variantOptions } = cp; | |
const className = style(css); | |
return { | |
className, | |
variantOptions, | |
}; | |
}); | |
return { | |
defaultClassName, | |
variantClassNames, | |
defaultVariants, | |
compoundVariantsValues, | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import mapValues from 'lodash/mapValues'; | |
import { style, mapToStyles } from '@vanilla-extract/css'; | |
import { StitchesOptions, StitchesResult, VariantGroups } from './vanilla-stitches-types'; | |
export function createPattern<Variants extends VariantGroups>( | |
options: StitchesOptions<Variants>, | |
): StitchesResult<Variants> { | |
const { variants, defaultVariants, compoundVariants = [], ...rest } = options; | |
const defaultClassName = style(rest); | |
const variantClassNames = mapValues(variants, (variantGroup) => | |
mapToStyles(variantGroup), | |
) as StitchesResult<Variants>['variantClassNames']; | |
const compoundVariantsValues = compoundVariants.map((cp) => { | |
const { css, ...variantOptions } = cp; | |
const className = style(css); | |
return { | |
className, | |
variantOptions, | |
}; | |
}); | |
return { | |
defaultClassName, | |
variantClassNames, | |
defaultVariants, | |
compoundVariantsValues, | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { StyleRule } from '@vanilla-extract/css'; | |
export type EnumVariant = Record<string | number, StyleRule>; | |
export type VariantTypes = EnumVariant; | |
export type VariantGroups = Record<string, VariantTypes>; | |
export type VariantSelection<Variants extends VariantGroups> = { | |
[variantGroup in keyof Variants]?: keyof Variants[variantGroup]; | |
}; | |
export interface StitchesResult<Variants extends VariantGroups> { | |
defaultClassName: string; | |
variantClassNames: { | |
[P in keyof Variants]: { [P in keyof Variants[keyof Variants]]: string }; | |
}; | |
defaultVariants?: VariantSelection<Variants>; | |
compoundVariantsValues: Array<{ | |
className: string; | |
variantOptions: Omit<CompoundVariant<Variants>, 'css'>; | |
}>; | |
} | |
export type CompoundVariant< | |
Variants extends VariantGroups | |
> = VariantSelection<Variants> & { | |
css: StyleRule; | |
}; | |
export type StitchesOptions<Variants extends VariantGroups> = StyleRule & { | |
variants?: Variants; | |
defaultVariants?: VariantSelection<Variants>; | |
compoundVariants?: Array<CompoundVariant<Variants>>; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
From twitter:
I've thrown together a codesandbox here to see if I could get this up and running.
As the
vanilla-stitches-runtime.ts
file above didn't look right, I quickly threw together the following code, which seems to work, but is missing some type definitions for theprops
value:I would definitely be interested in seeing if anyone else has attempted to do something similar to this. The variants API in stitches is 🔥 so combining that with vanilla-extract would be really neat.
I wonder if it's possible to support something similar to stitches responsive-variants with vanilla-extract? It basically lets you say "for small screens use this variant and for large screens use this other variant". I guess with the combinatorial effect of props on media queries, it might lend itself to being paired with sprinkles?