Skip to main content

Variants, createStyles and Style Prop

This documentation covers three essential styling concepts: component variants, the createStyles function, and how to use the style prop effectively in your components.

Component Variants

Variants are predefined style configurations that can be applied to components. They provide a consistent way to apply different visual styles without writing custom CSS each time.

Available Default Variants

All library components have access to a set of default variants that cover the most common use cases for layout, positioning, and alignment.

Display and Layout

// Display
<View style={['block']} /> // display: block
<View style={['flex']} /> // display: flex, flex: 1
<View style={['hidden']} /> // display: none

// Flex direction
<View style={['row']} /> // display: flex, flexDirection: row
<View style={['column']} /> // flexDirection: column
<View style={['centerRow']} /> // display: flex, flexDirection: row, alignItems: center

Positioning

// Position
<View style={['absolute']} /> // position: absolute
<View style={['relative']} /> // position: relative
<View style={['fixed']} /> // position: fixed
<View style={['sticky']} /> // position: sticky

// Positioning presets
<View style={['insetX']} /> // left: 0, right: 0
<View style={['insetY']} /> // top: 0, bottom: 0
<View style={['whole']} /> // top: 0, bottom: 0, left: 0, right: 0

Sizing

// Dimensions
<View style={['full']} /> // width: 100%, height: 100%
<View style={['fullWidth']} /> // width: 100%
<View style={['fullHeight']} /> // height: 100%

Flexbox Alignment

Align Items (cross axis)

<View style={['alignStart']} />     // alignItems: flex-start
<View style={['alignEnd']} /> // alignItems: flex-end
<View style={['alignCenter']} /> // alignItems: center
<View style={['alignStretch']} /> // alignItems: stretch

Justify Content (main axis)

<View style={['justifyStart']} />         // justifyContent: flex-start
<View style={['justifyEnd']} /> // justifyContent: flex-end
<View style={['justifyCenter']} /> // justifyContent: center
<View style={['justifySpaceBetween']} /> // justifyContent: space-between
<View style={['justifySpaceAround']} /> // justifyContent: space-around

Align Self (self-alignment)

<View style={['alignSelfCenter']} />    // alignSelf: center
<View style={['alignSelfStart']} /> // alignSelf: flex-start
<View style={['alignSelfEnd']} /> // alignSelf: flex-end
<View style={['alignSelfStretch']} /> // alignSelf: stretch

Centering Preset

<View style={['center']} />         // alignItems: center, justifyContent: center

Advanced Flexbox

// Flex wrap
<View style={['wrap']} /> // flexWrap: wrap

// Text
<Text style={['noWrap']} /> // whiteSpace: nowrap

Text Alignment

<Text style={['textLeft']} />       // textAlign: left
<Text style={['textCenter']} /> // textAlign: center
<Text style={['textRight']} /> // textAlign: right

Spacing Variants

Spacing variants require you to place the value after the : and remember that the final result will be a multiplication of the baseSpacing value defined in theme creation.

<View style={['padding:1']} />       // padding: baseSpacing * 1
<View style={['paddingBottom:2']} /> // paddingBottom: baseSpacing * 2
<View style={['margin:2']} /> // margin: baseSpacing * 2
<View style={['marginTop:2']} /> // marginTop: baseSpacing * 2
<View style={['gap:1']} /> // gap: baseSpacing * 1

Short Variants

Spacing variants can be used with their full name, but for brevity, you can use their short version:

<View style={['p:1']} />      // Padding
<View style={['pt:1']} /> // Padding top
<View style={['pb:1']} /> // Padding bottom
<View style={['pl:1']} /> // Padding left
<View style={['pr:1']} /> // Padding right
<View style={['px:1']} /> // Padding horizontal
<View style={['py:1']} /> // Padding vertical

<View style={['m:1']} /> // Margin
<View style={['mt:1']} /> // Margin top
<View style={['mb:1']} /> // Margin bottom
<View style={['ml:1']} /> // Margin left
<View style={['mr:1']} /> // Margin right
<View style={['mx:1']} /> // Margin horizontal
<View style={['my:1']} /> // Margin vertical

Practical Example with Short Variants

// Layout using short variants for spacing
<View style={['row', 'p:2', 'gap:1', 'bg:neutralSolid100']}>
<Text style={['color:primarySolid500']}>Title</Text>
<Button style={['primary']} />
</View>

Color Variants

Color variants require you to place which color after the :

// Text color variants
<Text style={['color:neutralSolid600']} />
<Text style={['color:neutralSolid500']} />
<Text style={['color:primarySolid500']} />

// Background variants
<View style={['bg:neutralSolid600']} />
<View style={['bg:neutralSolid500']} />
<View style={['bg:primarySolid500']} />

Practical Combination Examples

Header Layout

<View style={['row', 'alignCenter', 'justifySpaceBetween', 'fullWidth', 'p:2']}>
<Text style={['h2']}>Title</Text>
<Button style={['primary']} text="Action" />
</View>

Centered Card

<View style={['center', 'fullHeight', 'p:3']}>
<View style={['relative', 'centerRow', 'gap:2', 'bg:surface', 'p:4']}>
<Icon name="check" />
<Text style={['h3', 'color:success']}>Success!</Text>
</View>
</View>

Horizontal List with Scroll

<View style={['row', 'alignCenter', 'gap:2', 'wrap', 'p:2']}>
{items.map(item => (
<Button
key={item.id}
style={['secondary', 'px:3', 'py:1']}
text={item.name}
/>
))}
</View>

Custom Component Variants

When creating a stylesheet file for a component, you can create your own variants for it, and these variants you create will be available to use through the style prop.

const createComponentVariant = createStyles<ComponentComposition>

