native-variants
Version:
A library for handling variants in React Native components with theme support.
151 lines • 4.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.cn = cn;
exports.cnView = cnView;
exports.cnText = cnText;
exports.cnImage = cnImage;
/**
* Flattens a potentially nested style into an array of style objects.
* Handles arrays, nested arrays, and single style objects.
*
* @template T - The style type
* @param style - The style to flatten
* @returns An array of flattened style objects
*/
function flattenStyle(style) {
if (!style)
return [];
if (Array.isArray(style)) {
const result = [];
for (let i = 0; i < style.length; i++) {
const item = style[i];
if (item) {
if (Array.isArray(item)) {
// Handle nested arrays
const nested = flattenStyle(item);
for (let j = 0; j < nested.length; j++) {
result.push(nested[j]);
}
}
else {
result.push(item);
}
}
}
return result;
}
return [style];
}
/**
* Merges multiple style objects into a single style object.
* Optimized for performance with early returns and efficient iteration.
*
* @template T - The output style type
* @param styles - Array of styles to merge
* @returns A single merged style object
*/
function mergeStyles(styles) {
if (styles.length === 0)
return {};
if (styles.length === 1 && styles[0] && typeof styles[0] === "object") {
return styles[0];
}
const result = {};
for (let i = 0; i < styles.length; i++) {
const style = styles[i];
if (!style || typeof style !== "object")
continue;
const keys = Object.keys(style);
for (let j = 0; j < keys.length; j++) {
const key = keys[j];
const value = style[key];
if (value !== undefined) {
result[key] = value;
}
}
}
return result;
}
/**
* Combines multiple style objects into a single merged style.
* Supports React Native StyleProp, animated styles from react-native-reanimated,
* and regular style objects.
*
* Features:
* - Handles nested style arrays
* - Compatible with react-native-reanimated animated styles
* - Filters out null/undefined values
* - Returns a properly typed style object
*
* @param styles - Variable number of style inputs to merge
* @returns A single merged style object
*
* @example
* ```ts
* // Basic usage
* const style = cn(styles.root, { padding: 16 });
*
* // With animated styles (react-native-reanimated)
* const animatedStyle = useAnimatedStyle(() => ({
* transform: [{ translateX: translateX.value }],
* }));
* const style = cn(styles.wrapper, animatedStyle);
*
* // Multiple styles
* const style = cn(
* baseStyles,
* conditionalStyles,
* { opacity: isVisible ? 1 : 0 }
* );
* ```
*/
function cn(...styles) {
const flattened = [];
for (let i = 0; i < styles.length; i++) {
const style = styles[i];
if (!style)
continue;
if (Array.isArray(style)) {
const nested = flattenStyle(style);
for (let j = 0; j < nested.length; j++) {
if (nested[j])
flattened.push(nested[j]);
}
}
else if (typeof style === "object") {
flattened.push(style);
}
}
return mergeStyles(flattened);
}
/**
* Type-safe version of cn specifically for ViewStyle.
* Use this when you need explicit ViewStyle typing.
*
* @param styles - Variable number of style inputs to merge
* @returns A merged ViewStyle object
*/
function cnView(...styles) {
return cn(...styles);
}
/**
* Type-safe version of cn specifically for TextStyle.
* Use this when you need explicit TextStyle typing.
*
* @param styles - Variable number of style inputs to merge
* @returns A merged TextStyle object
*/
function cnText(...styles) {
return cn(...styles);
}
/**
* Type-safe version of cn specifically for ImageStyle.
* Use this when you need explicit ImageStyle typing.
*
* @param styles - Variable number of style inputs to merge
* @returns A merged ImageStyle object
*/
function cnImage(...styles) {
return cn(...styles);
}
//# sourceMappingURL=cn.js.map