> Leaf UI 0.6.0 · Package: @ifhover/leaf-ui · Source: b30c3d3a8fa9c5e15d0d0522cebfbd33f60c6b06
> Browser documentation: https://ifhover.github.io/leaf-ui/v/0.6.0/components/button.html

> For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms-full.txt.

# Button 按钮

用于触发操作，如提交表单、保存内容或删除记录。

## 基础用法

`solid` 适合主要操作，`outline` 使用白底、正文色和细边框，适合次要操作，`ghost` 适合低优先级操作，`link` 使用主题色文字，无内边距、边框和固定控件高度。页面跳转使用 Link 组件。

主按钮和描边按钮点击时，外缘波纹快速扩散后缓慢淡出，按钮与文字保持稳定；文字和链接按钮不展示波纹。主按钮悬停时提亮、按下时加深；描边按钮保持底色，通过文字和边框变色反馈。危险操作使用红色，波纹跟随主题；关闭动效或启用系统减少动态效果后不展示波纹。


主要按钮描边按钮文字按钮链接按钮

variants.tsx

复制代码

```tsx lineNumbers file="../../src/examples/button/variants.tsx"
import { Button, Space } from '@ifhover/leaf-ui';

export function ButtonVariants() {
  return (
    <Space wrap>
      <Button>主要按钮</Button>
      <Button variant="outline">描边按钮</Button>
      <Button variant="ghost">文字按钮</Button>
      <Button variant="link">链接按钮</Button>
    </Space>
  );
}
```

展开代码

