@aphrody/koharu-ui 0.0.0-stage → 0.1.0

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 (123) hide show
  1. package/README.md +37 -2
  2. package/package.json +70 -4
  3. package/src/assets/NotoSansCJK-VF.otf +0 -0
  4. package/src/assets/OFL.txt +92 -0
  5. package/src/components/ClientOnly.tsx +21 -0
  6. package/src/components/ShenronExportPanel.tsx +213 -0
  7. package/src/components/app/AboutDialog.tsx +64 -0
  8. package/src/components/app/KoharuApp.tsx +58 -0
  9. package/src/components/app/StartupView.tsx +67 -0
  10. package/src/components/app/TitleBar.tsx +322 -0
  11. package/src/components/app/Updater.tsx +143 -0
  12. package/src/components/app/WindowChrome.tsx +137 -0
  13. package/src/components/controls/ColorSampling.tsx +70 -0
  14. package/src/components/controls/ColorWell.tsx +139 -0
  15. package/src/components/controls/CommitTextarea.tsx +63 -0
  16. package/src/components/controls/FontPicker.tsx +543 -0
  17. package/src/components/controls/ModelPicker.tsx +178 -0
  18. package/src/components/controls/OutputPicker.tsx +170 -0
  19. package/src/components/editor/ActivityCenter.tsx +234 -0
  20. package/src/components/editor/AgentPanel.tsx +352 -0
  21. package/src/components/editor/CanvasCommandBar.tsx +38 -0
  22. package/src/components/editor/CanvasOverlay.tsx +194 -0
  23. package/src/components/editor/CanvasWorkspace.tsx +947 -0
  24. package/src/components/editor/Editor.tsx +56 -0
  25. package/src/components/editor/InferenceControl.tsx +457 -0
  26. package/src/components/editor/Inspector.tsx +1073 -0
  27. package/src/components/editor/PageRail.tsx +581 -0
  28. package/src/components/editor/ResourceMonitor.tsx +151 -0
  29. package/src/components/editor/RightSidebar.tsx +50 -0
  30. package/src/components/editor/SelectionControls.tsx +184 -0
  31. package/src/components/editor/StatusBar.tsx +41 -0
  32. package/src/components/editor/ToolBar.tsx +182 -0
  33. package/src/components/editor/useCanvas.ts +194 -0
  34. package/src/components/preferences/GenerationPreferences.tsx +118 -0
  35. package/src/components/preferences/KoharuSettings.tsx +229 -0
  36. package/src/components/preferences/PipelinePreferences.tsx +173 -0
  37. package/src/components/preferences/PreferenceFields.tsx +149 -0
  38. package/src/components/preferences/ProviderPreferences.tsx +173 -0
  39. package/src/components/preferences/SettingsPage.tsx +336 -0
  40. package/src/components/preferences/TranslationPreferences.tsx +187 -0
  41. package/src/components/preferences/TypesettingPreferences.tsx +142 -0
  42. package/src/components/preferences/models.ts +103 -0
  43. package/src/components/start/StartView.tsx +277 -0
  44. package/src/index.ts +59 -0
  45. package/src/internal/components/accordion.tsx +72 -0
  46. package/src/internal/components/alert-dialog.tsx +189 -0
  47. package/src/internal/components/alert.tsx +76 -0
  48. package/src/internal/components/aspect-ratio.tsx +22 -0
  49. package/src/internal/components/attachment.tsx +207 -0
  50. package/src/internal/components/avatar.tsx +109 -0
  51. package/src/internal/components/badge.tsx +52 -0
  52. package/src/internal/components/breadcrumb.tsx +125 -0
  53. package/src/internal/components/bubble.tsx +128 -0
  54. package/src/internal/components/button-group.tsx +87 -0
  55. package/src/internal/components/button.tsx +58 -0
  56. package/src/internal/components/card.tsx +103 -0
  57. package/src/internal/components/checkbox.tsx +29 -0
  58. package/src/internal/components/collapsible.tsx +21 -0
  59. package/src/internal/components/combobox.tsx +298 -0
  60. package/src/internal/components/context-menu.tsx +272 -0
  61. package/src/internal/components/dialog.tsx +162 -0
  62. package/src/internal/components/direction.tsx +6 -0
  63. package/src/internal/components/drawer.tsx +230 -0
  64. package/src/internal/components/dropdown-menu.tsx +278 -0
  65. package/src/internal/components/empty.tsx +104 -0
  66. package/src/internal/components/field.tsx +238 -0
  67. package/src/internal/components/hover-card.tsx +52 -0
  68. package/src/internal/components/input-group.tsx +158 -0
  69. package/src/internal/components/input.tsx +20 -0
  70. package/src/internal/components/item.tsx +201 -0
  71. package/src/internal/components/kbd.tsx +26 -0
  72. package/src/internal/components/label.tsx +20 -0
  73. package/src/internal/components/marker.tsx +71 -0
  74. package/src/internal/components/menubar.tsx +280 -0
  75. package/src/internal/components/message.tsx +92 -0
  76. package/src/internal/components/native-select.tsx +61 -0
  77. package/src/internal/components/navigation-menu.tsx +168 -0
  78. package/src/internal/components/number-field.tsx +68 -0
  79. package/src/internal/components/pagination.tsx +130 -0
  80. package/src/internal/components/popover.tsx +91 -0
  81. package/src/internal/components/progress.tsx +83 -0
  82. package/src/internal/components/radio-group.tsx +38 -0
  83. package/src/internal/components/resizable.tsx +50 -0
  84. package/src/internal/components/scroll-area.tsx +88 -0
  85. package/src/internal/components/select.tsx +191 -0
  86. package/src/internal/components/separator.tsx +25 -0
  87. package/src/internal/components/sheet.tsx +140 -0
  88. package/src/internal/components/sidebar.tsx +723 -0
  89. package/src/internal/components/skeleton.tsx +13 -0
  90. package/src/internal/components/slider.tsx +56 -0
  91. package/src/internal/components/spinner.tsx +10 -0
  92. package/src/internal/components/switch.tsx +32 -0
  93. package/src/internal/components/table.tsx +116 -0
  94. package/src/internal/components/tabs.tsx +82 -0
  95. package/src/internal/components/textarea.tsx +18 -0
  96. package/src/internal/components/toast.tsx +235 -0
  97. package/src/internal/components/toggle-group.tsx +89 -0
  98. package/src/internal/components/toggle.tsx +45 -0
  99. package/src/internal/components/tooltip.tsx +67 -0
  100. package/src/internal/hooks/use-mobile.ts +19 -0
  101. package/src/internal/lib/utils.ts +6 -0
  102. package/src/internal/styles/globals.css +73 -0
  103. package/src/lib/backend.ts +85 -0
  104. package/src/lib/document.ts +46 -0
  105. package/src/lib/geometry.ts +272 -0
  106. package/src/lib/i18n.ts +54 -0
  107. package/src/lib/queries.ts +110 -0
  108. package/src/lib/store.ts +191 -0
  109. package/src/lib/translation.ts +35 -0
  110. package/src/locales/en-US/translation.json +536 -0
  111. package/src/locales/es-ES/translation.json +536 -0
  112. package/src/locales/ja-JP/translation.json +536 -0
  113. package/src/locales/ko-KR/translation.json +536 -0
  114. package/src/locales/pt-BR/translation.json +536 -0
  115. package/src/locales/ru-RU/translation.json +536 -0
  116. package/src/locales/tr-TR/translation.json +536 -0
  117. package/src/locales/zh-CN/translation.json +536 -0
  118. package/src/locales/zh-TW/translation.json +536 -0
  119. package/src/navigation.ts +28 -0
  120. package/src/providers.tsx +132 -0
  121. package/src/shenron-pipeline-env.d.ts +14 -0
  122. package/src/styles.css +246 -0
  123. package/tsconfig.json +21 -0
