### Install Shadcn UI Dialog and Drawer Components
Source: https://credenza.rdev.pro/index
Command to add the `dialog` and `drawer` components from shadcn/ui to your project. These components are prerequisites for the Credenza component, providing the underlying UI for desktop and mobile modals.
```bash
npx shadcn@latest add dialog drawer
```
--------------------------------
### Importing Credenza UI Components
Source: https://credenza.rdev.pro/index
This snippet shows how to import all necessary Credenza components, such as Credenza, CredenzaBody, CredenzaTrigger, and others, from the local UI library path.
```typescript
import {
Credenza,
CredenzaBody,
CredenzaClose,
CredenzaContent,
CredenzaDescription,
CredenzaFooter,
CredenzaHeader,
CredenzaTitle,
CredenzaTrigger,
} from "@/components/ui/credenza"
```
--------------------------------
### Basic Credenza Modal with Trigger
Source: https://credenza.rdev.pro/index
Demonstrates the fundamental usage of the Credenza component. It uses a CredenzaTrigger wrapped around a Button to open the modal, which contains a header, description, body, and a close button in the footer.
```tsx
Credenza
A responsive modal component for shadcn/ui.
This component is built using shadcn/ui's dialog and drawer
component, which is built on top of Vaul.
```
--------------------------------
### Implement Responsive Credenza React Component
Source: https://credenza.rdev.pro/index
The core Credenza component and its sub-components (Trigger, Close, Content, Description, Header, Title, Body, Footer). This component dynamically renders either a `Dialog` (for desktop) or a `Drawer` (for mobile) based on the `useMediaQuery` hook, providing a unified API for responsive modal interactions.
```typescript
"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
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,
DrawerTitle,
DrawerTrigger
} from "@/components/ui/drawer"
interface BaseProps {
children: React.ReactNode
}
interface RootCredenzaProps extends BaseProps {
open?: boolean
onOpenChange?: (open: boolean) => void
}
interface CredenzaProps extends BaseProps {
className?: string
asChild?: true
}
const CredenzaContext = React.createContext<{ isDesktop: boolean }>(
{
isDesktop: false
}
);
const useCredenzaContext = () => {
const context = React.useContext(CredenzaContext);
if (!context) {
throw new Error(
"Credenza components cannot be rendered outside the Credenza Context"
);
}
return context;
};
const Credenza = ({ children, ...props }: RootCredenzaProps) => {
const isDesktop = useMediaQuery("(min-width: 768px)");
const Credenza = isDesktop ? Dialog : Drawer;
return (
{children}
);
};
const CredenzaTrigger = ({ className, children, ...props }: CredenzaProps) => {
const { isDesktop } = useCredenzaContext();
const CredenzaTrigger = isDesktop ? DialogTrigger : DrawerTrigger;
return (
{children}
);
};
const CredenzaClose = ({ className, children, ...props }: CredenzaProps) => {
const { isDesktop } = useCredenzaContext();
const CredenzaClose = isDesktop ? DialogClose : DrawerClose;
return (
{children}
);
};
const CredenzaContent = ({ className, children, ...props }: CredenzaProps) => {
const { isDesktop } = useCredenzaContext();
const CredenzaContent = isDesktop ? DialogContent : DrawerContent;
return (
{children}
);
};
const CredenzaDescription = ({
className,
children,
...props
}: CredenzaProps) => {
const { isDesktop } = useCredenzaContext();
const CredenzaDescription = isDesktop ? DialogDescription : DrawerDescription;
return (
{children}
);
};
const CredenzaHeader = ({ className, children, ...props }: CredenzaProps) => {
const { isDesktop } = useCredenzaContext();
const CredenzaHeader = isDesktop ? DialogHeader : DrawerHeader;
return (
{children}
);
};
const CredenzaTitle = ({ className, children, ...props }: CredenzaProps) => {
const { isDesktop } = useCredenzaContext();
const CredenzaTitle = isDesktop ? DialogTitle : DrawerTitle;
return (
{children}
);
};
const CredenzaBody = ({ className, children, ...props }: CredenzaProps) => {
return (
{children}
);
};
const CredenzaFooter = ({ className, children, ...props }: CredenzaProps) => {
const { isDesktop } = useCredenzaContext();
const CredenzaFooter = isDesktop ? DialogFooter : DrawerFooter;
return (
{children}
);
};
export {
Credenza,
CredenzaTrigger,
CredenzaClose,
CredenzaContent,
CredenzaDescription,
CredenzaHeader,
CredenzaTitle,
CredenzaBody,
CredenzaFooter
}
```
--------------------------------
### Wrap App with Vaul Drawer Wrapper for Background Scaling
Source: https://credenza.rdev.pro/index
HTML/JSX snippet to wrap your application's main content with a `div` element that includes the `vaul-drawer-wrapper` attribute and a background class. This enables visual effects like background scaling when the drawer component is active.
```jsx
{children}
```
--------------------------------
### Controlling Credenza Modal with React State
Source: https://credenza.rdev.pro/index
Illustrates how to manage the Credenza modal's open/close state programmatically using React's useState hook. The modal's visibility is controlled by the 'open' state variable, which is toggled by a button click.
```tsx
function StateModal() {
const [open, setOpen] = React.useState(false)
const handleOpen = () => {
setOpen(true)
}
return (
<>
Credenza
A responsive modal component for shadcn/ui.
This modal got triggered using state
>
)
}
```
--------------------------------
### Implement useMediaQuery React Hook
Source: https://credenza.rdev.pro/index
A custom React hook that tracks the state of a CSS media query. It returns a boolean indicating whether the query currently matches, enabling responsive behavior based on viewport size. This hook is crucial for the Credenza component to determine if it should render a Dialog or a Drawer.
```typescript
import * as React from "react"
export function useMediaQuery(query: string) {
const [value, setValue] = React.useState(false)
React.useEffect(() => {
function onChange(event: MediaQueryListEvent) {
setValue(event.matches)
}
const result = matchMedia(query)
result.addEventListener("change", onChange)
setValue(result.matches)
return () => result.removeEventListener("change", onChange)
}, [query])
return value
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.