Skip to main content

Styled components

An alternative to styling components manually is to use the createStyled() API, which creates a reusable component at the lowest level. This approach was made popular by the styled-components library.

The createStyled() function requires a standard View, Text, etc, and a partial style sheet (either an object or function), in which a single element is styled, instead of multiple elements.

import React from 'react';
import { View } from 'react-native';
import { createStyled } from '@aesthetic/react-native';
const Box = createStyled(View, (theme) => ({
flex: 1,
justifyContent: 'space-between',
padding: theme.tokens.spacing.df,
export default Box;

Because this API is based on existing native components, all props for that specific component are automatically supported and are typed correctly if using TypeScript.

<Box renderToHardwareTextureAndroid accessibilityLabel="Descriptive label">

Variant styles#

Styled components can support any number of customizable variations out of the box.

const Box = createStyled(View, (theme) => ({
flex: 1,
justifyContent: 'space-between',
padding: theme.tokens.spacing.df,
'@variants': {
'size:sm': { fontSize: },
'size:df': { fontSize: theme.tokens.text.df.size },
'size:lg': { fontSize: theme.tokens.text.lg.size },
'palette:brand': { backgroundColor: },
'palette:positive': { backgroundColor: },
'palette:warning': { backgroundColor: },
// Set default props to define default variants
Box.defaultProps = {
palette: 'brand',

You can then enable a variant by passing a prop with the name of a variant, and a value of one of its types.

<Box palette="brand" size="lg">
Large branded box

If using TypeScript, you'll need to type the variant props manually using the 2nd generic.

interface BoxVariants {
size?: 'sm' | 'df' | 'lg';
palette?: 'brand' | 'positive' | 'warning';
const Box = createStyled<typeof View, BoxVariants>(View, {
// ...

Composing components#

Styled components can also extend and compose around other styled components. When using this approach, all styles and their variants are inherited.

const Button = createStyled(View, (theme) => ({
flex: 1,
alignItems: 'center',
padding: theme.tokens.spacing.df,
const BlockButton = createStyled(Button, {
width: '100%',
const PillBlockButton = createStyled(BlockButton, {
borderRadius: 100,