fulldev-ui 0.12.0 → 0.13.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 (130) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +24 -20
  3. package/public/r/accordion.json +1 -1
  4. package/public/r/alert-dialog.json +1 -1
  5. package/public/r/aspect-ratio.json +23 -0
  6. package/public/r/attachment.json +66 -0
  7. package/public/r/button-group.json +41 -0
  8. package/public/r/carousel.json +8 -8
  9. package/public/r/collapsible.json +1 -1
  10. package/public/r/combobox.json +4 -4
  11. package/public/r/command.json +2 -2
  12. package/public/r/components.json +8 -0
  13. package/public/r/dialog.json +1 -1
  14. package/public/r/doc-1.json +1 -1
  15. package/public/r/drawer.json +109 -0
  16. package/public/r/dropdown-menu.json +1 -1
  17. package/public/r/hover-card.json +2 -2
  18. package/public/r/init.json +1 -1
  19. package/public/r/navigation-menu.json +2 -2
  20. package/public/r/pagination.json +59 -0
  21. package/public/r/popover.json +1 -1
  22. package/public/r/radio-group.json +1 -1
  23. package/public/r/registry.json +414 -24
  24. package/public/r/resizable.json +36 -0
  25. package/public/r/reviews-3.json +1 -1
  26. package/public/r/select.json +1 -1
  27. package/public/r/sheet.json +1 -1
  28. package/public/r/sidebar.json +1 -1
  29. package/public/r/slider.json +2 -2
  30. package/public/r/switch.json +1 -1
  31. package/public/r/tabs.json +1 -1
  32. package/public/r/toast.json +80 -0
  33. package/public/r/toggle-group.json +34 -0
  34. package/public/r/toggle.json +1 -1
  35. package/public/r/tooltip.json +1 -1
  36. package/public/r/typography.json +21 -16
  37. package/registry/init/global.css +2 -0
  38. package/registry.json +375 -24
  39. package/src/components/blocks/doc-1.astro +76 -0
  40. package/src/components/blocks/reviews-3.astro +1 -1
  41. package/src/components/ui/aspect-ratio/aspect-ratio.astro +25 -0
  42. package/src/components/ui/aspect-ratio/index.ts +1 -0
  43. package/src/components/ui/attachment/attachment-action.astro +20 -0
  44. package/src/components/ui/attachment/attachment-actions.astro +20 -0
  45. package/src/components/ui/attachment/attachment-content.astro +20 -0
  46. package/src/components/ui/attachment/attachment-description.astro +20 -0
  47. package/src/components/ui/attachment/attachment-group.astro +20 -0
  48. package/src/components/ui/attachment/attachment-media.astro +36 -0
  49. package/src/components/ui/attachment/attachment-title.astro +20 -0
  50. package/src/components/ui/attachment/attachment-trigger.astro +24 -0
  51. package/src/components/ui/attachment/attachment.astro +52 -0
  52. package/src/components/ui/attachment/index.ts +9 -0
  53. package/src/components/ui/button-group/button-group-separator.astro +29 -0
  54. package/src/components/ui/button-group/button-group-text.astro +20 -0
  55. package/src/components/ui/button-group/button-group-variants.ts +20 -0
  56. package/src/components/ui/button-group/button-group.astro +30 -0
  57. package/src/components/ui/button-group/index.ts +7 -0
  58. package/src/components/ui/carousel/carousel-content.astro +11 -13
  59. package/src/components/ui/carousel/carousel-item.astro +2 -5
  60. package/src/components/ui/carousel/carousel-next.astro +0 -3
  61. package/src/components/ui/carousel/carousel-previous.astro +0 -3
  62. package/src/components/ui/carousel/carousel.astro +19 -219
  63. package/src/components/ui/carousel/index.ts +1 -5
  64. package/src/components/ui/combobox/combobox-input.astro +11 -4
  65. package/src/components/ui/combobox/combobox-trigger.astro +7 -7
  66. package/src/components/ui/drawer/drawer-close.astro +13 -0
  67. package/src/components/ui/drawer/drawer-content.astro +43 -0
  68. package/src/components/ui/drawer/drawer-description.astro +17 -0
  69. package/src/components/ui/drawer/drawer-footer.astro +17 -0
  70. package/src/components/ui/drawer/drawer-header.astro +17 -0
  71. package/src/components/ui/drawer/drawer-indent-background.astro +11 -0
  72. package/src/components/ui/drawer/drawer-indent.astro +11 -0
  73. package/src/components/ui/drawer/drawer-overlay.astro +21 -0
  74. package/src/components/ui/drawer/drawer-popup.astro +36 -0
  75. package/src/components/ui/drawer/drawer-portal.astro +27 -0
  76. package/src/components/ui/drawer/drawer-provider.astro +11 -0
  77. package/src/components/ui/drawer/drawer-swipe-handle.astro +20 -0
  78. package/src/components/ui/drawer/drawer-title.astro +17 -0
  79. package/src/components/ui/drawer/drawer-trigger.astro +21 -0
  80. package/src/components/ui/drawer/drawer-viewport.astro +21 -0
  81. package/src/components/ui/drawer/drawer-virtual-keyboard-provider.astro +11 -0
  82. package/src/components/ui/drawer/drawer.astro +60 -0
  83. package/src/components/ui/drawer/index.ts +28 -0
  84. package/src/components/ui/navigation-menu/navigation-menu.astro +2 -2
  85. package/src/components/ui/pagination/index.ts +7 -0
  86. package/src/components/ui/pagination/pagination-content.astro +17 -0
  87. package/src/components/ui/pagination/pagination-ellipsis.astro +22 -0
  88. package/src/components/ui/pagination/pagination-item.astro +11 -0
  89. package/src/components/ui/pagination/pagination-link.astro +41 -0
  90. package/src/components/ui/pagination/pagination-next.astro +27 -0
  91. package/src/components/ui/pagination/pagination-previous.astro +27 -0
  92. package/src/components/ui/pagination/pagination.astro +19 -0
  93. package/src/components/ui/resizable/index.ts +4 -0
  94. package/src/components/ui/resizable/resizable-handle.astro +32 -0
  95. package/src/components/ui/resizable/resizable-panel.astro +36 -0
  96. package/src/components/ui/resizable/resizable.astro +43 -0
  97. package/src/components/ui/slider/slider.astro +1 -1
  98. package/src/components/ui/toast/index.ts +26 -0
  99. package/src/components/ui/toast/toast-action.astro +25 -0
  100. package/src/components/ui/toast/toast-close.astro +27 -0
  101. package/src/components/ui/toast/toast-content.astro +20 -0
  102. package/src/components/ui/toast/toast-description.astro +18 -0
  103. package/src/components/ui/toast/toast-icon.astro +37 -0
  104. package/src/components/ui/toast/toast-item.astro +28 -0
  105. package/src/components/ui/toast/toast-template.astro +11 -0
  106. package/src/components/ui/toast/toast-title.astro +17 -0
  107. package/src/components/ui/toast/toast-viewport.astro +20 -0
  108. package/src/components/ui/toast/toast.astro +51 -0
  109. package/src/components/ui/toast/toaster.astro +37 -0
  110. package/src/components/ui/toggle-group/index.ts +2 -0
  111. package/src/components/ui/toggle-group/toggle-group-item.astro +44 -0
  112. package/src/components/ui/toggle-group/toggle-group.astro +74 -0
  113. package/src/components/ui/typography/typeset.css +441 -0
  114. package/src/components/ui/typography/typography-a.astro +13 -22
  115. package/src/components/ui/typography/typography-blockquote.astro +4 -23
  116. package/src/components/ui/typography/typography-h1.astro +13 -26
  117. package/src/components/ui/typography/typography-h2.astro +13 -31
  118. package/src/components/ui/typography/typography-h3.astro +9 -26
  119. package/src/components/ui/typography/typography-h4.astro +9 -26
  120. package/src/components/ui/typography/typography-inline-code.astro +8 -27
  121. package/src/components/ui/typography/typography-lead.astro +4 -26
  122. package/src/components/ui/typography/typography-list-item.astro +4 -24
  123. package/src/components/ui/typography/typography-list.astro +10 -40
  124. package/src/components/ui/typography/typography-p.astro +9 -28
  125. package/src/components/ui/typography/typography-table-cell.astro +9 -40
  126. package/src/components/ui/typography/typography-table-head.astro +9 -35
  127. package/src/components/ui/typography/typography-table-row.astro +4 -23
  128. package/src/components/ui/typography/typography-table.astro +8 -28
  129. package/src/components/ui/typography/typography.astro +10 -283
  130. package/src/styles/global.css +2 -0
