@inferencesh/ui 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +68 -2
  3. package/components.json +22 -0
  4. package/package.json +231 -4
  5. package/src/components/audio-player.tsx +549 -0
  6. package/src/components/button.tsx +13 -0
  7. package/src/components/chart.tsx +403 -0
  8. package/src/components/circuit.tsx +276 -0
  9. package/src/components/code-block/code-block.tsx +260 -0
  10. package/src/components/code-block/index.ts +18 -0
  11. package/src/components/code-block/languages.ts +311 -0
  12. package/src/components/code-block/styles.ts +39 -0
  13. package/src/components/code-block/tokenizer.ts +290 -0
  14. package/src/components/code-block/types.ts +38 -0
  15. package/src/components/code-block/utils.ts +39 -0
  16. package/src/components/code.tsx +48 -0
  17. package/src/components/cookie-consent.tsx +137 -0
  18. package/src/components/copy-button.tsx +44 -0
  19. package/src/components/country-dropdown.tsx +188 -0
  20. package/src/components/glow-loader-fast.tsx +32 -0
  21. package/src/components/glow-loader-mono.tsx +33 -0
  22. package/src/components/glow-loader-sm-fast.tsx +32 -0
  23. package/src/components/glow-loader-sm-mono.tsx +34 -0
  24. package/src/components/glow-loader-sm.tsx +32 -0
  25. package/src/components/glow-loader.tsx +32 -0
  26. package/src/components/glow-logo.tsx +32 -0
  27. package/src/components/gradient.tsx +80 -0
  28. package/src/components/index.ts +45 -0
  29. package/src/components/inline-sidebar.tsx +351 -0
  30. package/src/components/input-color.tsx +349 -0
  31. package/src/components/logo-base.tsx +213 -0
  32. package/src/components/logo-color.tsx +23 -0
  33. package/src/components/logo-full.tsx +71 -0
  34. package/src/components/logo-svg.tsx +23 -0
  35. package/src/components/menu-navigation.tsx +359 -0
  36. package/src/components/multi-select.tsx +721 -0
  37. package/src/components/pastel-gradient.tsx +25 -0
  38. package/src/components/pixel-symmetry.tsx +151 -0
  39. package/src/components/progress.tsx +28 -0
  40. package/src/components/scroll-more.tsx +131 -0
  41. package/src/components/select.tsx +85 -0
  42. package/src/components/shimmering-text.tsx +108 -0
  43. package/src/components/sidebar-light.tsx +102 -0
  44. package/src/components/sonner.tsx +38 -0
  45. package/src/components/theme-switcher-sidebar.tsx +56 -0
  46. package/src/components/theme-switcher-simple.tsx +110 -0
  47. package/src/components/theme-switcher.tsx +47 -0
  48. package/src/components/toggle-group.tsx +55 -0
  49. package/src/components/tooltip-button.tsx +91 -0
  50. package/src/components/tooltip.tsx +71 -0
  51. package/src/components/tree-view.tsx +499 -0
  52. package/src/components/unglow-loader.tsx +33 -0
  53. package/src/components/waveform.tsx +1632 -0
  54. package/src/components/zoomable-image.tsx +76 -0
  55. package/src/docs/api-docs.tsx +763 -0
  56. package/src/docs/callout.tsx +160 -0
  57. package/src/docs/code-group.tsx +215 -0
  58. package/src/docs/copy-menu.tsx +143 -0
  59. package/src/docs/doc-tabs.tsx +84 -0
  60. package/src/docs/index.ts +16 -0
  61. package/src/docs/steps.tsx +105 -0
  62. package/src/docs/table-of-contents.tsx +174 -0
  63. package/src/examples/guide-markdown.ts +129 -0
  64. package/src/examples/index.ts +1153 -0
  65. package/src/global.d.ts +1 -0
  66. package/src/hooks/use-copy-to-clipboard.ts +36 -0
  67. package/src/hooks/use-mobile.ts +19 -0
  68. package/src/lib/display-name.ts +15 -0
  69. package/src/lib/example-input.ts +130 -0
  70. package/src/lib/plans.ts +44 -0
  71. package/src/lib/safe-content.ts +137 -0
  72. package/src/lib/schema.ts +320 -0
  73. package/src/lib/storage.ts +108 -0
  74. package/src/markdown/docs-markdown-renderer.tsx +518 -0
  75. package/src/markdown/helpers.ts +95 -0
  76. package/src/markdown/index.ts +24 -0
  77. package/src/markdown/markdown-renderer.tsx +232 -0
  78. package/src/markdown/youtube-embed.tsx +43 -0
  79. package/src/og/image.ts +312 -0
  80. package/src/og/index.tsx +430 -0
  81. package/src/og/query.ts +26 -0
  82. package/src/shadcn/accordion.tsx +71 -0
  83. package/src/shadcn/alert-dialog.tsx +187 -0
  84. package/src/shadcn/alert.tsx +75 -0
  85. package/src/shadcn/aspect-ratio.tsx +22 -0
  86. package/src/shadcn/attachment.tsx +207 -0
  87. package/src/shadcn/avatar.tsx +106 -0
  88. package/src/shadcn/badge.tsx +51 -0
  89. package/src/shadcn/breadcrumb.tsx +124 -0
  90. package/src/shadcn/bubble.tsx +127 -0
  91. package/src/shadcn/button-group.tsx +87 -0
  92. package/src/shadcn/button.tsx +57 -0
  93. package/src/shadcn/calendar.tsx +219 -0
  94. package/src/shadcn/card.tsx +102 -0
  95. package/src/shadcn/carousel.tsx +242 -0
  96. package/src/shadcn/chart.tsx +372 -0
  97. package/src/shadcn/checkbox.tsx +28 -0
  98. package/src/shadcn/collapsible.tsx +19 -0
  99. package/src/shadcn/combobox.tsx +297 -0
  100. package/src/shadcn/command.tsx +194 -0
  101. package/src/shadcn/context-menu.tsx +270 -0
  102. package/src/shadcn/dialog.tsx +158 -0
  103. package/src/shadcn/direction.tsx +4 -0
  104. package/src/shadcn/drawer.tsx +227 -0
  105. package/src/shadcn/dropdown-menu.tsx +265 -0
  106. package/src/shadcn/empty.tsx +103 -0
  107. package/src/shadcn/field.tsx +238 -0
  108. package/src/shadcn/form.tsx +173 -0
  109. package/src/shadcn/hover-card.tsx +50 -0
  110. package/src/shadcn/index.ts +53 -0
  111. package/src/shadcn/input-group.tsx +156 -0
  112. package/src/shadcn/input-otp.tsx +84 -0
  113. package/src/shadcn/input.tsx +19 -0
  114. package/src/shadcn/item.tsx +201 -0
  115. package/src/shadcn/kbd.tsx +26 -0
  116. package/src/shadcn/label.tsx +19 -0
  117. package/src/shadcn/marker.tsx +70 -0
  118. package/src/shadcn/menubar.tsx +278 -0
  119. package/src/shadcn/message-scroller.tsx +131 -0
  120. package/src/shadcn/message.tsx +91 -0
  121. package/src/shadcn/native-select.tsx +60 -0
  122. package/src/shadcn/navigation-menu.tsx +167 -0
  123. package/src/shadcn/pagination.tsx +130 -0
  124. package/src/shadcn/popover.tsx +87 -0
  125. package/src/shadcn/progress.tsx +82 -0
  126. package/src/shadcn/radio-group.tsx +35 -0
  127. package/src/shadcn/resizable.tsx +49 -0
  128. package/src/shadcn/scroll-area.tsx +52 -0
  129. package/src/shadcn/select.tsx +200 -0
  130. package/src/shadcn/separator.tsx +22 -0
  131. package/src/shadcn/sheet.tsx +136 -0
  132. package/src/shadcn/sidebar.tsx +721 -0
  133. package/src/shadcn/skeleton.tsx +13 -0
  134. package/src/shadcn/slider.tsx +51 -0
  135. package/src/shadcn/sonner.tsx +49 -0
  136. package/src/shadcn/spinner.tsx +10 -0
  137. package/src/shadcn/switch.tsx +29 -0
  138. package/src/shadcn/table.tsx +115 -0
  139. package/src/shadcn/tabs.tsx +79 -0
  140. package/src/shadcn/textarea.tsx +17 -0
  141. package/src/shadcn/toggle-group.tsx +89 -0
  142. package/src/shadcn/toggle.tsx +44 -0
  143. package/src/shadcn/tooltip.tsx +63 -0
  144. package/src/theme/config.ts +48 -0
  145. package/src/theme/css/base.css +92 -0
  146. package/src/theme/css/bitboy.css +75 -0
  147. package/src/theme/css/dark.css +47 -0
  148. package/src/theme/css/designer.css +122 -0
  149. package/src/theme/css/fonts.css +33 -0
  150. package/src/theme/css/globals.css +14 -0
  151. package/src/theme/css/hackintosh.css +57 -0
  152. package/src/theme/css/llama.css +103 -0
  153. package/src/theme/css/safelist.css +39 -0
  154. package/src/theme/css/shadcn.css +77 -0
  155. package/src/theme/css/theme.css +216 -0
  156. package/src/theme/embed-theme.ts +146 -0
  157. package/src/theme/fonts/FiraCode-VF.woff2 +0 -0
  158. package/src/theme/fonts/Hack-Regular.woff2 +0 -0
  159. package/src/theme/fonts/LICENSE-FiraCode.txt +93 -0
  160. package/src/theme/fonts/LICENSE-Hack.txt +45 -0
  161. package/src/theme/fonts/LICENSE-MonaSans.txt +93 -0
  162. package/src/theme/fonts/Mona-Sans.woff2 +0 -0
  163. package/src/theme/index.ts +15 -0
  164. package/src/utils/cn.ts +3 -0
  165. package/src/utils/index.ts +2 -0
