twind-react
twind-react copied to clipboard
expose typescript helpers to extract variants, infer props
There should be types for extracting the variants of a styled component and another type for extracting all the props of the styled-components.
// This is similar to the Variant generic props used in stitches
type VariantProps<T> = ...;
type StyledProps<T, P = {}> = ...;
const Button = styled("button", {
base: `
appearance-none border-none bg-transparent
rounded-full px-2.5
`,
variants: {
size: {
sm: `text-sm h-6`,
md: `text-base h-9`,
},
variant: {
gray: `
bg-gray-500
hover:bg-gray-600
`,
primary: `
text-white bg-purple-500
hover:bg-purple-600
`,
},
outlined: {
true: `bg-transparent ring-1`,
},
},
defaults: {
variant: "gray",
size: "sm",
},
matches: [
{
variant: "gray",
outlined: true,
use: `ring-gray-500`,
},
{
variant: "primary",
outlined: true,
use: `text-purple-500 ring-gray-500 hover:text-white`,
},
],
})
type ButtonVariants = VariantProps<typeof Button>;
/*
should return the type
type B = {
size?: "sm" | "md";
variant?: "gray" | "primary";
outlined: boolean
},
}
The defaults decide if the given property should be optional
*/
type StyledComponent<typeof Button, { myOwnProp: string; }> = ...;
/*
Should return the type:
type A = <T extends keyof JSX.IntrinsicElements = "button">(props: PropsWithChildren<{
size?: "sm" | "md";
variant?: "gray" | "primary";
outlined: boolean;
css?: CSS;
tw?: string;
as?: T;
myOwnProp: string;
} & JSX.IntrinsicElements[T]>) => JSX.Elements;
The css and tw prop is the same found in the styled-components. The as prop decides which element is used and it is given props, and it should be defaulted to "button". The rest of the props are taken from the VariantProps;
*/
// StyledComponent usage
const Button2: StyledProps<typeof Button> = ({ myOwnProp, children, ...props }) => {
return (
<Button
css={{
backgroundColor: myOwnProp
}}
{...props}>
{children}
</Button/>
);
}