Dialog

A dialog is a window overlaid on either the primary window or another dialog window.

Example

"use client";
import React from "react";
import * as Dialog from "@lora-ui/dialog";
import * as Backdrop from "@lora-ui/backdrop";
import * as Portal from "@lora-ui/portal";
import * as Button from "@lora-ui/button";
import * as Checkbox from "@lora-ui/checkbox";
export default function Base() {
const [isOpen, setOpen] = React.useState(false);
const buttonRef = React.useRef(null);
function closeDialog() {
setOpen(false);
buttonRef.current?.focus();
}
function openDialog() {
setOpen(true);
}
return (
<>
<Button.Root
ref={buttonRef}
onClick={openDialog}
className="box-border flex items-center whitespace-nowrap rounded-lg border border-[#7f56d9] bg-[#7f56d9] px-3 py-2 text-sm font-semibold text-[#ffffff] outline-offset-4 hover:bg-[#6941c6] dark:border-[#9e77ed] dark:bg-[#7f56d9] dark:text-[#f5f5f6] dark:hover:bg-[#9e77ed]"
>
Open
</Button.Root>
<Portal.Root>
{isOpen && (
<Backdrop.Root
onClick={closeDialog}
className="fixed left-0 top-0 z-10 h-full w-full bg-white/30 backdrop-blur-md dark:bg-black/30"
/>
)}
{isOpen && (
<Dialog.Root
onClose={closeDialog}
className="absolute left-1/2 top-1/2 z-20 w-[400px] -translate-x-1/2 -translate-y-1/2 rounded-lg border border-[#eaecf0] bg-[#ffffff] p-6 focus:outline-none dark:border-[#1f242f] dark:bg-[#0c111d]"
>
<div className="relative flex flex-col items-center">
<h1 className="mt-6 text-2xl font-semibold text-[#101828] dark:text-[#f5f5f6]">
Log in to your account
</h1>
<p className="mt-2 text-base font-normal text-[#475467] dark:text-[#94969c]">
Welcome back! Please enter your details.
</p>
</div>
<form action="" className="mt-8">
<fieldset className="flex flex-col">
<label
className="text-sm font-medium text-[#344054] dark:text-[#cecfd2]"
htmlFor="email"
>
Email
</label>
<input
id="email"
placeholder="Enter your email"
type="email"
autoComplete="off"
defaultValue=""
className="mt-[6px] h-[44px] w-full rounded-lg border border-[#d0d5dd] bg-[#ffffff] px-[14px] pl-3 font-normal text-[#101828] placeholder:text-base placeholder:text-[#667085] dark:border-[#333741] dark:bg-[#0c111d] dark:text-[#f5f5f6] dark:placeholder:text-[#94969c]"
/>
</fieldset>
<fieldset className="mt-5 flex flex-col">
<label
className="text-sm font-medium text-[#344054] dark:text-[#cecfd2]"
htmlFor="password"
>
Password
</label>
<input
id="password"
placeholder="Create a password"
type="text"
autoComplete="off"
defaultValue=""
className="mt-[6px] h-[44px] w-full rounded-lg border border-[#d0d5dd] bg-[#ffffff] px-[14px] pl-3 font-normal text-[#101828] placeholder:text-base placeholder:text-[#667085] dark:border-[#333741] dark:bg-[#0c111d] dark:text-[#f5f5f6] dark:placeholder:text-[#94969c]"
/>
</fieldset>
<fieldset className="mt-6 flex justify-between">
<div className="flex items-start">
<Checkbox.Root
id="checkbox-1"
defaultChecked
className="border-box group relative flex h-[18px] w-[18px] items-center justify-center rounded border border-[#d0d5dd] p-[2px] outline-offset-2 has-[:checked]:bg-[#7f56d9] has-[:checked]:has-[:disabled]:bg-[#f2f4f7] has-[:indeterminate]:bg-[#7f56d9] has-[:indeterminate]:has-[:disabled]:bg-[#f2f4f7] dark:border-[#333741] dark:has-[:checked]:bg-[#7f56d9] dark:has-[:checked]:has-[:disabled]:bg-[#1f242f] dark:has-[:indeterminate]:bg-[#7f56d9] dark:has-[:indeterminate]:has-[:disabled]:bg-[#1f242f]"
>
<Checkbox.Indicator className="invisible group-has-[:checked]:visible group-has-[:indeterminate]:visible group-has-[:checked]:group-has-[:disabled]:text-[#98a2b3] group-has-[:checked]:text-white dark:group-has-[:checked]:group-has-[:disabled]:text-[#85888e]">
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
/>
</svg>
</Checkbox.Indicator>
</Checkbox.Root>
<label htmlFor="checkbox-1">
<p className="ml-2 text-sm font-medium text-[#344054] dark:text-[#cecfd2]">
Remember me
</p>
</label>
</div>
<Button.Root className="text-sm font-semibold text-[#6941c6] dark:text-[#cecfd2]">
Forgot password
</Button.Root>
</fieldset>
<div className="mt-6 flex flex-col justify-center space-y-4">
<Button.Root className="rounded-xl border border-[#7f56d9] bg-[#7f56d9] px-4 py-[10px] text-base font-semibold text-[#ffffff] outline-offset-4 hover:bg-[#6941c6] dark:border-[#9e77ed] dark:bg-[#7f56d9] dark:text-[#f5f5f6] dark:hover:bg-[#9e77ed]">
Sign in
</Button.Root>
<Button.Root className="rounded-xl border border-[#d0d5dd] bg-[#ffffff] px-4 py-[10px] text-base font-semibold text-[#344054] outline-offset-4 hover:bg-[#f9fafb] dark:border-[#333741] dark:bg-[#0c111d] dark:text-[#cecfd2] dark:hover:bg-[#1f242f]">
<div className="flex justify-center gap-3">
<svg
width="25"
height="24"
viewBox="0 0 25 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clipPath="url(#clip0_7618_2716)">
<path
id="Vector"
d="M24.2663 12.2765C24.2663 11.4608 24.2001 10.6406 24.059 9.83813H12.7402V14.4591H19.222C18.953 15.9495 18.0888 17.2679 16.8233 18.1056V21.104H20.6903C22.9611 19.014 24.2663 15.9274 24.2663 12.2765Z"
fill="#4285F4"
/>
<path
id="Vector_2"
d="M12.7401 24.0008C15.9766 24.0008 18.7059 22.9382 20.6945 21.1039L16.8276 18.1055C15.7517 18.8375 14.3627 19.252 12.7445 19.252C9.61388 19.252 6.95946 17.1399 6.00705 14.3003H2.0166V17.3912C4.05371 21.4434 8.2029 24.0008 12.7401 24.0008Z"
fill="#34A853"
/>
<path
id="Vector_3"
d="M6.00277 14.3002C5.50011 12.8099 5.50011 11.196 6.00277 9.70569V6.61475H2.01674C0.314734 10.0055 0.314734 14.0004 2.01674 17.3912L6.00277 14.3002Z"
fill="#FBBC04"
/>
<path
id="Vector_4"
d="M12.7401 4.74966C14.4509 4.7232 16.1044 5.36697 17.3434 6.54867L20.7695 3.12262C18.6001 1.0855 15.7208 -0.034466 12.7401 0.000808666C8.2029 0.000808666 4.05371 2.55822 2.0166 6.61481L6.00264 9.70575C6.95064 6.86173 9.60947 4.74966 12.7401 4.74966Z"
fill="#EA4335"
/>
</g>
<defs>
<clipPaColumnHead id="clip0_7618_2716">
<rect
width="24"
height="24"
fill="white"
transform="translate(0.5)"
/>
</clipPaColumnHead>
</defs>
</svg>
Sign in with Google
</div>
</Button.Root>
</div>
</form>
</Dialog.Root>
)}
</Portal.Root>
</>
);
}

Installation

Install the component from your command line.

npm install @lora-ui/dialog

API Reference

Root

PropTypeDefaultExplanation
onCloseFunction() => {}Callback fn to handle dialog close

Keyboard

CommandDescription
Tab
  • Move focus to next focusable element inside dialog
  • If focus is on the last focusable element inside the dialog, moves focus to the first focusable element inside the dialog.
Shift+Tab
  • Move focus to previous focusable element inside dialog
  • If focus is on the first focusable element inside the dialog, moves focus to the last focusable element inside the dialog.
Escape
Closes the dialog

Other

All relevant ARIA attributes are automatically managed.