@@ -1,246 +1,46 @@
1
1
  ---
2
2
  import type { HTMLAttributes } from "astro/types"
3
- import type { EmblaOptionsType } from "embla-carousel"
4
3
 
5
4
  import { cn } from "@/lib/utils"
6
5
 
7
6
  type Props = HTMLAttributes<"div"> & {
8
- opts?: EmblaOptionsType
7
+ defaultIndex?: number
9
8
  orientation?: "horizontal" | "vertical"
9
+ drag?: boolean
10
+ loop?: boolean
10
11
  }
11
12
 
12
13
  const {
13
14
  class: className,
14
- opts,
15
+ defaultIndex,
15
16
  orientation = "horizontal",
17
+ drag,
18
+ loop,
16
19
  ...props
17
20
  } = Astro.props
18
-
19
- const resolvedOpts: EmblaOptionsType = {
20
- ...opts,
21
- axis: orientation === "horizontal" ? "x" : "y",
22
- }
23
21
  ---
24
22
 
25
23
  <div
26
24
  data-slot="carousel"
25
+ data-default-index={defaultIndex}
27
26
  data-orientation={orientation}
28
- data-carousel-options={JSON.stringify(resolvedOpts)}
27
+ data-drag={drag}
28
+ data-loop={loop}
29
29
  class={cn("group/carousel relative", className)}