@@ -0,0 +1,88 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { ScrollArea as ScrollAreaPrimitive } from "@base-ui/react/scroll-area"
5
+
6
+ import { cn } from "../lib/utils"
7
+
8
+ function ScrollArea({
9
+ className,
10
+ children,
11
+ viewportClassName,
12
+ viewportRef,
13
+ viewportRender,
14
+ scrollbarClassName,
15
+ orientation = "vertical",
16
+ ...props
17
+ }: ScrollAreaPrimitive.Root.Props & {
18
+ viewportClassName?: string
19
+ viewportRef?: React.Ref<React.ComponentRef<typeof ScrollAreaPrimitive.Viewport>>
20
+ viewportRender?: ScrollAreaPrimitive.Viewport.Props["render"]
21
+ scrollbarClassName?: string
22
+ orientation?: "vertical" | "horizontal" | "both"
23
+ }) {
24
+ return (
25
+ <ScrollAreaPrimitive.Root
26
+ data-slot="scroll-area"
27
+ className={cn("group/scroll-area relative", className)}
28
+ {...props}
29
+ >
30
+ <ScrollAreaPrimitive.Viewport
31
+ ref={viewportRef}
32
+ render={viewportRender}
33
+ data-slot="scroll-area-viewport"
34
+ className={cn(
35
+ "size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1",
36
+ viewportClassName
37
+ )}
38
+ >
39
+ <ScrollAreaPrimitive.Content
40
+ data-slot="scroll-area-content"
41
+ style={
42
+ orientation === "vertical"
43
+ ? { minWidth: "100%", width: "100%" }
44
+ : undefined
45
+ }
46
+ >
47
+ {children}
48
+ </ScrollAreaPrimitive.Content>
49
+ </ScrollAreaPrimitive.Viewport>
50
+ {orientation !== "horizontal" && (
51
+ <ScrollBar className={scrollbarClassName} />
52
+ )}
53
+ {orientation !== "vertical" && (
54
+ <ScrollBar
55
+ orientation="horizontal"
56
+ className={scrollbarClassName}
57
+ />
58
+ )}
59
+ <ScrollAreaPrimitive.Corner />
60
+ </ScrollAreaPrimitive.Root>
61
+ )
62
+ }
63
+
64
+ function ScrollBar({
65
+ className,
66
+ orientation = "vertical",
67
+ ...props
68
+ }: ScrollAreaPrimitive.Scrollbar.Props) {
69
+ return (
70
+ <ScrollAreaPrimitive.Scrollbar
71
+ data-slot="scroll-area-scrollbar"
72
+ data-orientation={orientation}
73
+ orientation={orientation}
74
+ className={cn(
75
+ "pointer-events-none flex touch-none p-px opacity-0 transition-opacity duration-150 select-none group-hover/scroll-area:pointer-events-auto group-hover/scroll-area:opacity-100 data-hovering:pointer-events-auto data-hovering:opacity-100 data-scrolling:pointer-events-auto data-scrolling:opacity-100 data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-l data-vertical:border-l-transparent",
76
+ className
77
+ )}
78
+ {...props}
79
+ >
80
+ <ScrollAreaPrimitive.Thumb
81
+ data-slot="scroll-area-thumb"
82
+ className="relative flex-1 rounded-full bg-border"
83
+ />
84
+ </ScrollAreaPrimitive.Scrollbar>
85
+ )
86
+ }
87
+
88
+ export { ScrollArea, ScrollBar }
@@ -0,0 +1,191 @@
1
+ 'use client'
2
+
3
+ import { Select as SelectPrimitive } from '@base-ui/react/select'
4
+ import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from 'lucide-react'
5
+ import * as React from 'react'
6
+
7
+ import { cn } from '../lib/utils'
8
+
9
+ const Select = SelectPrimitive.Root
10
+
11
+ function SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {
12
+ return (
13
+ <SelectPrimitive.Group
14
+ data-slot='select-group'
15
+ className={cn('scroll-my-1 p-1', className)}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
22
+ return (
23
+ <SelectPrimitive.Value
24
+ data-slot='select-value'
25
+ className={cn('flex flex-1 text-left', className)}
26
+ {...props}
27
+ />
28
+ )
29
+ }
30
+
31
+ function SelectTrigger({
32
+ className,
33
+ size = 'default',
34
+ children,
35
+ ...props
36
+ }: SelectPrimitive.Trigger.Props & {
37
+ size?: 'sm' | 'default'
38
+ }) {
39
+ return (
40
+ <SelectPrimitive.Trigger
41
+ data-slot='select-trigger'
42
+ data-size={size}
43
+ className={cn(
44
+ "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-6 data-[size=sm]:gap-1 data-[size=sm]:rounded-md data-[size=sm]:px-1.5 data-[size=sm]:py-0 data-[size=sm]:text-[11px] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
45
+ className,
46
+ )}
47
+ {...props}
48
+ >
49
+ {children}
50
+ <SelectPrimitive.Icon
51
+ render={<ChevronDownIcon className='pointer-events-none size-3.5 text-muted-foreground' />}
52
+ />
53
+ </SelectPrimitive.Trigger>
54
+ )
55
+ }
56
+
57
+ function SelectContent({
58
+ className,
59
+ children,
60
+ side = 'bottom',
61
+ sideOffset = 4,
62
+ align = 'center',
63
+ alignOffset = 0,
64
+ alignItemWithTrigger = true,
65
+ ...props
66
+ }: SelectPrimitive.Popup.Props &
67
+ Pick<
68
+ SelectPrimitive.Positioner.Props,
69
+ 'align' | 'alignOffset' | 'side' | 'sideOffset' | 'alignItemWithTrigger'
70
+ >) {
71
+ return (
72
+ <SelectPrimitive.Portal>
73
+ <SelectPrimitive.Positioner
74
+ side={side}
75
+ sideOffset={sideOffset}
76
+ align={align}
77
+ alignOffset={alignOffset}
78
+ alignItemWithTrigger={alignItemWithTrigger}
79
+ className='isolate z-50'
80
+ >
81
+ <SelectPrimitive.Popup
82
+ data-koharu-ui-layer=""
83
+ data-slot='select-content'
84
+ data-align-trigger={alignItemWithTrigger}
85
+ className={cn(
86
+ 'relative isolate z-50 max-h-(--available-height) w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-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',
87
+ className,
88
+ )}
89
+ {...props}
90
+ >
91
+ <SelectScrollUpButton />
92
+ <SelectPrimitive.List>{children}</SelectPrimitive.List>
93
+ <SelectScrollDownButton />
94
+ </SelectPrimitive.Popup>
95
+ </SelectPrimitive.Positioner>
96
+ </SelectPrimitive.Portal>
97
+ )
98
+ }
99
+
100
+ function SelectLabel({ className, ...props }: SelectPrimitive.GroupLabel.Props) {
101
+ return (
102
+ <SelectPrimitive.GroupLabel
103
+ data-slot='select-label'
104
+ className={cn('px-1.5 py-1 text-[10px] text-muted-foreground', className)}
105
+ {...props}
106
+ />
107
+ )
108
+ }
109
+
110
+ function SelectItem({ className, children, ...props }: SelectPrimitive.Item.Props) {
111
+ return (
112
+ <SelectPrimitive.Item
113
+ data-slot='select-item'
114
+ className={cn(
115
+ "relative flex min-h-6 w-full cursor-default items-center gap-1.5 rounded-md py-0.5 pr-6 pl-1.5 text-[11px] outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-1.5",
116
+ className,
117
+ )}
118
+ {...props}
119
+ >
120
+ <SelectPrimitive.ItemText className='flex flex-1 shrink-0 gap-2 whitespace-nowrap'>
121
+ {children}
122
+ </SelectPrimitive.ItemText>
123
+ <SelectPrimitive.ItemIndicator
124
+ render={
125
+ <span className='pointer-events-none absolute right-1.5 flex size-3.5 items-center justify-center' />
126
+ }
127
+ >
128
+ <CheckIcon className='pointer-events-none' />
129
+ </SelectPrimitive.ItemIndicator>
130
+ </SelectPrimitive.Item>
131
+ )
132
+ }
133
+
134
+ function SelectSeparator({ className, ...props }: SelectPrimitive.Separator.Props) {
135
+ return (
136
+ <SelectPrimitive.Separator
137
+ data-slot='select-separator'
138
+ className={cn('pointer-events-none -mx-1 my-1 h-px bg-border', className)}
139
+ {...props}
140
+ />
141
+ )
142
+ }
143
+
144
+ function SelectScrollUpButton({
145
+ className,
146
+ ...props
147
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {
148
+ return (
149
+ <SelectPrimitive.ScrollUpArrow
150
+ data-slot='select-scroll-up-button'
151
+ className={cn(
152
+ "top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
153
+ className,
154
+ )}
155
+ {...props}
156
+ >
157
+ <ChevronUpIcon />
158
+ </SelectPrimitive.ScrollUpArrow>
159
+ )
160
+ }
161
+
162
+ function SelectScrollDownButton({
163
+ className,
164
+ ...props
165
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {
166
+ return (
167
+ <SelectPrimitive.ScrollDownArrow
168
+ data-slot='select-scroll-down-button'
169
+ className={cn(
170
+ "bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
171
+ className,
172
+ )}
173
+ {...props}
174
+ >
175
+ <ChevronDownIcon />
176
+ </SelectPrimitive.ScrollDownArrow>
177
+ )
178
+ }
179
+
180
+ export {
181
+ Select,
182
+ SelectContent,
183
+ SelectGroup,
184
+ SelectItem,
185
+ SelectLabel,
186
+ SelectScrollDownButton,
187
+ SelectScrollUpButton,
188
+ SelectSeparator,
189
+ SelectTrigger,
190
+ SelectValue,
191
+ }
@@ -0,0 +1,25 @@
1
+ "use client"
2
+
3
+ import { Separator as SeparatorPrimitive } from "@base-ui/react/separator"
4
+
5
+ import { cn } from "../lib/utils"
6
+
7
+ function Separator({
8
+ className,
9
+ orientation = "horizontal",
10
+ ...props
11
+ }: SeparatorPrimitive.Props) {
12
+ return (
13
+ <SeparatorPrimitive
14
+ data-slot="separator"
15
+ orientation={orientation}
16
+ className={cn(
17
+ "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
18
+ className
19
+ )}
20
+ {...props}
21
+ />
22
+ )
23
+ }
24
+
25
+ export { Separator }
@@ -0,0 +1,140 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Dialog as SheetPrimitive } from "@base-ui/react/dialog"
5
+
6
+ import { cn } from "../lib/utils"
7
+ import { Button } from "./button"
8
+ import { XIcon } from "lucide-react"
9
+
10
+ function Sheet({ ...props }: SheetPrimitive.Root.Props) {
11
+ return <SheetPrimitive.Root data-slot="sheet" {...props} />
12
+ }
13
+
14
+ function SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {
15
+ return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
16
+ }
17
+
18
+ function SheetClose({ ...props }: SheetPrimitive.Close.Props) {
19
+ return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
20
+ }
21
+
22
+ function SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {
23
+ return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
24
+ }
25
+
26
+ function SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {
27
+ return (
28
+ <SheetPrimitive.Backdrop
29
+ data-koharu-ui-layer=""
30
+ data-slot="sheet-overlay"
31
+ className={cn(
32
+ "fixed inset-0 z-50 bg-black/10 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs",
33
+ className
34
+ )}
35
+ {...props}
36
+ />
37
+ )
38
+ }
39
+
40
+ function SheetContent({
41
+ className,
42
+ children,
43
+ side = "right",
44
+ showCloseButton = true,
45
+ ...props
46
+ }: SheetPrimitive.Popup.Props & {
47
+ side?: "top" | "right" | "bottom" | "left"
48
+ showCloseButton?: boolean
49
+ }) {
50
+ return (
51
+ <SheetPortal>
52
+ <SheetOverlay />
53
+ <SheetPrimitive.Popup
54
+ data-koharu-ui-layer=""
55
+ data-slot="sheet-content"
56
+ data-side={side}
57
+ className={cn(
58
+ "fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
59
+ className
60
+ )}
61
+ {...props}
62
+ >
63
+ {children}
64
+ {showCloseButton && (
65
+ <SheetPrimitive.Close
66
+ data-slot="sheet-close"
67
+ render={
68
+ <Button
69
+ variant="ghost"
70
+ className="absolute top-3 right-3"
71
+ size="icon-sm"
72
+ />
73
+ }
74
+ >
75
+ <XIcon
76
+ />
77
+ <span className="sr-only">Close</span>
78
+ </SheetPrimitive.Close>
79
+ )}
80
+ </SheetPrimitive.Popup>
81
+ </SheetPortal>
82
+ )
83
+ }
84
+
85
+ function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
86
+ return (
87
+ <div
88
+ data-slot="sheet-header"
89
+ className={cn("flex flex-col gap-0.5 p-4", className)}
90
+ {...props}
91
+ />
92
+ )
93
+ }
94
+
95
+ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
96
+ return (
97
+ <div
98
+ data-slot="sheet-footer"
99
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
100
+ {...props}
101
+ />
102
+ )
103
+ }
104
+
105
+ function SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {
106
+ return (
107
+ <SheetPrimitive.Title
108
+ data-slot="sheet-title"
109
+ className={cn(
110
+ "text-base font-medium text-foreground",
111
+ className
112
+ )}
113
+ {...props}
114
+ />
115
+ )
116
+ }
117
+
118
+ function SheetDescription({
119
+ className,
120
+ ...props
121
+ }: SheetPrimitive.Description.Props) {
122
+ return (
123
+ <SheetPrimitive.Description
124
+ data-slot="sheet-description"
125
+ className={cn("text-sm text-muted-foreground", className)}
126
+ {...props}
127
+ />
128
+ )
129
+ }
130
+
131
+ export {
132
+ Sheet,
133
+ SheetTrigger,
134
+ SheetClose,
135
+ SheetContent,
136
+ SheetHeader,
137
+ SheetFooter,
138
+ SheetTitle,
139
+ SheetDescription,
140
+ }