Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/redpangilinan/credenza
Ready-made responsive modal component for shadcn/ui.
https://github.com/redpangilinan/credenza
component drawer modal modal-dialog next-14 nextjs react shadcn-ui
Last synced: 3 months ago
JSON representation
Ready-made responsive modal component for shadcn/ui.
- Host: GitHub
- URL: https://github.com/redpangilinan/credenza
- Owner: redpangilinan
- License: mit
- Created: 2023-12-30T09:35:48.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2024-05-11T07:25:32.000Z (6 months ago)
- Last Synced: 2024-06-14T18:40:26.088Z (5 months ago)
- Topics: component, drawer, modal, modal-dialog, next-14, nextjs, react, shadcn-ui
- Language: TypeScript
- Homepage: https://credenza.rdev.pro
- Size: 796 KB
- Stars: 322
- Watchers: 2
- Forks: 10
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-shadcn-ui - credenza - Ready-made responsive modal component for shadcn/ui. (Libs and Components)
- awesome-shadcn-ui - Credenza - Ready-made responsive modal component for shadcn/ui. (Components)
- awesome-shadcn-ui - Credenza - Ready-made responsive modal component for shadcn/ui. (Components)
README
# Credenza
A responsive modal component for shadcn/ui.
![Demo](https://github.com/redpangilinan/credenza/assets/82772769/d22580b3-9dbc-4a56-95e9-15b4bd278ff0)
## Installation
1. Copy the `dialog` and `drawer` component from shadcn/ui.
```bash
npx shadcn-ui@latest add dialog
``````bash
npx shadcn-ui@latest add drawer
```Alternatively, if you are not using shadcn/ui cli, you can manually copy the components from [shadcn/ui](https://ui.shadcn.com/docs) or directly copy from [dialog.tsx](src/components/ui/dialog.tsx) and [drawer.tsx](src/components/ui/drawer.tsx).
If you copied the drawer component manually, make sure to install vaul.
```
npm install vaul
```2. Copy the `useMediaQuery` hook: [use-media-query.tsx](src/hooks/use-media-query.tsx)
```tsx
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
}
```3. Copy the `credenza` component: [credenza.tsx](src/components/ui/credenza.tsx)
Click to show code
```tsx
"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 desktop = "(min-width: 768px)"
const Credenza = ({ children, ...props }: RootCredenzaProps) => {
const isDesktop = useMediaQuery(desktop)
const Credenza = isDesktop ? Dialog : Drawerreturn {children}
}const CredenzaTrigger = ({ className, children, ...props }: CredenzaProps) => {
const isDesktop = useMediaQuery(desktop)
const CredenzaTrigger = isDesktop ? DialogTrigger : DrawerTriggerreturn (
{children}
)
}const CredenzaClose = ({ className, children, ...props }: CredenzaProps) => {
const isDesktop = useMediaQuery(desktop)
const CredenzaClose = isDesktop ? DialogClose : DrawerClosereturn (
{children}
)
}const CredenzaContent = ({ className, children, ...props }: CredenzaProps) => {
const isDesktop = useMediaQuery(desktop)
const CredenzaContent = isDesktop ? DialogContent : DrawerContentreturn (
{children}
)
}const CredenzaDescription = ({
className,
children,
...props
}: CredenzaProps) => {
const isDesktop = useMediaQuery(desktop)
const CredenzaDescription = isDesktop ? DialogDescription : DrawerDescriptionreturn (
{children}
)
}const CredenzaHeader = ({ className, children, ...props }: CredenzaProps) => {
const isDesktop = useMediaQuery(desktop)
const CredenzaHeader = isDesktop ? DialogHeader : DrawerHeaderreturn (
{children}
)
}const CredenzaTitle = ({ className, children, ...props }: CredenzaProps) => {
const isDesktop = useMediaQuery(desktop)
const CredenzaTitle = isDesktop ? DialogTitle : DrawerTitlereturn (
{children}
)
}const CredenzaBody = ({ className, children, ...props }: CredenzaProps) => {
return (
{children}
)
}const CredenzaFooter = ({ className, children, ...props }: CredenzaProps) => {
const isDesktop = useMediaQuery(desktop)
const CredenzaFooter = isDesktop ? DialogFooter : DrawerFooterreturn (
{children}
)
}export {
Credenza,
CredenzaTrigger,
CredenzaClose,
CredenzaContent,
CredenzaDescription,
CredenzaHeader,
CredenzaTitle,
CredenzaBody,
CredenzaFooter,
}
```4. Update the import paths based on your project structure.
5. If you want to enable background scaling, wrap your app with the `vaul-drawer-wrapper`.
```html
{children}
```See my implementation at [layout.tsx](src/app/layout.tsx). Make sure to update the background color to match your project's theme.
## Usage
```tsx
import {
Credenza,
CredenzaBody,
CredenzaClose,
CredenzaContent,
CredenzaDescription,
CredenzaFooter,
CredenzaHeader,
CredenzaTitle,
CredenzaTrigger,
} from "@/components/ui/credenza"
``````tsx
Open modal
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.
Close
```
## Credits
- [shadcn/ui](https://github.com/shadcn-ui/ui) by [shadcn](https://github.com/shadcn)
- [Vaul](https://github.com/emilkowalski/vaul) by [emilkowalski](https://github.com/emilkowalski)