How to write custom components
Passing styles to components
Pass the className
prop down to your custom component
function MyComponent({ className }) {
const defaultStyles = "text-black dark:text-white";
return <Text className={`${defaultStyles} ${className}`} />;
}
<MyComponent className="font-bold" />;
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]}
`}
/>
);
}
Creating your own variants and quickly become complex. We recommend using a class name management library to simplify the process
NativeWind previously exported a styled()
helper function, but it has been removed in favor of these libraries.
Each of these library has multiple "component" variants, so you can choose the one that best fits your needs.
Merging with inline styles
NativeWind will automatically merge with inline-styles. Inline styles have a higher priority.
<Text className="text-white" style={{ color: "black" }} /> // Will be black
Handling components with multiple style props
In React Native, some components may require style props for their internal child components. If you're designing such a component using NativeWind, we have a couple of recommended simply creating multiple class name props
Copy code
function MyComponent({ outerClass, innerClass }) {
return (
<View className={outerClass}>
<Text className={innerClass}>Hello, NativeWind!</Text>
</View>
);
}
If you're working with a third-party component that you can't modify directly, NativeWind provides a utility, remapProps
. This function allows you to create and map className props for the component.
import { remapProps } from "nativewind";
const CustomizedButton = remapProps(ThirdPartyButton, {
buttonClass: "nativeButtonClass",
labelClass: "nativeLabelClass",
});
// Usage
<CustomizedButton buttonClass="bg-blue-500" labelClass="text-white" />;
See the remapProps documentation for more information.
Handling components with style attribute props
Some components may require style attributes to be passed as props. For example, React Native's <StatusBar />
component accepts a backgroundColor
prop.
NativeWind can automatically move style attributes to props, but it requires the styles to be resolved. You will need to "tag" your component using cssInterop
and create a mapping configuration
See the cssInterop documentation for more information.
TypeScript
Both remapProps
and cssInterop
will return a typed version of your component. However, you can globally defined the types in a new declaration file.
declare module "<3rd party package>" {
interface 3rdPartyComponentProps {
customClassName?: string;
}
}
Example
Setting global types requires in-depth knowledge of TypeScript. Your interface declaration needs to exactly match the 3rd party declaration (including extends
and generics).
For example, NativeWind uses the follow types for React Native's <FlatList />
, which uses multiple interfaces for its props, across multiple packages.
import {
ScrollViewProps,
ScrollViewPropsAndroid,
ScrollViewPropsIOS,
Touchable,
VirtualizedListProps,
} from "react-native";
declare module "@react-native/virtualized-lists" {
export interface VirtualizedListWithoutRenderItemProps<ItemT>
extends ScrollViewProps {
ListFooterComponentClassName?: string;
ListHeaderComponentClassName?: string;
}
}
declare module "react-native" {
interface ScrollViewProps
extends ViewProps,
ScrollViewPropsIOS,
ScrollViewPropsAndroid,
Touchable {
contentContainerClassName?: string;
indicatorClassName?: string;
}
interface FlatListProps<ItemT> extends VirtualizedListProps<ItemT> {
columnWrapperClassName?: string;
}
interface ViewProps {
className?: string;
}
}