AIButton
An AIButton marks an action that calls a model. It is Button
with a sparkle as the leading icon and isGenerating in place of loading,
which announces "Generating" while the spinner shows. Every variant, size
and as of Button applies.
import AIButton from '@zuilib/components/ai-button'
Variants and sizes
Generating
isGenerating shows the spinner in place of the sparkle, sets aria-busy
and swallows clicks, but keeps the button focusable (Button's loading
behaviour). The announced text is always "Generating".
Without the sparkle
sparkle={false} drops the icon; trailingIcon still works.
Props
AIButtonProps<TTag> is ButtonProps<TTag> minus loading and
leadingIcon, plus:
| Prop | Type | Default | Description |
|---|---|---|---|
isGenerating | boolean | false | Button loading with loadingText="Generating"; spinner, aria-busy, clicks swallowed, stays focusable |
sparkle | boolean | true | Sparkle icon before the label; pulses on hover (not under reduced motion) |
variant | 'primary' | 'secondary' | 'destructive' | 'outline' | 'ghost' | 'link' | 'primary' | From Button |
size | 'sm' | 'md' | 'lg' | 'icon' | 'md' | From Button |
trailingIcon | ReactNode | — | From Button |
fullWidth | boolean | false | From Button |
disabled | boolean | false | From Button |
as | ElementType | 'button' | From Button; its props are typed |
className | string | — | Merged last |
Slots
The root keeps data-slot="button", so every [data-slot="button"] rule
applies; data-ai-button and data-generating single it out.
| Slot | Element | Notes |
|---|---|---|
[data-slot="button"] | button (or as) | Root. Also data-ai-button, data-generating, and Button's data-variant / data-size / data-loading |
[data-slot="ai-button-sparkle"] | svg | The sparkle, inside button-leading-icon; aria-hidden |
[data-slot="button-spinner"] | svg | Present while generating |
[data-slot="button-trailing-icon"] | span | Wraps trailingIcon |
[data-slot="button-content"] | span | The children |
/* Consumer CSS: gradient AI buttons only */
[data-slot="button"][data-ai-button] {
background-image: var(--gradient-primary);
}
Tokens
Same as Button: --control-height-*,
--button-padding-x-*, --radius-md, the variant colour pairs, --ring,
--duration-fast.
Accessibility
- A real
<button type="button">, keyboard focus ring onfocus-visibleonly. isGeneratingsetsaria-busyandaria-disabled, keeps focus, and reads "Generating" to screen readers.- The sparkle is
aria-hiddenandfocusable="false"; the label is the children, so an icon-only AIButton (size="icon") needs anaria-label. - The hover pulse is removed under
prefers-reduced-motion.