Skip to main content

Modal

Basic Usage

This is an example of using the <Modal> component in a basic scenario. Click the 'Open modal' button to open the modal dialog, where you can enter your name and address. You can cancel or confirm your input using the buttons in the footer.

Sign In
const LoginFormComponent = () => {
const [isOpen, setIsOpen] = React.useState(false);

return (
<Box alignItems="flex-start">
<Button onPress={() => setIsOpen(true)}>Sign In</Button>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
>
<Modal.Title>Welcome Back</Modal.Title>
<Modal.Subtitle>
Sign in to your account to continue shopping and track your orders.
</Modal.Subtitle>
<Modal.Body>
<VStack gap={"$4"} padding={"$4"}>
<Input placeholder="Enter your email..." required={true}>
<Input.Label>Email Address</Input.Label>
<Input.LeftIcon>
<Mail />
</Input.LeftIcon>
</Input>
<Input placeholder="Enter your password..." required={true}>
<Input.Label>Password</Input.Label>
<Input.LeftIcon>
<Lock />
</Input.LeftIcon>
</Input>
<Body marginBottom="$0" color="$primary.600" textAlign="right">
Forgot password?
</Body>
</VStack>
</Modal.Body>
<Modal.Footer>
<HStack padding={"$4"} justifyContent="space-between" width="$full">
<Button onPress={() => setIsOpen(false)} variant="tertiary">
Cancel
</Button>
<Button onPress={() => setIsOpen(false)}>Sign In</Button>
</HStack>
</Modal.Footer>
</Modal>
</Box>
);
};

Without Heading

This example demonstrates the use of the <Modal> component without a heading. Click the 'Open modal' button to open the modal dialog.

Checkout
const PaymentConfirmationComponent = () => {
const [isOpen, setIsOpen] = React.useState(false);

return (
<Box alignItems="flex-start">
<Button onPress={() => setIsOpen(true)}>Checkout</Button>
<Modal
_modalContent={{
borderRadius: "$0",
}}
isOpen={isOpen}
onClose={() => setIsOpen(false)}
>
<Modal.Title>Complete Payment</Modal.Title>
<Modal.Subtitle>
Enter your card details to finalize your purchase of $149.99
</Modal.Subtitle>
<Modal.Body>
<VStack gap={"$4"} padding={"$4"}>
<Input placeholder="1234 5678 9012 3456" required={true}>
<Input.Label>Card Number</Input.Label>
<Input.LeftIcon>
<CreditCard />
</Input.LeftIcon>
</Input>
<HStack gap="$4">
<Box flex={1}>
<Input placeholder="MM/YY" required={true}>
<Input.Label>Expiry Date</Input.Label>
...
</Input>
</Box>
<Box flex={1}>
<Input placeholder="123" required={true}>
<Input.Label>CVV</Input.Label>
...
</Input>
</Box>
</HStack>
...
</VStack>
</Modal.Body>
<Modal.Footer>
<HStack padding={"$4"} justifyContent="space-between" width="$full">
<Button onPress={() => setIsOpen(false)} variant="tertiary">
Cancel
</Button>
<Button onPress={() => setIsOpen(false)}>Pay $149.99</Button>
</HStack>
</Modal.Footer>
</Modal>
</Box>
);
};

With Custom Header

This example showcases the use of the <Modal> component with a custom header. Click the 'Open modal' button to open the modal dialog.

View Profile
const UserProfileComponent = () => {
const [isOpen, setIsOpen] = React.useState(false);

return (
<Box alignItems="flex-start">
<Button onPress={() => setIsOpen(true)}>View Profile</Button>
<Modal
onClose={() => setIsOpen(false)}
isOpen={isOpen}
>
<Modal.Title>User Profile</Modal.Title>
<Modal.Subtitle>Manage your account information</Modal.Subtitle>
<Modal.Header>
<VStack padding="$4" alignItems="center" gap="$2">
<Avatar
size="xl"
source={{ uri: "https://i.pravatar.cc/150?img=32" }}
/>
<TitleThree marginBottom="$0">Jane Doe</TitleThree>
<HStack gap="$1" alignItems="center">
<Star size={14} color="$amber.500" fill="$amber.500" />
<Subhead marginBottom="$0" color="$amber.600">
Premium Member
</Subhead>
</HStack>
</VStack>
</Modal.Header>
<Modal.Body>
<VStack gap={"$3"} padding={"$4"}>
<HStack justifyContent="space-between">
<Subhead marginBottom="$0" color="$primaryGray.600">
Email
</Subhead>
<Body marginBottom="$0">[email protected]</Body>
</HStack>
...
</VStack>
</Modal.Body>
<Modal.Footer>
<HStack padding={"$4"} justifyContent="center" width="$full">
<Button variant="secondary" onPress={() => setIsOpen(false)}>
Edit Profile
</Button>
</HStack>
</Modal.Footer>
</Modal>
</Box>
);
};

Override Color Mode

This example demonstrates the use of the <Modal> component with the ability to override the color mode. Click the 'Open modal' button to open the modal dialog.

