Skip to main content

Custom Components

NativeWind's strength really shines with writing your own custom components.

Passing styles to components

When passing styles between components, they are compiled on the parent and passed as a style prop to the child.

caution

You need to use style, className is not passed down!

function MyComponent({ style }) {
return <Text style={style} />;
}

<MyComponent className="font-bold" />

If you want to pass the className as a string use a different prop.

function A({ style }) {
return <B textClassName="font-bold" />;
}

function B({ textClassName }) {
return <Text className={textClassName} />;
}

Merging styles

NativeWind doesn't require you to merge or provide styles as an array. You can simply append the two classNames strings together

function MyComponent() {
const classes = `text-black`;
return <Text className={`font-bold ${classes}`} />;
}

This pattern is very useful for creating components with variants

const variantStyles = {
default: "rounded",
primary: "bg-blue-500 text-white",
secondary: "bg-white-500 text-black",
};

function MyComponent({ variant }) {
return (
<Text
className={`
font-bold
${variantStyles.default}
${variantStyles[variant]}
`}
/>
);
}

Merging with inline styles

NativeWind will automatically merge with inline-styles. Inline styles have a higher priority.

function MyText({ style }) {
// style is [{ fontWeight: "bold" }, { color: "black" }]
return <Text style={style} />;
}

<MyText className={`font-bold`} style={{ color: "black" }} />;

Typescript

styled() handles the Typescript complexity for you. Simply write your components as normal.

interface MyButtonProps extends PressableProps {
textStyle: TextProps["style"]
}

function MyButton({ textStyle, children, ...props }: MyButtonProps) {
return (
<Pressable {...props}>
<Text style={textStyle}>{children}</Text>
</Pressable>
)
}

export default styled(MyButton, {
props: {
textStyle: true
}
})

<MyButton textStyle="font-bold">This text will be bold</MyButton>



Complex logic

If you have complex styling logic consider using a library the className merging like clsx.

function A({ rounded, className }) {
const className = clsx(
"font-bold",
{ rounded },
variant === "primary" && "bg-blue-500 text-white",
variant === "secondary" && "bg-blue-500 text-white",
className
);
return <B className={className} />;
}