import { Platform } from 'react-native'; import { cva, type VariantProps } from 'class-variance-authority'; import { DISABLED_CURSOR, TRANSITION_COLORS } from '../../styles/constants'; // ── Trigger ───────────────────────────────────────────────── export const selectTriggerVariants = cva( [ 'flex w-full min-w-0 flex-row items-center justify-between text-start', 'bg-surface-primary', 'border border-stroke-primary', 'rounded-[var(--border-radius-default)]', TRANSITION_COLORS, 'data-[disabled=true]:bg-surface-secondary', 'data-[disabled=true]:opacity-[var(--opacity-disabled)]', DISABLED_CURSOR, 'data-[readonly=true]:cursor-default', 'data-[readonly=true]:bg-surface-secondary', 'web:data-[hover=true]:data-[focus=false]:data-[invalid=false]:border-stroke-hover', // Web: inset ring avoids a border-width change so no padding compensation is needed. // Recolor the border to match the ring so the two read as a single focus outline // instead of a gray border + colored ring. 'web:data-[focus=true]:ring-inset', 'web:data-[focus=true]:ring-[length:var(--border-width-focused)]', 'web:data-[focus=true]:data-[invalid=false]:ring-stroke-action', 'web:data-[focus=true]:data-[invalid=false]:border-stroke-action', 'web:data-[focus=true]:data-[invalid=true]:ring-stroke-danger', 'web:data-[focus=true]:data-[invalid=true]:border-stroke-danger', 'web:data-[state=open]:ring-inset', 'web:data-[state=open]:ring-[length:var(--border-width-focused)]', 'web:data-[state=open]:data-[invalid=false]:ring-stroke-action', 'web:data-[state=open]:data-[invalid=false]:border-stroke-action', 'web:data-[state=open]:data-[invalid=true]:ring-stroke-danger', 'web:data-[state=open]:data-[invalid=true]:border-stroke-danger', // Native: thicker border; size variants below compensate the layout shift. 'native:data-[focus=true]:border-[length:var(--border-width-focused)]', 'native:data-[field-state=focused]:border-stroke-action', 'native:data-[field-state=focused-invalid]:border-stroke-danger', 'native:data-[state=open]:border-[length:var(--border-width-focused)]', 'data-[invalid=true]:border-stroke-danger', ], { variants: { variant: { outline: [], }, size: { default: [ 'h-11 min-h-11 px-4 py-3 gap-4', // Native only: subtract one hairline so the wider focus border doesn't shift layout. 'native:data-[focus=true]:px-[calc(var(--spacing-4)-var(--spacing-px))]', 'native:data-[focus=true]:py-[calc(var(--spacing-3)-var(--spacing-px))]', 'native:data-[state=open]:px-[calc(var(--spacing-4)-var(--spacing-px))]', 'native:data-[state=open]:py-[calc(var(--spacing-3)-var(--spacing-px))]', ], small: [ 'h-8 min-h-8 px-3 py-2 gap-1.5', 'native:data-[focus=true]:px-[calc(var(--spacing-3)-var(--spacing-px))]', 'native:data-[focus=true]:py-[calc(var(--spacing-2)-var(--spacing-px))]', 'native:data-[state=open]:px-[calc(var(--spacing-3)-var(--spacing-px))]', 'native:data-[state=open]:py-[calc(var(--spacing-2)-var(--spacing-px))]', ], }, }, defaultVariants: { variant: 'outline', size: 'default', }, }, ); // ── Value ─────────────────────────────────────────────────── export const selectValueVariants = cva( [ 'min-w-0 flex-1 text-start', 'text-content-primary', 'data-[placeholder=true]:text-content-tertiary', 'data-[invalid=true]:text-content-danger', ], { variants: { size: { default: 'text-[0.875rem]', small: 'text-[0.75rem]', }, }, defaultVariants: { size: 'default', }, }, ); // ── Icon ──────────────────────────────────────────────────── export const selectIconVariants = cva( [ 'shrink-0 items-center justify-center self-center', 'text-content-tertiary', 'data-[invalid=true]:text-content-danger', ], { variants: { size: { default: 'size-5', small: 'size-4', }, }, defaultVariants: { size: 'default', }, }, ); // ── Content ───────────────────────────────────────────────── export const selectContentVariants = cva([ 'bg-surface-primary', 'border border-stroke-secondary', 'overflow-hidden', 'rounded-xl', Platform.select({ web: 'shadow-sm', default: '', }), 'max-h-60', 'py-1', ]); // ── Item ──────────────────────────────────────────────────── export const selectItemVariants = cva( [ 'flex-row items-center', 'transition-colors duration-100', 'data-[disabled=true]:opacity-50 data-[disabled=true]:pointer-events-none', 'data-[state=checked]:bg-surface-action-tint data-[state=checked]:font-medium', Platform.select({ default: 'data-[active=true]:bg-surface-action-tint-active', web: 'data-[hover=true]:bg-surface-action-tint-hover data-[active=true]:data-[hover=true]:bg-surface-action-tint-active data-[highlighted=true]:bg-surface-action-tint-hover', }), ], { variants: { size: { default: 'px-3 py-2', small: 'px-2.5 py-1.5', }, }, defaultVariants: { size: 'default', }, }, ); // ── ItemLabel ─────────────────────────────────────────────── export const selectItemLabelVariants = cva( ['text-content-primary', 'data-[state=checked]:font-medium'], { variants: { size: { default: 'text-[0.875rem]', small: 'text-[0.75rem]', }, }, defaultVariants: { size: 'default', }, }, ); export type SelectVariantProps = VariantProps;