Settings
const SettingsPanelComponent = () => {
const [isOpen, setIsOpen] = React.useState(false);
const { color } = getTokens();

const iconColor = useColorModeValue(
color["indigo.500"].val,
color["indigo.300"].val
);

const labelColor = useColorModeValue(
color["primary.500"].val,
color["primary.300"].val
);

const successLabelColor = useColorModeValue(
color["emerald.600"].val,
color["emerald.300"].val
);

return (
<Box alignItems="flex-start">
<Button colorMode="dark" onPress={() => setIsOpen(true)}>
<Button.LeftIcon>
<Settings size={18} color="white" />
</Button.LeftIcon>
Settings
</Button>
<Modal
colorMode="dark"
isOpen={isOpen}
onClose={() => setIsOpen(false)}
>
<Modal.Title>App Settings</Modal.Title>
<Modal.Subtitle>Customize your app experience</Modal.Subtitle>
<Modal.Body>
<VStack gap={"$4"} padding={"$4"}>
<HStack justifyContent="space-between" alignItems="center">
<HStack gap="$3" alignItems="center">
<Bell size={20} color={iconColor} />
<Body marginBottom="$0">Push Notifications</Body>
</HStack>
<Body marginBottom="$0" color={labelColor}>
Enabled
</Body>
</HStack>
...
</VStack>
</Modal.Body>
<Modal.Footer>
<HStack padding={"$4"} justifyContent="center" width="$full">
<Button onPress={() => setIsOpen(false)}>
Save Changes
</Button>
</HStack>
</Modal.Footer>
</Modal>
</Box>
);
};

Override Accent Color

This example illustrates the use of the <Modal> component with the ability to override the accent color. Click the 'Open modal' button to open the modal dialog.

Rate Us
const FeedbackFormComponent = () => {
const [isOpen, setIsOpen] = React.useState(false);
const [rating, setRating] = React.useState(4);
const { color } = getTokens();
const starFullFillColor = useColorModeValue(
color["amber.500"].val,
color["amber.300"].val
);

return (
<Box alignItems="flex-start">
<Button accentColor="amber" onPress={() => setIsOpen(true)}>
<Button.LeftIcon>
<Star size={18} color="white" />
</Button.LeftIcon>
Rate Us
</Button>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
accentColor="amber"
>
<Modal.Title>How was your experience?</Modal.Title>
<Modal.Subtitle>
Your feedback helps us improve our service
</Modal.Subtitle>
<Modal.Body>
<VStack gap={"$4"} padding={"$4"} alignItems="center">
<HStack gap="$2">
{[1, 2, 3, 4, 5].map((star) => (
<Star
key={star}
size={36}
color={starFullFillColor}
fill={star <= rating ? starFullFillColor : "transparent"}
/>
))}
</HStack>
<Body marginBottom="$0" color="$primaryGray.600">
{rating === 5 ? "Excellent!" : rating === 4 ? "Great!" : "..."}
</Body>
<Input
placeholder="Tell us more about your experience..."
accentColor="amber"
>
<Input.Label>Additional Comments (Optional)</Input.Label>
</Input>
</VStack>
</Modal.Body>
<Modal.Footer>
<HStack padding={"$4"} justifyContent="space-between" width="$full">
<Button
variant="tertiary"
accentColor="amber"
onPress={() => setIsOpen(false)}
>
Skip
</Button>
<Button accentColor="amber" onPress={() => setIsOpen(false)}>
Submit Feedback
</Button>
</HStack>
</Modal.Footer>
</Modal>
</Box>
);
};

Override Color Mode and Accent Color

You can use the accentColor and colorMode props to override the accent color and color mode of the <Modal> component. Click the 'Open modal' button to open the modal dialog.

Upgrade to Premium
const PremiumUpgradeComponent = () => {
const [isOpen, setIsOpen] = React.useState(false);
const { color } = getTokens();

const iconColor = useColorModeValue(
color["violet.500"].val,
color["violet.300"].val
);

const bgColor = useColorModeValue(
color["violet.100"].val,
color["violet.900"].val
);

const textColor = useColorModeValue(
color["violet.700"].val,
color["violet.200"].val
);

const secondaryTextColor = useColorModeValue(
color["violet.600"].val,
color["violet.300"].val
);

const features = [
"Unlimited downloads",
"Ad-free experience",
"Priority customer support",
"Exclusive content access",
"Early access to new features",
];

return (
<Box alignItems="flex-start">
<Button
colorMode="dark"
accentColor="violet"
onPress={() => setIsOpen(true)}
>
<Button.LeftIcon>
<Star size={18} color="white" />
</Button.LeftIcon>
Upgrade to Premium
</Button>
<Modal
colorMode="dark"
isOpen={isOpen}
onClose={() => setIsOpen(false)}
accentColor="violet"
>
<Modal.Title>Go Premium ✨</Modal.Title>
<Modal.Subtitle>
Unlock all features and take your experience to the next level
</Modal.Subtitle>
<Modal.Body>
<VStack gap={"$3"} padding={"$4"}>
{features.map((feature, index) => (
<HStack key={index} gap="$3" alignItems="center">
<ShieldCheck size={18} color={iconColor} />
<Body marginBottom="$0">{feature}</Body>
</HStack>
))}
<Box
backgroundColor={bgColor}
padding="$4"
borderRadius="$2"
marginTop="$2"
>
<HStack justifyContent="space-between" alignItems="center">
<VStack>
<TitleThree marginBottom="$0" color={textColor}>
$9.99/month
</TitleThree>
<Subhead marginBottom="$0" color={textColor}>
Cancel anytime
</Subhead>
</VStack>
<Body marginBottom="$0" color={secondaryTextColor}>
Save 20%
</Body>
</HStack>
</Box>
</VStack>
</Modal.Body>
<Modal.Footer>
<VStack padding={"$4"} gap="$3" width="$full">
<Button
width="$full"
accentColor="violet"
onPress={() => setIsOpen(false)}
>
Start Free Trial
</Button>
<Button
width="$full"
variant="tertiary"
accentColor="violet"
onPress={() => setIsOpen(false)}
>
Maybe Later
</Button>
</VStack>
</Modal.Footer>
</Modal>
</Box>
);
};