beUI Pro 移动端已上线:50 个 React Native 区块和页面
Animated Modal
1 个变体
The shared beUI Pro dialog with a soft entrance, accessible focus management, and composable titles, descriptions, and content.
Animated dialog
animated-modal.tsxCompose a focused dialog with the shared inputs and buttons, keyboard dismissal, and automatic focus restoration.
TSXcomponents/previews/premium/animated-modal-preview.tsx
"use client";
import { X } from "lucide-react";
import { useState } from "react";
import {
AnimatedModal,
AnimatedModalDescription,
AnimatedModalTitle,
} from "@/components/motion/animated-modal";
import { Button } from "@/components/motion/button";
import { Input } from "@/components/motion/input";
export function AnimatedModalPreview() {
const [open, setOpen] = useState(false);
const [email, setEmail] = useState("");
return (
<>
<Button onClick={() => setOpen(true)}>Open modal</Button>
<AnimatedModal open={open} onOpenChange={setOpen}>
<header className="flex items-start gap-4 border-b border-border px-5 py-4">
<div className="min-w-0 flex-1">
<AnimatedModalTitle className="text-xl font-medium">
Invite a teammate
</AnimatedModalTitle>
<AnimatedModalDescription className="mt-1 text-sm text-muted-foreground">
Give someone access to your workspace.
</AnimatedModalDescription>
</div>
<Button
size="icon"
variant="ghost"
aria-label="Close invitation"
onClick={() => setOpen(false)}
>
<X aria-hidden className="size-4" />
</Button>
</header>
<form
onSubmit={(event) => {
event.preventDefault();
setOpen(false);
}}
>
<div className="p-5">
<Input
label="Email address"
type="email"
name="email"
placeholder="teammate@example.com"
required
value={email}
onChange={setEmail}
data-autofocus
/>
</div>
<footer className="flex justify-end gap-2 border-t border-border px-5 py-4">
<Button variant="outline" onClick={() => setOpen(false)}>
Cancel
</Button>
<Button type="submit">Invite teammate</Button>
</footer>
</form>
</AnimatedModal>
</>
);
}
安装
$ bunx --bun shadcn add @beui-pro/animated-modal