or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

conditional-value-utilities.mdindex.mdproperty-definition.mdruntime-sprinkles.mdsprinkles-creation.md
tile.json

tessl/npm-vanilla-extract--sprinkles

Zero-runtime atomic CSS framework for vanilla-extract that generates static utility classes with type-safe composition

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@vanilla-extract/sprinkles@1.6.x

To install, run

npx @tessl/cli install tessl/npm-vanilla-extract--sprinkles@1.6.0

index.mddocs/

Vanilla Extract Sprinkles

Vanilla Extract Sprinkles is a zero-runtime atomic CSS framework that generates static utility classes for vanilla-extract. It enables developers to create type-safe, custom atomic CSS systems by defining properties, conditions (media queries, selectors), and shorthands through a declarative configuration API. All CSS is generated at build time with optional lightweight runtime composition for dynamic styling.

Package Information

  • Package Name: @vanilla-extract/sprinkles
  • Package Type: npm
  • Language: TypeScript
  • Installation:
    • npm: npm install @vanilla-extract/sprinkles
    • yarn: yarn add @vanilla-extract/sprinkles
    • pnpm: pnpm add @vanilla-extract/sprinkles

Core Imports

import { defineProperties, createSprinkles } from "@vanilla-extract/sprinkles";

For utilities:

import { createMapValueFn, createNormalizeValueFn } from "@vanilla-extract/sprinkles";

For runtime usage:

import { createSprinkles } from "@vanilla-extract/sprinkles/createRuntimeSprinkles";

For standalone utilities:

import { createMapValueFn, createNormalizeValueFn } from "@vanilla-extract/sprinkles/createUtils";

Basic Usage

import { defineProperties, createSprinkles } from "@vanilla-extract/sprinkles";

// Define properties with conditions and values
const responsiveProperties = defineProperties({
  conditions: {
    mobile: {},
    tablet: { '@media': 'screen and (min-width: 768px)' },
    desktop: { '@media': 'screen and (min-width: 1024px)' }
  },
  defaultCondition: 'mobile',
  properties: {
    display: ['none', 'flex', 'block', 'inline'],
    flexDirection: ['row', 'column'],
    paddingTop: {
      small: '4px',
      medium: '8px',
      large: '16px'
    }
  },
  shorthands: {
    padding: ['paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight'],
    paddingX: ['paddingLeft', 'paddingRight'],
    paddingY: ['paddingTop', 'paddingBottom']
  }
});

// Create sprinkles function
export const sprinkles = createSprinkles(responsiveProperties);

// Use in .css.ts files (build-time)
export const container = sprinkles({
  display: 'flex',
  paddingX: 'small',
  flexDirection: {
    mobile: 'column',
    desktop: 'row'
  }
});

// Use at runtime
const dynamicClass = sprinkles({
  display: 'flex',
  paddingTop: ['small', 'medium', 'large']
});

Architecture

Vanilla Extract Sprinkles is built around several key concepts:

  • Properties Definition: defineProperties creates atomic CSS class configurations with support for conditions, shorthands, and responsive arrays
  • Sprinkles Function: createSprinkles generates a type-safe function that composes utility classes
  • Build-time Generation: All CSS classes are generated during build via vanilla-extract's file scope
  • Runtime Composition: Optional runtime usage for dynamic class composition with minimal overhead
  • Type Safety: Full TypeScript support with conditional types and property validation
  • Conditions System: Support for media queries, selectors, @supports, and @container queries

Capabilities

Property Definition

Core functionality for defining atomic CSS properties with conditions, shorthands, and responsive configurations. This is the foundation for creating custom utility class systems.

function defineProperties<
  Properties extends AtomicProperties,
  Conditions extends BaseConditions,
  DefaultCondition extends keyof Conditions | Array<keyof Conditions> | false
>(
  options: ConditionalAtomicOptions<Properties, Conditions, DefaultCondition>
): ConditionalAtomicStyles<Properties, Conditions, DefaultCondition>;

Property Definition

Sprinkles Creation

Transform property definitions into type-safe utility functions that generate CSS class names. Supports both build-time and runtime usage patterns.

function createSprinkles<Args extends ReadonlyArray<SprinklesProperties>>(
  ...config: Args
): SprinklesFn<Args>;

type SprinklesFn<Args extends ReadonlyArray<SprinklesProperties>> = ((
  props: SprinkleProps<Args>
) => string) & { properties: Set<keyof SprinkleProps<Args>> };

Sprinkles Creation

Conditional Value Utilities

Helper functions for working with conditional values in responsive and theme-based styling scenarios.

function createMapValueFn<SprinklesProperties extends Conditions<string>>(
  properties: SprinklesProperties
): <OutputValue, Value>(
  value: Value,
  fn: (inputValue: ExtractValue<Value>, key: string) => OutputValue
) => OutputValue | Partial<Record<string, OutputValue>>;

function createNormalizeValueFn<SprinklesProperties extends Conditions<string>>(
  properties: SprinklesProperties
): <Value>(
  value: ConditionalValue<SprinklesProperties, Value>
) => Partial<Record<string, Value>>;

Conditional Value Utilities

Runtime Sprinkles

Lightweight runtime version of sprinkles creation for dynamic styling without build-time constraints.

function createSprinkles<Args extends ReadonlyArray<SprinklesProperties>>(
  ...args: Args
): SprinklesFn<Args>;

Runtime Sprinkles

Types

type ConditionalValue<
  SprinklesProperties extends Conditions<string>,
  Value extends string | number | boolean
> =
  | Value
  | Partial<Record<string, Value>>
  | ResponsiveArrayByMaxLength<number, Value>;

