ProComponents, templates & AI tooling
HeroUI
27.7k

Button

Button 从 HeroUI v2 到 v3 的迁移指南。

完整的 API 参考、样式指南与高级示例请参阅 v3 Button 文档。本指南只关注从 HeroUI v2 的迁移。

结构变化

在 v2 中,Button 通过 colorvariant 组合使用:

import { Button } from "@heroui/react";

export default function App() {
  return <Button color="primary" variant="solid">Button</Button>;
}

在 v3 中,Button 仅使用 variant prop(不再有独立的 color prop):

import { Button } from "@heroui/react";

export default function App() {
  return <Button variant="primary">Button</Button>;
}

主要变化

1. 变体与颜色

v2: 使用 color + variant 组合
v3: 仅使用 variant(无独立 color prop)

v2 color + variantv3 变体说明
color="primary" variant="solid"variant="primary"默认主按钮
color="default" variant="solid"variant="primary"使用 primary 变体
color="secondary" variant="solid"variant="secondary"相同
color="success" variant="solid"variant="primary"如需可配合自定义样式使用 primary
color="warning" variant="solid"variant="primary"如需可配合自定义样式使用 primary
color="danger" variant="solid"variant="danger"提供 danger 变体
color="primary" variant="bordered"variant="secondary"外观相近
color="primary" variant="light"variant="tertiary"外观相近
color="primary" variant="flat"variant="tertiary"外观相近
color="primary" variant="faded"variant="secondary"外观相近
color="primary" variant="ghost"variant="ghost"相同
color="danger" variant="flat"variant="danger-soft"新增柔和危险变体

v2 变体: solidborderedlightflatfadedshadowghost
v3 变体: primarysecondarytertiaryoutlineghostdangerdanger-soft

2. 加载状态:isLoadingisPending

v2: 使用 isLoading prop
v3: 使用 isPending prop

3. 默认宽度行为

