TypeScript
@cladd-ui/react is written in TypeScript and ships its own types — no @types/* package needed. Every component re-exports its props as <Name>Props, every sized control re-exports its size union as <Name>Size, and a handful of shared types (Color, TooltipPosition, hook option types) are exported from the package root. You can use them to type wrapper components, forward props, or constrain configuration objects without restating the union by hand.
Component prop types
Every component re-exports its props type alongside the component itself:
import { Button, type ButtonProps } from '@cladd-ui/react';The most common reason to reach for these is wrapping a cladd component in a project-specific one — a <SaveButton>, a <SettingsRow>, a <DangerDialog> — without having to restate the underlying API:
import { Button, type ButtonProps } from '@cladd-ui/react';
interface SaveButtonProps extends Omit<ButtonProps, 'children' | 'color'> {
label?: string;
}
export function SaveButton({ label = 'Save', ...props }: SaveButtonProps) {
return (
<Button color="brand" variant="gradient-fill" {...props}>
{label}
</Button>
);
}The same pattern works for every component: Input exports InputProps, Dialog exports DialogProps (and DialogRootProps, DialogTriggerProps, DialogCloseProps), Toolbar exports ToolbarProps, and so on — there are no hidden internal types you have to redeclare.
Size types
Components on the 2xs → 2xl scale also export their size union, so you can use the same set of tokens in your own props without restating them. The unions are narrowed per component — Button's ButtonSize covers the full seven steps, while Input's InputSize starts at sm, and Switch's SwitchSize is only 'sm' | 'md'. See Sizing for which component reads which slice of the scale.
import { Button, type ButtonSize } from '@cladd-ui/react';
interface ToolbarActionProps {
label: string;
size?: ButtonSize;
}
export function ToolbarAction({ label, size = 'sm' }: ToolbarActionProps) {
return <Button size={size}>{label}</Button>;
}The full set: ButtonSize, CheckboxSize, ChipSize, InputSize, NumberFieldSize, NumberScrubberSize, RadioSize, ShortcutSize, SliderSize, SpinnerSize, SwitchSize, TextareaSize.
Shared types
A few types aren't bound to a single component:
Color— the eleven-token accent union shared by every component that takes acolorprop.'neutral' | 'brand' | 'red' | 'pink' | 'purple' | 'blue' | 'cyan' | 'lime' | 'green' | 'yellow' | 'orange'(plus(string & {})to keep autocomplete open for custom accent tokens you've registered via CSS variables).SurfaceVariant— the five-token variant union shared bySurfaceand every component that layers on top of it (Button,Popover,Popup,Toast,Toolbar, etc.):'transparent' | 'solid' | 'gradient' | 'solid-fill' | 'gradient-fill'.TooltipPosition— the position union used byTooltipandTooltipPrimitive('top' | 'bottom' | 'left' | 'right'and corner variants).PopoverPosition— the twelve-anchor position union used byPopover: the four sides ('top','bottom','left','right') each in-start, plain, and-endalignment variants.
import { Chip, type Color } from '@cladd-ui/react';
const statusColor: Record<'ok' | 'warn' | 'error', Color> = {
ok: 'green',
warn: 'yellow',
error: 'red',
};
export function StatusChip({ status }: { status: keyof typeof statusColor }) {
return <Chip color={statusColor[status]}>{status}</Chip>;
}Hook option types
The imperative hooks re-export the option shapes they accept, so you can build typed wrappers around your app's confirms, alerts, and toasts:
useDialog—UseDialogOptions,UseDialogAlertOptions,UseDialogConfirmOptions.useToast—UseToastOptions.
import { useDialog, type UseDialogConfirmOptions } from '@cladd-ui/react';
const destructiveConfirm: Partial<UseDialogConfirmOptions> = {
confirmButtonText: 'Delete',
confirmButtonColor: 'red',
};
export function useDeleteConfirm() {
const dialog = useDialog();
return (text: string) =>
dialog.confirm({ title: 'Delete?', text, ...destructiveConfirm });
}Polymorphic as
Components that accept an as prop (Button, Link, Surface, ListButton, ToolbarButton, and others) are polymorphic — when you pass as={NextLink}, TypeScript narrows the props to include NextLink's own props (href, prefetch, etc.) alongside the component's. You don't need a separate LinkButtonProps type; the existing <Name>Props adapts.
import { Button } from '@cladd-ui/react';
import NextLink from 'next/link';
// `href` and `prefetch` are typed because `as={NextLink}` widens the prop set.
<Button as={NextLink} href="/docs" prefetch>
Docs
</Button>;If you're spreading external props into a wrapper, type the wrapper as generic over as or pin a concrete element — both work, and which one you reach for depends on how flexible the wrapper needs to be.