UNPKG

@nuxt/ui

Version:

A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.

89 lines (88 loc) 4.06 kB
import type { ClassValue, TVVariants, TVCompoundVariants, TVDefaultVariants } from 'tailwind-variants'; /** * A function form for a slot class that **replaces** the slot's default classes * instead of merging onto them, returning the classes to use in their place. * In `app.config.ui` it receives the slot's own theme classes and replaces only * those — `variants` and `compoundVariants` still apply on top. In `:ui` / `class` * it runs after variant resolution, so it receives the fully resolved class * string and replaces it, keeping only the plain classes passed alongside the * replacer (e.g. `[() => 'text-xl', 'opacity-50']` resolves to both). * @example title: defaults => 'text-xl font-bold' */ export type SlotClassReplacer = (defaults: string) => ClassValue; /** * The value accepted for a slot in `:ui`, the `class` prop or `app.config.ui`: * either classes to merge (the default) or a {@link SlotClassReplacer} to replace. */ export type SlotClass = ClassValue | SlotClassReplacer; /** * Defines the AppConfig object based on the tailwind-variants configuration. */ export type TVConfig<T extends Record<string, any>> = { [P in keyof T]?: P extends 'prose' ? TVConfig<T[P]> : { [K in keyof T[P] as K extends 'base' | 'slots' | 'variants' | 'defaultVariants' ? K : never]?: K extends 'base' ? SlotClass : K extends 'slots' ? { [S in keyof T[P]['slots']]?: SlotClass; } : K extends 'variants' ? TVVariants<T[P]['slots'], ClassValue, WidenVariantsValues<T[P]['variants']>> : K extends 'defaultVariants' ? TVDefaultVariants<WidenVariantsValues<T[P]['variants']>, T[P]['slots'], object, undefined> : never; }; } & { [P in keyof T]?: P extends 'prose' ? TVConfig<T[P]> : { compoundVariants?: TVCompoundVariants<WidenVariantsValues<T[P]['variants']>, T[P]['slots'], ClassValue, object, undefined>; }; }; type WidenVariantsValues<V extends Record<string, any> | undefined> = V extends Record<string, any> ? V & { [K in keyof V]: V[K] extends Record<string, any> ? V[K] & Record<string & {}, any> : V[K]; } : V; /** * Utility type to flatten intersection types for better IDE hover information. * @template T The type to flatten. */ type Id<T> = {} & { [P in keyof T]: T[P]; }; type ComponentVariants<T extends { variants?: Record<string, Record<string, any>>; }> = { [K in keyof T['variants']]: keyof T['variants'][K]; }; type ComponentSlots<T extends { slots?: Record<string, any>; }> = Id<{ [K in keyof T['slots']]?: SlotClass; }>; type ComponentUI<T extends { slots?: Record<string, any>; }> = Id<{ [K in keyof Required<T['slots']>]: (props?: Record<string, any>) => string; }>; type GetComponentAppConfig<A, U extends string, K extends string> = A extends Record<U, Record<K, any>> ? A[U][K] : {}; type ComponentAppConfig<T, A extends Record<string, any>, K extends string, U extends string = 'ui' | 'ui.prose'> = Omit<A, 'ui'> & { ui: U extends 'ui.prose' ? (A extends { ui: infer UI; } ? Omit<UI, 'prose'> : Record<string, never>) & { prose?: (A extends { ui: { prose?: infer P; }; } ? Omit<NonNullable<P>, K> : Record<string, never>) & { [k in K]?: Partial<T>; }; } : (A extends { ui: infer UI; } ? Omit<UI, K> : Record<string, never>) & { [k in K]?: Partial<T>; }; }; /** * Defines the configuration shape expected for a component. * @template T The component's theme imported from `#build/ui/*`. * @template A The base AppConfig type from `@nuxt/schema`. * @template K The key identifying the component (e.g., 'badge'). * @template U The top-level key in AppConfig ('ui' or 'uiPro'). */ export type ComponentConfig<T extends Record<string, any>, A extends Record<string, any>, K extends string, U extends 'ui' | 'ui.prose' = 'ui'> = { AppConfig: ComponentAppConfig<T, A, K, U>; variants: ComponentVariants<T & GetComponentAppConfig<A, U, K>>; slots: ComponentSlots<T>; ui: ComponentUI<T>; }; export {};