30
- role="region"
31
- aria-roledescription="carousel"
32
30
  {...props}
33
31
  >
34
32
  <slot />
35
33
  </div>
36
34
 
37
35
  <script>
38
- import EmblaCarousel, {
39
- type EmblaCarouselType,
40
- type EmblaOptionsType,
41
- } from "embla-carousel"
42
-
43
- type CarouselRoot = HTMLElement & {
44
- __fulldevCarouselApi?: EmblaCarouselType
45
- }
46
-
47
- type CarouselInstance = {
48
- cleanup: () => void
49
- }
50
-
51
- type CarouselStore = Map<CarouselRoot, CarouselInstance>
52
-
53
- declare global {
54
- interface Window {
55
- __fulldevCarouselInitialized?: boolean
56
- __fulldevCarouselStore?: CarouselStore
57
- }
58
- }
59
-
60
- if (!window.__fulldevCarouselInitialized) {
61
- window.__fulldevCarouselInitialized = true
62
- window.__fulldevCarouselStore ??= new Map<CarouselRoot, CarouselInstance>()
63
-
64
- const store = window.__fulldevCarouselStore
65
-
66
- const getDetails = (api: EmblaCarouselType) => ({
67
- api,
68
- canScrollPrev: api.canScrollPrev(),
69
- canScrollNext: api.canScrollNext(),
70
- selectedScrollSnap: api.selectedScrollSnap(),
71
- scrollSnapList: api.scrollSnapList(),
72
- })
73
-
74
- const emit = (
75
- root: CarouselRoot,
76
- type: "carousel:init" | "carousel:select",
77
- api: EmblaCarouselType
78
- ) => {
79
- root.dispatchEvent(
80
- new CustomEvent(type, {
81
- detail: getDetails(api),
82
- })
83
- )
84
- }
85
-
86
- const parseOptions = (root: CarouselRoot): EmblaOptionsType => {
87
- const rawOptions = root.getAttribute("data-carousel-options")
88
-
89
- if (!rawOptions) {
90
- return {}
91
- }
92
-
93
- try {
94
- return JSON.parse(rawOptions) as EmblaOptionsType
95
- } catch {
96
- return {}
97
- }
98
- }
99
-
100
- const syncButton = (button: Element | null, enabled: boolean) => {
101
- if (!(button instanceof HTMLButtonElement)) {
102
- return
103
- }
104
-
105
- if (button.dataset.manualDisabled === "true") {
106
- button.disabled = true
107
- return
108
- }
109
-
110
- button.disabled = !enabled
111
- }
112
-
113
- const cleanupDisconnectedCarousels = () => {
114
- for (const [root, instance] of store.entries()) {
115
- if (document.contains(root)) {
116
- continue
117
- }
118
-
119
- instance.cleanup()
120
- store.delete(root)
121
- }
122
- }
123
-
124
- const initCarousel = (root: Element) => {
125
- if (!(root instanceof HTMLElement) || store.has(root)) {
126
- return
127
- }
128
-
129
- const carouselRoot = root as CarouselRoot
130
- const viewport = carouselRoot.querySelector(
131
- '[data-slot="carousel-content"]'
132
- )
133
- const prevButton = carouselRoot.querySelector(
134
- '[data-slot="carousel-previous"]'
135
- )
136
- const nextButton = carouselRoot.querySelector(
137
- '[data-slot="carousel-next"]'
138
- )
139
-
140
- if (!(viewport instanceof HTMLElement)) {
141
- return
142
- }
143
-
144
- const api = EmblaCarousel(viewport, parseOptions(carouselRoot))
145
-
146
- const sync = () => {
147
- const details = getDetails(api)
148
-
149
- carouselRoot.dataset.canScrollPrev = details.canScrollPrev
150
- ? "true"
151
- : "false"
152
- carouselRoot.dataset.canScrollNext = details.canScrollNext
153
- ? "true"
154
- : "false"
155
- carouselRoot.dataset.selectedScrollSnap = String(
156
- details.selectedScrollSnap
157
- )
158
-
159
- syncButton(prevButton, details.canScrollPrev)
160
- syncButton(nextButton, details.canScrollNext)
161
-
162
- emit(carouselRoot, "carousel:select", api)
163
- }
164
-
165
- const onPrevClick = () => {
166
- api.scrollPrev()
167
- }
168
-
169
- const onNextClick = () => {
170
- api.scrollNext()
171
- }
172
-
173
- const onKeyDown = (event: KeyboardEvent) => {
174
- const isVertical = carouselRoot.dataset.orientation === "vertical"
175
-
176
- if (!isVertical && event.key === "ArrowLeft") {
177
- event.preventDefault()
178
- api.scrollPrev()
179
- }
180
-
181
- if (!isVertical && event.key === "ArrowRight") {
182
- event.preventDefault()
183
- api.scrollNext()
184
- }
185
-
186
- if (isVertical && event.key === "ArrowUp") {
187
- event.preventDefault()
188
- api.scrollPrev()
189
- }
190
-
191
- if (isVertical && event.key === "ArrowDown") {
192
- event.preventDefault()
193
- api.scrollNext()
194
- }
195
- }
196
-
197
- if (prevButton instanceof HTMLElement) {
198
- prevButton.addEventListener("click", onPrevClick)
199
- }
200
-
201
- if (nextButton instanceof HTMLElement) {
202
- nextButton.addEventListener("click", onNextClick)
203
- }
204
-
205
- carouselRoot.addEventListener("keydown", onKeyDown, true)
206
-
207
- api.on("reInit", sync)
208
- api.on("select", sync)
209
-
210
- carouselRoot.__fulldevCarouselApi = api
211
-
212
- sync()
213
- requestAnimationFrame(() => emit(carouselRoot, "carousel:init", api))
214
-
215
- store.set(carouselRoot, {
216
- cleanup: () => {
217
- api.off("reInit", sync)
218
- api.off("select", sync)
219
-
220
- if (prevButton instanceof HTMLElement) {
221
- prevButton.removeEventListener("click", onPrevClick)
222
- }
223
-
224
- if (nextButton instanceof HTMLElement) {
225
- nextButton.removeEventListener("click", onNextClick)
226
- }
227
-
228
- carouselRoot.removeEventListener("keydown", onKeyDown, true)
229
- delete carouselRoot.__fulldevCarouselApi
230
- api.destroy()
231
- },
232
- })
233
- }
234
-
235
- const initCarousels = () => {
236
- cleanupDisconnectedCarousels()
237
-
238
- document
239
- .querySelectorAll('[data-slot="carousel"]')
240
- .forEach((root) => initCarousel(root))
241
- }
242
-
243
- initCarousels()
244
- document.addEventListener("astro:page-load", initCarousels)
245
- }
36
+ import { create } from "@data-slot/carousel"
37
+
38
+ const controllers: ReturnType<typeof create> = []
39
+ const initialize = () => controllers.push(...create())
40
+ initialize()
41
+ document.addEventListener("astro:page-load", initialize)
42
+ document.addEventListener("astro:before-swap", () => {
43
+ for (const controller of controllers) controller.destroy()
44
+ controllers.length = 0
45
+ })
246
46
  </script>