@@ -0,0 +1,270 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { ContextMenu as ContextMenuPrimitive } from "@base-ui/react/context-menu"
5
+ import { cn } from "cn"
6
+ import { ChevronRightIcon, CheckIcon } from "lucide-react"
7
+
8
+ function ContextMenu({ ...props }: ContextMenuPrimitive.Root.Props) {
9
+ return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />
10
+ }
11
+
12
+ function ContextMenuPortal({ ...props }: ContextMenuPrimitive.Portal.Props) {
13
+ return (
14
+ <ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />
15
+ )
16
+ }
17
+
18
+ function ContextMenuTrigger({
19
+ className,
20
+ ...props
21
+ }: ContextMenuPrimitive.Trigger.Props) {
22
+ return (
23
+ <ContextMenuPrimitive.Trigger
24
+ data-slot="context-menu-trigger"
25
+ className={cn("select-none", className)}
26
+ {...props}
27
+ />
28
+ )
29
+ }
30
+
31
+ function ContextMenuContent({
32
+ className,
33
+ align = "start",
34
+ alignOffset = 4,
35
+ side = "right",
36
+ sideOffset = 0,
37
+ ...props
38
+ }: ContextMenuPrimitive.Popup.Props &
39
+ Pick<
40
+ ContextMenuPrimitive.Positioner.Props,
41
+ "align" | "alignOffset" | "side" | "sideOffset"
42
+ >) {
43
+ return (
44
+ <ContextMenuPrimitive.Portal>
45
+ <ContextMenuPrimitive.Positioner
46
+ className="isolate z-50 outline-none"
47
+ align={align}
48
+ alignOffset={alignOffset}
49
+ side={side}
50
+ sideOffset={sideOffset}
51
+ >
52
+ <ContextMenuPrimitive.Popup
53
+ data-slot="context-menu-content"
54
+ className={cn("z-50 max-h-(--available-height) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className )}
55
+ {...props}
56
+ />
57
+ </ContextMenuPrimitive.Positioner>
58
+ </ContextMenuPrimitive.Portal>
59
+ )
60
+ }
61
+
62
+ function ContextMenuGroup({ ...props }: ContextMenuPrimitive.Group.Props) {
63
+ return (
64
+ <ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />
65
+ )
66
+ }
67
+
68
+ function ContextMenuLabel({
69
+ className,
70
+ inset,
71
+ ...props
72
+ }: ContextMenuPrimitive.GroupLabel.Props & {
73
+ inset?: boolean
74
+ }) {
75
+ return (
76
+ <ContextMenuPrimitive.GroupLabel
77
+ data-slot="context-menu-label"
78
+ data-inset={inset}
79
+ className={cn(
80
+ "px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7",
81
+ className
82
+ )}
83
+ {...props}
84
+ />
85
+ )
86
+ }
87
+
88
+ function ContextMenuItem({
89
+ className,
90
+ inset,
91
+ variant = "default",
92
+ ...props
93
+ }: ContextMenuPrimitive.Item.Props & {
94
+ inset?: boolean
95
+ variant?: "default" | "destructive"
96
+ }) {
97
+ return (
98
+ <ContextMenuPrimitive.Item
99
+ data-slot="context-menu-item"
100
+ data-inset={inset}
101
+ data-variant={variant}
102
+ className={cn(
103
+ "group/context-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 focus:*:[svg]:text-accent-foreground data-[variant=destructive]:*:[svg]:text-destructive",
104
+ className
105
+ )}
106
+ {...props}
107
+ />
108
+ )
109
+ }
110
+
111
+ function ContextMenuSub({ ...props }: ContextMenuPrimitive.SubmenuRoot.Props) {
112
+ return (
113
+ <ContextMenuPrimitive.SubmenuRoot data-slot="context-menu-sub" {...props} />
114
+ )
115
+ }
116
+
117
+ function ContextMenuSubTrigger({
118
+ className,
119
+ inset,
120
+ children,
121
+ ...props
122
+ }: ContextMenuPrimitive.SubmenuTrigger.Props & {
123
+ inset?: boolean
124
+ }) {
125
+ return (
126
+ <ContextMenuPrimitive.SubmenuTrigger
127
+ data-slot="context-menu-sub-trigger"
128
+ data-inset={inset}
129
+ className={cn(
130
+ "flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
131
+ className
132
+ )}
133
+ {...props}
134
+ >
135
+ {children}
136
+ <ChevronRightIcon className="ml-auto" />
137
+ </ContextMenuPrimitive.SubmenuTrigger>
138
+ )
139
+ }
140
+
141
+ function ContextMenuSubContent({
142
+ ...props
143
+ }: React.ComponentProps<typeof ContextMenuContent>) {
144
+ return (
145
+ <ContextMenuContent
146
+ data-slot="context-menu-sub-content"
147
+ className="shadow-lg"
148
+ side="right"
149
+ {...props}
150
+ />
151
+ )
152
+ }
153
+
154
+ function ContextMenuCheckboxItem({
155
+ className,
156
+ children,
157
+ checked,
158
+ inset,
159
+ ...props
160
+ }: ContextMenuPrimitive.CheckboxItem.Props & {
161
+ inset?: boolean
162
+ }) {
163
+ return (
164
+ <ContextMenuPrimitive.CheckboxItem
165
+ data-slot="context-menu-checkbox-item"
166
+ data-inset={inset}
167
+ className={cn(
168
+ "relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
169
+ className
170
+ )}
171
+ checked={checked}
172
+ {...props}
173
+ >
174
+ <span className="pointer-events-none absolute right-2">
175
+ <ContextMenuPrimitive.CheckboxItemIndicator>
176
+ <CheckIcon
177
+ />
178
+ </ContextMenuPrimitive.CheckboxItemIndicator>
179
+ </span>
180
+ {children}
181
+ </ContextMenuPrimitive.CheckboxItem>
182
+ )
183
+ }
184
+
185
+ function ContextMenuRadioGroup({
186
+ ...props
187
+ }: ContextMenuPrimitive.RadioGroup.Props) {
188
+ return (
189
+ <ContextMenuPrimitive.RadioGroup
190
+ data-slot="context-menu-radio-group"
191
+ {...props}
192
+ />
193
+ )
194
+ }
195
+
196
+ function ContextMenuRadioItem({
197
+ className,
198
+ children,
199
+ inset,
200
+ ...props
201
+ }: ContextMenuPrimitive.RadioItem.Props & {
202
+ inset?: boolean
203
+ }) {
204
+ return (
205
+ <ContextMenuPrimitive.RadioItem
206
+ data-slot="context-menu-radio-item"
207
+ data-inset={inset}
208
+ className={cn(
209
+ "relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
210
+ className
211
+ )}
212
+ {...props}
213
+ >
214
+ <span className="pointer-events-none absolute right-2">
215
+ <ContextMenuPrimitive.RadioItemIndicator>
216
+ <CheckIcon
217
+ />
218
+ </ContextMenuPrimitive.RadioItemIndicator>
219
+ </span>
220
+ {children}
221
+ </ContextMenuPrimitive.RadioItem>
222
+ )
223
+ }
224
+
225
+ function ContextMenuSeparator({
226
+ className,
227
+ ...props
228
+ }: ContextMenuPrimitive.Separator.Props) {
229
+ return (
230
+ <ContextMenuPrimitive.Separator
231
+ data-slot="context-menu-separator"
232
+ className={cn("-mx-1 my-1 h-px bg-border", className)}
233
+ {...props}
234
+ />
235
+ )
236
+ }
237
+
238
+ function ContextMenuShortcut({
239
+ className,
240
+ ...props
241
+ }: React.ComponentProps<"span">) {
242
+ return (
243
+ <span
244
+ data-slot="context-menu-shortcut"
245
+ className={cn(
246
+ "ml-auto text-xs tracking-widest text-muted-foreground group-focus/context-menu-item:text-accent-foreground",
247
+ className
248
+ )}
249
+ {...props}
250
+ />
251
+ )
252
+ }
253
+
254
+ export {
255
+ ContextMenu,
256
+ ContextMenuTrigger,
257
+ ContextMenuContent,
258
+ ContextMenuItem,
259
+ ContextMenuCheckboxItem,
260
+ ContextMenuRadioItem,
261
+ ContextMenuLabel,
262
+ ContextMenuSeparator,
263
+ ContextMenuShortcut,
264
+ ContextMenuGroup,
265
+ ContextMenuPortal,
266
+ ContextMenuSub,
267
+ ContextMenuSubContent,
268
+ ContextMenuSubTrigger,
269
+ ContextMenuRadioGroup,
270
+ }
@@ -0,0 +1,158 @@
1
+ import * as React from "react"
2
+ import { Dialog as DialogPrimitive } from "@base-ui/react/dialog"
3
+ import { cn } from "cn"
4
+
5
+ import { Button } from "@inferencesh/ui/shadcn/button"
6
+ import { XIcon } from "lucide-react"
7
+
8
+ function Dialog({ ...props }: DialogPrimitive.Root.Props) {
9
+ return <DialogPrimitive.Root data-slot="dialog" {...props} />
10
+ }
11
+
12
+ function DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {
13
+ return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
14
+ }
15
+
16
+ function DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {
17
+ return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
18
+ }
19
+
20
+ function DialogClose({ ...props }: DialogPrimitive.Close.Props) {
21
+ return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
22
+ }
23
+
24
+ function DialogOverlay({
25
+ className,
26
+ ...props
27
+ }: DialogPrimitive.Backdrop.Props) {
28
+ return (
29
+ <DialogPrimitive.Backdrop
30
+ data-slot="dialog-overlay"
31
+ className={cn(
32
+ "fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
33
+ className
34
+ )}
35
+ {...props}
36
+ />
37
+ )
38
+ }
39
+
40
+ function DialogContent({
41
+ className,
42
+ children,
43
+ showCloseButton = true,
44
+ ...props
45
+ }: DialogPrimitive.Popup.Props & {
46
+ showCloseButton?: boolean
47
+ }) {
48
+ return (
49
+ <DialogPortal>
50
+ <DialogOverlay />
51
+ <DialogPrimitive.Popup
52
+ data-slot="dialog-content"
53
+ className={cn(
54
+ "fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
55
+ className
56
+ )}
57
+ {...props}
58
+ >
59
+ {children}
60
+ {showCloseButton && (
61
+ <DialogPrimitive.Close
62
+ data-slot="dialog-close"
63
+ render={
64
+ <Button
65
+ variant="ghost"
66
+ className="absolute top-2 right-2"
67
+ size="icon-sm"
68
+ />
69
+ }
70
+ >
71
+ <XIcon
72
+ />
73
+ <span className="sr-only">Close</span>
74
+ </DialogPrimitive.Close>
75
+ )}
76
+ </DialogPrimitive.Popup>
77
+ </DialogPortal>
78
+ )
79
+ }
80
+
81
+ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
82
+ return (
83
+ <div
84
+ data-slot="dialog-header"
85
+ className={cn("flex flex-col gap-2", className)}
86
+ {...props}
87
+ />
88
+ )
89
+ }
90
+
91
+ function DialogFooter({
92
+ className,
93
+ showCloseButton = false,
94
+ children,
95
+ ...props
96
+ }: React.ComponentProps<"div"> & {
97
+ showCloseButton?: boolean
98
+ }) {
99
+ return (
100
+ <div
101
+ data-slot="dialog-footer"
102
+ className={cn(
103
+ "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end",
104
+ className
105
+ )}
106
+ {...props}
107
+ >
108
+ {children}
109
+ {showCloseButton && (
110
+ <DialogPrimitive.Close render={<Button variant="outline" />}>
111
+ Close
112
+ </DialogPrimitive.Close>
113
+ )}
114
+ </div>
115
+ )
116
+ }
117
+
118
+ function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
119
+ return (
120
+ <DialogPrimitive.Title
121
+ data-slot="dialog-title"
122
+ className={cn(
123
+ "text-base leading-none font-medium",
124
+ className
125
+ )}
126
+ {...props}
127
+ />
128
+ )
129
+ }
130
+
131
+ function DialogDescription({
132
+ className,
133
+ ...props
134
+ }: DialogPrimitive.Description.Props) {
135
+ return (
136
+ <DialogPrimitive.Description
137
+ data-slot="dialog-description"
138
+ className={cn(
139
+ "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
140
+ className
141
+ )}
142
+ {...props}
143
+ />
144
+ )
145
+ }
146
+
147
+ export {
148
+ Dialog,
149
+ DialogClose,
150
+ DialogContent,
151
+ DialogDescription,
152
+ DialogFooter,
153
+ DialogHeader,
154
+ DialogOverlay,
155
+ DialogPortal,
156
+ DialogTitle,
157
+ DialogTrigger,
158
+ }
@@ -0,0 +1,4 @@
1
+ export {
2
+ DirectionProvider,
3
+ useDirection,
4
+ } from "@base-ui/react/direction-provider"
@@ -0,0 +1,227 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Drawer as DrawerPrimitive } from "@base-ui/react/drawer"
5
+ import { cn } from "cn"
6
+
7
+ type DrawerContextProps = {
8
+ hasSnapPoints: boolean
9
+ modal: DrawerPrimitive.Root.Props["modal"]
10
+ showSwipeHandle: boolean
11
+ swipeDirection: NonNullable<DrawerPrimitive.Root.Props["swipeDirection"]>
12
+ }
13
+
14
+ const DrawerContext = React.createContext<DrawerContextProps | null>(null)
15
+
16
+ function useDrawer() {
17
+ const context = React.useContext(DrawerContext)
18
+
19
+ if (!context) {
20
+ throw new Error("useDrawer must be used within a Drawer.")
21
+ }
22
+
23
+ return context
24
+ }
25
+
26
+ function Drawer({
27
+ modal = true,
28
+ showSwipeHandle = false,
29
+ snapPoints,
30
+ swipeDirection = "down",
31
+ ...props
32
+ }: DrawerPrimitive.Root.Props & {
33
+ showSwipeHandle?: boolean
34
+ }) {
35
+ const hasSnapPoints = snapPoints != null && snapPoints.length > 0
36
+ const contextValue = React.useMemo(
37
+ () => ({ hasSnapPoints, modal, showSwipeHandle, swipeDirection }),
38
+ [hasSnapPoints, modal, showSwipeHandle, swipeDirection]
39
+ )
40
+
41
+ return (
42
+ <DrawerContext.Provider value={contextValue}>
43
+ <DrawerPrimitive.Root
44
+ data-slot="drawer"
45
+ modal={modal}
46
+ snapPoints={snapPoints}
47
+ swipeDirection={swipeDirection}
48
+ {...props}
49
+ />
50
+ </DrawerContext.Provider>
51
+ )
52
+ }
53
+
54
+ function DrawerTrigger({ ...props }: DrawerPrimitive.Trigger.Props) {
55
+ return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
56
+ }
57
+
58
+ function DrawerPortal({ ...props }: DrawerPrimitive.Portal.Props) {
59
+ return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />
60
+ }
61
+
62
+ function DrawerClose({ ...props }: DrawerPrimitive.Close.Props) {
63
+ return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />
64
+ }
65
+
66
+ function DrawerOverlay({
67
+ className,
68
+ ...props
69
+ }: DrawerPrimitive.Backdrop.Props) {
70
+ return (
71
+ <DrawerPrimitive.Backdrop
72
+ data-slot="drawer-overlay"
73
+ className={cn(
74
+ "fixed inset-0 z-50 min-h-dvh bg-black/10 opacity-[max(var(--drawer-overlay-min-opacity,0),calc(1-var(--drawer-swipe-progress)))] transition-opacity duration-450 ease-[cubic-bezier(0.32,0.72,0,1)] select-none data-ending-style:pointer-events-none data-ending-style:opacity-0 data-ending-style:duration-[calc(var(--drawer-swipe-strength)*400ms)] data-snap-points:[--drawer-overlay-min-opacity:0.5] data-starting-style:opacity-0 data-swiping:duration-0 supports-backdrop-filter:backdrop-blur-xs supports-[-webkit-touch-callout:none]:absolute",
75
+ className
76
+ )}
77
+ {...props}
78
+ />
79
+ )
80
+ }
81
+
82
+ function DrawerSwipeHandle({
83
+ className,
84
+ ...props
85
+ }: React.ComponentProps<"div">) {
86
+ return (
87
+ <div
88
+ data-slot="drawer-swipe-handle"
89
+ aria-hidden="true"
90
+ className={cn(
91
+ "relative z-10 flex shrink-0 cursor-grab transition-opacity duration-200 group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-drawer-swiping/drawer-popup:opacity-100 group-data-[swipe-axis=x]/drawer-popup:h-full group-data-[swipe-axis=x]/drawer-popup:w-3 group-data-[swipe-axis=x]/drawer-popup:items-center group-data-[swipe-axis=y]/drawer-popup:h-3 group-data-[swipe-axis=y]/drawer-popup:w-full group-data-[swipe-axis=y]/drawer-popup:justify-center group-data-[swipe-direction=down]/drawer-popup:items-end group-data-[swipe-direction=left]/drawer-popup:order-last group-data-[swipe-direction=left]/drawer-popup:justify-start group-data-[swipe-direction=right]/drawer-popup:justify-end group-data-[swipe-direction=up]/drawer-popup:order-last group-data-[swipe-direction=up]/drawer-popup:items-start after:block after:shrink-0 after:rounded-full after:bg-muted group-data-[swipe-axis=x]/drawer-popup:after:h-24 group-data-[swipe-axis=x]/drawer-popup:after:w-1 group-data-[swipe-axis=y]/drawer-popup:after:h-1 group-data-[swipe-axis=y]/drawer-popup:after:w-24 active:cursor-grabbing",
92
+ className
93
+ )}
94
+ {...props}
95
+ />
96
+ )
97
+ }
98
+
99
+ function DrawerContent({
100
+ className,
101
+ children,
102
+ ...props
103
+ }: DrawerPrimitive.Popup.Props) {
104
+ const { hasSnapPoints, modal, showSwipeHandle, swipeDirection } = useDrawer()
105
+ const swipeAxis =
106
+ swipeDirection === "down" || swipeDirection === "up" ? "y" : "x"
107
+
108
+ return (
109
+ <DrawerPortal data-slot="drawer-portal">
110
+ {modal === true && (
111
+ <DrawerOverlay data-snap-points={hasSnapPoints ? "" : undefined} />
112
+ )}
113
+ <DrawerPrimitive.Viewport
114
+ data-slot="drawer-viewport"
115
+ data-modal={modal}
116
+ className="pointer-events-none fixed inset-0 z-50 select-none data-[modal=true]:pointer-events-auto"
117
+ >
118
+ <DrawerPrimitive.Popup
119
+ data-slot="drawer-popup"
120
+ data-swipe-axis={swipeAxis}
121
+ data-snap-points={hasSnapPoints ? "" : undefined}
122
+ className={cn(
123
+ // Base.
124
+ "group/drawer-popup pointer-events-auto fixed z-50 m-(--drawer-inset,0px) flex h-(--drawer-content-height) max-h-(--drawer-content-max-height,none) min-h-0 w-(--drawer-content-width,auto) transform-[translate3d(var(--translate-x,0px),var(--translate-y,0px),0)_scale(var(--stack-scale))] flex-col bg-popover text-sm text-popover-foreground transition-[transform,height,opacity,filter] duration-450 ease-[cubic-bezier(0.22,1,0.36,1)] will-change-transform outline-none select-none [interpolate-size:allow-keywords] data-[swipe-direction=down]:rounded-t-xl data-[swipe-direction=down]:border-t data-[swipe-direction=left]:rounded-r-xl data-[swipe-direction=left]:border-r data-[swipe-direction=right]:rounded-l-xl data-[swipe-direction=right]:border-l data-[swipe-direction=up]:rounded-b-xl data-[swipe-direction=up]:border-b",
125
+ // Nested.
126
+ "data-nested-drawer-open:overflow-hidden data-nested-drawer-open:brightness-95",
127
+ // Bleed.
128
+ "after:pointer-events-none after:absolute after:bg-(--drawer-bleed-background,var(--color-popover)) data-[swipe-axis=x]:after:inset-y-0 data-[swipe-axis=x]:after:w-(--bleed) data-[swipe-axis=y]:after:inset-x-0 data-[swipe-axis=y]:after:h-(--bleed) data-[swipe-direction=down]:after:top-full data-[swipe-direction=left]:after:right-full data-[swipe-direction=right]:after:left-full data-[swipe-direction=up]:after:bottom-full",
129
+ // Sizing.
130
+ "[--drawer-content-height:var(--drawer-height,auto)] data-[swipe-axis=x]:[--drawer-content-width:75%] data-[swipe-axis=y]:[--drawer-content-max-height:calc(100dvh-6rem)] data-[swipe-axis=y]:data-snap-points:[--drawer-content-height:100dvh] data-[swipe-axis=x]:sm:[--drawer-content-width:24rem]",
131
+ // Stack.
132
+ "[--bleed:3rem] [--peek:1rem] [--stack-height:var(--drawer-frontmost-height,var(--drawer-height,0px))] [--stack-peek-offset:max(0px,calc((var(--nested-drawers)-var(--stack-progress))*var(--peek)))] [--stack-progress:clamp(0,var(--drawer-swipe-progress),1)] [--stack-scale-base:max(0,calc(1-(var(--nested-drawers)*var(--stack-step))))] [--stack-scale:clamp(0,calc(var(--stack-scale-base)+(var(--stack-step)*var(--stack-progress))),1)] [--stack-shrink:calc(1-var(--stack-scale))] [--stack-step:0.05]",
133
+ // Transitions.
134
+ "data-ending-style:transform-(--closed-transform) data-ending-style:opacity-[0.9999] data-ending-style:duration-[calc(var(--drawer-swipe-strength)*400ms)] data-nested-drawer-swiping:duration-0 data-ending-style:data-nested-drawer-swiping:duration-[calc(var(--drawer-swipe-strength)*400ms)] data-starting-style:transform-(--closed-transform) data-swiping:duration-0 data-ending-style:data-swiping:duration-[calc(var(--drawer-swipe-strength)*400ms)]",
135
+ // Axis: y.
136
+ "data-[swipe-axis=y]:inset-x-0 data-[swipe-axis=y]:data-nested-drawer-open:h-(--stack-height)",
137
+ // Axis: x.
138
+ "data-[swipe-axis=x]:inset-y-0 data-[swipe-axis=x]:flex-row",
139
+ // Direction: down.
140
+ "data-[swipe-direction=down]:bottom-0 data-[swipe-direction=down]:origin-bottom data-[swipe-direction=down]:[--closed-transform:translate3d(0,calc(100%+var(--drawer-inset,0px)+2px),0)] data-[swipe-direction=down]:[--translate-y:calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-y)-var(--stack-peek-offset)-(var(--stack-shrink)*var(--stack-height)))]",
141
+ // Direction: up.
142
+ "data-[swipe-direction=up]:top-0 data-[swipe-direction=up]:origin-top data-[swipe-direction=up]:[--closed-transform:translate3d(0,calc(-100%-var(--drawer-inset,0px)-2px),0)] data-[swipe-direction=up]:[--translate-y:calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-y)+var(--stack-peek-offset)+(var(--stack-shrink)*var(--stack-height)))]",
143
+ // Direction: left.
144
+ "data-[swipe-direction=left]:left-0 data-[swipe-direction=left]:origin-left data-[swipe-direction=left]:[--closed-transform:translate3d(calc(-100%-var(--drawer-inset,0px)-2px),0,0)] data-[swipe-direction=left]:[--translate-x:calc(var(--drawer-swipe-movement-x)+var(--stack-peek-offset)+(var(--stack-shrink)*100%))]",
145
+ // Direction: right.
146
+ "data-[swipe-direction=right]:right-0 data-[swipe-direction=right]:origin-right data-[swipe-direction=right]:[--closed-transform:translate3d(calc(100%+var(--drawer-inset,0px)+2px),0,0)] data-[swipe-direction=right]:[--translate-x:calc(var(--drawer-swipe-movement-x)-var(--stack-peek-offset)-(var(--stack-shrink)*100%))]",
147
+ className
148
+ )}
149
+ {...props}
150
+ >
151
+ {showSwipeHandle && <DrawerSwipeHandle />}
152
+ <DrawerPrimitive.Content
153
+ data-slot="drawer-content"
154
+ className={cn(
155
+ "flex min-h-0 flex-1 flex-col overflow-hidden overscroll-contain rounded-[inherit] transition-opacity duration-300 ease-[cubic-bezier(0.45,1.005,0,1.005)] select-text group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-drawer-swiping/drawer-popup:opacity-100 group-data-swiping/drawer-popup:select-none"
156
+ )}
157
+ >
158
+ {children}
159
+ </DrawerPrimitive.Content>
160
+ </DrawerPrimitive.Popup>
161
+ </DrawerPrimitive.Viewport>
162
+ </DrawerPortal>
163
+ )
164
+ }
165
+
166
+ function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
167
+ return (
168
+ <div
169
+ data-slot="drawer-header"
170
+ className={cn(
171
+ "flex shrink-0 flex-col gap-0.5 p-4 pb-0 group-data-[swipe-axis=y]/drawer-popup:text-center md:gap-0.5 md:text-left",
172
+ className
173
+ )}
174
+ {...props}
175
+ />
176
+ )
177
+ }
178
+
179
+ function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
180
+ return (
181
+ <div
182
+ data-slot="drawer-footer"
183
+ className={cn("mt-auto flex shrink-0 flex-col gap-2 p-4 pt-0", className)}
184
+ {...props}
185
+ />
186
+ )
187
+ }
188
+
189
+ function DrawerTitle({ className, ...props }: DrawerPrimitive.Title.Props) {
190
+ return (
191
+ <DrawerPrimitive.Title
192
+ data-slot="drawer-title"
193
+ className={cn(
194
+ "text-base font-medium text-foreground",
195
+ className
196
+ )}
197
+ {...props}
198
+ />
199
+ )
200
+ }
201
+
202
+ function DrawerDescription({
203
+ className,
204
+ ...props
205
+ }: DrawerPrimitive.Description.Props) {
206
+ return (
207
+ <DrawerPrimitive.Description
208
+ data-slot="drawer-description"
209
+ className={cn("text-sm text-balance text-muted-foreground", className)}
210
+ {...props}
211
+ />
212
+ )
213
+ }
214
+
215
+ export {
216
+ Drawer,
217
+ DrawerPortal,
218
+ DrawerOverlay,
219
+ DrawerSwipeHandle,
220
+ DrawerTrigger,
221
+ DrawerClose,
222
+ DrawerContent,
223
+ DrawerHeader,
224
+ DrawerFooter,
225
+ DrawerTitle,
226
+ DrawerDescription,
227
+ }