drawer.tsx 4.1 KB

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