Last active
March 15, 2021 17:45
-
-
Save jord-goldberg/6c46ffce82530525e5da6783e8fe02c5 to your computer and use it in GitHub Desktop.
Opinionated styled-system css and variant function typings that enforce use of theme-defined values.
This file contains 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
/** | |
* `Multiples`, `Scales` & `Aliases` types from | |
* [@styled-system/css](https://github.com/styled-system/styled-system/blob/master/packages/css/src/index.js) | |
*/ | |
declare module "@styled-system/css" { | |
import * as CSS from "csstype"; | |
export interface Theme {} | |
type CSSPropertiesFallback = CSS.PropertiesFallback<number | string>; | |
type CSSProperties = { | |
[Prop in keyof CSSPropertiesFallback]: | |
| CSSPropertiesFallback[Prop] | |
| Array<Extract<CSSPropertiesFallback[Prop], string>>; | |
}; | |
type CSSPseudos<CSSObjectType = CSSObject> = { | |
[Prop in CSS.Pseudos]?: CSSObjectType; | |
}; | |
interface NestedCSSObject<CSSObjectType = CSSObject> { | |
[propertyName: string]: | |
| undefined | |
| null | |
| boolean | |
| number | |
| string | |
| Array<number | string> | |
| CSSObjectType; | |
} | |
export interface CSSObject | |
extends CSSProperties, | |
CSSPseudos, | |
NestedCSSObject {} | |
type Multiples = { | |
marginX: ["marginLeft", "marginRight"]; | |
marginY: ["marginTop", "marginBottom"]; | |
paddingX: ["paddingLeft", "paddingRight"]; | |
paddingY: ["paddingTop", "paddingBottom"]; | |
size: ["width", "height"]; | |
}; | |
type MaybeMultiple<Prop> = keyof Multiples[Prop] extends never | |
? Prop | |
: Multiples[Prop][0]; | |
type Scales = { | |
color: "colors"; | |
backgroundColor: "colors"; | |
borderColor: "colors"; | |
margin: "space"; | |
marginTop: "space"; | |
marginRight: "space"; | |
marginBottom: "space"; | |
marginLeft: "space"; | |
marginX: "space"; | |
marginY: "space"; | |
padding: "space"; | |
paddingTop: "space"; | |
paddingRight: "space"; | |
paddingBottom: "space"; | |
paddingLeft: "space"; | |
paddingX: "space"; | |
paddingY: "space"; | |
top: "space"; | |
right: "space"; | |
bottom: "space"; | |
left: "space"; | |
gridGap: "space"; | |
gridColumnGap: "space"; | |
gridRowGap: "space"; | |
gap: "space"; | |
columnGap: "space"; | |
rowGap: "space"; | |
fontFamily: "fonts"; | |
fontSize: "fontSizes"; | |
fontWeight: "fontWeights"; | |
lineHeight: "lineHeights"; | |
letterSpacing: "letterSpacings"; | |
border: "borders"; | |
borderTop: "borders"; | |
borderRight: "borders"; | |
borderBottom: "borders"; | |
borderLeft: "borders"; | |
borderWidth: "borderWidths"; | |
borderStyle: "borderStyles"; | |
borderRadius: "radii"; | |
borderTopRightRadius: "radii"; | |
borderTopLeftRadius: "radii"; | |
borderBottomRightRadius: "radii"; | |
borderBottomLeftRadius: "radii"; | |
borderTopWidth: "borderWidths"; | |
borderTopColor: "colors"; | |
borderTopStyle: "borderStyles"; | |
borderBottomWidth: "borderWidths"; | |
borderBottomColor: "colors"; | |
borderBottomStyle: "borderStyles"; | |
borderLeftWidth: "borderWidths"; | |
borderLeftColor: "colors"; | |
borderLeftStyle: "borderStyles"; | |
borderRightWidth: "borderWidths"; | |
borderRightColor: "colors"; | |
borderRightStyle: "borderStyles"; | |
outlineColor: "colors"; | |
boxShadow: "shadows"; | |
textShadow: "shadows"; | |
zIndex: "zIndices"; | |
width: "sizes"; | |
minWidth: "sizes"; | |
maxWidth: "sizes"; | |
height: "sizes"; | |
minHeight: "sizes"; | |
maxHeight: "sizes"; | |
flexBasis: "sizes"; | |
size: "sizes"; | |
// svg | |
fill: "colors"; | |
stroke: "colors"; | |
}; | |
type ScalesCSSObject = { | |
[Scale in keyof Scales]?: keyof Theme[Scales[Scale]] extends never | |
? CSSProperties[MaybeMultiple<Scale>] | |
: keyof Theme[Scales[Scale]] | Array<keyof Theme[Scales[Scale]]>; | |
}; | |
type Aliases = { | |
bg: "backgroundColor"; | |
m: "margin"; | |
mt: "marginTop"; | |
mr: "marginRight"; | |
mb: "marginBottom"; | |
ml: "marginLeft"; | |
mx: "marginX"; | |
my: "marginY"; | |
p: "padding"; | |
pt: "paddingTop"; | |
pr: "paddingRight"; | |
pb: "paddingBottom"; | |
pl: "paddingLeft"; | |
px: "paddingX"; | |
py: "paddingY"; | |
}; | |
type AliasesCSSObject = { | |
[Alias in keyof Aliases]?: ScalesCSSObject[Aliases[Alias]]; | |
}; | |
export interface StyledCSSObject | |
extends ScalesCSSObject, | |
AliasesCSSObject, | |
Omit<CSSProperties, keyof ScalesCSSObject | keyof AliasesCSSObject>, | |
CSSPseudos<StyledCSSObject>, | |
NestedCSSObject<StyledCSSObject> { | |
variant?: string; | |
} | |
/** | |
* Opinionated typing of the [@styled-system/css](https://styled-system.com/css) function. | |
* | |
* @param styleObject CSS-in-JS style object. | |
* | |
* For CSS properties with a corresponding Styled System scale, you are | |
* constrained to using the scale keys in your theme _if_ your theme | |
* has that scale defined. | |
*/ | |
export function css<Props>( | |
styleObject: StyledCSSObject | |
): (props: Props) => CSSObject; | |
} | |
declare module "@styled-system/variant" { | |
import { CSSObject, StyledCSSObject, Theme } from "@styled-system/css"; | |
export function variant<Props, Prop extends string = "variant">(args: { | |
scale?: keyof Theme; | |
prop?: Prop; | |
variants?: Prop extends keyof Props | |
? Record<Props[Prop], StyledCSSObject> | |
: never; | |
}): (props: Props) => CSSObject; | |
} |
This file contains 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 "@emotion/react"; | |
type AppTheme = typeof import("./theme").default; | |
declare module "@emotion/react" { | |
export interface Theme extends AppTheme {} | |
} | |
declare module "@styled-system/css" { | |
export interface Theme extends AppTheme {} | |
} |
This file contains 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
const theme = { | |
colors: { | |
text: "#000", | |
background: "#fff", | |
primary: "#07c", | |
secondary: "#30c", | |
gray: "#999", | |
muted: "#f6f6f6", | |
highlight: "#e0e", | |
transparent: "transparent", | |
}, | |
fonts: { | |
body: | |
'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif', | |
heading: "inherit", | |
monospace: "Menlo, monospace", | |
}, | |
fontSizes: [12, 14, 16, 20, 24, 32, 48, 64, 72], | |
fontWeights: { | |
body: 400, | |
heading: 700, | |
bold: 700, | |
}, | |
lineHeights: { | |
body: 1.5, | |
heading: 1.125, | |
}, | |
space: [0, 4, 8, 16, 32, 64, 128, 256, 512], | |
radii: { | |
rounded: 4, | |
circle: 99999, | |
}, | |
} as const; | |
export default theme; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment