drawer.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. "use client"
  2. import * as React from "react"
  3. import { Drawer as DrawerPrimitive } from "vaul"
  4. import { cn } from "@/lib/utils"
  5. function Drawer({
  6. ...props
  7. }: React.ComponentProps<typeof DrawerPrimitive.Root>) {
  8. return <DrawerPrimitive.Root data-slot="drawer" {...props} />
  9. }
  10. function DrawerTrigger({
  11. ...props
  12. }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
  13. return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
  14. }
  15. function DrawerPortal({
  16. ...props
  17. }: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
  18. return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />
  19. }
  20. function DrawerClose({
  21. ...props
  22. }: React.ComponentProps<typeof DrawerPrimitive.Close>) {
  23. return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />
  24. }
  25. function DrawerOverlay({
  26. className,
  27. ...props
  28. }: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
  29. return (
  30. <DrawerPrimitive.Overlay
  31. data-slot="drawer-overlay"
  32. className={cn(
  33. "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
  34. className
  35. )}
  36. {...props}
  37. />
  38. )
  39. }
  40. function DrawerContent({
  41. className,
  42. children,
  43. ...props
  44. }: React.ComponentProps<typeof DrawerPrimitive.Content>) {
  45. return (
  46. <DrawerPortal data-slot="drawer-portal">
  47. <DrawerOverlay />
  48. <DrawerPrimitive.Content
  49. data-slot="drawer-content"
  50. className={cn(
  51. "group/drawer-content bg-background fixed z-50 flex h-auto flex-col",
  52. "data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg data-[vaul-drawer-direction=top]:border-b",
  53. "data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg data-[vaul-drawer-direction=bottom]:border-t",
  54. "data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=right]:sm:max-w-sm",
  55. "data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=left]:sm:max-w-sm",
  56. className
  57. )}
  58. {...props}
  59. >
  60. <div className="bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
  61. {children}
  62. </DrawerPrimitive.Content>
  63. </DrawerPortal>
  64. )
  65. }
  66. function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
  67. return (
  68. <div
  69. data-slot="drawer-header"
  70. className={cn(
  71. "flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-1.5 md:text-left",
  72. className
  73. )}
  74. {...props}
  75. />
  76. )
  77. }
  78. function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
  79. return (
  80. <div
  81. data-slot="drawer-footer"
  82. className={cn("mt-auto flex flex-col gap-2 p-4", className)}
  83. {...props}
  84. />
  85. )
  86. }
  87. function DrawerTitle({
  88. className,
  89. ...props
  90. }: React.ComponentProps<typeof DrawerPrimitive.Title>) {
  91. return (
  92. <DrawerPrimitive.Title
  93. data-slot="drawer-title"
  94. className={cn("text-foreground font-semibold", className)}
  95. {...props}
  96. />
  97. )
  98. }
  99. function DrawerDescription({
  100. className,
  101. ...props
  102. }: React.ComponentProps<typeof DrawerPrimitive.Description>) {
  103. return (
  104. <DrawerPrimitive.Description
  105. data-slot="drawer-description"
  106. className={cn("text-muted-foreground text-sm", className)}
  107. {...props}
  108. />
  109. )
  110. }
  111. export {
  112. Drawer,
  113. DrawerPortal,
  114. DrawerOverlay,
  115. DrawerTrigger,
  116. DrawerClose,
  117. DrawerContent,
  118. DrawerHeader,
  119. DrawerFooter,
  120. DrawerTitle,
  121. DrawerDescription,
  122. }