@@ -1,8 +1,4 @@
1
- export type {
2
- EmblaCarouselType as CarouselApi,
3
- EmblaOptionsType as CarouselOptions,
4
- EmblaPluginType as CarouselPlugin,
5
- } from "embla-carousel"
1
+ export type { CarouselController, CarouselOptions } from "@data-slot/carousel"
6
2
 
7
3
  export { default as Carousel } from "./carousel.astro"
8
4
  export { default as CarouselContent } from "./carousel-content.astro"
@@ -4,6 +4,7 @@ import XIcon from "@lucide/astro/icons/x"
4
4
 
5
5
  import { cn } from "@/lib/utils"
6
6
  import InputGroupAddon from "@/components/ui/input-group/input-group-addon.astro"
7
+ import InputGroupButton from "@/components/ui/input-group/input-group-button.astro"
7
8
  import InputGroupInput from "@/components/ui/input-group/input-group-input.astro"
8
9
  import InputGroup from "@/components/ui/input-group/input-group.astro"
9
10
 
@@ -24,7 +25,12 @@ const {
24
25
  } = Astro.props
25
26
  ---
26
27
 
27
- <InputGroup class={cn("w-auto", className)}>
28
+ <InputGroup
29
+ class={cn(
30
+ "has-[[data-slot=combobox-input]:focus-visible]:border-ring has-[[data-slot=combobox-input]:focus-visible]:ring-ring/50 w-auto has-[[data-slot=combobox-input]:focus-visible]:ring-3",
31
+ className
32
+ )}
33
+ >
28
34
  <InputGroupInput
