@cleartrip/ct-design-style-manager
@cleartrip/ct-design-style-manager
A collection of styling utilities for the Cleartrip Design System. Provides hooks and factory functions that convert style definitions into Emotion class names for web, while keeping full compatibility with the React Native style shape.
Installation
pnpm add @cleartrip/ct-design-style-manager
API Reference
makeStyles
A non-hook factory for React-Native-first styles.
Accepts a factory function that receives the current theme and returns a NamedStyles object (using ViewStyle, TextStyle, or ImageStyle properties). The styles are validated, preprocessed (RN → web conversions, shadow/textShadow expansion), and each key is converted to an Emotion class name string.
import { makeStyles } from '@cleartrip/ct-design-style-manager';
const styles = makeStyles((theme) => ({
container: {
flexDirection: 'row',
backgroundColor: theme.color.neutral_10,
padding: theme.spacing.s4,
},
title: {
fontSize: theme.font.size.large,
color: theme.color.neutral_90,
},
}));
// styles.container → 'css-<hash>'
// styles.title → 'css-<hash>'
Signature
function makeStyles<T extends NamedStyles<T>>(
styleFactory: (theme: Theme) => T | NamedStyles<T> | NamedStyles<unknown>,
customTheme?: Theme,
): T;
Use
customThemeto override the active theme (e.g. in tests or server-side rendering).
useStyles
The hook counterpart of makeStyles. Uses useTheme() to read the active theme reactively and memoises the result via useStableMemo so styles are only recomputed when deps change.
import { useStyles } from '@cleartrip/ct-design-style-manager';
function MyComponent() {
const styles = useStyles(
(theme) => ({
container: { padding: theme.spacing.s4 },
label: { color: theme.color.neutral_90 },
}),
[],
);
return <div className={styles.container}>…</div>;
}
Signature
function useStyles<T extends NamedStyles<T>>(
styleFactory: (theme: Theme) => T | NamedStyles<T> | NamedStyles<unknown>,
deps: DependencyList,
): T;
makeWebStyles new
A non-hook factory for web-only styles using standard React CSSProperties.
Unlike makeStyles, no React-Native preprocessing is applied — values are passed directly to Emotion. Use this when you are authoring web-only components and want to use standard CSS property names (e.g. backgroundColor, fontSize, display).
import { makeWebStyles } from '@cleartrip/ct-design-style-manager';
const styles = makeWebStyles((theme) => ({
container: {
display: 'flex',
gap: theme.spacing.s4,
backgroundColor: theme.color.neutral_10,
},
title: {
color: theme.color.neutral_90,
fontSize: 16,
fontWeight: 600,
},
}));
// styles.container → 'css-<hash>'
// styles.title → 'css-<hash>'
Signature
function makeWebStyles<T extends NamedWebStyles<T>>(
styleFactory: (theme: Theme) => T | NamedWebStyles<T>,
customTheme?: Theme,
): { [P in keyof T]: string };
where NamedWebStyles<T> = { [P in keyof T]: CSSProperties }.
Use
customThemeto override the active theme (e.g. in tests or SSR).
useWebStyles new
The hook counterpart of makeWebStyles. Reads the active theme via useTheme() and memoises via useStableMemo.
import { useWebStyles } from '@cleartrip/ct-design-style-manager';
function MyComponent() {
const styles = useWebStyles(
(theme) => ({
wrapper: {
display: 'flex',
flexDirection: 'column',
gap: theme.spacing.s4,
},
heading: {
color: theme.color.neutral_90,
fontSize: 20,
},
}),
[],
);
return (
<div className={styles.wrapper}>
<h1 className={styles.heading}>Hello</h1>
</div>
);
}
Signature
function useWebStyles<T extends NamedWebStyles<T>>(
styleFactory: (theme: Theme) => T | NamedWebStyles<T>,
deps: DependencyList,
): { [P in keyof T]: string };
useWebMergeStyles (deprecated)
Merges an array of style sources — existing Emotion class name strings or raw style objects — into a single Emotion class string. Only use in terminal/leaf components.
import { useWebMergeStyles } from '@cleartrip/ct-design-style-manager';
const className = useWebMergeStyles([styles.base, isActive && styles.active, propClassName], [isActive, propClassName]);
Signature
const useWebMergeStyles: <T extends Styles | string>(styles: T[], deps: DependencyList) => string;
useNativeMergeStyles (deprecated)
Merges an array of React Native StyleProp values. Only use in terminal/leaf native components.
import { useNativeMergeStyles } from '@cleartrip/ct-design-style-manager';
const merged = useNativeMergeStyles([baseStyle, conditionalStyle], [dep]);
Signature
function useNativeMergeStyles<T extends ViewStyle | ImageStyle | TextStyle>(
styles: StyleProp<T>[],
deps: DependencyList,
): StyleProp<T>;
gs — Global Layout Styles
Pre-built global layout utility class names generated once at module load time (no theme dependency). Import specific keys as needed.
import { gs } from '@cleartrip/ct-design-style-manager';
<div className={gs.flexRow}>…</div>
Choosing the right API
| Scenario | Use |
|---|---|
| Cross-platform component (web + RN) using RN-style properties | makeStyles / useStyles |
| Web-only component using standard CSS properties | makeWebStyles / useWebStyles |
| Merging multiple class names / style objects at runtime (web) | useWebMergeStyles |
| Merging multiple style objects at runtime (native) | useNativeMergeStyles |
| Static layout utilities (no theme needed) | gs |
Key differences: makeStyles vs makeWebStyles
makeStyles |
makeWebStyles |
|
|---|---|---|
| Input property type | ViewStyle / TextStyle / ImageStyle (RN) |
CSSProperties (React / web) |
| Preprocessing | RN → web conversions, shadow expansion | None — passed directly to Emotion |
| Validation | RN style validation | Not applied |
| Platform | Cross-platform | Web only |
| Output | Emotion class name strings (same key shape as input) | Emotion class name strings (same key shape as input) |