# @askrjs/ui/button

> Published API exports for @askrjs/ui/button.

Source: [https://askrjs.com/docs/reference/api/ui/button](https://askrjs.com/docs/reference/api/ui/button)

Status: stable. Packages: @askrjs/ui/button.

**Published packages are authoritative.** Examples may lag behind a published contract. When guidance differs, verify the exports and TypeScript declarations in your installed package, then file an issue.

## Exports

This entrypoint publishes 11 exports from the declarations shipped by @askrjs/ui.

### `Button`

```ts
Button: { (props: ButtonNativeProps): JSX.Element; (props: ButtonAsChildProps): JSX.Element; }
```

Headless Button component

## Responsibilities
- Compose pressable foundation for interaction behavior
- Enforce type="button" default to prevent accidental form submission
- Forward props and refs to native button or child element

## Non-Responsibilities (delegated to pressable foundation)
- Keyboard event handling (Enter/Space)
- Pointer event handling
- Disabled state enforcement
- ARIA attribute application

## Invariants
- MUST NOT contain any event handler logic
- MUST NOT check disabled prop directly
- MUST use pressable() for ALL interaction behavior
- MUST use mergeProps() for ALL prop composition
Renders the `button` part of `button`.

Supports polymorphic rendering via `asChild`.

````tsx
Native button (prevents accidental submit)
```tsx
<Button onPress={handleSave}>Save</Button>
```
````

````tsx
Explicit form submission
```tsx
<Button type="submit" onPress={handleSubmit}>Submit</Button>
```
````

````tsx
Polymorphic rendering (asChild)
```tsx
<Button asChild onPress={handleNav}>
<a href="/home">Home</a>
</Button>
```
````

### `BUTTON_A11Y_CONTRACT`

```ts
BUTTON_A11Y_CONTRACT: { readonly KEYBOARD_ACTIVATION: readonly ["Enter", "Space"]; readonly ROLE: "button"; readonly DISABLED_ATTRIBUTES: { readonly native: "disabled"; readonly asChild: "aria-disabled"; }; readonly DATA_ATTRIBUTES: { readonly disabled: "data-disabled"; }; readonly FOCUS_RULES: { readonly enabled: "focusable"; readonly disabled: "not-focusable"; }; }
```

Accessibility contract for Button component

Following WAI-ARIA Button Pattern:
https://www.w3.org/WAI/ARIA/apg/patterns/button/

## Role
- Native <button>: implicit role="button"
- asChild: preserves child role (e.g., role="button" on <div>)

## States
- disabled (native): uses `disabled` attribute
- disabled (asChild): uses `aria-disabled="true"` + `tabindex="-1"`

## Keyboard
- Space: Activates button (handled by pressable foundation)
- Enter: Activates button (handled by pressable foundation)
- Disabled buttons do not respond to interaction

## Focus
- Native buttons: focusable by default
- asChild elements: receive tabindex if not naturally focusable
- Disabled: removed from tab order (tabindex="-1" or native disabled)

## Screen Reader
- Announces role as "button"
- Announces disabled state
- Announces accessible name from text content or aria-label

## Implementation Notes
- All interaction behavior is delegated to `pressable` foundation
- Button component does NOT implement keyboard handling directly
- Button component does NOT check disabled prop directly
- All ARIA attributes are applied by foundation, not component

### `ButtonA11yContract`

```ts
ButtonA11yContract: typeof BUTTON_A11Y_CONTRACT
```

Type-safe accessibility contract

### `ButtonAsChildElement`

```ts
ButtonAsChildElement: JSXElement | JSX.Element
```

Button As Child Element.

### `ButtonAsChildProps`

```ts
ButtonAsChildProps: ButtonOwnProps & {
  asChild: true;
  children: ButtonAsChildElement;
  ref?: Ref<Element>;
  type?: never;
}
```

Props when rendering with asChild (polymorphic)

- `asChild`: asChild: true;

- `children`: children: ButtonAsChildElement;

- `disabled`: disabled?: boolean | undefined;

- `onPress`: onPress?: ((e: PressEvent) => void) | undefined;

- `ref`: ref?: Ref<Element>;

- `size`: size?: ButtonSize | undefined;

- `type`: type?: undefined;

- `variant`: variant?: ButtonVariant | undefined;

- `width`: width?: ButtonWidth | undefined;

### `ButtonNativeProps`

```ts
ButtonNativeProps: Omit<JSX.IntrinsicElements['button'], 'children' | 'onClick' | 'disabled' | 'type' | 'ref'> & ButtonOwnProps & {
  asChild?: false;
  ref?: Ref<HTMLButtonElement>;
  type?: 'button' | 'submit' | 'reset';
}
```

Props when rendering as native <button>

- `asChild`: asChild?: false | undefined;

- `children`: children?: unknown;

- `disabled`: disabled?: boolean | undefined;

- `onPress`: onPress?: ((e: PressEvent) => void) | undefined;

- `ref`: ref?: Ref<HTMLButtonElement>;

- `size`: size?: ButtonSize | undefined;

- `type`: type?: "button" | "submit" | "reset" | undefined;

- `variant`: variant?: ButtonVariant | undefined;

- `width`: width?: ButtonWidth | undefined;

### `ButtonOwnProps`

```ts
ButtonOwnProps: {
  children?: unknown;
  onPress?: (e: PressEvent) => void;
  disabled?: boolean;
  variant?: ButtonVariant;
  size?: ButtonSize;
  width?: ButtonWidth;
}
```

Core Button props shared across all variants

- `children`: children?: unknown;

- `disabled`: disabled?: boolean | undefined;

- `onPress`: onPress?: ((e: PressEvent) => void) | undefined;

- `size`: size?: ButtonSize | undefined;

- `variant`: variant?: ButtonVariant | undefined;

- `width`: width?: ButtonWidth | undefined;

### `ButtonProps`

```ts
ButtonProps: ButtonNativeProps | ButtonAsChildProps
```

Union of all Button prop variants

- `asChild`: asChild?: boolean | undefined;

- `children`: children?: unknown;

- `disabled`: disabled?: boolean | undefined;

- `onPress`: onPress?: ((e: PressEvent) => void) | undefined;

- `ref`: ref?: ((value: Element | null) => void) | { current: Element | null; } | ((value: HTMLButtonElement | null) => void) | { current: HTMLButtonElement | null; } | null | undefined;

- `size`: size?: ButtonSize | undefined;

- `type`: type?: "button" | "submit" | "reset" | undefined;

- `variant`: variant?: ButtonVariant | undefined;

- `width`: width?: ButtonWidth | undefined;

### `ButtonSize`

```ts
ButtonSize: 'xs' | 'sm' | 'md' | 'lg' | 'icon' | 'icon-xs' | 'icon-sm' | 'icon-lg'
```

Button Size.

### `ButtonVariant`

```ts
ButtonVariant: 'default' | 'primary' | 'secondary' | 'outline' | 'ghost' | 'destructive' | 'link'
```

Button Variant.

### `ButtonWidth`

```ts
ButtonWidth: 'auto' | 'full'
```

Button Width.

## Documentation navigation

[Previous](https://askrjs.com/docs/reference/api/ui/avatar/index.md) | [Next](https://askrjs.com/docs/reference/api/ui/checkbox/index.md)
