import { Button, buttonVariants } from '@hanzo/ui'
Every visual variant, from the filled default to the bare link.
export function Variants() {return (<XStack flexWrap="wrap" gap="$3" items="center"><Button>Default</Button><Button variant="primary">Primary</Button><Button variant="secondary">Secondary</Button><Button variant="outline">Outline</Button><Button variant="ghost">Ghost</Button><Button variant="destructive">Destructive</Button><Button variant="link">Link</Button></XStack>)}
Three text sizes and a square icon size for each of them.
export function Sizes() {return (<XStack flexWrap="wrap" gap="$3" items="center"><Button size="sm">Small</Button><Button>Default</Button><Button size="lg">Large</Button><Button size="icon-sm" aria-label="Small icon">+</Button><Button size="icon" aria-label="Icon">+</Button><Button size="icon-lg" aria-label="Large icon">+</Button></XStack>)}
A button that is loading shows a spinner and takes no clicks; a disabled one takes none and says so.
export function States() {return (<XStack flexWrap="wrap" gap="$3" items="center"><Button isLoading>Saving</Button><Button disabled>Disabled</Button><Button variant="outline" disabled>Disabled outline</Button></XStack>)}
`asChild` styles the element you pass instead of rendering its own button.
export function AsChild() {return (<Button asChild variant="outline"><a href="https://github.com/hanzoai/ui">Source on GitHub</a></Button>)}
export type ButtonVariant =| 'default'| 'destructive'| 'outline'| 'secondary'| 'ghost'| 'link'| 'primary'| 'linkFG'| 'linkMuted'
export type ButtonSize = 'default' | 'sm' | 'lg' | 'icon' | 'icon-sm' | 'icon-lg'
export type ButtonProps = Omit<ComponentProps<typeof Frame>,'variant' | 'size' | 'children' | 'onClick'> & {variant?: ButtonVariant | nullsize?: ButtonSize | nullisLoading?: booleanchildren?: ReactNode/*** The DOM click. Frame types this from the cross-platform stack, where the* event carries `currentTarget: number | ReactNativeElement` — so a handler* written the way every web caller writes it, `(e: React.MouseEvent) => …`,* is a type error on a prop that works perfectly.** On web the handler IS a DOM handler: props spread onto Frame, which renders* a real <button>, and React hands it a MouseEvent. Declaring what actually* arrives is the same trade as `title` below, and for the same reason — the* alternative is call sites re-declaring the component as `any`, which hides* every real error in the file along with this one.*/onClick?: MouseEventHandler<HTMLElement>/*** The DOM tooltip. Already reached the element -- every unrecognised prop is* spread onto Frame, which forwards it -- but the Frame's props come from the* cross-platform stack and name no DOM attribute, so passing it did not type.* Callers either dropped the tooltip or re-declared the whole component as* `any`, and the second hides every real error in the file.** Declared here because it is true on web and harmless elsewhere: native* ignores an attribute it does not know. Widening the type to match the* behaviour beats asking ~60 call sites to work around it.*/title?: string/*** The DOM button type. Not cosmetic: inside a form the default is "submit",* so a control meant to do something else submits the form instead. Callers* write type="button" to stop that, and dropping it would be a real bug* rather than a lost attribute. Reaches the element the same way title does.*/type?: 'button' | 'submit' | 'reset'/*** How the button identifies itself to the form it submits.** A submitter contributes its own `name`/`value` pair to the form data, which* is how one form tells "save" from "save and close" — so dropping these is* losing which button was pressed, not losing an attribute. They reach the* element the same way `type` does.*/name?: stringvalue?: string} & Microdata