Theme

Theme at core is nothing but a collection of styles defined using the React Native's StyleSheet.create() API. The themes are defined inside the app and are completely owned by the app, not by the Stylo library. Stylo theme is based on two key concepts: StyleName & StyleNamespace.

StyleName

StyleName is the name of a standard style definition provided to the StyleSheet.create API. A unified collection of StyleNames & their style definitions results into a Theme. Any suitable naming convention can be used for the StyleNames. A common good practice is to group the style definitions per React Native component.

In the code snippet below 'Align.Center', H1, Small are the style names.

Type definition

type TTextStyle = 'Align.Center' | 'Align.Right' | 'H1' | 'H2' | 'H3' | 'Small' | 'Size.Tiny'; type TInputTextStyle = 'Align.Center' | 'Align.Right' | 'Small' | 'Size.Tiny';

The document explains the significance & usage of the type definitions in the theme in the later section. The StyleName type definitions are passed to & used by Styler hooks & Stylish components. They are not directly used in the StyleSheet.create() API.

Styles defined using the StyleNames

const TextStyles = StyleSheet.create({ Default: { color: '#000000', fontSize: 16, fontWeight: '400', lineHeight: 24 }, 'Align.Center': { textAlign: 'center' }, 'Align.Right': { textAlign: 'right' }, H1: { fontSize: 32, fontWeight: '400', lineHeight: 40, marginBottom: 16 }, H2: { fontSize: 28, fontWeight: '400', lineHeight: 36, marginBottom: 16 }, H3: { fontSize: 24, fontWeight: '400', lineHeight: 32, marginBottom: 8 }, Small: { fontSize: 12, lineHeight: 18 }, 'Size.Tiny': { fontSize: 8, lineHeight: 14 }, }); const TextInputStyles = StyleSheet.create({ Default: { borderRadius: 8, color: '#000000', fontSize: 16, paddingTop: 12, paddingBottom: 12, paddingLeft: 8, paddingRight: 8 }, 'Align.Center': { textAlign: 'center' }, 'Align.Right': { textAlign: 'right' }, Small: { fontSize: 12, paddingTop: 8, paddingBottom: 8 }, Large: { fontSize: 24, paddingTop: 16, paddingBottom: 16, paddingLeft: 10, paddingRight: 10 }, });

Reserved StyleName Default

Default is a reserved StyleName. It's used for the core React Native components like Text, View, TextInput, Image etc. Stylo applies the styles defined under Default StyleName as a default style to the components.

In the code snipper below, the style defined as Default will get applied by default to Text component.

const TextStyles = StyleSheet.create({ Default: { color: '#000000', fontSize: 16, fontWeight: '400', lineHeight: 24 }, H1: { fontSize: 32, fontWeight: '400', lineHeight: 40, marginBottom: 16 }, H2: { fontSize: 28, fontWeight: '400', lineHeight: 36, marginBottom: 16 }, ... });

import { Text } from 'react-native-stylo'; const ComponentA = () => ( <Text>React Native Stylo</Text> );

StyleNamespace

StyleNamespaces are used to organize the style definitions by logically grouping them together. Means, all style definitions for React Native's Text component can be grouped together under a namespace called TextStyles, likewise ViewStyles, TouchableStyles, TextInputStyles etc. This prevents collisions of the StyleName & eventually the collisions of styles. For example, a StyleName Small can exist for both Text & View and can have different style definitions for each. So placing these different stye definitions with same StyleName Small under separate namespaces TextStyles & ViewStyles will avoid the collision or accidental overriding of style definitions.

Stylo considers each React Native component as one StyleNamespace. To keep it simple & easily understandable, Stylo uses a pattern [ReactNativeComponentName]Styles to name the StyleNamespace. The library uses following StyleNamespaces defined for each React Native component.

type TStyleNamespace = | 'IconStyles' | 'ImageBackgroundStyles' | 'ImageStyles' | 'SafeAreaViewStyles' | 'ScrollViewStyles' | 'ScrollViewContentContainerStyles' | 'TextInputStyles' | 'TextStyles' | 'TouchableStyles' | 'ViewStyles';

Note: New StyleNamespaces for remaining components will be added soon.

The styles are defined and assigned to these namespaces. And then are used to define a theme.

const TextStyles = StyleSheet.create({ ... }); const IconStyles = StyleSheet.create({ ... }); const ImageBackgroundStyles = StyleSheet.create({ ... }); // & so on ... const Theme = { TextStyles, IconStyles, ImageBackgroundStyles, ... };