v2: 按钮按尺寸带有最小宽度(sm:min-w-16,md:min-w-20,lg:min-w-24
v3: 按钮默认使用 w-fit(宽度随内容,无最小宽度)

因此当文案较短时,v3 按钮会比 v2 更窄。若要保留 v2 的最小宽度行为,请添加 Tailwind 类,请见下方 尺寸与最小宽度 示例小节。

4. Prop 变更

v2 propv3 位置说明
isLoadingButton已重命名为 isPending
isIconOnlyButtonv3 仍支持 — 渲染仅含图标的方形按钮
color已移除(由变体负责样式)
radius已移除(请使用 Tailwind,例如 rounded-lg
startContent, endContent请将图标作为 children 放置
spinner, spinnerPlacement请通过渲染 prop 自行处理加载态
disableRipple已移除(v3 已移除波纹)
disableAnimation已移除(动画由内部处理)
classNames请使用 className

5. ButtonGroup 仍可用

v2: 提供独立的 ButtonGroup 组件
v3: ButtonGroup 仍然存在。详见 ButtonGroup 迁移指南

迁移示例

变体

<Button color="primary" variant="solid">Solid</Button>
<Button color="primary" variant="bordered">Bordered</Button>
<Button color="primary" variant="ghost">Ghost</Button>
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="ghost">Ghost</Button>

danger-soft 变体

danger-soft 变体为 v3 新增,用于替代 v2 中 color="danger" variant="flat" 的用法。

<Button color="danger" variant="flat">Delete</Button>
<Button variant="danger-soft">Delete</Button>

仅图标(isIconOnly

isIconOnly prop 在 v2 与 v3 中均可用,用于渲染适配单个图标的方形按钮。v3 中请用 variant 替代 color 控制样式。

<Button isIconOnly color="danger" variant="flat">
  <HeartIcon />
</Button>
<Button isIconOnly color="primary" variant="bordered" size="sm">
  <SearchIcon />
</Button>
import { Icon } from "@iconify/react";

<Button isIconOnly variant="danger-soft">
  <Icon icon="gravity-ui:heart" />
</Button>
<Button isIconOnly variant="secondary" size="sm">
  <Icon icon="gravity-ui:magnifier" />
</Button>

加载状态

{/* Simple loading */}
<Button isLoading color="primary">
  Loading
</Button>

{/* Loading with conditional content */}
<Button 
  isLoading={isLoading}
  spinnerPlacement="start"
  color="primary"
  onPress={() => setIsLoading(true)}
>
  Upload File
</Button>
import { useState } from "react";
import { Spinner } from "@heroui/react";
import { Icon } from "@iconify/react";

const [isLoading, setIsLoading] = useState(false);

{/* Simple loading */}
<Button isPending={isLoading}>
  {({isPending}) => (
    <>
      {isPending && <Spinner color="current" size="sm" />}
      Loading
    </>
  )}
</Button>

{/* Loading with conditional content */}
<Button 
  isPending={isLoading}
  onPress={() => setIsLoading(true)}
>
  {({isPending}) => (
    <>
      {isPending ? (
        <Spinner color="current" size="sm" />
      ) : (
        <Icon icon="gravity-ui:paperclip" />
      )}
      {isPending ? "Uploading..." : "Upload File"}
    </>
  )}
</Button>

带图标

import { Icon } from "@iconify/react";

<Button 
  color="success" 
  endContent={<Icon icon="gravity-ui:camera" />}
>
  Take a photo
</Button>
<Button 
  color="danger" 
  startContent={<Icon icon="gravity-ui:trash-bin" />}
  variant="bordered"
>
  Delete user
</Button>
import { Icon } from "@iconify/react";

<Button variant="primary">
  <Icon icon="gravity-ui:camera" />
  Take a photo
</Button>
<Button variant="secondary">
  <Icon icon="gravity-ui:trash-bin" />
  Delete user
</Button>

仅图标按钮

<Button isIconOnly color="danger">
  <HeartIcon />
</Button>
import { Icon } from "@iconify/react";

<Button isIconOnly variant="danger">
  <Icon icon="gravity-ui:heart" />
</Button>

按钮组

import { Button, ButtonGroup } from "@heroui/react";

<ButtonGroup size="sm" color="primary" variant="solid">
  <Button>One</Button>
  <Button>Two</Button>
  <Button>Three</Button>
</ButtonGroup>
import { Button, ButtonGroup } from "@heroui/react";

<ButtonGroup size="sm" variant="primary">
  <Button>One</Button>
  <Button>Two</Button>
  <Button>Three</Button>
</ButtonGroup>

尺寸与最小宽度

{/* v2 automatically applies minimum widths */}
<Button size="md" color="primary">Save</Button>
{/* v3 uses w-fit by default - add min-width to match v2 */}
<Button size="md" variant="primary" className="min-w-20">
  Save
</Button>

渲染 prop 模式

v3 Button 支持渲染 prop 模式,可拿到状态信息:

<Button isPending={isLoading}>
  {({isPending, isPressed, isHovered, isFocused, isFocusVisible, isDisabled}) => (
    <>
      {isPending && <Spinner size="sm" />}
      {isPressed ? "Pressed!" : "Click me"}
    </>
  )}
</Button>

可用的渲染 prop:

  • isPending — 是否处于加载状态
  • isPressed — 是否正被按下
  • isHovered — 是否悬停
  • isFocused — 是否聚焦
  • isFocusVisible — 是否应显示焦点环
  • isDisabled — 是否禁用

总结

  1. color prop 已移除:请用 variant 替代 color + variant 组合
  2. 变体体系变更:新变体系统(primarysecondarytertiaryoutlineghostdangerdanger-soft
  3. danger-soft 变体:v3 新增,替代 v2 的 color="danger" variant="flat"
  4. isLoadingisPending:加载相关 prop 已重命名
  5. isIconOnly:v3 仍支持 — 用于仅图标的方形按钮
  6. 默认宽度变更:按钮默认 w-fit,不再内置最小宽度 — 可添加 min-w-* 贴近 v2
  7. 图标startContent / endContent 已移除 — 请将图标作为 children
  8. 加载指示器:需通过渲染 prop 自行组合 Spinner 等
  9. 渲染 prop:v3 Button 的 children 可为函数,参数包含 isPendingisPressedisHoveredisFocusedisFocusVisibleisDisabled
  10. radius 已移除:请使用 Tailwind CSS 类
  11. 波纹已移除:v3 无波纹效果
  12. ButtonGroup:参见 ButtonGroup 迁移指南
  13. classNames 已移除:请使用 className prop

本页目录