229 lines
5.4 KiB
TypeScript
229 lines
5.4 KiB
TypeScript
"use client";
|
|
|
|
import { useMediaQuery } from "~/hooks/use-media-query";
|
|
import {
|
|
Dialog,
|
|
DialogClose,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogTrigger,
|
|
} from "~/components/ui/dialog";
|
|
import {
|
|
Drawer,
|
|
DrawerClose,
|
|
DrawerContent,
|
|
DrawerDescription,
|
|
DrawerFooter,
|
|
DrawerHeader,
|
|
//DrawerNested,
|
|
DrawerTitle,
|
|
DrawerTrigger,
|
|
} from "~/components/ui/drawer";
|
|
import { type Drawer as DrawerPrimitive } from "vaul";
|
|
import { cn } from "~/lib/utils";
|
|
import { createContext, useContext, type ReactNode } from "react";
|
|
|
|
interface BaseProps {
|
|
children: ReactNode;
|
|
}
|
|
|
|
interface RootCredenzaProps extends BaseProps {
|
|
open?: boolean;
|
|
onOpenChange?: (open: boolean) => void;
|
|
drawerProps?: React.ComponentProps<typeof DrawerPrimitive.Root>;
|
|
}
|
|
|
|
interface CredenzaProps extends BaseProps {
|
|
className?: string;
|
|
asChild?: true;
|
|
}
|
|
const CredenzaContext = createContext<{ isDesktop: boolean }>({
|
|
isDesktop: false,
|
|
});
|
|
|
|
const useCredenzaContext = () => {
|
|
const context = useContext(CredenzaContext);
|
|
if (!context) {
|
|
throw new Error(
|
|
"Credenza components cannot be rendered outside the Credenza Context",
|
|
);
|
|
}
|
|
return context;
|
|
};
|
|
/**
|
|
* Drawer-Dialog component
|
|
* @example
|
|
* import {
|
|
* Credenza,
|
|
* CredenzaTrigger,
|
|
* CredenzaContent,
|
|
* CredenzaHeader,
|
|
* CredenzaTitle,
|
|
* CredenzaDescription,
|
|
* CredenzaBody,
|
|
* CredenzaFooter,
|
|
* CredenzaClose,
|
|
* } from "~/components/custom_ui/credenza";
|
|
*
|
|
* <Credenza>
|
|
* <CredenzaTrigger asChild>
|
|
* <button>Open modal</button>
|
|
* </CredenzaTrigger>
|
|
* <CredenzaContent>
|
|
* <CredenzaHeader>
|
|
* <CredenzaTitle>Credenza</CredenzaTitle>
|
|
* <CredenzaDescription>
|
|
* Description of the component.
|
|
* </CredenzaDescription>
|
|
* </CredenzaHeader>
|
|
* <CredenzaBody>
|
|
* This component body.
|
|
* </CredenzaBody>
|
|
* <CredenzaFooter>
|
|
* <CredenzaClose asChild>
|
|
* <button>Close</button>
|
|
* </CredenzaClose>
|
|
* </CredenzaFooter>
|
|
* </CredenzaContent>
|
|
* </Credenza>
|
|
*/
|
|
const Credenza = ({ children, drawerProps, ...props }: RootCredenzaProps) => {
|
|
const isDesktop = useMediaQuery("(min-width: 768px)");
|
|
const Credenza = isDesktop ? Dialog : Drawer;
|
|
|
|
return (
|
|
<CredenzaContext.Provider value={{ isDesktop }}>
|
|
<Credenza
|
|
{...props}
|
|
{...(!isDesktop && { ...drawerProps, autoFocus: true })}
|
|
>
|
|
{children}
|
|
</Credenza>
|
|
</CredenzaContext.Provider>
|
|
);
|
|
};
|
|
|
|
/*const CredenzaNested = ({
|
|
children,
|
|
drawerProps,
|
|
...props
|
|
}: RootCredenzaProps) => {
|
|
const isDesktop = useMediaQuery("(min-width: 768px)");
|
|
const Credenza = isDesktop ? Dialog : DrawerNested;
|
|
|
|
return (
|
|
<CredenzaContext.Provider value={{ isDesktop }}>
|
|
<Credenza
|
|
{...props}
|
|
{...(!isDesktop && { ...drawerProps, autoFocus: true })}
|
|
>
|
|
{children}
|
|
</Credenza>
|
|
</CredenzaContext.Provider>
|
|
);
|
|
};*/
|
|
|
|
const CredenzaTrigger = ({ className, children, ...props }: CredenzaProps) => {
|
|
const { isDesktop } = useCredenzaContext();
|
|
const CredenzaTrigger = isDesktop ? DialogTrigger : DrawerTrigger;
|
|
|
|
return (
|
|
<CredenzaTrigger className={className} {...props}>
|
|
{children}
|
|
</CredenzaTrigger>
|
|
);
|
|
};
|
|
|
|
const CredenzaClose = ({ className, children, ...props }: CredenzaProps) => {
|
|
const { isDesktop } = useCredenzaContext();
|
|
const CredenzaClose = isDesktop ? DialogClose : DrawerClose;
|
|
|
|
return (
|
|
<CredenzaClose className={className} {...props}>
|
|
{children}
|
|
</CredenzaClose>
|
|
);
|
|
};
|
|
|
|
const CredenzaContent = ({ className, children, ...props }: CredenzaProps) => {
|
|
const { isDesktop } = useCredenzaContext();
|
|
const CredenzaContent = isDesktop ? DialogContent : DrawerContent;
|
|
|
|
return (
|
|
<CredenzaContent className={className} {...props}>
|
|
{children}
|
|
</CredenzaContent>
|
|
);
|
|
};
|
|
|
|
const CredenzaDescription = ({
|
|
className,
|
|
children,
|
|
...props
|
|
}: CredenzaProps) => {
|
|
const { isDesktop } = useCredenzaContext();
|
|
const CredenzaDescription = isDesktop ? DialogDescription : DrawerDescription;
|
|
|
|
return (
|
|
<CredenzaDescription className={className} {...props}>
|
|
{children}
|
|
</CredenzaDescription>
|
|
);
|
|
};
|
|
|
|
const CredenzaHeader = ({ className, children, ...props }: CredenzaProps) => {
|
|
const { isDesktop } = useCredenzaContext();
|
|
const CredenzaHeader = isDesktop ? DialogHeader : DrawerHeader;
|
|
|
|
return (
|
|
<CredenzaHeader className={className} {...props}>
|
|
{children}
|
|
</CredenzaHeader>
|
|
);
|
|
};
|
|
|
|
const CredenzaTitle = ({ className, children, ...props }: CredenzaProps) => {
|
|
const { isDesktop } = useCredenzaContext();
|
|
const CredenzaTitle = isDesktop ? DialogTitle : DrawerTitle;
|
|
|
|
return (
|
|
<CredenzaTitle className={className} {...props}>
|
|
{children}
|
|
</CredenzaTitle>
|
|
);
|
|
};
|
|
|
|
const CredenzaBody = ({ className, children, ...props }: CredenzaProps) => {
|
|
return (
|
|
<div className={cn("px-4 md:px-0", className)} {...props}>
|
|
{children}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const CredenzaFooter = ({ className, children, ...props }: CredenzaProps) => {
|
|
const { isDesktop } = useCredenzaContext();
|
|
const CredenzaFooter = isDesktop ? DialogFooter : DrawerFooter;
|
|
|
|
return (
|
|
<CredenzaFooter className={className} {...props}>
|
|
{children}
|
|
</CredenzaFooter>
|
|
);
|
|
};
|
|
|
|
export {
|
|
Credenza,
|
|
//CredenzaNested,
|
|
CredenzaTrigger,
|
|
CredenzaClose,
|
|
CredenzaContent,
|
|
CredenzaDescription,
|
|
CredenzaHeader,
|
|
CredenzaTitle,
|
|
CredenzaBody,
|
|
CredenzaFooter,
|
|
};
|