组件样式会自动加载，接入步骤见[快速开始](https://ifhover.github.io/leaf-ui/v/0.6.0/guide/getting-started.md)。

## 危险操作

为删除、清空、撤销等操作使用 danger。所有样式、图标和加载状态都会使用独立的红色语义主题。


删除项目撤销授权清空禁止删除正在删除

danger.tsx

复制代码

```tsx lineNumbers file="../../src/examples/button/danger.tsx"
import { Button, Space } from '@ifhover/leaf-ui';

import { Trash2 } from 'lucide-react';

export function ButtonDanger() {
  return (
    <Space wrap>
      <Button danger startIcon={<Trash2 />}>
        删除项目
      </Button>
      <Button danger variant="outline">
        撤销授权
      </Button>
      <Button danger variant="ghost">
        清空
      </Button>
      <Button danger disabled>
        禁止删除
      </Button>
      <Button danger loading>
        正在删除
      </Button>
    </Space>
  );
}
```

展开代码

## 尺寸

提供小、中、大三种尺寸，适配不同密度的操作区。外观可通过[主题变量](https://ifhover.github.io/leaf-ui/v/0.6.0/guide/theming.md)定制。


小按钮默认按钮大按钮

sizes.tsx

复制代码

```tsx lineNumbers file="../../src/examples/button/sizes.tsx"
import { Button, Space } from '@ifhover/leaf-ui';

export function ButtonSizes() {
  return (
    <Space wrap>
      <Button size="sm">小按钮</Button>
      <Button size="md">默认按钮</Button>
      <Button size="lg">大按钮</Button>
    </Space>
  );
}
```

展开代码

## 禁用与加载

加载时会显示旋转指示器，自动禁用按钮，并设置 `aria-busy`。原有文字保留，帮助用户理解正在进行的操作。


暂不可用加载中已禁用

states.tsx

复制代码

```tsx lineNumbers file="../../src/examples/button/states.tsx"
import { Button, Space } from '@ifhover/leaf-ui';

export function ButtonStates() {
  return (
    <Space wrap>
      <Button disabled>暂不可用</Button>
      <Button loading>加载中</Button>
      <Button variant="outline" disabled>
        已禁用
      </Button>
    </Space>
  );
}
```

展开代码

## 实际交互

通过应用状态控制 `loading`。下面的示例会在 1.2 秒后完成保存；实际使用时，把计时器替换成你的异步业务操作。


保存更改点击试试保存操作。

loading.tsx

复制代码

```tsx lineNumbers file="../../src/examples/button/loading.tsx"
import { Button, Space } from '@ifhover/leaf-ui';

import { useEffect, useRef, useState } from 'react';

export function ButtonLoading() {
  const [status, setStatus] = useState<'idle' | 'loading' | 'saved'>('idle');
  const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);

  useEffect(() => () => clearTimeout(timer.current), []);

  function save() {
    clearTimeout(timer.current);
    setStatus('loading');
    // 示例模拟一次异步保存；实际使用时替换成你的业务请求。
    timer.current = setTimeout(() => setStatus('saved'), 1200);
  }

  return (
    <Space wrap>
      <Button loading={status === 'loading'} onClick={save}>
        {status === 'loading' ? '正在保存' : status === 'saved' ? '再次保存' : '保存更改'}
      </Button>
      <span role="status">{status === 'saved' ? '更改已保存。' : '点击试试保存操作。'}</span>
    </Space>
  );
}
```

展开代码

## 图标

示例使用 `lucide-react` 的按需导入图标。`startIcon` 和 `endIcon` 接受 React 节点。图标容器默认对辅助技术隐藏，按钮文字提供名称；只有图标时请设置 `aria-label`。


新建项目继续下一步

icons.tsx

复制代码

```tsx lineNumbers file="../../src/examples/button/icons.tsx"
import { Button, Space } from '@ifhover/leaf-ui';

import { ArrowRight, Plus, Trash2 } from 'lucide-react';

export function ButtonIcons() {
  return (
    <Space wrap>
      <Button startIcon={<Plus />}>新建项目</Button>
      <Button variant="outline" endIcon={<ArrowRight />}>
        继续下一步
      </Button>
      <Button variant="outline" aria-label="添加项目" startIcon={<Plus />} />
      <Button danger variant="outline" aria-label="删除项目" startIcon={<Trash2 />} />
    </Space>
  );
}
```

展开代码

## 整行显示

`fullWidth` 让按钮填满父容器宽度，适合表单提交和移动端操作区。


继续下一步

full-width.tsx

复制代码

```tsx lineNumbers file="../../src/examples/button/full-width.tsx"
import { Button } from '@ifhover/leaf-ui';

export function ButtonFullWidth() {
  return <Button fullWidth>继续下一步</Button>;
}
```

展开代码

## 扩展用法


按钮组上一步下一步

分裂按钮保存

extensions.tsx

复制代码

```tsx lineNumbers file="../../src/examples/button/extensions.tsx"
import { Button, ButtonGroup, Flex, Space, SplitButton, Text } from '@ifhover/leaf-ui';

export function ExtensionDemo() {
  return (
    <Space direction="vertical" align="start">
      <Flex direction="column" gap="sm" align="center">
        <Text>按钮组</Text>
        <ButtonGroup>
          <Button variant="outline">上一步</Button>
          <Button variant="outline">下一步</Button>
        </ButtonGroup>
      </Flex>
      <Flex direction="column" gap="sm" align="center">
        <Text>分裂按钮</Text>
        <SplitButton
          items={[
            { key: 'copy', label: '保存副本' },
            { key: 'draft', label: '存为草稿' },
          ]}
        >
          保存
        </SplitButton>
      </Flex>
    </Space>
  );
}
```

展开代码

## Button API

| 属性          | 类型                                          | 默认值        | 说明                    |
| ----------- | ------------------------------------------- | ---------- | --------------------- |
| `variant`   | `'solid' \| 'outline' \| 'ghost' \| 'link'` | `'solid'`  | 视觉样式                  |
| `size`      | `'sm' \| 'md' \| 'lg'`                      | `'md'`     | 按钮尺寸                  |
| `danger`    | `boolean`                                   | `false`    | 使用红色危险语义，支持所有 variant |
| `loading`   | `boolean`                                   | `false`    | 显示加载指示器并禁用交互          |
| `fullWidth` | `boolean`                                   | `false`    | 填满父容器宽度               |
| `startIcon` | `ReactNode`                                 | —          | 文字前的图标，加载时由指示器替代      |
| `endIcon`   | `ReactNode`                                 | —          | 文字后的图标                |
| `disabled`  | `boolean`                                   | `false`    | 禁用交互。                 |
| `type`      | `'button' \| 'submit' \| 'reset'`           | `'button'` | 原生按钮类型                |
| `ref`       | `Ref<HTMLButtonElement>`                    | —          | 按钮 DOM 引用             |

支持其他原生 `button` 属性，例如 `onClick`、`name`、`value`、`form`、`className`、`style`、`aria-*` 和 `data-*`。

## 类型

可导入 [`ButtonProps`](#button-api) 定义组件属性，或单独使用以下样式、尺寸类型：

```ts
import type { ButtonProps, ButtonVariant, ButtonSize } from '@ifhover/leaf-ui';
```

## 表单与键盘

默认 `type="button"`，放进表单时不会意外提交。需要提交表单，请显式设置 `type="submit"`。

组件保留原生键盘行为：Tab 聚焦，Enter 或 Space 触发。禁用和加载状态会阻止交互；聚焦时显示清晰的焦点轮廓。

## 定制样式

```tsx
<ConfigProvider theme={{ primaryColor: '#7654c6', borderRadius: 18 }}>
  <Button>自定义主题</Button>
</ConfigProvider>
```

配置选项与实时示例见[定制主题](https://ifhover.github.io/leaf-ui/v/0.6.0/guide/theming.md)。

## 扩展类型

```ts
import type { ButtonGroupProps, SplitButtonProps } from '@ifhover/leaf-ui';
```

## ButtonGroupProps API

| 属性         | 类型                     | 默认值    | 说明      |
| ---------- | ---------------------- | ------ | ------- |
| `size`     | `'sm' \| 'md' \| 'lg'` | —      | 尺寸或间距预设 |
| `disabled` | `boolean`              | —      | 禁用交互。   |
| `attached` | `boolean`              | `true` | 连接相邻按钮  |

## SplitButtonProps API

| 属性              | 类型                                                                                                                                              | 默认值 | 说明                   |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | --- | -------------------- |
| `variant`       | `'solid' \| 'outline' \| 'ghost' \| 'link'`                                                                                                     | —   | 按钮样式                 |
| `size`          | `'sm' \| 'md' \| 'lg'`                                                                                                                          | —   | 尺寸或间距预设              |
| `danger`        | `boolean`                                                                                                                                       | —   | 危险操作颜色               |
| `loading`       | `boolean`                                                                                                                                       | —   | 加载状态                 |
| `fullWidth`     | `boolean`                                                                                                                                       | —   | 占满宽度                 |
| `startIcon`     | `ReactNode`                                                                                                                                     | —   | 前置图标                 |
| `endIcon`       | `ReactNode`                                                                                                                                     | —   | 后置图标                 |
| `items`         | `readonly `[`DropdownItem`](https://ifhover.github.io/leaf-ui/v/0.6.0/components/dropdown.md#dropdownitem)`[]`                                  | 必填  | 必需。数据项目，保持 key 唯一且稳定 |
| `menuLabel`     | `string`                                                                                                                                        | —   | 菜单按钮的可访问名称           |
| `dropdownProps` | `Omit<`[`DropdownProps`](https://ifhover.github.io/leaf-ui/v/0.6.0/components/dropdown.md#dropdown-api)`, 'items' \| 'children' \| 'disabled'>` | —   | 操作菜单属性               |
