ProComponents, templates & AI tooling
2.3k

Dialog 对话框更新

模态浮层,带动画过渡并支持手势关闭。

导入

import { Dialog } from 'heroui-native';

结构

<Dialog>
  <Dialog.Trigger>...</Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay>...</Dialog.Overlay>
    <Dialog.Content>
      <Dialog.Close>...</Dialog.Close>
      <Dialog.Title>...</Dialog.Title>
      <Dialog.Description>...</Dialog.Description>
    </Dialog.Content>
  </Dialog.Portal>
</Dialog>
  • Dialog:根组件,管理开关状态并向子级提供上下文。
  • Dialog.Trigger:按下后打开对话框的可按压区域。
  • Dialog.Portal:在 Portal 中渲染内容,居中布局并控制动画。
  • Dialog.Overlay:内容背后的遮罩,按下通常可关闭对话框。
  • Dialog.Content:主容器,支持拖拽关闭等手势。
  • Dialog.Close:关闭按钮;可自定义子节点或使用默认关闭图标。
  • Dialog.Title:标题,语义为标题角色。
  • Dialog.Description:补充说明文字。

用法

基础对话框

包含标题、描述与关闭按钮的简单对话框。

<Dialog isOpen={isOpen} onOpenChange={setIsOpen}>
  <Dialog.Trigger asChild>
    <Button>打开对话框</Button>
  </Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay />
    <Dialog.Content>
      <Dialog.Close />
      <Dialog.Title>...</Dialog.Title>
      <Dialog.Description>...</Dialog.Description>
    </Dialog.Content>
  </Dialog.Portal>
</Dialog>

可滚动内容

长内容使用滚动容器承载。

<Dialog isOpen={isOpen} onOpenChange={setIsOpen}>
  <Dialog.Trigger>...</Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay />
    <Dialog.Content>
      <Dialog.Close />
      <Dialog.Title>...</Dialog.Title>
      <View className="h-[300px]">
        <ScrollView>...</ScrollView>
      </View>
    </Dialog.Content>
  </Dialog.Portal>
</Dialog>

表单对话框

包含输入与键盘避让的对话框。

<Dialog isOpen={isOpen} onOpenChange={setIsOpen}>
  <Dialog.Trigger>...</Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay />
    <KeyboardAvoidingView behavior="padding">
      <Dialog.Content>
        <Dialog.Close />
        <Dialog.Title>...</Dialog.Title>
        <TextField>...</TextField>
        <Button onPress={handleSubmit}>提交</Button>
      </Dialog.Content>
    </KeyboardAvoidingView>
  </Dialog.Portal>
</Dialog>

示例

import { Button, Dialog } from 'heroui-native';
import { View } from 'react-native';
import { useState } from 'react';

export default function DialogExample() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <Dialog isOpen={isOpen} onOpenChange={setIsOpen}>
      <Dialog.Trigger asChild>
        <Button variant="primary">打开对话框</Button>
      </Dialog.Trigger>
      <Dialog.Portal>
        <Dialog.Overlay />
        <Dialog.Content>
          <Dialog.Close variant="ghost" />
          <View className="mb-5 gap-1.5">
            <Dialog.Title>确认操作</Dialog.Title>
            <Dialog.Description>
              确定要继续吗?此操作无法撤销。
            </Dialog.Description>
          </View>
          <View className="flex-row justify-end gap-3">
            <Button variant="ghost" size="sm" onPress={() => setIsOpen(false)}>
              取消
            </Button>
            <Button size="sm">确认</Button>
          </View>
        </Dialog.Content>
      </Dialog.Portal>
    </Dialog>
  );
}

更多示例见 GitHub 仓库

API 参考

Dialog

proptypedefaultdescription
childrenReact.ReactNode-触发器与对话框内容
isOpenboolean-受控开关状态
isDefaultOpenbooleanfalse非受控初始是否打开
animationAnimationRootDisableAll-动画配置
onOpenChange(value: boolean) => void-开关状态变化回调
...ViewPropsViewProps-支持 React Native View 的全部属性

AnimationRootDisableAll

根动画配置,可为:

  • false"disabled":仅禁用根级动画
  • "disable-all":禁用全部动画(含子级)
  • trueundefined:使用默认动画

Dialog.Trigger

proptypedefaultdescription
childrenReact.ReactNode-触发器内容
asChildboolean-是否无包裹渲染为子元素
...TouchableOpacityPropsTouchableOpacityProps-支持 React Native TouchableOpacity 的全部属性

