@chipmobilesdk/rn-theme
v0.2.2
Published
Reusable React Native theme generation and token contracts for ChipMobileSdk-family mobile apps.
Readme
@chipmobilesdk/rn-theme
Reusable React Native theme generation and token contracts for ChipMobileSdk-family mobile apps.
License:
UNLICENSED. Published publicly for use by the owner's applications; no open-source license is granted.
- Version:
0.2.0 - Entrypoint:
@chipmobilesdk/rn-theme - Demo:
src/screens/ExampleScreen.tsx
Install
Install the package from the public npm registry, then install the host styling dependencies in the consuming app:
npm install @chipmobilesdk/rn-theme react-native-unistylesThe host app owns react, react-native, and react-native-unistyles. If the app uses a safe-area shell like the ChipMobileSdk demo, install react-native-safe-area-context in the app as an app dependency. The theme package itself does not import safe-area APIs.
Compatibility
The current ChipMobileSdk demo validates against:
- React
19.2.3 - React Native
0.85.3 - React Native Unistyles
^3.2.5 - TypeScript
^5.8.3 - Node.js
>=22.11.0 - Android and iOS host apps supported by the current React Native/Unistyles setup
The package is TypeScript-only and does not include native Android or iOS code, permissions, entitlements, analytics, tracking, billing, storage, or network behavior.
Setup Order
Create app-owned brand values:
import type { BrandColors, TypographyConfig } from '@chipmobilesdk/rn-theme';
export const BRAND_COLORS: BrandColors = {
primary: '#046b63',
secondary: '#625b71',
tertiary: '#7d5260',
};
export const BRAND_TYPOGRAPHY: TypographyConfig = {
fontFamily: 'System',
baseFontSize: 16,
fontScale: 1,
};Configure Unistyles before any themed component renders:
import { StyleSheet } from 'react-native-unistyles';
import { createUnistylesConfig } from '@chipmobilesdk/rn-theme';
import type { UnistylesThemeFromBrand } from '@chipmobilesdk/rn-theme';
import { BRAND_COLORS, BRAND_TYPOGRAPHY } from './brand';
declare module 'react-native-unistyles' {
export interface UnistylesThemes extends UnistylesThemeFromBrand {}
}
StyleSheet.configure(
createUnistylesConfig(
{
brandColors: BRAND_COLORS,
typographyConfig: BRAND_TYPOGRAPHY,
},
{ initialTheme: 'dark' },
),
);Import the setup module first in the app entrypoint.
Theme Start Strategy
Choose exactly one startup strategy.
Manual initial theme:
createUnistylesConfig(config, { initialTheme: 'light' });System adaptive themes:
createUnistylesConfig(config, { adaptiveThemes: true });Using initialTheme and adaptiveThemes: true together is invalid. Persisting a user theme preference, if needed, belongs in the consuming app.
Unistyles 3 Style Authoring and TypeScript Diagnostics
Style arrays and variants solve different problems
Unistyles 3 supports React Native's array syntax and recommends it when merging independent styles because the array preserves merge order and each style's attached Unistyles state:
<View style={[styles.container, styles.emphasis]} />Do not merge Unistyles entries with object spread. After a stylesheet recalculation, Unistyles may no longer know the intended override order.
Use styles.useVariants(...) instead when a finite component prop or state such as
selected, disabled, or size changes one or more style entries. Variants model
semantic component states; they are not a replacement for every style array.
If a valid array does not typecheck, inspect the inferred type of every entry. A member may be a dynamic function that was not called, or TypeScript may have widened a mixed stylesheet to an object/function union. Fix that inference instead of casting the array.
Dynamic functions and inference
Unistyles supports static objects and dynamic functions, including both in one
stylesheet. Call a dynamic entry before passing it to a style prop, and pass only
serializable arguments:
<View style={[styles.container, styles.sized(width)]} />If TypeScript widens sibling entries to a union such as
UnistylesValues | ((...) => UnistylesValues), move the dynamic entries into a separate
StyleSheet.create call. This is a TypeScript inference workaround, not an Unistyles
runtime restriction. Prefer variants for a finite set of states and dynamic functions
for open-ended values such as a measured width.
Localize vague TypeScript errors
Keep stylesheets at module scope. When TypeScript reports a vague error at every JSX
use instead of at the invalid style property, temporarily move the relevant
StyleSheet.create declaration above the component or extract the suspect entries into
a smaller stylesheet. This often makes inference fail at the actual initializer. It is
a debugging technique, not a required declaration order; the real runtime ordering rule
remains that StyleSheet.configure must run before importing themed components.
See the official Unistyles 3 guidance for merging styles, variants, and dynamic functions.
Public Runtime Exports
createUnistylesConfig(config, options?)generateLightPalette(brandColors)generateDarkPalette(brandColors)
Public Type Exports
BrandColorsThemeColorsTypographyConfigTypographyTokenTypographySpacingTokensRadiusTokensShadowTokenShadowTokensZIndexTokensDeepPartialStyleConfigStyleThemeUnistylesThemesUnistylesConfigOptionsUnistylesConfigUnistylesThemeFromBrand
Private Modules
Only @chipmobilesdk/rn-theme is public. Imports from @chipmobilesdk/rn-theme/src/..., @chipmobilesdk/rn-theme/utils/..., @chipmobilesdk/rn-theme/tokens/..., @chipmobilesdk/rn-theme/types/..., or @chipmobilesdk/rn-theme/unistyles/... are unsupported.
Configuration Validation
The package validates required brand colors, positive typography values, valid color strings, and invalid theme-start combinations before returning a Unistyles config. Missing optional typography fields use documented defaults.
Dependency Classification
dependencies: runtime implementation packages imported by package code, currentlytinycolor2.peerDependencies: host framework/integration packages supplied by each app:react,react-native, andreact-native-unistyles.devDependencies: package-local type and validation tooling such as@types/tinycolor2.react-native-safe-area-context: app/demo dependency only, because the package does not import it.
Release Validation
Run from the repository root:
npm run lint
npm test
npm run typecheck
npm run typecheck:theme
npm run pack:themeRecord Android and iOS demo evidence under specs/001-enhance-theme-package/validation/ before another app adopts the package.
Semver and Migration
- Patch: internal fix with no public shape or behavior change.
- Minor: backward-compatible public additions or documentation/package metadata improvements.
- Major: removed export, renamed token, changed token shape, changed default semantics, or changed required consumer setup.
Breaking changes require migration notes and a deprecation decision before release.
