API Reference

SzrCustomConfig

Module augmentation pattern that feeds your createUi configuration into the Stareezy UI type system — enabling typed breakpoints and custom shorthand props everywhere.

What is SzrCustomConfig?

SzrCustomConfig is a TypeScript interface exported from @stareezy-ui/tokens that acts as a bridge between your createUi() configuration and the rest of the type system. By augmenting it with typeof ui, you inject your custom breakpoints and shorthands into BreakpointKey, BoxProps, and BoxLayoutProps.

Module augmentation is a standard TypeScript mechanism — you are not patching a runtime object, only extending a type declaration. It has zero runtime cost.

How to augment SzrCustomConfig

Add the declare module block after calling createUi() in your stareezy.config.ts:

// stareezy.config.ts
import { createUi, themes } from '@stareezy-ui/tokens'

export const ui = createUi({
  themes: {
    aurora:  themes.aurora,
    dark:    themes.dark,
    light:   themes.light,
  },
  media: {
    sm:  480,
    md:  768,
    lg:  1024,
    xl:  1280,
  },
  shorthands: {
    p:  'padding',
    px: 'paddingHorizontal',
    py: 'paddingVertical',
    m:  'margin',
    br: 'borderRadius',
    w:  'width',
    h:  'height',
    f:  'flex',
  } as const,  // ← as const is required
})

// ── Module augmentation ──────────────────────────────────────────────
// Extend SzrCustomConfig with the full type of your ui config.
// This single declaration makes your media keys and shorthands
// available everywhere in the type system.
type AppConfig = typeof ui
declare module '@stareezy-ui/tokens' {
  interface SzrCustomConfig extends AppConfig {}
}

export default ui

What changes after augmentation

1
BreakpointKey derives from your media config
// Before augmentation (default):
// BreakpointKey = "base" | "sm" | "md" | "lg" | "xl" | "2xl"

// After augmenting with { media: { sm: 480, md: 768, lg: 1024, xl: 1280 } }:
// BreakpointKey = "base" | "sm" | "md" | "lg" | "xl"

// TypeScript will now error on undeclared keys:
<Box p={{ '2xl': 24 }} />  // ❌ "2xl" is not in your media config
2
Custom shorthands appear on BoxProps and every component
// Before augmentation:
<Box br={8} />   // ❌ Property 'br' does not exist on type 'BoxProps'

// After augmentation:
<Box br={8} />   // ✅ br → borderRadius, fully typed
<Box p={12} />   // ✅ p  → padding
<Box w="100%" /> // ✅ w  → width

// Also works on all other components:
<Button br={12} p={{ base: 8, md: 12 }} />
<Input  w={{ base: '100%', md: 360 }} />
3
Responsive objects on shorthands are typed
// Custom shorthands accept responsive objects after augmentation:
<Box br={{ base: 4, md: 8, lg: 12 }} />  // ✅ typed
<Box px={{ base: 12, lg: 24 }} />        // ✅ typed

// Type safety applies here too:
<Box br={{ tablet: 8 }} />  // ❌ "tablet" not in BreakpointKey
4
$-prefixed breakpoint props derive from your keys
// With { media: { sm, md, lg, xl } }, these $-props are available:
<Box $sm={{ p: 8 }} />   // ✅
<Box $md={{ p: 16 }} />  // ✅
<Box $lg={{ p: 24 }} />  // ✅
<Box $xl={{ p: 32 }} />  // ✅

// Undeclared breakpoints are not available:
<Box $2xl={{ p: 40 }} /> // ❌ "2xl" not in your media config

Custom media breakpoints

You can declare any breakpoint names you want — there is no restriction to sm, md, etc. The values must be number (min-width in pixels).

export const ui = createUi({
  media: {
    compact:  600,
    regular:  900,
    expanded: 1200,
  },
  // ...
})

// After augmentation:
// BreakpointKey = "base" | "compact" | "regular" | "expanded"

<Box p={{ base: 8, compact: 12, regular: 16, expanded: 24 }} />
<Box $compact={{ flexDirection: 'row' }} />
<Box $expanded={{ maxWidth: 1200, mx: 'auto' }} />

Custom shorthands declaration

Shorthands map a short prop name to a CSS/React Native style property. The as const assertion is required so TypeScript infers literal key types rather than widening to string.

export const ui = createUi({
  shorthands: {
    // spacing
    p:   'padding',
    px:  'paddingHorizontal',
    py:  'paddingVertical',
    pt:  'paddingTop',
    pb:  'paddingBottom',
    pl:  'paddingLeft',
    pr:  'paddingRight',
    m:   'margin',
    mx:  'marginHorizontal',
    my:  'marginVertical',
    mt:  'marginTop',
    mb:  'marginBottom',
    // sizing
    w:   'width',
    h:   'height',
    minW: 'minWidth',
    maxW: 'maxWidth',
    // appearance
    br:  'borderRadius',
    bg:  'backgroundColor',
    f:   'flex',
    z:   'zIndex',
  } as const,  // ← required
})
Omitting as const is the most common mistake. Without it, TypeScript sees Record<string, string> instead of the literal key types, and no new props are added to BoxProps.

Minimal config (no augmentation needed)

If you do not call createUi() or do not augment SzrCustomConfig, the defaults apply:

  • BreakpointKey = "base" | "sm" | "md" | "lg" | "xl" | "2xl"
  • No custom shorthand props on BoxProps
  • No $-prefixed breakpoint props beyond the defaults

You can start without augmentation and add it later as your app grows.

Where to put the augmentation

The declare module block must be in a module — a file that has at least one import or export statement. The recommended location is your stareezy.config.ts, which satisfies this requirement because it already imports from @stareezy-ui/tokens.

TypeScript picks up the augmentation automatically as long as the file is included in your tsconfig.json's include paths.

The compiler also reads stareezy.config.ts at build time to pick up your custom shorthands. Keeping the augmentation in the same file means there is exactly one source of truth for your configuration.