fulldev-ui 0.10.1 → 0.11.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 (252) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +7 -1
  3. package/package.json +6 -4
  4. package/public/r/accordion.json +7 -1
  5. package/public/r/alert-dialog.json +7 -1
  6. package/public/r/alert.json +6 -0
  7. package/public/r/article-1.json +7 -1
  8. package/public/r/article-2.json +7 -1
  9. package/public/r/articles-1.json +7 -1
  10. package/public/r/articles-2.json +7 -1
  11. package/public/r/articles-3.json +7 -1
  12. package/public/r/articles-4.json +7 -1
  13. package/public/r/avatar.json +6 -0
  14. package/public/r/badge.json +6 -0
  15. package/public/r/banner-1.json +7 -1
  16. package/public/r/banner-2.json +7 -1
  17. package/public/r/banner.json +7 -1
  18. package/public/r/blocks-1.json +6 -1
  19. package/public/r/blocks.json +92 -0
  20. package/public/r/breadcrumb.json +6 -0
  21. package/public/r/button.json +6 -0
  22. package/public/r/card.json +6 -0
  23. package/public/r/carousel.json +6 -0
  24. package/public/r/checkbox.json +6 -0
  25. package/public/r/collapsible.json +7 -1
  26. package/public/r/combobox.json +6 -0
  27. package/public/r/command.json +6 -0
  28. package/public/r/components.json +14 -3
  29. package/public/r/contact-1.json +10 -2
  30. package/public/r/contact-2.json +10 -2
  31. package/public/r/contact-3.json +10 -2
  32. package/public/r/content-1.json +7 -1
  33. package/public/r/content-2.json +7 -1
  34. package/public/r/content-3.json +7 -1
  35. package/public/r/content-4.json +7 -1
  36. package/public/r/cta-1.json +7 -1
  37. package/public/r/cta-2.json +7 -1
  38. package/public/r/cta-3.json +7 -1
  39. package/public/r/cta-4.json +7 -1
  40. package/public/r/cta-5.json +7 -1
  41. package/public/r/cta-6.json +7 -1
  42. package/public/r/cta-7.json +7 -1
  43. package/public/r/cta-8.json +7 -1
  44. package/public/r/dialog.json +7 -1
  45. package/public/r/doc-1.json +7 -1
  46. package/public/r/dropdown-menu.json +7 -1
  47. package/public/r/empty.json +6 -0
  48. package/public/r/faqs-1.json +7 -1
  49. package/public/r/faqs-2.json +7 -1
  50. package/public/r/faqs-3.json +7 -1
  51. package/public/r/faqs-4.json +7 -1
  52. package/public/r/features-1.json +7 -1
  53. package/public/r/features-2.json +7 -1
  54. package/public/r/features-3.json +7 -1
  55. package/public/r/features-4.json +7 -1
  56. package/public/r/features-5.json +7 -1
  57. package/public/r/features-6.json +7 -1
  58. package/public/r/field.json +6 -0
  59. package/public/r/footer-1.json +7 -1
  60. package/public/r/footer-2.json +7 -1
  61. package/public/r/footer-3.json +7 -1
  62. package/public/r/form.json +6 -0
  63. package/public/r/header-1.json +7 -1
  64. package/public/r/header-2.json +7 -1
  65. package/public/r/header-3.json +7 -1
  66. package/public/r/header-4.json +7 -1
  67. package/public/r/header-5.json +7 -1
  68. package/public/r/header.json +6 -0
  69. package/public/r/hero-1.json +7 -1
  70. package/public/r/hero-10.json +7 -1
  71. package/public/r/hero-11.json +7 -1
  72. package/public/r/hero-12.json +7 -1
  73. package/public/r/hero-13.json +7 -1
  74. package/public/r/hero-2.json +7 -1
  75. package/public/r/hero-3.json +7 -1
  76. package/public/r/hero-4.json +7 -1
  77. package/public/r/hero-5.json +7 -1
  78. package/public/r/hero-6.json +7 -1
  79. package/public/r/hero-7.json +7 -1
  80. package/public/r/hero-8.json +7 -1
  81. package/public/r/hero-9.json +7 -1
  82. package/public/r/hover-card.json +7 -1
  83. package/public/r/icon.json +7 -1
  84. package/public/r/init.json +28 -0
  85. package/public/r/input-group.json +6 -0
  86. package/public/r/input.json +6 -0
  87. package/public/r/item.json +6 -0
  88. package/public/r/kbd.json +6 -0
  89. package/public/r/label.json +6 -0
  90. package/public/r/layout.json +6 -0
  91. package/public/r/links-2.json +7 -1
  92. package/public/r/logo.json +6 -0
  93. package/public/r/logos-1.json +7 -1
  94. package/public/r/logos-2.json +7 -1
  95. package/public/r/logos-3.json +7 -1
  96. package/public/r/marquee.json +6 -0
  97. package/public/r/native-select.json +6 -0
  98. package/public/r/navigation-menu.json +7 -1
  99. package/public/r/popover.json +7 -1
  100. package/public/r/price.json +6 -0
  101. package/public/r/pricing-1.json +7 -1
  102. package/public/r/pricing-2.json +7 -1
  103. package/public/r/pricing-3.json +7 -1
  104. package/public/r/product-1.json +7 -1
  105. package/public/r/products-1.json +7 -1
  106. package/public/r/products-2.json +7 -1
  107. package/public/r/products-3.json +7 -1
  108. package/public/r/products-4.json +7 -1
  109. package/public/r/products-5.json +7 -1
  110. package/public/r/radio-group.json +7 -1
  111. package/public/r/rating.json +6 -0
  112. package/public/r/registry.json +1645 -457
  113. package/public/r/reviews-1.json +7 -1
  114. package/public/r/reviews-2.json +7 -1
  115. package/public/r/reviews-3.json +7 -1
  116. package/public/r/reviews-4.json +7 -1
  117. package/public/r/reviews-5.json +7 -1
  118. package/public/r/section.json +18 -2
  119. package/public/r/select.json +6 -0
  120. package/public/r/separator.json +6 -0
  121. package/public/r/services-1.json +7 -1
  122. package/public/r/services-2.json +7 -1
  123. package/public/r/services-3.json +7 -1
  124. package/public/r/services-4.json +7 -1
  125. package/public/r/services-5.json +7 -1
  126. package/public/r/services-6.json +7 -1
  127. package/public/r/services-7.json +7 -1
  128. package/public/r/sheet.json +8 -2
  129. package/public/r/sidebar-1.json +6 -1
  130. package/public/r/sidebar.json +6 -0
  131. package/public/r/skeleton.json +6 -0
  132. package/public/r/slider.json +7 -1
  133. package/public/r/spinner.json +6 -0
  134. package/public/r/switch.json +7 -1
  135. package/public/r/table.json +6 -0
  136. package/public/r/tabs.json +7 -1
  137. package/public/r/textarea.json +6 -0
  138. package/public/r/theme-toggle.json +6 -0
  139. package/public/r/toc.json +6 -0
  140. package/public/r/toggle.json +7 -1
  141. package/public/r/tooltip.json +7 -1
  142. package/public/r/typography.json +7 -1
  143. package/public/r/video.json +6 -0
  144. package/registry/init/global.css +187 -0
  145. package/registry.json +1137 -454
  146. package/src/components/blocks/article-1.astro +4 -3
  147. package/src/components/blocks/article-2.astro +4 -3
  148. package/src/components/blocks/articles-1.astro +18 -9
  149. package/src/components/blocks/articles-2.astro +4 -3
  150. package/src/components/blocks/articles-3.astro +11 -9
  151. package/src/components/blocks/articles-4.astro +11 -4
  152. package/src/components/blocks/banner-1.astro +4 -3
  153. package/src/components/blocks/banner-2.astro +16 -7
  154. package/src/components/blocks/blocks-1.astro +1 -1
  155. package/src/components/blocks/contact-1.astro +74 -40
  156. package/src/components/blocks/contact-2.astro +71 -36
  157. package/src/components/blocks/contact-3.astro +63 -35
  158. package/src/components/blocks/content-1.astro +15 -10
  159. package/src/components/blocks/content-2.astro +15 -10
  160. package/src/components/blocks/content-3.astro +14 -12
  161. package/src/components/blocks/content-4.astro +15 -10
  162. package/src/components/blocks/cta-1.astro +14 -10
  163. package/src/components/blocks/cta-2.astro +11 -8
  164. package/src/components/blocks/cta-3.astro +15 -8
  165. package/src/components/blocks/cta-4.astro +14 -9
  166. package/src/components/blocks/cta-5.astro +12 -8
  167. package/src/components/blocks/cta-6.astro +11 -8
  168. package/src/components/blocks/cta-7.astro +17 -10
  169. package/src/components/blocks/cta-8.astro +15 -10
  170. package/src/components/blocks/doc-1.astro +1 -1
  171. package/src/components/blocks/faqs-1.astro +22 -11
  172. package/src/components/blocks/faqs-2.astro +19 -9
  173. package/src/components/blocks/faqs-3.astro +19 -9
  174. package/src/components/blocks/faqs-4.astro +12 -9
  175. package/src/components/blocks/features-1.astro +21 -13
  176. package/src/components/blocks/features-2.astro +22 -13
  177. package/src/components/blocks/features-3.astro +14 -13
  178. package/src/components/blocks/features-4.astro +18 -9
  179. package/src/components/blocks/features-5.astro +22 -13
  180. package/src/components/blocks/features-6.astro +19 -9
  181. package/src/components/blocks/footer-1.astro +4 -3
  182. package/src/components/blocks/footer-2.astro +4 -3
  183. package/src/components/blocks/footer-3.astro +4 -3
  184. package/src/components/blocks/header-1.astro +13 -7
  185. package/src/components/blocks/header-2.astro +12 -6
  186. package/src/components/blocks/header-3.astro +12 -6
  187. package/src/components/blocks/header-4.astro +13 -6
  188. package/src/components/blocks/header-5.astro +16 -6
  189. package/src/components/blocks/hero-1.astro +11 -8
  190. package/src/components/blocks/hero-10.astro +7 -3
  191. package/src/components/blocks/hero-11.astro +4 -2
  192. package/src/components/blocks/hero-12.astro +11 -4
  193. package/src/components/blocks/hero-13.astro +11 -4
  194. package/src/components/blocks/hero-2.astro +11 -8
  195. package/src/components/blocks/hero-3.astro +11 -3
  196. package/src/components/blocks/hero-4.astro +4 -2
  197. package/src/components/blocks/hero-5.astro +4 -3
  198. package/src/components/blocks/hero-6.astro +4 -3
  199. package/src/components/blocks/hero-7.astro +4 -3
  200. package/src/components/blocks/hero-8.astro +11 -4
  201. package/src/components/blocks/hero-9.astro +4 -3
  202. package/src/components/blocks/links-2.astro +4 -4
  203. package/src/components/blocks/logos-1.astro +14 -16
  204. package/src/components/blocks/logos-2.astro +14 -12
  205. package/src/components/blocks/logos-3.astro +5 -4
  206. package/src/components/blocks/pricing-1.astro +13 -16
  207. package/src/components/blocks/pricing-2.astro +14 -13
  208. package/src/components/blocks/pricing-3.astro +20 -16
  209. package/src/components/blocks/product-1.astro +4 -3
  210. package/src/components/blocks/products-1.astro +11 -9
  211. package/src/components/blocks/products-2.astro +12 -9
  212. package/src/components/blocks/products-3.astro +12 -9
  213. package/src/components/blocks/products-4.astro +18 -9
  214. package/src/components/blocks/products-5.astro +18 -9
  215. package/src/components/blocks/reviews-1.astro +13 -12
  216. package/src/components/blocks/reviews-2.astro +4 -4
  217. package/src/components/blocks/reviews-3.astro +13 -12
  218. package/src/components/blocks/reviews-4.astro +13 -12
  219. package/src/components/blocks/reviews-5.astro +13 -12
  220. package/src/components/blocks/services-1.astro +19 -9
  221. package/src/components/blocks/services-2.astro +11 -8
  222. package/src/components/blocks/services-3.astro +11 -8
  223. package/src/components/blocks/services-4.astro +19 -9
  224. package/src/components/blocks/services-5.astro +11 -8
  225. package/src/components/blocks/services-6.astro +4 -3
  226. package/src/components/blocks/services-7.astro +12 -8
  227. package/src/components/blocks/sidebar-1.astro +2 -2
  228. package/src/components/ui/accordion/accordion.astro +1 -0
  229. package/src/components/ui/alert-dialog/alert-dialog.astro +1 -0
  230. package/src/components/ui/banner/banner.astro +23 -41
  231. package/src/components/ui/collapsible/collapsible.astro +1 -0
  232. package/src/components/ui/dialog/dialog.astro +1 -0
  233. package/src/components/ui/dropdown-menu/dropdown-menu.astro +1 -0
  234. package/src/components/ui/hover-card/hover-card.astro +7 -3
  235. package/src/components/ui/icon/icon.astro +46 -29
  236. package/src/components/ui/navigation-menu/navigation-menu.astro +1 -0
  237. package/src/components/ui/popover/popover.astro +1 -0
  238. package/src/components/ui/radio-group/radio-group.astro +1 -0
  239. package/src/components/ui/section/index.ts +2 -0
  240. package/src/components/ui/section/section-container.astro +1 -0
  241. package/src/components/ui/section/section-description.astro +20 -0
  242. package/src/components/ui/section/section-title.astro +20 -0
  243. package/src/components/ui/sheet/sheet-close.astro +4 -2
  244. package/src/components/ui/sheet/sheet.astro +1 -0
  245. package/src/components/ui/slider/slider.astro +1 -0
  246. package/src/components/ui/switch/switch.astro +1 -0
  247. package/src/components/ui/tabs/tabs.astro +1 -0
  248. package/src/components/ui/toggle/toggle.astro +1 -0
  249. package/src/components/ui/tooltip/tooltip.astro +1 -0
  250. package/src/components/ui/typography/typography.astro +1 -1
  251. package/src/lib/pages.ts +12 -0
  252. package/src/styles/global.css +2 -2
