Typescript
Native Variants provides typing out of the box, but this page contains some further utilities and tips.
Extract variants from a component
You can use the VariantProps
utility to extract variants from a component.
import { nv } from 'native-variants'
const buttonVariants = nv({
slots: ["root", "text"],
base: {
root: { paddingHorizontal: 16, paddingVertical: 12 },
text: { color: "#ffffff", textAlign: "center" },
},
variants: {
variant: {
solid: {
root: { backgroundColor: "#ff0006" },
text: { color: "#ffffff" },
},
ghost: {
root: { backgroundColor: "transparent" },
text: { color: "#ff0006" },
},
},
size: {
sm: {
root: {
paddingHorizontal: 8,
paddingVertical: 12
}
text: {
fontSize: 14
}
},
md: {
root: {
paddingHorizontal: 12,
paddingVertical: 16
},
text: {
fontSize: 16
}
},
}
},
});
type ButtonVariants = VariantProps<typeof buttonVariants>
interface ButtonProps extends ButtonVariants {
children: React.ReactNode;
}
export const Button = (props: ButtonProps) => {
const { root, text } = buttonVarints(props)
return
<TouchableOpacity style={root}>
<Text style={text}>
{props.children}
</Text>
</TouchableOpacity>;
};
Required variants
Native Variants doesn't offer a way to make variants required yet, but you can use TypeScript's Utility Types to achieve this.
import { nv } from 'native-variants'
const buttonVariants = nv({
slots: ['root', 'text'],
base: "px-4 py-1.5 rounded-full hover:opacity-80",
variants: {
color: {
primary: {
root: {
backgroundColor: 'blue'
},
text: {
color: 'white'
}
},
neutral: {
root: {
backgroundColor: 'gray'
},
text: {
color: 'white'
}
}
},
requiredFlat: {
true: {
root: {
backgroundColor: 'transparent'
}
},
false: {
backgroundColor: 'black'
},
},
},
defaultVariants: {
color: "primary",
},
compoundVariants: [...],
});
type ButtonVariants = VariantProps<typeof buttonVariants>
export interface ButtonProps
extends Omit<ButtonVariants, "requiredFlat">,
Required<Pick<ButtonVariants, "requiredFlat">> {}
export const button = (props: ButtonProps) => buttonVariants(props);
// ❌ TypeScript Error:
// Argument of type "{}": is not assignable to parameter of type "ButtonProps".
// Property "requiredFlat" is missing in type "{}" but required in type "ButtonProps".
button({});
// ✅
button({ requiredFlat: true });