The approach of one namespace per React Native component makes it highly scalable & easily manageable. New namespaces for remaining or new ReactNative components can be added without impacting existing onces. Stylo uses these namespaces by default.

Variables

Variables are the core configuration values which are used to define the styles. Like, colors, paddings, margins etc. These variable definitions can look like below.

Type definition

export type TVariable = | 'Color.Primary' | 'Color.Secondary' | 'Padding' | 'Padding.Small' | 'Padding.Large' | 'Border.Radius';

The document explains the significance & usage of the type definitions in the theme in the later section. The variables type definitions are passed to & used by useVariables() hook.

Variable values

const variables = { 'Color.Primary': '#000000', 'Color.Secondary': '#888888', 'Border.Radius': 6, Padding: 12, 'Padding.Small': 8, 'Padding.Large': 24, };

Type definitions

Thanks to TypeScript, the StyleNames & Variables are strongly typed. The type definitions are passed to & used by useVariables() hook, Styler hooks & Stylish components. This completely avoids accidental usage of wrong StyleNames & Variables, out of the box. On top of that, the StyleNames are strongly typed against each React Native component, like View, Text, TouchableOpacity etc. This adds an extra level of strong typing which forces to use only those values which are intended for a particular component.

Variables type definition

type TFontColorStyle = 'Color.Primary' | 'Color.Secondary' | 'Color.Info' | 'Color.Warning' | 'Color.Danger' | 'Color.Border' | 'Color.Grey1' | 'Color.Grey2' | 'Color.Grey1' | ... ; type TBackgroundColorStyle = 'BackgroundColor.Primary' | 'BackgroundColor.Secondary' | 'BackgroundColor.Info' | 'BackgroundColor.Warning' | 'BackgroundColor.Danger' | 'BackgroundColor.Grey1' | 'BackgroundColor.Grey2' | 'BackgroundColor.Grey1' | ... ; type TPaddingStyle = 'Padding' | 'Padding.Small' | 'Padding.Large'; type TMarginStyle = 'Margin' | 'Margin.Small' | 'Margin.Large'; type TBorderStyle = 'Border.Radius' | 'Border.Radius.Small' | 'Border.Radius.Large'; ... export type TVariable = TFontColorStyle | TBackgroundColorStyle | TPaddingStyle | TMarginStyle | TBorderStyle | ...;

StyleName type definition

type TBorderStyle = 'Border' | 'Border.Top' | 'Border.Right' | 'Border.Bottom' | 'Border.Left' | 'Border.Radius' | 'Border.Radius.Small' | 'Border.Radius.Large' | 'Border.Color.Primary' | 'Border.Color.Secondary' | 'Border.Color.Info' | 'Border.Color.Warning' | 'Border.Color.Danger' | 'Border.Color.Grey1' | 'Border.Color.Grey2' | ...; export type TTextStyle = TFontColorStyle | 'Align.Center' | 'Align.Right' | 'Bold' | 'H1' | 'H2' | 'H3' | 'H4' | 'Small' | 'Large' | 'Paragraph' | 'Margin' | 'Margin.Top' | 'Margin.Right' | 'Margin.Bottom' | 'Margin.Left' | 'Margin.Mini' | 'Margin.Small' | 'Margin.Large' | 'Margin.Top.Small' | 'Margin.Right.Small' | 'Margin.Bottom.Small' | 'Margin.Left.Small' | 'Margin.Top.Mini' | 'Margin.Right.Mini' | 'Margin.Bottom.Mini' | 'Margin.Left.Mini' | 'Margin.Top.Large' | 'Margin.Right.Large' | 'Margin.Bottom.Large' | 'Margin.Left.Large'; export type TViewStyle = TBackgroundColorStyle | TPaddingStyle | TMarginStyle | TBorderStyle | ...; export type TTouchableStyle = TBackgroundColorStyle | TPaddingStyle | TMarginStyle | TBorderStyle | 'Button' | 'Button.Small' | 'Button.Large' | 'Button.Round' | 'Button.Circle' | ...; ...

Intellisense friendly styles

The Variables & StyleNames are intellisense friendly, it helps you choose correct styles & values.

E.g. Alignment styles for View & Text are different. As you start typing the alignment styles, the editor intellisense helps you choose correct styles for View & Text.

Strongly typed styles: ViewStrongly typed styles: Text