drawer.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. "use client"
  2. import * as React from "react"
  3. import { Drawer as DrawerPrimitive } from "vaul"
  4. import { cn } from "@/lib/utils"
  5. const Drawer = ({
  6. shouldScaleBackground = true,
  7. ...props
  8. }: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
  9. <DrawerPrimitive.Root
  10. shouldScaleBackground={shouldScaleBackground}
  11. {...props}
  12. />
  13. )
  14. Drawer.displayName = "Drawer"
  15. const DrawerTrigger = DrawerPrimitive.Trigger
  16. const DrawerPortal = DrawerPrimitive.Portal
  17. const DrawerClose = DrawerPrimitive.Close
  18. const DrawerOverlay = React.forwardRef<
  19. React.ElementRef<typeof DrawerPrimitive.Overlay>,
  20. React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
  21. >(({ className, ...props }, ref) => (
  22. <DrawerPrimitive.Overlay
  23. ref={ref}
  24. className={cn("fixed inset-0 z-50 bg-black/80", className)}
  25. {...props}
  26. />
  27. ))
  28. DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName
  29. const DrawerContent = React.forwardRef<
  30. React.ElementRef<typeof DrawerPrimitive.Content>,
  31. React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
  32. >(({ className, children, ...props }, ref) => (
  33. <DrawerPortal>
  34. <DrawerOverlay />
  35. <DrawerPrimitive.Content
  36. ref={ref}
  37. className={cn(
  38. "fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
  39. className
  40. )}
  41. {...props}
  42. >
  43. <div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
  44. {children}
  45. </DrawerPrimitive.Content>
  46. </DrawerPortal>
  47. ))
  48. DrawerContent.displayName = "DrawerContent"
  49. const DrawerHeader = ({
  50. className,
  51. ...props
  52. }: React.HTMLAttributes<HTMLDivElement>) => (
  53. <div
  54. className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
  55. {...props}
  56. />
  57. )
  58. DrawerHeader.displayName = "DrawerHeader"
  59. const DrawerFooter = ({
  60. className,
  61. ...props
  62. }: React.HTMLAttributes<HTMLDivElement>) => (
  63. <div
  64. className={cn("mt-auto flex flex-col gap-2 p-4", className)}
  65. {...props}
  66. />
  67. )
  68. DrawerFooter.displayName = "DrawerFooter"
  69. const DrawerTitle = React.forwardRef<
  70. React.ElementRef<typeof DrawerPrimitive.Title>,
  71. React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
  72. >(({ className, ...props }, ref) => (
  73. <DrawerPrimitive.Title
  74. ref={ref}
  75. className={cn(
  76. "text-lg font-semibold leading-none tracking-tight",
  77. className
  78. )}
  79. {...props}
  80. />
  81. ))
  82. DrawerTitle.displayName = DrawerPrimitive.Title.displayName
  83. const DrawerDescription = React.forwardRef<
  84. React.ElementRef<typeof DrawerPrimitive.Description>,
  85. React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
  86. >(({ className, ...props }, ref) => (
  87. <DrawerPrimitive.Description
  88. ref={ref}
  89. className={cn("text-sm text-muted-foreground", className)}
  90. {...props}
  91. />
  92. ))
  93. DrawerDescription.displayName = DrawerPrimitive.Description.displayName
  94. export {
  95. Drawer,
  96. DrawerPortal,
  97. DrawerOverlay,
  98. DrawerTrigger,
  99. DrawerClose,
  100. DrawerContent,
  101. DrawerHeader,
  102. DrawerFooter,
  103. DrawerTitle,
  104. DrawerDescription,
  105. }