# Styling **Category**: native **URL**: https://www.heroui.com/docs/native/getting-started/styling **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/styling.mdx > Style HeroUI Native components with Tailwind or StyleSheet API *** HeroUI Native components provide flexible styling options: Tailwind CSS utilities, StyleSheet API, and render props for dynamic styling. ## Styling Principles HeroUI Native is built with `className` as the go-to styling solution. You can use Tailwind CSS classes via the `className` prop on all components. **StyleSheet precedence:** The `style` prop (StyleSheet API) can be used and has precedence over `className` when both are provided. This allows you to override Tailwind classes when needed. **Animated styles:** Some style properties are animated using `react-native-reanimated` and, like StyleSheet styles, they have precedence over `className`. To identify which styles are animated and cannot be used via `className`: - **Hover over `className` in your IDE** - The TypeScript definitions will show which properties are available - **Check component documentation** - Each component page includes a link to the component's style source at the top, which contains notes about animated properties **Customizing animated styles:** If styles are occupied by animation, you can modify them via the `animation` prop on components that support it. ## Basic Styling **Using className:** All HeroUI Native components accept `className` props: ```tsx import { Button } from 'heroui-native'; ; ``` **Using style:** Components also accept inline styles via the `style` prop: ```tsx import { Button } from 'heroui-native'; ; ``` ## Render Props Use a render function to access component state and customize content dynamically: ```tsx import { RadioGroup, Label, cn } from 'heroui-native'; {({ isSelected, isInvalid, isDisabled }) => ( <> {isSelected && } )} ; ``` ## Creating Wrapper Components Create reusable custom components using [tailwind-variants](https://tailwind-variants.org/)—a Tailwind CSS first-class variant API: ```tsx import { Button } from 'heroui-native'; import type { ButtonRootProps } from 'heroui-native'; import { tv, type VariantProps } from 'tailwind-variants'; const customButtonVariants = tv({ base: 'font-semibold rounded-lg', variants: { intent: { primary: 'bg-blue-500', secondary: 'bg-gray-200', danger: 'bg-red-500', }, }, defaultVariants: { intent: 'primary', }, }); const customLabelVariants = tv({ base: '', variants: { intent: { primary: 'text-white', secondary: 'text-gray-800', danger: 'text-white', }, }, defaultVariants: { intent: 'primary', }, }); type CustomButtonVariants = VariantProps; interface CustomButtonProps extends Omit, CustomButtonVariants { className?: string; labelClassName?: string; } export function CustomButton({ intent, className, labelClassName, children, ...props }: CustomButtonProps) { return ( ); } ``` ## Using Component classNames Each HeroUI Native component exports a `classNames` object that contains the same styling functions used internally by the component. This is particularly useful when you want to style your own custom components to match the appearance of HeroUI Native components. For example, you can style a custom `Link` component to look like a `Button`: ```tsx import { buttonClassNames, cn } from 'heroui-native'; import { Pressable, Text } from 'react-native'; interface LinkProps { href: string; variant?: 'primary' | 'secondary' | 'outline' | 'ghost'; size?: 'sm' | 'md' | 'lg'; children: React.ReactNode; className?: string; } export function Link({ href, variant = 'primary', size = 'md', children, className, }: LinkProps) { return ( { // Handle navigation }} > {children} ); } ``` **Available classNames exports:** Each component exports its `classNames` object. For example: - `buttonClassNames` - Contains `root` and `label` functions - `cardClassNames` - Contains `root`, `header`, `body`, `footer`, `label`, and `description` functions - `chipClassNames` - Contains `root` and `label` functions - And many more... **Usage pattern:** ```tsx import { buttonClassNames } from 'heroui-native'; // Use with variant and size options const rootClasses = buttonClassNames.root({ variant: 'primary', size: 'md', className: 'custom-class', // Optional: merge with your own classes }); const labelClasses = buttonClassNames.label({ variant: 'primary', size: 'md', }); ``` The `classNames` functions accept the same variant props as the components themselves, allowing you to maintain visual consistency across your custom components and HeroUI Native components. ## Responsive Design HeroUI Native supports Tailwind's responsive breakpoint system via [Uniwind](https://docs.uniwind.dev/breakpoints). Use breakpoint prefixes like `sm:`, `md:`, `lg:`, and `xl:` to apply styles conditionally based on screen width. **Mobile-first approach:** Start with mobile styles (no prefix), then use breakpoints to enhance for larger screens. ### Responsive Typography and Spacing ```tsx import { Button } from 'heroui-native'; import { View, Text } from 'react-native'; Responsive Heading ; ``` ### Responsive Layouts ```tsx import { View, Text } from 'react-native'; {/* Mobile: 1 column, Tablet: 2 columns, Desktop: 3 columns */} Item 1 ; ``` **Default breakpoints:** - `sm`: 640px - `md`: 768px - `lg`: 1024px - `xl`: 1280px - `2xl`: 1536px For custom breakpoints and more details, see the [Uniwind breakpoints documentation](https://docs.uniwind.dev/breakpoints). ## Utilities HeroUI Native provides utility functions to assist with styling components. ### cn Utility The `cn` utility function merges Tailwind CSS classes with proper conflict resolution. It's particularly useful when combining conditional classes or merging classes from props: ```tsx import { cn } from 'heroui-native'; import { View } from 'react-native'; function MyComponent({ className, isActive }) { return ( ); } ```; The `cn` utility is powered by `tailwind-variants` and includes: - Automatic Tailwind class merging (`twMerge: true`) - Custom opacity class group support - Proper conflict resolution (later classes override earlier ones) **Example with conflicts:** ```tsx // 'bg-accent' overrides 'bg-background' cn('bg-background p-4', 'bg-accent'); // Result: 'p-4 bg-accent' ``` ### useThemeColor Hook Retrieves theme color values from CSS variables. Supports both single color and multiple colors for efficient batch retrieval. **Single color usage:** ```tsx import { useThemeColor } from 'heroui-native'; function MyComponent() { const accentColor = useThemeColor('accent'); const dangerColor = useThemeColor('danger'); return ( Error message ); } ```; **Multiple colors usage (more efficient):** ```tsx import { useThemeColor } from 'heroui-native'; function MyComponent() { const [accentColor, backgroundColor, dangerColor] = useThemeColor([ 'accent', 'background', 'danger', ]); return ( Error message ); } ```; **Type signatures:** ```tsx // Single color useThemeColor(themeColor: ThemeColor): string // Multiple colors (with type inference for tuples) useThemeColor( themeColor: T ): CreateStringTuple // Multiple colors (array) useThemeColor(themeColor: ThemeColor[]): string[] ``` Available theme colors include: `background`, `foreground`, `surface`, `accent`, `default`, `success`, `warning`, `danger`, and all their variants (hover, soft, foreground, etc.), plus semantic colors like `muted`, `border`, `separator`, `field`, `overlay`, and more. ## Next Steps - Learn about [Animation](/docs/native/getting-started/animation) techniques - Explore [Theming](/docs/native/getting-started/theming) system - Explore [Colors](/docs/native/getting-started/colors) documentation