Dialog.Portal

proptypedefaultdescription
childrenReact.ReactNode-Portal 内容(遮罩与对话框)
disableFullWindowOverlaybooleanfalseiOS 为 true 时使用普通 View 替代 FullWindowOverlay,便于检查器;遮罩不再叠在原生模态之上
unstable_accessibilityContainerViewIsModalbooleanfalse是否将覆盖窗口视为模态容器(VoiceOver)。仅 iOS;可能随 react-native-screens 变化
classNamestring-Portal 容器额外 class
styleStyleProp<ViewStyle>-Portal 容器额外样式
hostNamestring-可选 Portal 宿主名
forceMountboolean-关闭时仍挂载以配合动画

Dialog.Overlay

proptypedefaultdescription
childrenReact.ReactNode-自定义遮罩内容
classNamestring-遮罩额外 class
styleViewStyle-遮罩容器样式
animationDialogOverlayAnimation-动画配置
isAnimatedStyleActivebooleantrue是否启用 Reanimated 动画样式
isCloseOnPressbooleantrue按下遮罩是否关闭
forceMountboolean-关闭时仍挂载以配合动画
...PressablePropsPressableProps-支持 React Native Pressable 的全部属性

DialogOverlayAnimation

遮罩动画配置,可为:

  • false"disabled":禁用全部动画
  • trueundefined:使用默认动画
  • object:自定义动画配置
proptypedefaultdescription
state'disabled' | boolean-在自定义属性时禁用动画
opacity.value[number, number, number][0, 1, 0]不透明度 [空闲, 打开, 关闭](基于进度,用于呈现)
enteringEntryOrExitLayoutTypeFadeIn.duration(200)自定义进入动画(Popover 呈现用)
exitingEntryOrExitLayoutTypeFadeOut.duration(150)自定义退出动画(Popover 呈现用)

Dialog.Content

proptypedefaultdescription
childrenReact.ReactNode-对话框内容
classNamestring-内容容器额外 class
styleStyleProp<ViewStyle>-内容容器额外样式
animationDialogContentAnimation-动画配置
isSwipeablebooleantrue是否可滑动关闭
forceMountboolean-关闭时仍挂载以配合动画
...Animated.ViewPropsAnimated.ViewProps-支持 Reanimated Animated.View 的全部属性

DialogContentAnimation

内容动画配置,可为:

  • false"disabled":禁用全部动画
  • trueundefined:使用默认动画
  • object:自定义动画配置
proptypedefaultdescription
state'disabled' | boolean-在自定义属性时禁用动画
enteringEntryOrExitLayoutType关键帧 scale: 0.96→1opacity: 0→1(200ms,缓动 Easing.out(Easing.ease)自定义进入动画
exitingEntryOrExitLayoutType关键帧 scale: 1→0.96opacity: 1→0(150ms,缓动 Easing.in(Easing.ease)自定义退出动画

Dialog.Close

Dialog.Close 继承 CloseButton,按下时自动关闭对话框。

Dialog.Title

proptypedefaultdescription
childrenReact.ReactNode-标题内容
classNamestring-标题额外 class
...TextPropsTextProps-支持 React Native Text 的全部属性

Dialog.Description

proptypedefaultdescription
childrenReact.ReactNode-描述内容
classNamestring-描述额外 class
...TextPropsTextProps-支持 React Native Text 的全部属性

Hooks

useDialog

访问对话框原语上下文。

const { isOpen, onOpenChange } = useDialog();
propertytypedescription
isOpenboolean当前是否打开
onOpenChange(value: boolean) => void修改开关状态

useDialogAnimation

访问对话框动画上下文,用于高级定制。

const { progress, isDragging, isGestureReleaseAnimationRunning } =
  useDialogAnimation();
propertytypedescription
progressSharedValue<number>动画进度(0=空闲,1=打开,2=关闭)
isDraggingSharedValue<boolean>是否正在拖拽
isGestureReleaseAnimationRunningSharedValue<boolean>手势释放动画是否进行中

特别说明

元素检查器(iOS)

Dialog 在 iOS 使用 FullWindowOverlay。开发时若需启用 React Native 元素检查器,可在 Dialog.Portal 设置 disableFullWindowOverlay={true}。代价:对话框将无法叠在原生系统模态之上。

本页目录