Docs
PopoverForm
PopoverForm
A headless popover form animation component with customizable options.
Theme
References
Inspiration
Installation
Install the required dependencies.
npx shadcn@latest add "http://skiper-ui.com/registry/minimal-card.json"
Usage
import {
PopoverForm,
PopoverFormButton,
PopoverFormCutOutLeftIcon,
PopoverFormCutOutRightIcon,
PopoverFormSeparator,
PopoverFormSuccess,
} from "@/registry/default/ui/popover-form"
export default function PopoverFormFeedbackExample() {
const [formState, setFormState] = useState<FormState>("idle")
const [open, setOpen] = useState(false)
const [feedback, setFeedback] = useState("")
function submit() {
setFormState("loading")
setTimeout(() => {
setFormState("success")
}, 1500)
setTimeout(() => {
setOpen(false)
setFormState("idle")
setFeedback("")
}, 3300)
}
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") {
setOpen(false)
}
if (
(event.ctrlKey || event.metaKey) &&
event.key === "Enter" &&
open &&
formState === "idle"
) {
submit()
}
}
window.addEventListener("keydown", handleKeyDown)
return () => window.removeEventListener("keydown", handleKeyDown)
}, [open, formState])
return (
<div className="flex w-full items-center justify-center">
<PopoverForm
title="Feedback"
open={open}
setOpen={setOpen}
width="364px"
height="192px"
showCloseButton={formState !== "success"}
showSuccess={formState === "success"}
openChild={
<form
onSubmit={(e) => {
e.preventDefault()
if (!feedback) return
submit()
}}
>
<div className="relative">
<textarea
autoFocus
placeholder="Feedback"
value={feedback}
onChange={(e) => setFeedback(e.target.value)}
className="h-32 w-full resize-none rounded-t-lg p-3 text-sm outline-none"
required
/>
</div>
<div className="relative flex h-12 items-center px-[10px]">
<PopoverFormSeparator />
<div className="absolute left-0 top-0 -translate-x-[1.5px] -translate-y-1/2">
<PopoverFormCutOutLeftIcon />
</div>
<div className="absolute right-0 top-0 translate-x-[1.5px] -translate-y-1/2 rotate-180">
<PopoverFormCutOutRightIcon />
</div>
<PopoverFormButton loading={formState === "loading"} />
</div>
</form>
}
successChild={
<PopoverFormSuccess
title="Feedback Received"
description="Thank you for supporting our project!"
/>
}
/>
</div>
)
}