suiss/uim · React Native Component

Dialog

A modal window centered over the screen for focused tasks and messages.

Dialog is an open-source mobile component from suiss/uim for React Native and Expo, with SwiftUI and Jetpack Compose versions built from the same design tokens. The @esuiss/uim CLI copies its source into your project, so you own the code.

iOS
Dialog (open by default) on iOS in light mode

Dialog opens a centered card over a dimmed scrim. DialogContent renders through a portal (inside a full-window overlay on iOS), scales and fades in, and shows a round close button in the top-right corner by default. Tapping the scrim closes the dialog.

Use it for short forms and information that the user can dismiss freely. When the user must make an explicit choice, use Alert Dialog instead.

Installation

$ pnpm dlx @esuiss/uim@latest add dialog

The CLI also adds what it builds on: Button, Icon, Text.

Manual

  1. Install the dependencies:
npx expo install cn phosphor-react-native react-native-reanimated react-native-screens react-native-svg react-native-worklets
  1. Add the pieces it builds on: Button, Icon, Text, and the primitives components/primitives/dialog.tsx, components/primitives/use-render.tsx.

  2. Copy the source into components/ui/dialog.tsx:

uniwind/components/ui/dialog.tsx
import { cn } from "cn"
import { XIcon } from "phosphor-react-native"
import * as React from "react"
import { Platform, View, type ViewProps } from "react-native"
import {
  FadeIn,
  FadeOut,
  Keyframe,
  ReduceMotion,
} from "react-native-reanimated"
import { FullWindowOverlay as RNFullWindowOverlay } from "react-native-screens"
import * as DialogPrimitive from "@/components/primitives/dialog"
import { resolveClassName } from "@/components/primitives/use-render"
import { AnimatedView } from "@/components/ui/animated-view"
import { Button } from "@/components/ui/button"
import { Icon } from "@/components/ui/icon"
  1. Update the import paths to match your project.

Usage

import { DialogOverlay, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription } from "@/components/ui/dialog"
<View className="items-start">
  <Dialog defaultOpen>
    <DialogTrigger render={<Button variant="outline" />}>
      <Text>Edit profile</Text>
    </DialogTrigger>
    <EditProfileContent />
  </Dialog>
</View>

Compose DialogTrigger and DialogContent with a DialogHeader (DialogTitle, DialogDescription), your content, and a DialogFooter. Footer buttons stack vertically with the first child at the bottom, and sit in a row aligned to the end on wider screens. Use DialogClose with render to turn any Button into a close button.

Set showCloseButton={false} on the content to hide the corner button, or pass closeLabel to show a text button such as "Done" instead of the icon. The header adds end padding so the title does not run under it. DialogFooter takes showCloseButton to append a secondary Close button.

Use open and onOpenChange for controlled state, or defaultOpen for uncontrolled.

Examples

Default

iOS
Dialog on iOS in light mode

Destructive

A destructive action with a cancel button in the footer.

iOS
Dialog (destructive) on iOS in light mode

Without close button

No corner button, with a Close button in the footer.

iOS
Dialog (without close button) on iOS in light mode

With close label

A text close button through closeLabel.

iOS
Dialog (with close label) on iOS in light mode

API Reference

DialogOverlay

Dimmed scrim that closes the dialog when tapped.

ExtendsReact.ComponentProps<typeof DialogPrimitive.Backdrop>

DialogContent

Centered card with an optional close button.

ExtendsReact.ComponentProps<typeof DialogPrimitive.Popup>
PropType
About
Name of the portal host to render into.
Type
string
Default
—
About
Shows the corner close button. Defaults to true.
Type
boolean
Default
true
About
Text for the close button instead of the icon.
Type
string
Default
—

DialogHeader

Column for the title and description.

ExtendsViewProps

DialogFooter

Area for actions.

ExtendsViewProps
PropType
About
Appends a secondary Close button.
Type
boolean
Default
false

DialogTitle

Dialog heading.

ExtendsReact.ComponentProps<typeof DialogPrimitive.Title>

DialogDescription

Supporting text.

ExtendsReact.ComponentProps<typeof DialogPrimitive.Description>

Accessibility

  • The popup has the dialog role, is labelled by the title and is marked as modal for VoiceOver.
  • Focus moves to the title when the dialog opens.
  • The Android back button and the VoiceOver escape gesture close it.
  • The icon close button is labelled "Close".

Notes

  • On iOS the content is wrapped in a full-window overlay so it appears above native navigation.
  • Animations respect the system Reduce Motion setting.
  • Uses bg-surface-raised, bg-scrim and bg-surface-tertiary tokens; light and dark follow the system appearance.