Skip to main content

Component Stylesheet

After creating a component, you must create its stylesheet. Stylesheets contain all component variants, with specific styling for each element of its composition.

What are Stylesheets

Stylesheets are files that define the visual variants of a component. They allow you to create different styles (the default, or variants like primary/secondary, etc.).

Basic Structure

⚠️ IMPORTANT: The default variant is mandatory and necessary for the stylesheet to work. The default variant is the default style that will always be applied to the component, and the created variants can modify this default style.

import { createStyles } from '@codeleap/styles'
import { ComponentComposition } from '@codeleap/mobile'
import { StyleRegistry } from '../styles'

const createComponentVariant = createStyles<ComponentComposition>

export const ComponentStyles = {
default: createComponentVariant((theme) => ({
wrapper: {
...theme.presets.center,
...theme.presets.fullWidth,
},
text: {
...theme.presets.textCenter,
...theme.presets.fullWidth,
...theme.spacing.paddingVertical(2),
},
})),
}

StyleRegistry.registerVariants('Component', ComponentStyles)

Stylesheet Anatomy

1. Creating the Variant Creator

const createComponentVariant = createStyles<ComponentComposition>

createStyles is a generic function that receives the component's composition type and returns a function to create typed variants.

2. Defining Variants

export const ComponentStyles = {
default: createComponentVariant((theme) => ({
wrapper: {
backgroundColor: theme.colors.surface,
padding: theme.spacing.value(2),
},
content: {
fontSize: theme.typography.defaults.fontSize,
},
})),

primary: createComponentVariant((theme) => ({
wrapper: {
backgroundColor: theme.colors.primary,
borderRadius: theme.radius.large,
},
content: {
color: theme.colors.onPrimary,
fontWeight: '600',
},
})),
}

3. StyleRegistry Registration

StyleRegistry.registerVariants('ComponentName', ComponentStyles)

Using the Theme

Inside the variant function, you have complete access to the theme:

createComponentVariant((theme) => ({
wrapper: {
// Colors
backgroundColor: theme.colors.surface,
borderColor: theme.colors.primary,

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

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

// Presets (useful functions)
...theme.presets.center,
...theme.presets.shadow,

// Custom values
height: theme.values.buttonHeight,
},
}))

Composition Slot Names and State Keys

For composed components, the stylesheet must follow the exact composition contract for that specific component.

Where to find that contract:

  • library/package component: inspect the installed source, usually in node_modules/@codeleap/mobile/src/components/ComponentName/styles.ts or node_modules/@codeleap/web/...
  • project component: inspect the project stylesheet file, where the composition type usually lives beside the variant declarations

That means:

  • import the exact composition type
  • create the variant creator with createStyles<CompositionType>
  • style only the declared slots
  • use state keys like slot:disabled only when that composition supports them
import { createStyles } from '@codeleap/styles'
import { ActionIconComposition } from '@codeleap/mobile'

const createActionIconVariant = createStyles<ActionIconComposition>

export const ActionIconStyles = {
default: createActionIconVariant((theme) => ({
touchableWrapper: {
...theme.presets.center,
...theme.spacing.padding(1),
borderRadius: theme.radius.full,
},
'touchableWrapper:disabled': {
opacity: 0.4,
},
icon: {
color: theme.colors.textHeadingRegular,
},
'icon:disabled': {
color: theme.colors.textDisabled,
},
})),
}

ActionIcon is only an example of the rule. Do not copy its keys into another component unless that other component exposes the same composition contract.

Do not invent keys from memory such as wrapperDisabled, buttonIcon, or any other slot that is not part of the real composition type.

Export

After finishing the stylesheet creation, you need to export the Stylesheet in the index, example:

// ...other exports
export { SortablePhotosStyles } from './SortablePhotos'
export { TabsStyles } from './Tabs'
export { CalendarInputStyles } from './CalendarInput'
export { TimeInputStyles } from './TimeInput'
// export the new stylesheet:
export { ComponentStyles } from './Component'