jacaranda
Version:
A lightweight styling library for React Native
71 lines (70 loc) • 3.59 kB
TypeScript
/**
* ISC License
* Copyright 2025 Javier Diaz Chamorro
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby
* granted, provided that the above copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
* OR PERFORMANCE OF THIS SOFTWARE.
*/
import { type ComponentType } from 'react';
import { ImageStyle, TextStyle, ViewStyle, StyleProp } from 'react-native';
type ResolvedStyle = ViewStyle & TextStyle & ImageStyle;
type StyleObject<Tokens extends TokenConfig = TokenConfig> = {
[K in keyof ResolvedStyle]?: ResolvedStyle[K] | (string extends ResolvedStyle[K] ? TokenPaths<Tokens> : number extends ResolvedStyle[K] ? TokenPaths<Tokens> : ResolvedStyle[K] extends string | number | undefined ? TokenPaths<Tokens> : never);
};
type VariantOptions<V, Tokens extends TokenConfig = TokenConfig> = {
[P in keyof V]: {
[K in keyof V[P]]: StyleObject<Tokens>;
};
};
type CompoundVariant<V, Tokens extends TokenConfig = TokenConfig> = {
variants: Partial<{
[P in keyof V]: keyof V[P] | boolean | Array<keyof V[P]>;
}>;
style: StyleObject<Tokens>;
};
type DefaultVariants<V> = Partial<{
[P in keyof V]: keyof V[P] | boolean;
}>;
type VariantStyleConfig<V extends VariantOptions<V, Tokens>, Tokens extends TokenConfig = TokenConfig> = {
base?: StyleObject<Tokens>;
variants: V;
compoundVariants?: CompoundVariant<V, Tokens>[];
defaultVariants?: DefaultVariants<V>;
};
export type OmitUndefined<T> = T extends undefined ? never : T;
export type VariantProps<T> = T extends (props?: infer P) => StyleProp<ResolvedStyle> ? P : never;
/**** Tokens definition */
interface AllowedTokenCategories {
colors: string;
space: number;
fontSize: number;
fonts: string;
lineHeight: number;
}
type TokenConfig = {
[K in keyof AllowedTokenCategories]?: Record<string, AllowedTokenCategories[K]>;
};
type KeysToStrings<T> = T extends Record<string | number, any> ? `${keyof T & (string | number)}` : never;
type TokenPaths<T extends TokenConfig> = {
[Category in keyof T]: T[Category] extends Record<string | number, any> ? `$${Category & string}.${KeysToStrings<T[Category]>}` : never;
}[keyof T];
type ComponentProps<T> = T extends ComponentType<infer P> ? P : never;
type StyledFunction<Tokens extends TokenConfig = TokenConfig> = <C extends ComponentType<any>>(Component: C) => <P extends object = {}>(styleObject: StyleObject<Tokens> | ((props: P & Omit<ComponentProps<C>, 'style'>) => StyleObject<Tokens>)) => ComponentType<P & Omit<ComponentProps<C>, 'style'> & {
style?: StyleProp<ViewStyle | TextStyle | ImageStyle>;
}>;
interface CreateTokensReturn<Tokens extends TokenConfig = TokenConfig> {
sva: <V extends VariantOptions<V, Tokens>>(config: VariantStyleConfig<V, Tokens>) => (props?: any) => StyleProp<ResolvedStyle>;
tokens: Readonly<Tokens>;
styled: StyledFunction<Tokens>;
}
/**
* Creates a token system and returns the styles function
*/
export declare function defineTokens<T extends TokenConfig>(tokenConfig: T): CreateTokensReturn<T>;
export {};