29
35
  type={type}
30
36
  data-slot="combobox-input"
@@ -42,14 +48,15 @@ const {
42
48
  }
43
49
  {
44
50
  showClear && (
45
- <button
51
+ <InputGroupButton
46
52
  type="button"
53
+ variant="ghost"
54
+ size="icon-xs"
47
55
  data-slot="combobox-clear"
48
- class="inline-flex size-6 shrink-0 items-center justify-center rounded-[calc(var(--radius)-5px)] p-0 text-sm shadow-none outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
49
56
  disabled={disabled}
50
57
  >
51
58
  <XIcon class="pointer-events-none" />
52
- </button>
59
+ </InputGroupButton>
53
60
  )
54
61
  }
55
62
  </InputGroupAddon>
@@ -3,6 +3,7 @@ import type { HTMLAttributes } from "astro/types"
3
3
  import ChevronDownIcon from "@lucide/astro/icons/chevron-down"
4
4
 
5
5
  import { cn } from "@/lib/utils"
6
+ import InputGroupButton from "@/components/ui/input-group/input-group-button.astro"
6
7
 
7
8
  type Props = HTMLAttributes<"button"> & {
8
9
  showIcon?: boolean
@@ -16,13 +17,12 @@ const {
16
17
  } = Astro.props
17
18
  ---
18
19
 
19
- <button
20
- type={type}
20
+ <InputGroupButton
21
+ type={type ?? "button"}
22
+ variant="ghost"
23
+ size="icon-xs"
21
24
  data-slot="combobox-trigger"
22
- class={cn(
23
- "[&_svg]:text-muted-foreground inline-flex size-6 shrink-0 items-center justify-center gap-2 rounded-[calc(var(--radius)-5px)] p-0 text-sm shadow-none outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
24
- className
25
- )}
25
+ class={cn("[&_svg]:text-muted-foreground", className)}
26
26
  {...props}
27
27
  >
28
28
  <slot />
@@ -31,4 +31,4 @@ const {
31
31
  <ChevronDownIcon class="text-muted-foreground pointer-events-none size-4" />
32
32
  )
33
33
  }
