Button
A simple button component
- Size prop that works on all styles.
- Place an icon before or after.
- Control icon size explicitly with
iconSize. - Theme groups of buttons with
Button.Apply.
Installation
Button is already installed in @hanzo/gui, or you can install it independently:
npm install @hanzogui/buttonUsage
import { Button } from '@hanzo/gui'
export default () => <Button>Lorem ipsum</Button>Sizing
Sizing buttons provides a unique challenge especially for a compiler, because
you need to adjust many different properties - not just on the outer frame, but
on the text wrapped inside. Hanzo GUI supports adjusting the padding, border
radius, font size and icons sizes all in one with the size prop.
import { Button } from '@hanzo/gui'
export default () => <Button size="$6">Lorem ipsum</Button>Given your theme defines a size 6, the button will adjust all of the
properties appropriately. You can also pass a plain number to get an arbitrary
size.
Variants
The Button component supports different visual styles through the variant
prop. Currently, the primary available variant is "outlined".
import { Button, XStack } from '@hanzo/gui'
export default () => (
<XStack gap="$2">
<Button>Default</Button>
<Button variant="outlined">Outlined</Button>
</XStack>
)When variant="outlined" is applied, the button typically has a transparent
background with a visible border. The exact appearance (border color,
hover/press states) is determined by your theme's definitions for an outlined
button.
Icon Theming
You can pass icons as either elements or components. If passing components,
Hanzo GUI will automatically theme them (passing size). The icon size is
determined by the Button's size prop by default.
You can also explicitly set the icon size using the iconSize prop, which
accepts a SizeTokens value (e.g., "$2"). The scaleIcon prop can be used to
further adjust the size relative to the determined or explicitly set icon size.
When an icon is present, Hanzo GUI automatically adds spacing between the icon and
the button's text. This space is calculated as 40% of the icon's final computed
size (after considering size, iconSize, and scaleIcon). This margin is
applied to the right of an icon and to the left of an iconAfter.
import { Button, Star } from '@hanzo/gui'
export default () => (
<>
<Button icon={Star} size="$5">
Icon sized by Button
</Button>
<Button icon={Star} iconSize="$2" size="$5">
Icon sized explicitly
</Button>
</>
)You can use the source of Button itself to see in more detail what variants you can override, and how we use this pattern internally to create our Button component.
Group Theming
You can use Button.Apply to theme a group of Buttons using a shared context.
This is useful for applying consistent sizing or variants to multiple buttons
without passing props to each one individually.
import { Button, ButtonDemo, YStack } from '@hanzo/gui'
export default () => (
<YStack gap="$4">
<Button.Apply size="$2" variant="outlined">
<Button>Small Outlined 1</Button>
<Button>Small Outlined 2</Button>
<Button icon={ButtonDemo}>With Icon</Button>
</Button.Apply>
<Button.Apply size="$5">
<Button>Large 1</Button>
<Button theme="blue">Large Themed</Button>
</Button.Apply>
</YStack>
)Web Form Props
Button supports all standard HTML <button> attributes for form integration.
These props are web-only and ignored on native:
import { Button, Form } from '@hanzo/gui'
export default () => (
<Form action="/submit">
<Button type="submit">Submit Form</Button>
<Button type="reset">Reset</Button>
<Button type="button">Regular Button (default)</Button>
{/* Override form attributes */}
<Button type="submit" formAction="/alternative-endpoint" formMethod="post">
Submit to Different Endpoint
</Button>
</Form>
)Button defaults to type="button" to prevent unintended form submissions. Use
type="submit" explicitly when you want form submission behavior.
Text Styling
Button does not support a color prop directly. Instead, use Button.Text
for full control over text styling. Combine it with the group prop on
Button to coordinate interactive styles between the frame and its children:
import { Button } from '@hanzo/gui'
export default () => (
<Button group="btn" bg="pink">
<Button.Text color="blue" $group-btn-hover={{ color: 'red' }}>
Hello world
</Button.Text>
</Button>
)The group prop lets any child reference interactive states like
$group-btn-hover, $group-btn-press, and $group-btn-focus for
precise styling per interaction state.
Creating Your Own Button
Hanzo GUI now has all the features necessary to make creating a custom Button easy enough that you may want to roll your own button. Learn how to do it with our dedicated guide, How to Build a Button.
API Reference
Buttons extend Stack views inheriting all the Gui standard props, plus:
| Prop | Type | Default | Required |
|---|---|---|---|
| size | SizeTokens | number | - | - |
| variant | "outlined" | undefined | - | - |
| disabled | boolean | - | - |
| theme | string | - | - |
| icon | React.ReactNode | React.ComponentType<{ color?: string, size?: number }> | - | - |
| iconAfter | React.ReactNode | React.ComponentType<{ color?: string, size?: number }> | - | - |
| iconSize | SizeTokens | - | - |
| scaleIcon | number | - | - |
| circular | boolean | - | - |
| chromeless | boolean | "all" | - | - |
| unstyled | boolean | - | - |
| // Web Form Props | --- | - | - |
| type | "button" | "submit" | "reset" | - | - |
| formAction | string | - | - |
| formMethod | "get" | "post" | - | - |
| formEncType | string | - | - |
| formNoValidate | boolean | - | - |
| formTarget | string | - | - |
| name | string | - | - |
| value | string | - | - |
| popoverTarget | string | - | - |
| popoverTargetAction | "hide" | "show" | "toggle" | - | - |
| // Text Styling | --- | - | - |
Last updated on