@@ -1,14 +1,14 @@
1
1
  ---
2
2
  import type { ImageMetadata } from "astro"
3
3
  import { Image } from "astro:assets"
4
+ import type { HTMLAttributes } from "astro/types"
4
5
 
5
6
  import { cn } from "@/lib/utils"
6
7
  import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
7
8
  import { Badge } from "@/components/ui/badge"
8
9
  import { Section, SectionContainer } from "@/components/ui/section"
9
10
 
10
- type Props = {
11
- class?: string
11
+ type Props = HTMLAttributes<"section"> & {
12
12
  badge?: string
13
13
  title: string
14
14
  description: string
@@ -31,10 +31,11 @@ const {
31
31
  description,
32
32
  author,
33
33
  image,
34
+ ...props
34
35
  } = Astro.props
35
36
  ---
36
37
 
37
- <Section class={cn("", className)}>
38
+ <Section class={cn("", className)} {...props}>
38
39
  <SectionContainer class="mx-auto max-w-2xl gap-8">
39
40
  <div class="mx-auto flex w-full max-w-2xl flex-col gap-6">
40
41
  {
@@ -1,14 +1,14 @@
1
1
  ---
2
2
  import type { ImageMetadata } from "astro"
3
3
  import { Image } from "astro:assets"
4
+ import type { HTMLAttributes } from "astro/types"
4
5
 
5
6
  import { cn } from "@/lib/utils"
6
7
  import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
7
8
  import { Badge } from "@/components/ui/badge"
8
9
  import { Section, SectionContainer } from "@/components/ui/section"
9
10
 
10
- type Props = {
11
- class?: string
11
+ type Props = HTMLAttributes<"section"> & {
12
12
  badge?: string
13
13
  title: string
14
14
  description: string
@@ -32,10 +32,11 @@ const {
32
32
  description,
33
33
  author,
34
34
  image,
35
+ ...props
35
36
  } = Astro.props
36
37
  ---
37
38
 
38
- <Section class={cn("", className)}>
39
+ <Section class={cn("", className)} {...props}>
39
40
  <SectionContainer class="mx-auto max-w-2xl items-center gap-8 text-center">
40
41
  <div class="mx-auto flex w-full max-w-2xl flex-col items-center gap-6">
41
42
  {badge && <Badge variant="secondary">{badge}</Badge>}
@@ -1,14 +1,18 @@
1
1
  ---
2
2
  import type { ImageMetadata } from "astro"
3
3
  import { Image } from "astro:assets"
4
+ import type { HTMLAttributes } from "astro/types"
4
5
 
5
6
  import { cn } from "@/lib/utils"
6
7
  import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
7
8
  import { Badge } from "@/components/ui/badge"
8
- import { Section, SectionContainer } from "@/components/ui/section"
9
+ import {
10
+ Section,
11
+ SectionContainer,
12
+ SectionTitle,
13
+ } from "@/components/ui/section"
9
14
 
10
- type Props = {
11
- class?: string
15
+ type Props = HTMLAttributes<"section"> & {
12
16
  badge?: string
13
17
  title: string
14
18
  description: string
@@ -30,10 +34,17 @@ type Props = {
30
34
  }[]
31
35
  }
32
36
 
33
- const { class: className, badge, title, description, articles } = Astro.props
37
+ const {
38
+ class: className,
39
+ badge,
40
+ title,
41
+ description,
42
+ articles,
43
+ ...props
44
+ } = Astro.props
34
45
  ---
35
46
 
36
- <Section class={cn("", className)}>
47
+ <Section class={cn("", className)} {...props}>
37
48
  <SectionContainer class="gap-8">
38
49
  <div class="flex max-w-2xl flex-col gap-4">
39
50
  {
@@ -43,11 +54,9 @@ const { class: className, badge, title, description, articles } = Astro.props
43
54
  </Badge>
44
55
  )
45
56
  }
46
- <h2
47
- class="text-3xl font-semibold tracking-tight text-balance sm:text-4xl"
48
- >
57
+ <SectionTitle>
49
58
  {title}
50
- </h2>
59
+ </SectionTitle>
51
60
  <p class="text-muted-foreground text-base leading-7">
52
61
  {description}
53
62
  </p>
@@ -1,14 +1,14 @@
1
1
  ---
2
2
  import type { ImageMetadata } from "astro"
3
3
  import { Image } from "astro:assets"
4
+ import type { HTMLAttributes } from "astro/types"
4
5
 
5
6
  import { cn } from "@/lib/utils"
6
7
  import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
7
8
  import { Badge } from "@/components/ui/badge"
8
9
  import { Section, SectionContainer } from "@/components/ui/section"
9
10
 
10
- type Props = {
11
- class?: string
11
+ type Props = HTMLAttributes<"section"> & {
12
12
  badge?: string
13
13
  title: string
14
14
  description: string
@@ -53,10 +53,11 @@ const {
53
53
  description,
54
54
  featured,
55
55
  articles,
56
+ ...props
56
57
  } = Astro.props
57
58
  ---
58
59
 
59
- <Section class={cn("", className)}>
60
+ <Section class={cn("", className)} {...props}>
60
61
  <SectionContainer class="gap-8">
61
62
  <div class="mx-auto max-w-2xl text-center">
62
63
  {badge && <Badge variant="secondary">{badge}</Badge>}
@@ -1,14 +1,18 @@
1
1
  ---
2
2
  import type { ImageMetadata } from "astro"
3
3
  import { Image } from "astro:assets"
4
+ import type { HTMLAttributes } from "astro/types"
4
5
 
5
6
  import { cn } from "@/lib/utils"
6
7
  import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
7
8
  import { Badge } from "@/components/ui/badge"
8
- import { Section, SectionContainer } from "@/components/ui/section"
9
+ import {
10
+ Section,
11
+ SectionContainer,
12
+ SectionTitle,
13
+ } from "@/components/ui/section"
9
14
 
10
- type Props = {
11
- class?: string
15
+ type Props = HTMLAttributes<"section"> & {
12
16
  badge?: string
13
17
  title: string
14
18
  articles: {
@@ -29,10 +33,10 @@ type Props = {
29
33
  }[]
30
34
  }
31
35
 
32
- const { class: className, badge, title, articles } = Astro.props
36
+ const { class: className, badge, title, articles, ...props } = Astro.props
33
37
  ---
34
38
 
35
- <Section class={cn("", className)}>
39
+ <Section class={cn("", className)} {...props}>
36
40
  <SectionContainer class="gap-8">
37
41
  <div class="flex flex-wrap items-end justify-between gap-4">
38
42
  <div class="flex flex-col gap-4">
@@ -43,11 +47,9 @@ const { class: className, badge, title, articles } = Astro.props
43
47
  </Badge>
44
48
  )
45
49
  }
46
- <h2
47
- class="text-3xl font-semibold tracking-tight text-balance sm:text-4xl"
48
- >
50
+ <SectionTitle>
49
51
  {title}
50
- </h2>
52
+ </SectionTitle>
51
53
  </div>
52
54
  </div>
53
55
 
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  import type { ImageMetadata } from "astro"
3
+ import type { HTMLAttributes } from "astro/types"
3
4
 
4
5
  import { cn } from "@/lib/utils"
5
6
  import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
6
7
  import { Badge } from "@/components/ui/badge"
7
8
  import { Section, SectionContainer } from "@/components/ui/section"
8
9
 
9
- type Props = {
10
- class?: string
10
+ type Props = HTMLAttributes<"section"> & {
11
11
  badge?: string
12
12
  title: string
13
13
  description: string
@@ -25,10 +25,17 @@ type Props = {
25
25
  }[]
26
26
  }
27
27
 
28
- const { class: className, badge, title, description, articles } = Astro.props
28
+ const {
29
+ class: className,
30
+ badge,
31
+ title,
32
+ description,
33
+ articles,
34
+ ...props
35
+ } = Astro.props
29
36
  ---
30
37
 
31
- <Section class={cn("", className)}>
38
+ <Section class={cn("", className)} {...props}>
32
39
  <SectionContainer class="gap-8">
33
40
  <div class="mx-auto max-w-2xl text-center">
34
41
  {badge && <Badge variant="secondary">{badge}</Badge>}
@@ -1,11 +1,11 @@
1
1
  ---
2
+ import type { HTMLAttributes } from "astro/types"
2
3
  import ArrowRightIcon from "@lucide/astro/icons/arrow-right"
3
4
 
4
5
  import { cn } from "@/lib/utils"
5
6
  import { Banner, BannerContainer } from "@/components/ui/banner"
6
7
 
7
- type Props = {
8
- class?: string
8
+ type Props = HTMLAttributes<"aside"> & {
9
9
  title: string
10
10
  description: string
11
11
  link?: {
@@ -14,12 +14,13 @@ type Props = {
14
14
  }
15
15
  }
16
16
 
17
- const { class: className, title, description, link } = Astro.props
17
+ const { class: className, title, description, link, ...props } = Astro.props
18
18
  ---
19
19
 
20
20
  <Banner
21
21
  storageKey="banner-1"
22
22
  class={cn("dark bg-background text-foreground", className)}
23
+ {...props}
23
24
  >
24
25
  <BannerContainer class="flex-row items-center gap-x-4 gap-y-1">
25
26
  <p class="text-sm leading-relaxed">
@@ -1,10 +1,11 @@
1
1
  ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
2
4
  import { cn } from "@/lib/utils"
3
5
  import { Banner, BannerContainer } from "@/components/ui/banner"
4
6
  import { Button } from "@/components/ui/button"
5
7
 
6
- type Props = {
7
- class?: string
8
+ type Props = HTMLAttributes<"aside"> & {
8
9
  title: string
9
10
  description: string
10
11
  buttons?: {
@@ -14,20 +15,28 @@ type Props = {
14
15
  }[]
15
16
  }
16
17
 
17
- const { class: className, title, description, buttons } = Astro.props
18
+ const { class: className, title, description, buttons, ...props } = Astro.props
18
19
  ---
19
20
 
20
- <Banner variant="floating" storageKey="banner-2" class={cn("", className)}>
21
- <BannerContainer class="gap-4 py-1" showClose={false}>
21
+ <Banner
22
+ variant="floating"
23
+ storageKey="banner-2"
24
+ class={cn("@container", className)}
25
+ {...props}
26
+ >
27
+ <BannerContainer
28
+ class="flex-col items-start gap-4 py-1 @2xl:flex-row @2xl:items-center"
29
+ showClose={false}
30
+ >
22
31
  <div
23
- class="flex flex-1 flex-col gap-0.5 @5xl:flex-row @5xl:items-center @5xl:gap-x-4"
32
+ class="flex min-w-0 flex-1 flex-col gap-0.5 @5xl:flex-row @5xl:items-center @5xl:gap-x-4"
24
33
  >
25
34
  <p class="text-sm font-semibold">{title}</p>
26
35
  <p class="text-muted-foreground text-sm">{description}</p>
27
36
  </div>
28
37
  {
29
38
  buttons?.length && (
30
- <div class="flex shrink-0 items-center gap-2">
39
+ <div class="flex flex-wrap items-center gap-2">
31
40
  {buttons.map(({ href, label, ...button }, index) => (
32
41
  <Button
33
42
  as="a"
@@ -70,7 +70,7 @@ const showCopyButton = Boolean(copyButton)
70
70
  const showOpenButton = Boolean(markdownUrl)
71
71
  const showPagination = Boolean(previousPage || nextPage)
72
72
  const assistantPrompt = markdownUrl
73
- ? `Read ${markdownUrl}, I want to ask questions about it.`
73
+ ? `Read ${new URL(markdownUrl, Astro.site ?? Astro.url.origin).href}, I want to ask questions about it.`
74
74
  : ""
75
75
  const openLinks = markdownUrl
76
76
  ? [
@@ -1,4 +1,6 @@
1
1
  ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
2
4
  import { cn } from "@/lib/utils"
3
5
  import { Button } from "@/components/ui/button"
4
6
  import {
@@ -9,13 +11,18 @@ import {
9
11
  FieldLegend,
10
12
  FieldSet,
11
13
  } from "@/components/ui/field"
14
+ import { Form } from "@/components/ui/form"
12
15
  import { Icon } from "@/components/ui/icon"
13
16
  import { Input } from "@/components/ui/input"
14
- import { Section, SectionContainer } from "@/components/ui/section"
17
+ import {
18
+ Section,
19
+ SectionContainer,
20
+ SectionDescription,
21
+ SectionTitle,
22
+ } from "@/components/ui/section"
15
23
  import { Textarea } from "@/components/ui/textarea"
16
24
 
17
- type Props = {
18
- class?: string
25
+ type Props = HTMLAttributes<"section"> & {
19
26
  title: string
20
27
  description: string
21
28
  contactItems: {
@@ -25,6 +32,9 @@ type Props = {
25
32
  href?: string
26
33
  }[]
27
34
  form: {
35
+ id?: string
36
+ action?: string
37
+ method?: "get" | "post"
28
38
  legend: string
29
39
  nameLabel: string
30
40
  namePlaceholder: string
@@ -37,22 +47,26 @@ type Props = {
37
47
  }
38
48
  }
39
49
 
40
- const { class: className, title, description, contactItems, form } = Astro.props
50
+ const {
51
+ class: className,
52
+ title,
53
+ description,
54
+ contactItems,
55
+ form,
56
+ ...props
57
+ } = Astro.props
58
+ const formId = form.id ?? `contact-${crypto.randomUUID()}`
41
59
  ---
42
60
 
43
- <Section class={cn("", className)}>
61
+ <Section class={cn("", className)} {...props}>
44
62
  <SectionContainer class="items-center gap-6 text-center">
45
63
  <div class="flex max-w-2xl flex-col items-center gap-4">
46
- <h2
47
- class="text-foreground text-3xl font-semibold tracking-tight text-balance sm:text-4xl"
48
- >
64
+ <SectionTitle>
49
65
  {title}
50
- </h2>
51
- <p
52
- class="text-muted-foreground max-w-2xl text-lg leading-relaxed text-balance"
53
- >
66
+ </SectionTitle>
67
+ <SectionDescription class="max-w-2xl">
54
68
  {description}
55
- </p>
69
+ </SectionDescription>
56
70
  </div>
57
71
  </SectionContainer>
58
72
  <SectionContainer>
@@ -73,10 +87,11 @@ const { class: className, title, description, contactItems, form } = Astro.props
73
87
  </Button>
74
88
  ) : (
75
89
  <Button
90
+ as="span"
76
91
  variant="secondary"
77
92
  size="icon"
78
93
  class="text-primary"
79
- aria-label={item.title}
94
+ aria-hidden="true"
80
95
  >
81
96
  <Icon name={item.icon} />
82
97
  </Button>
@@ -92,35 +107,54 @@ const { class: className, title, description, contactItems, form } = Astro.props
92
107
  </SectionContainer>
93
108
  <SectionContainer>
94
109
  <div class="mx-auto w-full max-w-2xl rounded-xl border p-6 sm:p-8">
95
- <FieldSet>
96
- <FieldLegend class="sr-only">{form.legend}</FieldLegend>
97
- <FieldGroup>
98
- <div class="grid gap-4 md:grid-cols-2">
110
+ <Form id={formId} action={form.action} method={form.method ?? "post"}>
111
+ <FieldSet>
112
+ <FieldLegend class="sr-only">{form.legend}</FieldLegend>
113
+ <FieldGroup>
114
+ <div class="grid gap-4 md:grid-cols-2">
115
+ <Field>
116
+ <FieldLabel for={`${formId}-name`}>{form.nameLabel}</FieldLabel>
117
+ <Input
118
+ id={`${formId}-name`}
119
+ name="name"
120
+ autocomplete="name"
121
+ required
122
+ placeholder={form.namePlaceholder}
123
+ />
124
+ </Field>
125
+ <Field>
126
+ <FieldLabel for={`${formId}-email`}
127
+ >{form.emailLabel}</FieldLabel
128
+ >
129
+ <Input
130
+ id={`${formId}-email`}
131
+ name="email"
132
+ autocomplete="email"
133
+ required
134
+ type="email"
135
+ placeholder={form.emailPlaceholder}
136
+ />
137
+ </Field>
138
+ </div>
99
139
  <Field>
100
- <FieldLabel for="contact-name-1">{form.nameLabel}</FieldLabel>
101
- <Input id="contact-name-1" placeholder={form.namePlaceholder} />
102
- </Field>
103
- <Field>
104
- <FieldLabel for="contact-email-1">{form.emailLabel}</FieldLabel>
105
- <Input
106
- id="contact-email-1"
107
- type="email"
108
- placeholder={form.emailPlaceholder}
140
+ <FieldLabel for={`${formId}-message`}
141
+ >{form.messageLabel}</FieldLabel
142
+ >
143
+ <Textarea
144
+ id={`${formId}-message`}
145
+ name="message"
146
+ required
147
+ rows={5}
148
+ placeholder={form.messagePlaceholder}
109
149
  />
150
+ <FieldDescription>{form.messageDescription}</FieldDescription>
110
151
  </Field>
111
- </div>
112
- <Field>
113
- <FieldLabel for="contact-message-1">{form.messageLabel}</FieldLabel>
114
- <Textarea
115
- id="contact-message-1"
116
- rows={5}
117
- placeholder={form.messagePlaceholder}
118
- />
119
- <FieldDescription>{form.messageDescription}</FieldDescription>
120
- </Field>
121
- <Button size="lg" class="w-full">{form.actionLabel}</Button>
122
- </FieldGroup>
123
- </FieldSet>
152
+ <Button type="submit" size="lg" class="w-full"
153
+ >{form.actionLabel}</Button
154
+ >
155
+ </FieldGroup>
156
+ </FieldSet>
157
+ </Form>
124
158
  </div>
125
159
  </SectionContainer>
126
160
  </Section>
@@ -1,4 +1,6 @@
1
1
  ---
2
+ import type { HTMLAttributes } from "astro/types"
3
+
2
4
  import { cn } from "@/lib/utils"
3
5
  import { Button } from "@/components/ui/button"
4
6
  import {
@@ -8,13 +10,17 @@ import {
8
10
  FieldLegend,
9
11
  FieldSet,
10
12
  } from "@/components/ui/field"
13
+ import { Form } from "@/components/ui/form"
11
14
  import { Icon } from "@/components/ui/icon"
12
15
  import { Input } from "@/components/ui/input"
13
- import { Section, SectionContainer } from "@/components/ui/section"
16
+ import {
17
+ Section,
18
+ SectionContainer,
19
+ SectionTitle,
20
+ } from "@/components/ui/section"
14
21
  import { Textarea } from "@/components/ui/textarea"
15
22
 
16
- type Props = {
17
- class?: string
23
+ type Props = HTMLAttributes<"section"> & {
18
24
  title: string
19
25
  description: string
20
26
  contactItems: {
@@ -24,6 +30,9 @@ type Props = {
24
30
  href?: string
25
31
  }[]
26
32
  form: {
33
+ id?: string
34
+ action?: string
35
+ method?: "get" | "post"
27
36
  title: string
28
37
  legend: string
29
38
  nameLabel: string
@@ -36,20 +45,26 @@ type Props = {
36
45
  }
37
46
  }
38
47
 
39
- const { class: className, title, description, contactItems, form } = Astro.props
48
+ const {
49
+ class: className,
50
+ title,
51
+ description,
52
+ contactItems,
53
+ form,
54
+ ...props
55
+ } = Astro.props
56
+ const formId = form.id ?? `contact-${crypto.randomUUID()}`
40
57
  ---
41
58
 
42
- <Section class={cn("", className)}>
59
+ <Section class={cn("", className)} {...props}>
43
60
  <SectionContainer
44
61
  class="grid gap-10 lg:grid-cols-[minmax(0,1fr)_22rem] lg:items-start"
45
62
  >
46
63
  <div class="flex flex-col gap-6">
47
64
  <div class="flex flex-col gap-4">
48
- <h2
49
- class="text-foreground text-3xl font-semibold tracking-tight text-balance sm:text-4xl"
50
- >
65
+ <SectionTitle>
51
66
  {title}
52
- </h2>
67
+ </SectionTitle>
53
68
  <p class="text-muted-foreground max-w-xl text-base leading-relaxed">
54
69
  {description}
55
70
  </p>
@@ -58,36 +73,55 @@ const { class: className, title, description, contactItems, form } = Astro.props
58
73
  <div class="mb-6">
59
74
  <h3 class="text-lg font-medium">{form.title}</h3>
60
75
  </div>
61
- <FieldSet>
62
- <FieldLegend class="sr-only">{form.legend}</FieldLegend>
63
- <FieldGroup>
64
- <div class="grid gap-4 md:grid-cols-2">
65
- <Field>
66
- <FieldLabel for="contact-name-2">{form.nameLabel}</FieldLabel>
67
- <Input id="contact-name-2" placeholder={form.namePlaceholder} />
68
- </Field>
76
+ <Form id={formId} action={form.action} method={form.method ?? "post"}>
77
+ <FieldSet>
78
+ <FieldLegend class="sr-only">{form.legend}</FieldLegend>
79
+ <FieldGroup>
80
+ <div class="grid gap-4 md:grid-cols-2">
81
+ <Field>
82
+ <FieldLabel for={`${formId}-name`}
83
+ >{form.nameLabel}</FieldLabel
84
+ >
85
+ <Input
86
+ id={`${formId}-name`}
87
+ name="name"
88
+ autocomplete="name"
89
+ required
90
+ placeholder={form.namePlaceholder}
91
+ />
92
+ </Field>
93
+ <Field>
94
+ <FieldLabel for={`${formId}-email`}
95
+ >{form.emailLabel}</FieldLabel
96
+ >
97
+ <Input
98
+ id={`${formId}-email`}
99
+ name="email"
100
+ autocomplete="email"
101
+ required
102
+ type="email"
103
+ placeholder={form.emailPlaceholder}
104
+ />
105
+ </Field>
106
+ </div>
69
107
  <Field>
70
- <FieldLabel for="contact-email-2">{form.emailLabel}</FieldLabel>
71
- <Input
72
- id="contact-email-2"
73
- type="email"
74
- placeholder={form.emailPlaceholder}
108
+ <FieldLabel for={`${formId}-message`}
109
+ >{form.messageLabel}</FieldLabel
110
+ >
111
+ <Textarea
112
+ id={`${formId}-message`}
113
+ name="message"
114
+ required
115
+ rows={5}
116
+ placeholder={form.messagePlaceholder}
75
117
  />
76
118
  </Field>
77
- </div>
78
- <Field>
79
- <FieldLabel for="contact-message-2"
80
- >{form.messageLabel}</FieldLabel
119
+ <Button type="submit" size="lg" class="w-full"
120
+ >{form.actionLabel}</Button
81
121
  >
82
- <Textarea
83
- id="contact-message-2"
84
- rows={5}
85
- placeholder={form.messagePlaceholder}
86
- />
87
- </Field>
88
- <Button size="lg" class="w-full">{form.actionLabel}</Button>
89
- </FieldGroup>
90
- </FieldSet>
122
+ </FieldGroup>
123
+ </FieldSet>
124
+ </Form>
91
125
  </div>
92
126
  </div>
93
127
 
@@ -108,10 +142,11 @@ const { class: className, title, description, contactItems, form } = Astro.props
108
142
  </Button>
109
143
  ) : (
110
144
  <Button
145
+ as="span"
111
146
  variant="secondary"
112
147
  size="icon"
113
148
  class="text-primary shrink-0"
114
- aria-label={item.title}
149
+ aria-hidden="true"
115
150
  >
116
151
  <Icon name={item.icon} />
117
152
  </Button>