type RequiredConditionalValue<
  SprinklesProperties extends Conditions<string>,
  Value extends string | number | boolean
> = Value | RequiredConditionalObject<string, string, Value> | ResponsiveArray<number, Value>;

interface ResponsiveArray<Length extends number, Value> extends ReadonlyArray<Value> {
  0: Value;
  length: Length;
}

interface SprinklesProperties {
  styles: {
    [property: string]:
      | ConditionalWithResponsiveArrayProperty
      | ConditionalProperty
      | ShorthandProperty
      | UnconditionalProperty;
  };
}

interface ConditionalPropertyValue {
  defaultClass: string | undefined;
  conditions: {
    [conditionName: string]: string;
  };
}

interface ConditionalProperty {
  values: {
    [valueName: string]: ConditionalPropertyValue;
  };
}

interface UnconditionalProperty {
  values: {
    [valueName: string]: {
      defaultClass: string;
    };
  };
}

interface ShorthandProperty {
  mappings: Array<string>;
}

interface ConditionalWithResponsiveArrayProperty {
  responsiveArray: Array<string>;
  values: {
    [valueName: string]: ConditionalPropertyValue;
  };
}

type AtomicProperties = {
  [Property in keyof CSSProperties]?:
    | Record<string, CSSProperties[Property] | Omit<StyleRule, ConditionKey>>
    | ReadonlyArray<CSSProperties[Property]>;
} | Record<string, Record<string | number, Omit<StyleRule, ConditionKey>>>;

type BaseConditions = { [conditionName: string]: Partial<Record<ConditionKey, string>> };

type ConditionKey = '@media' | '@supports' | '@container' | 'selector';

type AtomicCSSProperties = {
  [Property in keyof CSSProperties]?:
    | Record<string, CSSProperties[Property] | Omit<StyleRule, ConditionKey>>
    | ReadonlyArray<CSSProperties[Property]>;
};

type AtomicCustomProperties = Record<
  string,
  Record<string | number, Omit<StyleRule, ConditionKey>>
>;

type ResponsiveArrayByMaxLength<MaxLength extends number, Value> = 
  MaxLength extends 1 ? ResponsiveArray<1, Value | null> :
  MaxLength extends 2 ? ResponsiveArray<1 | 2, Value | null> :
  MaxLength extends 3 ? ResponsiveArray<1 | 2 | 3, Value | null> :
  MaxLength extends 4 ? ResponsiveArray<1 | 2 | 3 | 4, Value | null> :
  MaxLength extends 5 ? ResponsiveArray<1 | 2 | 3 | 4 | 5, Value | null> :
  MaxLength extends 6 ? ResponsiveArray<1 | 2 | 3 | 4 | 5 | 6, Value | null> :
  MaxLength extends 7 ? ResponsiveArray<1 | 2 | 3 | 4 | 5 | 6 | 7, Value | null> :
  MaxLength extends 8 ? ResponsiveArray<1 | 2 | 3 | 4 | 5 | 6 | 7 | 8, Value | null> :
  never;

type ResponsiveArrayConfig<Value> = ResponsiveArray<2 | 3 | 4 | 5 | 6 | 7 | 8, Value>;

type ConditionalAtomicOptions<
  Properties extends AtomicProperties,
  Conditions extends BaseConditions,
  DefaultCondition extends keyof Conditions | Array<keyof Conditions> | false
> = {
  '@layer'?: string;
  properties: Properties;
  conditions: Conditions;
  defaultCondition: DefaultCondition;
};

type UnconditionalAtomicOptions<Properties extends AtomicProperties> = {
  '@layer'?: string;
  properties: Properties;
};

type ShorthandOptions<
  Properties extends AtomicProperties,
  Shorthands extends { [shorthandName: string]: Array<keyof Properties> }
> = {
  shorthands: Shorthands;
};

type ResponsiveArrayOptions<
  Conditions extends BaseConditions,
  ResponsiveLength extends number
> = {
  responsiveArray: ResponsiveArrayConfig<keyof Conditions> & {
    length: ResponsiveLength;
  };
};

Deprecated Exports

The following exports are deprecated but still available for backward compatibility:

Main Entry (@vanilla-extract/sprinkles)

/**
 * @deprecated Use `defineProperties` instead
 */
const createAtomicStyles = defineProperties;

/**
 * @deprecated Use `createSprinkles` instead  
 */
const createAtomsFn = createSprinkles;

Runtime Entry (@vanilla-extract/sprinkles/createRuntimeSprinkles)

/**
 * @deprecated Use `createSprinkles` instead  
 */
const createAtomsFn = createSprinkles;

Migration Guide

From createAtomicStyles to defineProperties:

// Old (deprecated)
import { createAtomicStyles } from "@vanilla-extract/sprinkles";
const styles = createAtomicStyles({ /* config */ });

// New (recommended)
import { defineProperties } from "@vanilla-extract/sprinkles";
const styles = defineProperties({ /* config */ });

From createAtomsFn to createSprinkles:

// Old (deprecated) - Build-time
import { createAtomsFn } from "@vanilla-extract/sprinkles";
const atoms = createAtomsFn(properties);

// New (recommended) - Build-time
import { createSprinkles } from "@vanilla-extract/sprinkles";
const sprinkles = createSprinkles(properties);

// Old (deprecated) - Runtime
import { createAtomsFn } from "@vanilla-extract/sprinkles/createRuntimeSprinkles";
const atoms = createAtomsFn(properties);

// New (recommended) - Runtime
import { createSprinkles } from "@vanilla-extract/sprinkles/createRuntimeSprinkles";
const sprinkles = createSprinkles(properties);