# Props

Type-only helpers that infer a component's props from a variants definition.

`Props` holds types only, so it adds nothing to a bundle. Import it with `import type` or an inline `type` specifier.

```tsx title="Button.tsx"
import type { ReactNode } from 'react'
import { type Props, variants } from 'zyzz'

export function Button(props: Button.Props) {
  const { children, ...selection } = props
  return (
    <button {...styles.button(selection)} type="button">
      {children}
    </button>
  )
}

export declare namespace Button {
  // Accepts `size` plus the styling overrides
  type Props = Props.Variants<typeof styles.button> & { children: ReactNode }
}

namespace styles {
  export const button = variants({
    variants: {
      size: { compact: { padding: '4px' }, regular: { padding: '8px' } },
    },
  })
}
```

## Types

### Props.Variants

* **Type:** `Props.Variants<typeof recipe>`

The input of an applied recipe: every selection, dynamic choice payloads, `conditions` when the recipe declares them, and the `className`, `style`, and `vars` overrides. Optional selections stay optional. It equals `NonNullable<Parameters<typeof recipe>[0]>`.

```ts
// { className?, size?, style?, vars? }
type ButtonProps = Props.Variants<typeof styles.button>
```

Undeclared values fail type checking at the call site, such as `size="huge"` on the component above. [`variants`](/docs/api/core/variants#types) shows the recipe side of the contract.
