import type { AnyStyle, ClassProps, ClassValue, CombinedProps, Conditions, Options, Scheme, Style, StyleArguments, UntypedScheme, } from './types.js'; function isConditions(value: ClassValue | Conditions): value is Conditions { return typeof value === 'object' && value !== null && !Array.isArray(value); } function resolve(value: ClassValue | Conditions, props: Record): ClassValue { if (!isConditions(value)) return value; const { $base, $default } = value; const classes: ClassValue[] = []; let matchedBoolean = false; for (const key of Object.keys(value)) { if (key === '$base' || key === '$default') continue; const branch = value[key]; const selected = props[key]; if (selected === '$default') { throw new Error( `"$default" is reserved for defining fallback styles and cannot be used as a value for "${key}".`, ); } if (/^(is|allows)[A-Z]/.test(key)) { if (selected) { matchedBoolean = true; classes.push(resolve(branch, props)); } } else if (isConditions(branch)) { const variant = typeof selected === 'string' && Object.hasOwn(branch, selected) ? selected : '$default'; classes.push(resolve(branch[variant], props)); } } return [ isConditions($base) ? undefined : $base, matchedBoolean ? undefined : resolve($default, props), ...classes, ]; } export function createNtv({ twMerge }: Options) { function ntv

(scheme: Scheme

): Style

; function ntv(scheme: UntypedScheme): Style>; function ntv(scheme: Conditions) { for (const key of ['class', 'className']) { if (key in scheme) { throw new Error(`The "${key}" property is not allowed in ntv scheme. Use "$base" instead.`); } } return ({ class: extra, className, ...props }: Record & ClassProps = {}) => twMerge(resolve(scheme, props), extra, className); } function combine( ...styles: F & StyleArguments ): Style>; function combine(...styles: ((props: Record) => string)[]) { return ({ class: extra, className, ...props }: Record & ClassProps = {}) => twMerge(...styles.map((style) => style(props)), extra, className); } return Object.assign(ntv, { combine }); }