export const ComponentStyles = {
default: createComponentVariant((theme) => ({
wrapper: {
...theme.presets.center,
...theme.presets.fullWidth,
},
})),
primary: createComponentVariant((theme) => ({
wrapper: {
backgroundColor: theme.colors.primary,
borderRadius: theme.radius.medium,
...theme.spacing.padding(2),
},
})),
outlined: createComponentVariant((theme) => ({
wrapper: {
borderWidth: 1,
borderColor: theme.colors.primary,
backgroundColor: 'transparent',
},
})),
}

You can use it in the component:

<Component style={['primary']} />
<Component style={['outlined', 'p:3']} />

The createStyles Function

createStyles is used to create custom styles that have access to the theme. It's particularly useful for styles that cannot be achieved through variants alone.

Basic Usage

import { createStyles } from '@codeleap/styles'

// Without theme access
const styles = createStyles({
imageWrapper: {
flex: 1,
height: 200,
borderRadius: 12,
},
image: {
width: '70%',
aspectRatio: 1,
},
})

Accessing Theme Properties

The createStyles function receives the application theme and with that you have access to all the functionalities we've already described in the theme section.

const styles = createStyles((theme) => ({
container: {
// Colors
backgroundColor: theme.colors.surface,
borderColor: theme.colors.primary,

// Spacing
...theme.spacing.padding(2),
...theme.spacing.marginVertical(1),

// Border radius
borderRadius: theme.radius.medium,

// Presets
...theme.presets.center,
...theme.presets.shadow,

// Custom values
height: theme.values.buttonHeight,
width: theme.values.width / 2,
},

header: {
...theme.presets.row,
...theme.spacing.paddingHorizontal(3),
backgroundColor: theme.colors.primarySolid100,
},

content: {
flex: 1,
...theme.spacing.padding(2),
},
}))

The Style Prop

The style prop is the heart of the system, accepting a flexible array of styles that can include variants, custom objects, nested styles, and responsive breakpoints.

Basic Style Prop Syntax

// Single variant as string
<View style='flex' />

// Multiple variants and utilities
<View style={['flex', 'gap:2', 'padding:1']} />

// Combining variants with custom styles
<View style={['flex', 'center', styles.customContainer]} />

Inline Style Objects

// Custom CSS directly in the prop
<View style={[
'flex',
'center',
{
backgroundColor: 'red',
borderRadius: 8,
boxShadow: '0 2px 4px rgba(0,0,0,0.1)'
}
]} />

Nested Styles

You can style directly the composition components of the main component

// Styling child elements through the parent component
<View style={[
'flex',
'center',
{
backgroundColor: 'red',

// Styles for child elements
innerWrapper: ['flex', 'center', { opacity: 0.5 }],
title: ['h1', { color: 'white', textAlign: 'center' }],
button: ['primary', { marginTop: 16 }],

// Pseudo-states
hover: { opacity: 0.8 },
active: { transform: 'scale(0.98)' },
}
]} />

Responsive Breakpoints (web only)

You can open a breakpoints object and the key will be one of the breakpoints defined in theme creation

// Different styles for different screen sizes
<View style={[
'flex',
'center',
{ backgroundColor: 'red' },
{
breakpoints: {
mobile: [
'column',
'p:2',
{ gap: 8 }
],
tablet: [
'alignStart',
'p:3',
{
backgroundColor: 'blue',
maxWidth: 768
}
],
desktop: [
'row',
'p:4',
{
padding: 20,
maxWidth: 1200,
margin: '0 auto'
}
]
}
}
]} />

Best Practices

When to Use Each Approach

Variants: For quick and direct styles

// Default variants for layout
<View style={['row', 'alignCenter', 'gap:2']} />
<Text style={['h1', 'textCenter', 'color:primary']} />

// Custom variants for specific components
<Button style={['primary']} />
<Card style={['elevated', 'rounded']} />

createStyles: For complex and custom styles that need theme access

const styles = createStyles((theme) => ({
complexLayout: {
height: theme.values.height / 3,
...theme.presets.center,
background: `linear-gradient(45deg, ${theme.colors.primary}, ${theme.colors.secondary})`,
},
}))

Inline Objects: For specific and unique adjustments

<View style={['flex', { backgroundColor: 'rgba(0,0,0,0.05)' }]} />

Combining All Approaches

// ✅ Complete example using all functionalities
<View style={[
// 1. Base variants for structure
'flex',
'column',

// 2. Short variants for quick spacing
'gap:2',
'p:2',

// 3. Custom styles from createStyles
styles.containerBase,

// 4. Inline objects for specific adjustments
{
backgroundColor: 'rgba(0,0,0,0.05)',
borderRadius: 12,

// 5. Nested styles for child elements
header: [
'row',
'alignCenter',
'justifySpaceBetween',
'pb:2',
{ borderBottomWidth: 1, borderBottomColor: '#eee' }
],

content: [
'flex',
'gap:1',
styles.contentArea
]
},

// 6. Breakpoints for responsiveness
{
breakpoints: {
mobile: [
'p:1',
{
header: ['column', 'alignStart', 'gap:1'],
content: ['gap:0.5']
}
],
desktop: [
'p:3',
{
maxWidth: 800,
margin: '0 auto'
}
]
}
}
]} />

// ✅ For simple components, keep it simple
<View style={['row', 'alignCenter', 'gap:2', 'p:2']} />
<Text style={['h1', 'textCenter', 'color:primary']} />
<Button style={['primary']} />

Final Tips

  • Prioritize variants for consistency, simplicity, and performance
  • Use createStyles when you need theme access
  • Combine approaches when necessary, but maintain readability
  • Prefer short variants (p:2 vs padding:2) for cleaner code