UNPKG

native-variants

Version:

A library for handling variants in React Native components with theme support.

215 lines (214 loc) 9.18 kB
import type { Base, ColorSchemeConfig, Config, ConfigWithUtils, DefaultVariants, DefaultVariantsWithUtils, UtilsConfig, Variants, VariantsWithUtils } from "../types.js"; import { tailwindColors, tailwindSpacing, tailwindFontSizes, tailwindRadii, tailwindShadows, tailwindZIndex, tailwindOpacity, tailwindLineHeights, tailwindFontWeights, tailwindLetterSpacing, tailwindBorderWidths, tailwindDurations } from "../tokens/default-tokens.js"; /** * Creates a styled component function with variant support. * Provides caching for optimal performance in React Native. * * @template S - Union type of slot names * @template V - Variants configuration type * * @param config - The styled component configuration * @returns A function that computes styles based on variant props * * @example * ```ts * const buttonStyles = styled({ * slots: ["root", "text"], * base: { * root: { padding: 16 }, * text: { fontSize: 14 } * }, * variants: { * size: { * small: { root: { padding: 8 } }, * large: { root: { padding: 24 } } * } * }, * defaultVariants: { * size: "small" * } * }); * * // Usage * const styles = buttonStyles({ size: "large" }); * ``` */ export declare function styled<const S extends string, V extends Variants<S>>(config: Config<S, V>): (props?: DefaultVariants<S, V>) => Base<S>; /** * Validates that two record types have the same keys. * Returns true type if valid, error message type if not. */ type ValidateColorKeys<D extends Record<string, string>, K extends Record<string, string>> = Exclude<keyof K, keyof D> extends never ? Exclude<keyof D, keyof K> extends never ? true : { _error: "⚠️ 'dark' is missing colors that exist in 'default'"; missingInDark: Exclude<keyof D, keyof K>; } : { _error: "⚠️ 'default' is missing colors that exist in 'dark'"; missingInDefault: Exclude<keyof K, keyof D>; }; /** * Theme configuration input for createNVA. * Colors must have matching keys in default and dark. */ interface CreateNVATheme<D extends Record<string, string>, K extends Record<string, string>> { colors: { /** Light theme colors (default) */ default: D; /** Dark theme colors - must have exactly the same keys as default */ dark: ValidateColorKeys<D, K> extends true ? K : ValidateColorKeys<D, K>; }; } /** * Creates a themed NVA (Native Variants API) instance. * Provides a styled function with access to theme tokens and custom utils. * * Colors support light/dark mode via `default` and `dark` keys. * Both must have the same color keys for type safety - TypeScript will * error if dark is missing any keys from default or vice versa. * * Utils are style shortcuts that expand to multiple CSS properties. * They work like Stitches utils - you define them once and use them * throughout your styles. * * Tailwind CSS tokens (spacing, fontSizes, radii, etc.) are included by default. * * @template D - Default colors type (inferred from colors.default) * @template K - Dark colors type (must have same keys as D) * @template U - Utils configuration type * * @param options - Configuration options * @param options.theme - Theme configuration with colors (default/dark) * @param options.utils - Custom style utilities (like Stitches) * @returns An object containing the flattened theme, styled function, and utils * * @example * ```ts * const { styled, theme, colorScheme, utils } = createNVA({ * theme: { * colors: { * default: { * primary: "#007AFF", * background: "#FFFFFF", * }, * dark: { * primary: "#0A84FF", * background: "#000000", * }, * }, * }, * utils: { * // Margin shortcuts * mx: (value) => ({ marginLeft: value, marginRight: value }), * my: (value) => ({ marginTop: value, marginBottom: value }), * // Padding shortcuts * px: (value) => ({ paddingLeft: value, paddingRight: value }), * py: (value) => ({ paddingTop: value, paddingBottom: value }), * // Size shortcut * size: (value) => ({ width: value, height: value }), * }, * }); * * // Use utils in your styles! * const buttonStyles = styled((ctx, t) => ctx({ * slots: ["root"], * base: { * root: { * backgroundColor: t.colors.primary, * px: 16, // → paddingLeft: 16, paddingRight: 16 * py: 12, // → paddingTop: 12, paddingBottom: 12 * }, * }, * })); * ``` */ export declare function createNVA<D extends Record<string, string>, K extends Record<string, string> = D, U extends UtilsConfig = {}>(options?: { theme?: CreateNVATheme<D, K>; utils?: U; }): { /** * The resolved theme object with flattened colors. * Colors use the default (light) scheme. * Use ThemeProvider to access dark mode colors. */ theme: { /** * Colors: User-defined semantic colors merged with Tailwind palette. * User colors override Tailwind colors if keys conflict. */ colors: typeof tailwindColors & D; /** Spacing scale (0, px, 0.5, 1, 2, 4, 8, etc.) */ spacing: typeof tailwindSpacing; /** Font size scale (xs, sm, base, lg, xl, 2xl, etc.) */ fontSizes: typeof tailwindFontSizes; /** Border radius scale (none, sm, md, lg, xl, full, etc.) */ radii: typeof tailwindRadii; /** Shadow definitions for iOS and Android */ shadows: typeof tailwindShadows; /** Z-index scale (0, 10, 20, 30, 40, 50) */ zIndex: typeof tailwindZIndex; /** Opacity scale (0, 5, 10, ..., 95, 100) */ opacity: typeof tailwindOpacity; /** Line height scale (3, 4, ..., 10, none, tight, normal, etc.) */ lineHeights: typeof tailwindLineHeights; /** Font weight scale (thin, light, normal, medium, bold, etc.) */ fontWeights: typeof tailwindFontWeights; /** Letter spacing scale (tighter, tight, normal, wide, wider, widest) */ letterSpacing: typeof tailwindLetterSpacing; /** Border width scale (0, DEFAULT, 2, 4, 8) */ borderWidths: typeof tailwindBorderWidths; /** Animation duration scale (0, 75, 100, 150, 200, 300, 500, 700, 1000) */ durations: typeof tailwindDurations; }; /** * The color scheme configuration with both default and dark colors. * Pass this to ThemeProvider for dark mode support. */ colorScheme: ColorSchemeConfig<D> | undefined; /** * Creates styled components with variant support and theme access. * Utils defined in createNVA are automatically expanded in styles. */ styled: { <const S extends string, const V extends VariantsWithUtils<S, U>>(config: ConfigWithUtils<S, V, U>): (props?: DefaultVariantsWithUtils<S, V, U>) => Base<S>; <const S extends string, const V extends VariantsWithUtils<S, U>>(configFactory: (defineConfig: <const S_1 extends string, const V_1 extends VariantsWithUtils<S_1, U>>(config: ConfigWithUtils<S_1, V_1, U>) => ConfigWithUtils<S_1, V_1, U>, theme: { /** * Colors: User-defined semantic colors merged with Tailwind palette. * User colors override Tailwind colors if keys conflict. */ colors: typeof tailwindColors & D; /** Spacing scale (0, px, 0.5, 1, 2, 4, 8, etc.) */ spacing: typeof tailwindSpacing; /** Font size scale (xs, sm, base, lg, xl, 2xl, etc.) */ fontSizes: typeof tailwindFontSizes; /** Border radius scale (none, sm, md, lg, xl, full, etc.) */ radii: typeof tailwindRadii; /** Shadow definitions for iOS and Android */ shadows: typeof tailwindShadows; /** Z-index scale (0, 10, 20, 30, 40, 50) */ zIndex: typeof tailwindZIndex; /** Opacity scale (0, 5, 10, ..., 95, 100) */ opacity: typeof tailwindOpacity; /** Line height scale (3, 4, ..., 10, none, tight, normal, etc.) */ lineHeights: typeof tailwindLineHeights; /** Font weight scale (thin, light, normal, medium, bold, etc.) */ fontWeights: typeof tailwindFontWeights; /** Letter spacing scale (tighter, tight, normal, wide, wider, widest) */ letterSpacing: typeof tailwindLetterSpacing; /** Border width scale (0, DEFAULT, 2, 4, 8) */ borderWidths: typeof tailwindBorderWidths; /** Animation duration scale (0, 75, 100, 150, 200, 300, 500, 700, 1000) */ durations: typeof tailwindDurations; }) => ConfigWithUtils<S, V, U>): (props?: DefaultVariantsWithUtils<S, V, U>) => Base<S>; }; /** * The utils configuration for use outside of styled. * Useful for applying utils to inline styles. */ utils: U; }; /** * Clears all style caches. Useful for testing or hot reloading scenarios. * Note: This only clears the primitive cache. WeakMap entries are * automatically garbage collected when their keys are no longer referenced. */ export declare function clearStyleCache(): void; export {};