34
- </button>
34
+ </InputGroupButton>
@@ -0,0 +1,13 @@
1
+ ---
2
+ import type { ComponentProps } from "astro/types"
3
+
4
+ import { Button } from "@/components/ui/button"
5
+
6
+ type Props = ComponentProps<typeof Button>
7
+
8
+ const { ...props } = Astro.props
9
+ ---
10
+
11
+ <Button data-slot="drawer-close" {...props}>
12
+ <slot />
13
+ </Button>
@@ -0,0 +1,43 @@
1
+ ---
2
+ import type { ComponentProps } from "astro/types"
3
+
4
+ import DrawerOverlay from "./drawer-overlay.astro"
5
+ import DrawerPopup from "./drawer-popup.astro"
6
+ import DrawerPortal from "./drawer-portal.astro"
7
+ import DrawerSwipeHandle from "./drawer-swipe-handle.astro"
8
+ import DrawerViewport from "./drawer-viewport.astro"
9
+
10
+ type Props = ComponentProps<typeof DrawerPopup> & {
11
+ showOverlay?: boolean
12
+ showSwipeHandle?: boolean
13
+ container?: string
14
+ keepMounted?: boolean
15
+ overlayClass?: string
16
+ viewportClass?: string
17
+ }
18
+
19
+ const {
20
+ showOverlay = true,
21
+ showSwipeHandle = false,
22
+ container,
23
+ keepMounted,
24
+ overlayClass,
25
+ viewportClass,
26
+ ...props
27
+ } = Astro.props
28
+ ---
29
+
30
+ <DrawerPortal container={container} keepMounted={keepMounted}>
31
+ {showOverlay && <DrawerOverlay class={overlayClass} />}
32
+ <DrawerViewport class={viewportClass}>
33
+ <DrawerPopup {...props}>
34
+ {showSwipeHandle && <DrawerSwipeHandle />}
35
+ <div
36
+ data-slot="drawer-content"
37
+ class="flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-contain rounded-[inherit] transition-opacity duration-300 select-text group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-swiping/drawer-popup:opacity-100 group-data-swiping/drawer-popup:select-none"
38
+ >
39
+ <slot />
40
+ </div>
41
+ </DrawerPopup>
42
+ </DrawerViewport>
43
+ </DrawerPortal>
@@ -0,0 +1,17 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ type Props = HTMLAttributes<"p">
7
+
8
+ const { class: className, ...props } = Astro.props
9
+ ---
10
+
11
+ <p
12
+ data-slot="drawer-description"
13
+ class={cn("text-muted-foreground text-sm text-balance", className)}
14
+ {...props}
15
+ >
16
+ <slot />
17
+ </p>
@@ -0,0 +1,17 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ type Props = HTMLAttributes<"div">
7
+
8
+ const { class: className, ...props } = Astro.props
9
+ ---
10
+
11
+ <div
12
+ data-slot="drawer-footer"
13
+ class={cn("mt-auto flex shrink-0 flex-col gap-2 p-4 pt-0", className)}
14
+ {...props}
15
+ >
16
+ <slot />
17
+ </div>
@@ -0,0 +1,17 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ type Props = HTMLAttributes<"div">
7
+
8
+ const { class: className, ...props } = Astro.props
9
+ ---
10
+
11
+ <div
12
+ data-slot="drawer-header"
13
+ class={cn("flex shrink-0 flex-col gap-1.5 p-4 pb-0", className)}
14
+ {...props}
15
+ >
16
+ <slot />
17
+ </div>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ type Props = HTMLAttributes<"div">
5
+
6
+ const { class: className, ...props } = Astro.props
7
+ ---
8
+
9
+ <div data-slot="drawer-indent-background" class={className} {...props}>
10
+ <slot />
11
+ </div>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ type Props = HTMLAttributes<"div">
5
+
6
+ const { class: className, ...props } = Astro.props
7
+ ---
8
+
9
+ <div data-slot="drawer-indent" class={className} {...props}>
10
+ <slot />
11
+ </div>
@@ -0,0 +1,21 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ type Props = HTMLAttributes<"div">
7
+
8
+ const { class: className, hidden = true, ...props } = Astro.props
9
+ ---
10
+
11
+ <div
12
+ data-slot="drawer-backdrop"
13
+ hidden={hidden}
14
+ class={cn(
15
+ "fixed inset-0 z-50 min-h-dvh bg-black/10 opacity-[calc(1-var(--drawer-swipe-progress,0))] transition-opacity duration-300 ease-[cubic-bezier(0.32,0.72,0,1)] select-none data-ending-style:pointer-events-none data-ending-style:opacity-0 data-starting-style:opacity-0 data-swiping:duration-0 supports-backdrop-filter:backdrop-blur-xs",
16
+ className
17
+ )}
18
+ {...props}
19
+ >
20
+ <slot />
21
+ </div>
@@ -0,0 +1,36 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ type Props = HTMLAttributes<"div"> & {
7
+ initialFocus?: boolean | string
8
+ finalFocus?: boolean | string
9
+ }
10
+
11
+ const {
12
+ class: className,
13
+ initialFocus,
14
+ finalFocus,
15
+ hidden = true,
16
+ ...props
17
+ } = Astro.props
18
+ ---
19
+
20
+ <div
21
+ data-slot="drawer-popup"
22
+ data-initial-focus={initialFocus}
23
+ data-final-focus={finalFocus}
24
+ hidden={hidden}
25
+ class={cn(
26
+ "group/drawer-popup bg-popover text-popover-foreground pointer-events-auto fixed z-50 flex min-h-0 transform-gpu flex-col text-sm shadow-lg transition-[transform,height,opacity,filter] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] will-change-transform outline-none select-none data-ending-style:duration-[calc(var(--drawer-swipe-strength,1)*400ms)] data-nested-drawer-open:overflow-hidden data-nested-drawer-open:brightness-95 data-swiping:duration-0",
27
+ "data-[swipe-direction=down]:inset-x-0 data-[swipe-direction=down]:bottom-0 data-[swipe-direction=down]:max-h-[calc(100dvh-3rem)] data-[swipe-direction=down]:[transform:translate3d(0,calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-amount-y,0px)),0)] data-[swipe-direction=down]:rounded-t-xl data-[swipe-direction=down]:border-t data-[swipe-direction=down]:data-ending-style:[transform:translate3d(0,calc(100%+2px),0)] data-[swipe-direction=down]:data-starting-style:[transform:translate3d(0,calc(100%+2px),0)]",
28
+ "data-[swipe-direction=up]:inset-x-0 data-[swipe-direction=up]:top-0 data-[swipe-direction=up]:max-h-[calc(100dvh-3rem)] data-[swipe-direction=up]:[transform:translate3d(0,calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-amount-y,0px)),0)] data-[swipe-direction=up]:rounded-b-xl data-[swipe-direction=up]:border-b data-[swipe-direction=up]:data-ending-style:[transform:translate3d(0,calc(-100%-2px),0)] data-[swipe-direction=up]:data-starting-style:[transform:translate3d(0,calc(-100%-2px),0)]",
29
+ "data-[swipe-direction=left]:inset-y-0 data-[swipe-direction=left]:left-0 data-[swipe-direction=left]:h-full data-[swipe-direction=left]:w-3/4 data-[swipe-direction=left]:max-w-sm data-[swipe-direction=left]:[transform:translate3d(calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-amount-x,0px)),0,0)] data-[swipe-direction=left]:flex-row data-[swipe-direction=left]:rounded-r-xl data-[swipe-direction=left]:border-r data-[swipe-direction=left]:data-ending-style:[transform:translate3d(calc(-100%-2px),0,0)] data-[swipe-direction=left]:data-starting-style:[transform:translate3d(calc(-100%-2px),0,0)]",
30
+ "data-[swipe-direction=right]:inset-y-0 data-[swipe-direction=right]:right-0 data-[swipe-direction=right]:h-full data-[swipe-direction=right]:w-3/4 data-[swipe-direction=right]:max-w-sm data-[swipe-direction=right]:[transform:translate3d(calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-amount-x,0px)),0,0)] data-[swipe-direction=right]:flex-row data-[swipe-direction=right]:rounded-l-xl data-[swipe-direction=right]:border-l data-[swipe-direction=right]:data-ending-style:[transform:translate3d(calc(100%+2px),0,0)] data-[swipe-direction=right]:data-starting-style:[transform:translate3d(calc(100%+2px),0,0)]",
31
+ className
32
+ )}
33
+ {...props}
34
+ >
35
+ <slot />
36
+ </div>
@@ -0,0 +1,27 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ type Props = HTMLAttributes<"div"> & {
5
+ container?: string
6
+ keepMounted?: boolean
7
+ }
8
+
9
+ const {
10
+ class: className,
11
+ container,
12
+ keepMounted,
13
+ hidden = true,
14
+ ...props
15
+ } = Astro.props
16
+ ---
17
+
18
+ <div
19
+ data-slot="drawer-portal"
20
+ data-container={container}
21
+ data-keep-mounted={keepMounted}
22
+ class={className}
23
+ hidden={hidden}
24
+ {...props}
25
+ >
26
+ <slot />
27
+ </div>
@@ -0,0 +1,11 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ type Props = HTMLAttributes<"div">
5
+
6
+ const { class: className, ...props } = Astro.props
7
+ ---
8
+
9
+ <div data-slot="drawer-provider" class={className} {...props}>
10
+ <slot />
11
+ </div>
@@ -0,0 +1,20 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ type Props = HTMLAttributes<"div">
7
+
8
+ const { class: className, ...props } = Astro.props
9
+ ---
10
+
11
+ <div
12
+ data-slot="drawer-handle"
13
+ aria-hidden="true"
14
+ class={cn(
15
+ "after:bg-muted relative z-10 flex shrink-0 cursor-grab transition-opacity duration-200 group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-swiping/drawer-popup:opacity-100 group-data-[swipe-direction=down]/drawer-popup:h-3 group-data-[swipe-direction=down]/drawer-popup:w-full group-data-[swipe-direction=down]/drawer-popup:items-end group-data-[swipe-direction=down]/drawer-popup:justify-center group-data-[swipe-direction=left]/drawer-popup:order-last group-data-[swipe-direction=left]/drawer-popup:h-full group-data-[swipe-direction=left]/drawer-popup:w-3 group-data-[swipe-direction=left]/drawer-popup:items-center group-data-[swipe-direction=left]/drawer-popup:justify-start group-data-[swipe-direction=right]/drawer-popup:h-full group-data-[swipe-direction=right]/drawer-popup:w-3 group-data-[swipe-direction=right]/drawer-popup:items-center 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:h-3 group-data-[swipe-direction=up]/drawer-popup:w-full group-data-[swipe-direction=up]/drawer-popup:items-start group-data-[swipe-direction=up]/drawer-popup:justify-center after:block after:shrink-0 after:rounded-full group-data-[swipe-direction=down]/drawer-popup:after:h-1.5 group-data-[swipe-direction=down]/drawer-popup:after:w-24 group-data-[swipe-direction=left]/drawer-popup:after:h-24 group-data-[swipe-direction=left]/drawer-popup:after:w-1.5 group-data-[swipe-direction=right]/drawer-popup:after:h-24 group-data-[swipe-direction=right]/drawer-popup:after:w-1.5 group-data-[swipe-direction=up]/drawer-popup:after:h-1.5 group-data-[swipe-direction=up]/drawer-popup:after:w-24 active:cursor-grabbing",
16
+ className
17
+ )}
18
+ {...props}
19
+ >
20
+ </div>
@@ -0,0 +1,17 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ type Props = HTMLAttributes<"h2">
7
+
8
+ const { class: className, ...props } = Astro.props
9
+ ---
10
+
11
+ <h2
12
+ data-slot="drawer-title"
13
+ class={cn("text-foreground font-medium", className)}
14
+ {...props}
15
+ >
16
+ <slot />
17
+ </h2>
@@ -0,0 +1,21 @@
1
+ ---
2
+ import type { ComponentProps } from "astro/types"
3
+
4
+ import { Button } from "@/components/ui/button"
5
+
6
+ type Props = ComponentProps<typeof Button> & {
7
+ drawerTarget?: string
8
+ payload?: string
9
+ }
10
+
11
+ const { drawerTarget, payload, ...props } = Astro.props
12
+ ---
13
+
14
+ <Button
15
+ data-slot="drawer-trigger"
16
+ data-drawer-target={drawerTarget}
17
+ data-payload={payload}
18
+ {...props}
19
+ >
20
+ <slot />
21
+ </Button>
@@ -0,0 +1,21 @@
1
+ ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
4
+ import { cn } from "@/lib/utils"
5
+
6
+ type Props = HTMLAttributes<"div">
7
+
8
+ const { class: className, hidden = true, ...props } = Astro.props
9
+ ---
10
+
11
+ <div
12
+ data-slot="drawer-viewport"
13
+ hidden={hidden}
14
+ class={cn(
15
+ "pointer-events-none fixed inset-0 z-50 min-h-dvh select-none",
16
+ className
17
+ )}
18
+ {...props}
19
+ >
20
+ <slot />
21
+ </div>