Variants & States Types 
In Arto, variants and states are core concepts for styling flexibility. Variants allow you to define different “modes” (like size, theme, etc.), while states handle ephemeral or boolean-driven styles (like disabled, hover, focused). This page covers the TypeScript definitions behind these features.
VariantValue 
export type VariantValue = string | numberVariants typically map string or number values to classes. For instance, size could have possible values: 'small', 'medium', 'large' (all strings), or '1', '2', 3 if you prefer numeric.
VariantOptions 
export type VariantOptions<
  TVariants extends Record<string, VariantValue>,
  TStates extends string,
  TContext = unknown,
> = {
  /**
   * Each key (e.g., 'size', 'theme') maps to an object
   * whose keys are possible variant values (e.g., 'small', 'large'),
   * and whose values are either:
   *   - ClassName<TContext> (string, array, or callback)
   *   - A VariantConfig with optional nested states
   */
  [K in keyof TVariants]?: {
    [V in TVariants[K]]: ClassName<TContext> | VariantConfig<TStates, TContext>
  }
}Explanation:
- A VariantOptionsobject has keys that match your variant names (likesize,theme).
- Each variant key is an object whose keys are the possible values of that variant (e.g., 'small','large').
- The values can be class strings, arrays, or even a VariantConfigthat contains advanced options and nested states.
VariantConfig 
export interface VariantConfig<TStates extends string = never, TContext = unknown> {
  /**
   * Base class names to apply when this variant is selected
   */
  className?: ClassName<TContext>
  /**
   * Nested states that only apply if this variant is selected (and the state is active)
   */
  states?: StatesOptions<TStates, TContext>
}Explanation 
A VariantConfig allows you to specify:
- className: Classes for that variant value.
- states: A nested- StatesOptionsthat only apply if the user picks this variant value.
For example:
{
  size: {
    small: {
      className: "px-2 py-1 text-sm",
      states: {
        hover: "bg-gray-50"
      }
    },
    large: {
      className: "px-4 py-2 text-base",
      states: {
        hover: "bg-gray-100"
      }
    }
  }
}StatesOptions 
export type StatesOptions<TStates extends string, TContext = unknown> = {
  [K in TStates]?: ClassName<TContext> | StateConfig<TStates, TContext>
}A StatesOptions object maps each state name to either a direct class name or a StateConfig.
StateConfig 
export interface StateConfig<TStates extends string, TContext = unknown> {
  /**
   * Class(es) to apply if this state is active
   */
  className: ClassName<TContext>
  /**
   * Optional dependencies:
   *   - An array describing states that must/must not be active
   *   - A function receiving (activeStates, context) => boolean
   */
  dependsOn?: StateDependency<TStates, TContext>
}Explanation 
- className: The classes (or callback) to apply if the state is active.
- dependsOn: Additional conditions specifying that this state only applies if certain other states are (or are not) active, or a function returning- true/falsebased on advanced logic.
StateDependency 
export type StateDependency<TStates extends string, TContext = unknown> =
  | Array<TStates | { not: TStates[] }>
  | ((activeStates: Set<TStates>, context?: TContext) => boolean)Possible Forms: An array of required states or not: states:
dependsOn: ['hover', { not: ['disabled'] }]means hover must be active and disabled must not be active. 2. A function that returns true or false based on (activeStates, context).
Putting It All Together 
Here’s a snippet that defines variants and states using these types under the hood:
import { arto } from 'arto'
const cardConfig = arto({
  className: 'transition-shadow border rounded-md',
  variants: {
    shadow: {
      none: 'shadow-none',
      small: {
        className: 'shadow-sm',
        states: {
          hover: {
            className: 'shadow-md',
            dependsOn: ['hover', { not: ['disabled'] }],
          },
        },
      },
      large: {
        className: 'shadow-lg',
        states: {
          hover: 'shadow-xl',
        },
      },
    },
  },
  states: {
    disabled: 'opacity-60 pointer-events-none',
  },
})
// If user picks shadow=small and hover + not disabled => "shadow-md"Summary 
- Variants map keys (like size,theme) to possible string or numeric values, each corresponding to certain classes.
- VariantConfigallows advanced usage, including nested- statesthat only apply when that variant value is selected.
- States can be simple ("bg-red-500") or complex ({ className: ..., dependsOn: ... }).
- dependsOnarrays or functions let you define conditions on other states before applying the class.
These types power Arto’s flexible system for building dynamic, composable class strings. Check out:
- Rules & Logic Types for removing or adding classes conditionally,
- arto() Function to see how variants & states tie into the main config.