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.tsornode_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:disabledonly 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'