ProComponents, templates & AI tooling
2.3k

Button 按钮更新

按下时触发操作的交互组件。

导入

import { Button } from 'heroui-native';

结构

<Button>
  <Button.Label>...</Button.Label>
</Button>
  • Button:主容器,负责按压交互、动画与变体。字符串子节点会渲染为标签,也可使用复合子组件自定义布局。
  • Button.Label:按钮文字,继承父级 Button 上下文中的尺寸与变体样式。

用法

基础用法

Button 可直接传入字符串子节点,会自动渲染为标签。

<Button>基础按钮</Button>

使用复合子组件

使用 Button.Label 显式控制标签部分。

<Button>
  <Button.Label>点我</Button.Label>
</Button>

与图标组合

将图标与文字组合,增强可读性。

<Button>
  <Icon name="add" size={20} />
  <Button.Label>添加项目</Button.Label>
</Button>

<Button>
  <Button.Label>下载</Button.Label>
  <Icon name="download" size={18} />
</Button>

仅图标

使用 isIconOnly 创建方形纯图标按钮。

<Button isIconOnly>
  <Icon name="heart" size={18} />
</Button>

尺寸

通过三种尺寸控制按钮大小。

<Button size="sm">小</Button>
<Button size="md">中</Button>
<Button size="lg">大</Button>

变体

提供七种视觉变体,用于不同强调层级。

<Button variant="primary">主要</Button>
<Button variant="secondary">次要</Button>
<Button variant="tertiary">第三级</Button>
<Button variant="outline">描边</Button>
<Button variant="ghost">幽灵</Button>
<Button variant="danger">危险</Button>
<Button variant="danger-soft">柔和危险</Button>

反馈变体

feedbackVariant 控制渲染哪些按压反馈效果:

  • 'scale-highlight'(默认):内置缩放 + 高亮遮罩
  • 'scale-ripple':内置缩放 + 水波纹遮罩
  • 'scale':仅内置缩放(无遮罩)
  • 'none':无任何反馈动画
{/* 缩放 + 高亮(默认) */}
<Button feedbackVariant="scale-highlight">高亮效果</Button>

{/* 缩放 + 水波纹 */}
<Button feedbackVariant="scale-ripple">水波纹效果</Button>

{/* 仅缩放 */}
<Button feedbackVariant="scale">仅缩放</Button>

{/* 无反馈 */}
<Button feedbackVariant="none">无反馈</Button>

自定义动画

animation 控制各子动画,其结构取决于 feedbackVariant

{/* 自定义缩放与高亮(默认 feedbackVariant) */}
<Button
  animation={{
    scale: { value: 0.97 },
    highlight: {
      backgroundColor: { value: '#3b82f6' },
      opacity: { value: [0, 0.2] },
    },
  }}
>
  自定义高亮
</Button>

{/* 自定义缩放与水波纹 */}
<Button
  feedbackVariant="scale-ripple"
  animation={{
    scale: { value: 0.97 },
    ripple: {
      backgroundColor: { value: '#3b82f6' },
      opacity: { value: [0, 0.3, 0] },
    },
  }}
>
  自定义水波纹
</Button>

关闭部分子动画

将某个子动画设为 false 即可单独关闭:

{/* 关闭缩放,保留高亮 */}
<Button animation={{ scale: false }}>无缩放</Button>

{/* 关闭高亮,保留缩放 */}
<Button animation={{ highlight: false }}>无高亮</Button>

{/* 两者都关 */}
<Button animation={{ scale: false, highlight: false }}>无动画</Button>

关闭全部动画

使用 animation={false} 关闭所有反馈,或使用 animation="disable-all" 级联关闭:

<Button animation={false}>已禁用动画</Button>
<Button animation="disable-all">全部禁用(级联)</Button>

加载态与 Spinner

配合 Spinner 展示加载状态。

const themeColorAccentForeground = useThemeColor('accent-foreground');

<Button
  layout={LinearTransition.springify()}
  variant="primary"
  onPress={() => {
    setIsDownloading(true);
    setTimeout(() => {
      setIsDownloading(false);
    }, 3000);
  }}
  isIconOnly={isDownloading}
  className="self-center"
>
  {isDownloading ? (
    <Spinner entering={FadeIn.delay(50)} color={themeColorAccentForeground} />
  ) : (
    '立即下载'
  )}
</Button>;

使用 LinearGradient 自定义背景

通过绝对定位元素添加渐变背景。使用 feedbackVariant="none" 关闭默认高亮遮罩,或使用 feedbackVariant="scale-ripple" 自定义水波纹。

import { Button, PressableFeedback } from 'heroui-native';
import { LinearGradient } from 'expo-linear-gradient';
import { StyleSheet } from 'react-native';

{/* 无反馈遮罩的渐变 */}
<Button feedbackVariant="none">
  <LinearGradient
    colors={['#9333ea', '#ec4899']}
    start={{ x: 0, y: 0 }}
    end={{ x: 1, y: 0 }}
    style={StyleSheet.absoluteFill}
  />
  <Button.Label className="text-white font-bold">渐变</Button.Label>
</Button>

