form: fix popover, improve form types

This commit is contained in:
dswbx
2025-02-08 15:43:02 +01:00
parent 3fa682bfe1
commit f7e6928dba
9 changed files with 56 additions and 49 deletions
+10 -6
View File
@@ -1,7 +1,7 @@
import { useClickOutside } from "@mantine/hooks";
import { type ReactElement, cloneElement, useState } from "react";
import { type ComponentPropsWithoutRef, type ReactElement, cloneElement, useState } from "react";
import { twMerge } from "tailwind-merge";
import { useEvent } from "../../hooks/use-event";
import { useEvent } from "ui/hooks/use-event";
export type PopoverProps = {
className?: string;
@@ -10,6 +10,7 @@ export type PopoverProps = {
backdrop?: boolean;
target: (props: { toggle: () => void }) => ReactElement;
children: ReactElement<{ onClick: () => void }>;
overlayProps?: ComponentPropsWithoutRef<"div">;
};
export function Popover({
@@ -18,20 +19,21 @@ export function Popover({
defaultOpen = false,
backdrop = false,
position = "bottom-start",
className,
overlayProps,
className
}: PopoverProps) {
const [open, setOpen] = useState(defaultOpen);
const clickoutsideRef = useClickOutside(() => setOpen(false));
const toggle = useEvent((delay: number = 50) =>
setTimeout(() => setOpen((prev) => !prev), typeof delay === "number" ? delay : 0),
setTimeout(() => setOpen((prev) => !prev), typeof delay === "number" ? delay : 0)
);
const pos = {
"bottom-start": "mt-1 top-[100%]",
"bottom-end": "right-0 top-[100%] mt-1",
"top-start": "bottom-[100%] mb-1",
"top-end": "bottom-[100%] right-0 mb-1",
"top-end": "bottom-[100%] right-0 mb-1"
}[position];
return (
@@ -43,9 +45,11 @@ export function Popover({
{cloneElement(children as any, { onClick: toggle })}
{open && (
<div
{...overlayProps}
className={twMerge(
"animate-fade-in absolute z-20 flex flex-col bg-background border border-muted px-1 py-1 rounded-lg shadow-lg min-w-full max-w-20 backdrop-blur-sm",
"animate-fade-in absolute z-20 flex flex-col bg-background border border-muted px-1 py-1 rounded-lg shadow-lg backdrop-blur-sm min-w-0 max-w-20",
pos,
overlayProps?.className
)}
>
{target({ toggle })}