Using sloth-ui-mobile
This skill provides instructions for using the @rapid-recovery-agency-inc/sloth-ui-mobile design system library in a React Native app.
For the complete component catalog and Figma design links, see references/component-catalog.md. If you need UI components from react-native core, review the component catalog first.
Preferences
- SHOULD AVOID using hardcoded color values (hex, rgb, rgba) in styles. Use theme color tokens instead.
- SHOULD AVOID using inline styles. Use
createThemeStyleSheet+useThemedStylesinstead. - SHOULD AVOID creating styles with
font-*orcolorproperties directly. UseMainTextor theme tokens. - SHOULD AVOID using deprecated components.
- PREFER importing all components from
'@rapid-recovery-agency-inc/sloth-ui-mobile'. - PREFER using
createThemeStyleSheetinstead ofStyleSheet.createto ensure theme compatibility. - PREFER using
MainTextfor all text rendering, never raw<Text>from React Native. - PREFER using the
themeColorprop onMainTextandIcon— thecolorprop is deprecated on both. - PREFER using
<Background>and<Container>for layout structure instead of manually setting background colors on<View>. - PREFER using the
LoaderV2component instead ofActivityIndicator. - PREFER using the
DividerV2component instead of a custom view. - PREFER using the
Buttoncomponent instead ofTouchableOpacity.
Theming System
The library uses semantic color tokens that automatically resolve to light/dark mode values. The theming pipeline is:
createThemeStyleSheet → useThemedStyles → resolved StyleSheet
Step 1: Define Styles with createThemeStyleSheet
Define styles outside the component. Use theme token names (strings) for any color-related property instead of hardcoded hex values.
Token-supported properties: color, backgroundColor, borderColor, borderTopColor, borderRightColor, borderBottomColor, borderLeftColor, shadowColor, textDecorationColor, textShadowColor, tintColor, overlayColor.
import {
createThemeStyleSheet,
DeviceSize,
} from "@rapid-recovery-agency-inc/sloth-ui-mobile";
const styleSheet = createThemeStyleSheet({
container: {
backgroundColor: "bgSurfaceBase", // theme token, NOT a hex value
padding: 16,
},
titleContainer: {
marginBottom: 12,
flexDirection: "row",
alignItems: "center",
backgroundColor: "bgSurfaceElevated",
[DeviceSize.LG]: {
padding: 24,
},
},
});
Step 2: Consume Styles with useThemedStyles
Call useThemedStyles inside the component. It resolves theme tokens to actual colors AND applies responsive breakpoints.
import { useThemedStyles } from '@rapid-recovery-agency-inc/sloth-ui-mobile';
const MyComponent = () => {
const styles = useThemedStyles(styleSheet);
return <View style={styles.container}>...</View>;
};
Dynamic Styles (Factory Pattern)
useThemedStyles accepts either a style object or a factory function. The factory function receives the current colors object, allowing for dynamic logic:
import { useThemedStyles, createThemeStyleSheet } from '@rapid-recovery-agency-inc/sloth-ui-mobile';
const MyComponent = ({ isActive }) => {
const styles = useThemedStyles((colors) => ({
container: {
backgroundColor: isActive ? colors.bgBrandSoft : colors.bgSurfaceBase,
borderWidth: 1,
borderColor: colors.uiPrimary,
},
}));
return <View style={styles.container} />;
};
Using Colors Outside Styles
Don't use useThemeColor when you need a color value, create a new class object inside of createThemeStyleSheet and use it.
PREFER. useTheme() to get the colors object.
import {
createThemeStyleSheet,
useThemedStyles,
useTheme,
Background,
MainText,
Icon
} from "@rapid-recovery-agency-inc/sloth-ui-mobile";
const Component = () => {
const { colors } = useTheme();
const styles = useThemedStyles(styleSheet);
return (
<Background style={styles.background}>
<MainText themeColor="fgPrimary" type="BOOK_LG">Content here</MainText>
<Icon iconName="check" size={18} color={colors.fgPrimary} />
</Background>
);
}
const styleSheet = createThemeStyleSheet({
background: {
backgroundColor: "bgSurfaceElevated", // theme token string, NOT a hex value
padding: 16,
},
});
In this example, MainText should still use themeColor because that API accepts a token. The Icon uses color={colors.fgPrimary} only to demonstrate the fallback pattern for APIs that need a resolved color value.
Theme Color Tokens
Tokens follow a naming convention: {category}{Semantic}.
| Category | Purpose | Examples |
|---|---|---|
bg* |
Background colors | bgSurfaceBase, bgSurfaceElevated, bgPrimaryElevated, bgAccent, bgBrandSoft, bgErrorSoft, bgSuccessSoft, bgWarningSoft, bgModal |
fg* |
Foreground colors (text & icons) | fgPrimary, fgSecondary, fgBrandContrast, fgAlwaysWhite, fgAlwaysBlack, fgErrorContrast, fgSuccessContrast, fgWarningContrast |
ui* |
Dual-purpose colors (bg or fg) | uiBrandSolid, uiPrimary, uiSecondary, uiErrorSolid, uiSuccessSolid, uiWarningSolid |
Special tokens: transparent (always transparent), bgPositionGold/Silver/Bronze (leaderboard).
Responsive Styles
useThemedStyles handles responsiveness automatically. Define breakpoint-specific overrides using DeviceSize keys inside any style:
import {
createThemeStyleSheet,
DeviceSize,
} from "@rapid-recovery-agency-inc/sloth-ui-mobile";
const styleSheet = createThemeStyleSheet({
container: {
padding: 16, // default (all sizes)
[DeviceSize.MD]: { padding: 24 }, // tablets
[DeviceSize.LG]: { padding: 32 }, // large tablets
},
});
Breakpoints: XS (<400px), SM (≤700px), MD (700-1024px), LG (1024-1200px), XL (≥1200px).
Device-Adaptive Component Rendering
Use selectRenderV2 to render entirely different components for phone vs tablet:
import { selectRenderV2 } from '@rapid-recovery-agency-inc/sloth-ui-mobile';
const MyScreen = () => selectRenderV2({
NormalComponent: <PhoneLayout />,
LargeComponent: <TabletLayout />,
});
LargeComponent renders on MD, LG, XL. NormalComponent renders on XS, SM.
Responsive Breakpoints
| Breakpoint | Condition | Use Case |
|---|---|---|
XS |
<400px |
Mobile phones |
SM |
≤700px |
Mobile phones |
MD |
700-1024px |
Tablets |
LG |
1024-1200px |
Large tablets |
XL |
≥1200px |
Extra large tablets |
PREFER using for responsive design isLargeDevice over DeviceSize.
Layout Components
Two backbone components ensure consistent background coloring and Dark Mode support for layout structure.
<Background>
Represents the base background of a screen or section.
- Default style:
backgroundColor: 'bgSurfaceBase' - Use case: Top-level wrappers for screens
<Container>
Represents a content block or card-like container.
- Default style:
backgroundColor: 'bgSurfaceElevated' - Use case: Cards, sections, list items
- Supports border shorthand props for quick styling
Border Props (all use uiPrimary color by default):
borderTop, borderBottom, borderLeft, borderRight, borderHorizontal, borderVertical, borderAll
Allowed Style Props (both components accept ContainerViewStyle — layout properties only):
padding, margin (and variations), flex, flexDirection, justifyContent, alignItems, width, height, gap, borderRadius
import { Background, Container, useThemedStyles, createThemeStyleSheet, MainText } from '@rapid-recovery-agency-inc/sloth-ui-mobile';
const Component = () => {
const styles = useThemedStyles(styleSheet);
return (
<Background style={styles.background}>
<Container borderBottom style={styles.container}>
<MainText themeColor="fgPrimary" type="BOOK_LG">Content here</MainText>
</Container>
</Background>
)
}
const styleSheet = createThemeStyleSheet({
background: {
flex: 1,
},
container: {
padding: 16,
},
});
Text Component
MUST use MainText for all text. Never use React Native's <Text> directly.
import { MainText } from '@rapid-recovery-agency-inc/sloth-ui-mobile';
<MainText type="BOLD_LG" themeColor="fgPrimary">Hello</MainText>
<MainText type="BOOK_SM" themeColor="fgSecondary">Subtitle</MainText>
<MainText type="BLACK_XL" themeColor="fgBrandContrast">Heading</MainText>
Text Type Format
{Weight}_{Size} where:
- Weights:
BLACK(900),BOLD(700),BOOK(400) - Sizes:
XXS(10px),XS(12px),SM(14px),MD(16px),LG(18px),XL(20px),XL2(22px),XL3(24px),XL4(26px),XL5(32px),XL6(40px),XL7(48px),XL8(64px)
Font family: CircularStd (Black, Bold, Book).
Text Color
// ❌ Deprecated
<MainText color="primary" type="BOOK_LG">Hello</MainText>
// ✅ Correct
<MainText themeColor="fgPrimary" type="BOOK_LG">Hello</MainText>
Icon Component
MUST use themeColor prop. The color prop is deprecated.
import { Icon } from '@rapid-recovery-agency-inc/sloth-ui-mobile';
// ❌ Deprecated
<Icon iconName="user" color="#000" />
<Icon iconName="clock" color={Color.GRAY2} />
// ✅ Correct
<Icon iconName="user" themeColor="fgPrimary" />
<Icon iconName="clock" themeColor="fgSecondary" solid />
Button Component
Buttons use theme colors internally for backgrounds and text.
import { Button } from '@rapid-recovery-agency-inc/sloth-ui-mobile';
<Button text="Save" color="blue" size="lg" variant="solid" />
<Button text="Cancel" color="grey" variant="transparent" />
<Button text="Delete" color="red" size="sm" loading={isDeleting} />
<Button leftIcon="plus" text="Add" color="green" />
Props:
size:'xl'|'lg'(default) |'sm'color:'blue'(default) |'grey'|'green'|'orange'|'red'variant:'solid'(default) |'transparent'loading: shows spinner, disables pressdisabled: reduces opacity, disables pressleftIcon/rightIcon: FontAwesome icon name (mutually exclusive)
Note:
MainButtonandPlainButtonare deprecated. UseButtonfor all new code.
Common Components Quick Reference
| Component | Use Case | Key Props |
|---|---|---|
MainText |
Text rendering | type, themeColor |
Button |
Actions, CTAs | text, color, size, variant, onPress |
Icon |
FontAwesome icons | iconName, size, themeColor, solid |
Background |
Screen base wrapper | style (layout props only) |
Container |
Card / content block | style, borderTop, borderBottom, ... |
InputField / Input |
Text input | Standard input props |
Dropdown |
Select dropdown | Options, selection callbacks |
Pill |
Status labels | color, variant, size |
Avatar / AvatarRow |
User avatars | Name, image, size |
DividerV2 |
Visual separators | — |
LoaderV2 |
Loading indicators | — |
ConfirmationModal |
Confirm/cancel dialogs | title, message, onConfirm |
MainModal |
General modal | isVisible, onClose |
Checkbox / Radio |
Selection controls | checked, onChange, size |
Toggle |
On/Off switch | — |
DatePicker |
Date range selection | Date range model |
BlueTabs / FloatingTabs / SimpleTabs |
Tab navigation | Tab items, selection |
Carousel / GridCarousel |
Image/card carousel | Items array |
StatsCardBlue / StatsCardWhite |
Dashboard stat cards | Value, label, tendency |
NotesSection |
Notes display | Notes data |
UserDetails |
User info display | Name, avatar, size |
Complete Example
import {
createThemeStyleSheet,
useThemedStyles,
MainText,
Button,
Pill,
Icon,
Background,
Container,
DeviceSize,
} from '@rapid-recovery-agency-inc/sloth-ui-mobile';
import { View } from 'react-native';
export const VehicleCard = ({ vehicle, onSpot }: VehicleCardProps) => {
const styles = useThemedStyles(styleSheet);
return (
<Background style={styles.background}>
<Container borderBottom style={styles.card}>
<View style={styles.header}>
<MainText type="BOLD_LG" themeColor="fgPrimary">{vehicle.make}</MainText>
<Pill color="green" variant="soft" size="sm">{vehicle.status}</Pill>
</View>
<MainText type="BOOK_SM" themeColor="fgSecondary">{vehicle.plate}</MainText>
<View style={styles.actions}>
<Icon iconName="camera" size={18} themeColor="fgSecondary" solid />
<Button
text="Spot Vehicle"
color="blue"
size="lg"
leftIcon="camera"
/>
</View>
</Container>
</Background>
);
};
const styleSheet = createThemeStyleSheet({
background: {
flex: 1,
},
card: {
padding: 16,
[DeviceSize.MD]: { padding: 24 },
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 8,
},
actions: {
marginTop: 16,
paddingTop: 16,
gap: 12,
},
});
Deprecated APIs
| Deprecated | Replacement |
|---|---|
MainButton / PlainButton |
Button |
Color constant object |
ThemeColor tokens via createThemeStyleSheet |
StyleSheet.create() |
createThemeStyleSheet() |
createResponsiveStyles() |
createThemeStyleSheet() (has responsive built-in) |
useResponsiveStyles() |
useThemedStyles() (has responsive built-in) |
selectRender() |
selectRenderV2() |
MainText color prop |
MainText themeColor prop |
Icon color prop |
Icon themeColor prop |