{/* 带自定义水波纹的渐变 */}
<Button
  feedbackVariant="scale-ripple"
  animation={{
    ripple: {
      backgroundColor: { value: 'white' },
      opacity: { value: [0, 0.5, 0] },
    },
  }}
>
  <LinearGradient
    colors={['#0d9488', '#ec4899']}
    start={{ x: 0, y: 0 }}
    end={{ x: 1, y: 0 }}
    style={StyleSheet.absoluteFill}
  />
  <Button.Label className="text-white font-bold" pointerEvents="none">
    带水波纹的渐变
  </Button.Label>
</Button>

示例

import { Button, useThemeColor } from 'heroui-native';
import { Ionicons } from '@expo/vector-icons';
import { View } from 'react-native';

export default function ButtonExample() {
  const [
    themeColorAccentForeground,
    themeColorAccentSoftForeground,
    themeColorDangerForeground,
    themeColorDefaultForeground,
  ] = useThemeColor([
    'accent-foreground',
    'accent-soft-foreground',
    'danger-foreground',
    'default-foreground',
  ]);

  return (
    <View className="gap-4 p-4">
      <Button variant="primary">
        <Ionicons name="add" size={20} color={themeColorAccentForeground} />
        <Button.Label>添加项目</Button.Label>
      </Button>

      <View className="flex-row gap-4">
        <Button size="sm" isIconOnly>
          <Ionicons name="heart" size={16} color={themeColorAccentForeground} />
        </Button>
        <Button size="sm" variant="secondary" isIconOnly>
          <Ionicons
            name="bookmark"
            size={16}
            color={themeColorAccentSoftForeground}
          />
        </Button>
        <Button size="sm" variant="danger" isIconOnly>
          <Ionicons name="trash" size={16} color={themeColorDangerForeground} />
        </Button>
      </View>

      <Button variant="tertiary">
        <Button.Label>了解更多</Button.Label>
        <Ionicons
          name="chevron-forward"
          size={18}
          color={themeColorDefaultForeground}
        />
      </Button>
    </View>
  );
}

更多示例见 GitHub 仓库

API 参考

Button

Button 继承 PressableFeedback 的全部属性(animation 除外,已重新定义),并增加按钮专用属性。

proptypedefaultdescription
variant'primary' | 'secondary' | 'tertiary' | 'outline' | 'ghost' | 'danger' | 'danger-soft''primary'按钮视觉变体
size'sm' | 'md' | 'lg''md'按钮尺寸
isIconOnlybooleanfalse是否为仅图标按钮(方形比例)
feedbackVariant'scale-highlight' | 'scale-ripple' | 'scale' | 'none''scale-highlight'决定渲染哪些反馈效果
animationButtonAnimation-动画配置(结构取决于 feedbackVariant

继承属性(含 isDisabledclassNamechildren 及所有 Pressable 属性)见 PressableFeedback API 参考

ButtonAnimation

animation 是按 feedbackVariant 区分的联合类型,遵循 AnimationRoot 控制流:

  • trueundefined:使用默认动画
  • false"disabled":关闭所有反馈动画
  • "disable-all":级联关闭所有动画(含子复合部件)
  • object:自定义子动画配置(见下)

feedbackVariant="scale-highlight"(默认)时:

proptypedefaultdescription
scalePressableFeedbackScaleAnimation-缩放动画配置(false 为关闭)
highlightPressableFeedbackHighlightAnimation-高亮遮罩配置(false 为关闭)
state'disabled' | 'disable-all' | boolean-在保留配置的同时控制动画状态(运行时切换)

feedbackVariant="scale-ripple" 时:

proptypedefaultdescription
scalePressableFeedbackScaleAnimation-缩放动画配置(false 为关闭)
ripplePressableFeedbackRippleAnimation-水波纹遮罩配置(false 为关闭)
state'disabled' | 'disable-all' | boolean-在保留配置的同时控制动画状态(运行时切换)

feedbackVariant="scale" 时:

proptypedefaultdescription
scalePressableFeedbackScaleAnimation-缩放动画配置(false 为关闭)
state'disabled' | 'disable-all' | boolean-在保留配置的同时控制动画状态(运行时切换)

feedbackVariant="none" 时:

仅接受字符串 'disable-all'。所有反馈效果均被禁用。

动画子类型(PressableFeedbackScaleAnimationPressableFeedbackHighlightAnimationPressableFeedbackRippleAnimation)详见 PressableFeedback API 参考

Button.Label

proptypedefaultdescription
childrenReact.ReactNode-作为标签渲染的内容
classNamestring-额外 CSS 类
...TextPropsTextProps-支持全部标准 Text 属性

Hooks

useButton

用于读取 Button 上下文,返回尺寸、变体与禁用状态。

import { useButton } from 'heroui-native';

const { size, variant, isDisabled } = useButton();

返回值

propertytypedescription
size'sm' | 'md' | 'lg'按钮尺寸
variant'primary' | 'secondary' | 'tertiary' | 'outline' | 'ghost' | 'danger' | 'danger-soft'按钮视觉变体
isDisabledboolean是否禁用

说明: 必须在 Button 内使用;在按钮上下文外调用会抛错。

本页目录