fulldev-ui 0.10.1 → 0.11.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 (248) hide show
  1. package/CHANGELOG.md +6 -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 +6 -0
  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 +5 -0
  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 +6 -0
  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 +10 -4
  154. package/src/components/blocks/blocks-1.astro +1 -1
  155. package/src/components/blocks/contact-1.astro +72 -39
  156. package/src/components/blocks/contact-2.astro +69 -35
  157. package/src/components/blocks/contact-3.astro +61 -34
  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/ui/accordion/accordion.astro +1 -0
  228. package/src/components/ui/alert-dialog/alert-dialog.astro +1 -0
  229. package/src/components/ui/collapsible/collapsible.astro +1 -0
  230. package/src/components/ui/dialog/dialog.astro +1 -0
  231. package/src/components/ui/dropdown-menu/dropdown-menu.astro +1 -0
  232. package/src/components/ui/hover-card/hover-card.astro +7 -3
  233. package/src/components/ui/icon/icon.astro +46 -29
  234. package/src/components/ui/navigation-menu/navigation-menu.astro +1 -0
  235. package/src/components/ui/popover/popover.astro +1 -0
  236. package/src/components/ui/radio-group/radio-group.astro +1 -0
  237. package/src/components/ui/section/index.ts +2 -0
  238. package/src/components/ui/section/section-container.astro +1 -0
  239. package/src/components/ui/section/section-description.astro +20 -0
  240. package/src/components/ui/section/section-title.astro +20 -0
  241. package/src/components/ui/sheet/sheet-close.astro +4 -2
  242. package/src/components/ui/sheet/sheet.astro +1 -0
  243. package/src/components/ui/slider/slider.astro +1 -0
  244. package/src/components/ui/switch/switch.astro +1 -0
  245. package/src/components/ui/tabs/tabs.astro +1 -0
  246. package/src/components/ui/toggle/toggle.astro +1 -0
  247. package/src/components/ui/tooltip/tooltip.astro +1 -0
  248. package/src/lib/pages.ts +12 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Fulldev UI
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`4b0ccf6`](https://github.com/fulldotdev/ui/commit/4b0ccf6a70b0fd38e750755a1e9416e42e967352) Thanks [@silveltman](https://github.com/silveltman)! - Restore portable registry setup and complete component and block bundles. Add functional contact forms, mobile header links and slots, section heading primitives, HTML attribute forwarding, explicit icon sources, and Astro navigation reinitialization while preserving the latest component APIs. Add registry metadata and Markdown documentation indexes for agents.
8
+
3
9
  ## 0.10.1
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -56,7 +56,13 @@ npx shadcn@latest init
56
56
  }
57
57
  ```
58
58
 
59
- 5. **Copy the base stylesheet** from [`src/styles/global.css`](./src/styles/global.css) into your project, then import it in your layout.
59
+ 5. **Install the base stylesheet and shared helpers**, then import the stylesheet in your layout:
60
+
61
+ ```bash
62
+ npx shadcn@latest add @fulldev/init
63
+ ```
64
+
65
+ Review stylesheet changes in an existing project to preserve your theme.
60
66
 
61
67
  6. **Use a container-aware app shell** because Fulldev UI uses Tailwind v4 container-query variants like `@2xl:` and `@max-5xl:`:
62
68
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fulldev-ui",
3
3
  "type": "module",
4
- "version": "0.10.1",
4
+ "version": "0.11.0",
5
5
  "description": "Open-source Astro UI components and blocks",
6
6
  "homepage": "https://ui.full.dev",
7
7
  "bugs": "https://github.com/fulldotdev/ui/issues",
@@ -38,7 +38,8 @@
38
38
  "src/components/blocks",
39
39
  "src/components/ui",
40
40
  "src/lib",
41
- "src/styles/global.css"
41
+ "src/styles/global.css",
42
+ "registry/init"
42
43
  ],
43
44
  "publishConfig": {
44
45
  "access": "public"
@@ -110,11 +111,12 @@
110
111
  "build:prod": "pnpm check && pnpm registry:build && pnpm build",
111
112
  "build:preview": "pnpm registry:build && pnpm build && astro preview --host 127.0.0.1 --port 4321",
112
113
  "build:test": "pnpm check && pnpm registry:build && pnpm build && astro preview --host 127.0.0.1 --port 4321",
113
- "registry:build": "shadcn build && pnpm format:write --log-level warn",
114
+ "registry:build": "pnpm registry:meta && shadcn build && pnpm format:write --log-level warn",
114
115
  "registry:check": "pnpm registry:build && git diff --exit-code -- registry.json public/r",
115
116
  "format:write": "prettier --write .",
116
117
  "format:check": "prettier --check .",
117
118
  "release": "changeset version && pnpm install --lockfile-only",
118
- "release:publish": "pnpm registry:check && pnpm build && changeset publish"
119
+ "release:publish": "pnpm registry:check && pnpm build && changeset publish",
120
+ "registry:meta": "node scripts/registry-meta.mjs"
119
121
  }
120
122
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "accordion",
4
+ "title": "Accordion",
5
+ "description": "A vertically stacked set of interactive headings that each reveal a section of content.",
4
6
  "dependencies": [
5
7
  "@data-slot/accordion",
6
8
  "@lucide/astro"
@@ -8,7 +10,7 @@
8
10
  "files": [
9
11
  {
10
12
  "path": "src/components/ui/accordion/accordion.astro",
11
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n multiple?: boolean\n defaultValue?: string | string[]\n disabled?: boolean\n orientation?: \"horizontal\" | \"vertical\"\n loopFocus?: boolean\n hiddenUntilFound?: boolean\n collapsible?: boolean\n}\n\nconst {\n class: className,\n multiple,\n defaultValue,\n disabled,\n orientation = \"vertical\",\n loopFocus,\n hiddenUntilFound,\n collapsible,\n ...props\n} = Astro.props\n\nconst serializedDefaultValue = Array.isArray(defaultValue)\n ? JSON.stringify(defaultValue)\n : defaultValue\n---\n\n<div\n data-slot=\"accordion\"\n data-multiple={multiple}\n data-default-value={serializedDefaultValue}\n data-disabled={disabled}\n data-orientation={orientation}\n data-loop-focus={loopFocus}\n data-hidden-until-found={hiddenUntilFound}\n data-collapsible={collapsible}\n class={cn(\"flex w-full flex-col\", className)}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { create } from \"@data-slot/accordion\"\n\n create()\n</script>\n",
13
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n multiple?: boolean\n defaultValue?: string | string[]\n disabled?: boolean\n orientation?: \"horizontal\" | \"vertical\"\n loopFocus?: boolean\n hiddenUntilFound?: boolean\n collapsible?: boolean\n}\n\nconst {\n class: className,\n multiple,\n defaultValue,\n disabled,\n orientation = \"vertical\",\n loopFocus,\n hiddenUntilFound,\n collapsible,\n ...props\n} = Astro.props\n\nconst serializedDefaultValue = Array.isArray(defaultValue)\n ? JSON.stringify(defaultValue)\n : defaultValue\n---\n\n<div\n data-slot=\"accordion\"\n data-multiple={multiple}\n data-default-value={serializedDefaultValue}\n data-disabled={disabled}\n data-orientation={orientation}\n data-loop-focus={loopFocus}\n data-hidden-until-found={hiddenUntilFound}\n data-collapsible={collapsible}\n class={cn(\"flex w-full flex-col\", className)}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { create } from \"@data-slot/accordion\"\n\n create()\n document.addEventListener(\"astro:page-load\", () => create())\n</script>\n",
12
14
  "type": "registry:ui"
13
15
  },
14
16
  {
@@ -32,5 +34,9 @@
32
34
  "type": "registry:ui"
33
35
  }
34
36
  ],
37
+ "docs": "https://ui.full.dev/components/accordion/",
38
+ "categories": [
39
+ "ui"
40
+ ],
35
41
  "type": "registry:ui"
36
42
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "alert-dialog",
4
+ "title": "Alert Dialog",
5
+ "description": "A modal dialog for important confirmations that expects a response.",
4
6
  "dependencies": [
5
7
  "@data-slot/alert-dialog"
6
8
  ],
@@ -10,7 +12,7 @@
10
12
  "files": [
11
13
  {
12
14
  "path": "src/components/ui/alert-dialog/alert-dialog.astro",
13
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n lockScroll?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n closeOnClickOutside,\n closeOnEscape,\n lockScroll,\n ...props\n} = Astro.props\n---\n\n<div\n data-slot=\"alert-dialog\"\n data-default-open={defaultOpen}\n data-close-on-click-outside={closeOnClickOutside}\n data-close-on-escape={closeOnEscape}\n data-lock-scroll={lockScroll}\n class={className}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { create } from \"@data-slot/alert-dialog\"\n\n create()\n</script>\n",
15
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n lockScroll?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n closeOnClickOutside,\n closeOnEscape,\n lockScroll,\n ...props\n} = Astro.props\n---\n\n<div\n data-slot=\"alert-dialog\"\n data-default-open={defaultOpen}\n data-close-on-click-outside={closeOnClickOutside}\n data-close-on-escape={closeOnEscape}\n data-lock-scroll={lockScroll}\n class={className}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { create } from \"@data-slot/alert-dialog\"\n\n create()\n document.addEventListener(\"astro:page-load\", () => create())\n</script>\n",
14
16
  "type": "registry:ui"
15
17
  },
16
18
  {
@@ -74,5 +76,9 @@
74
76
  "type": "registry:ui"
75
77
  }
76
78
  ],
79
+ "docs": "https://ui.full.dev/components/alert-dialog/",
80
+ "categories": [
81
+ "ui"
82
+ ],
77
83
  "type": "registry:ui"
78
84
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "alert",
4
+ "title": "Alert",
5
+ "description": "Displays a callout for user attention.",
4
6
  "files": [
5
7
  {
6
8
  "path": "src/components/ui/alert/alert.astro",
@@ -23,5 +25,9 @@
23
25
  "type": "registry:ui"
24
26
  }
25
27
  ],
28
+ "docs": "https://ui.full.dev/components/alert/",
29
+ "categories": [
30
+ "ui"
31
+ ],
26
32
  "type": "registry:ui"
27
33
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "article-1",
4
+ "title": "Article 1",
5
+ "description": "Editorial article layouts for long-form stories, interviews, and analysis.",
4
6
  "registryDependencies": [
5
7
  "@fulldev/avatar",
6
8
  "@fulldev/badge",
@@ -9,9 +11,13 @@
9
11
  "files": [
10
12
  {
11
13
  "path": "src/components/blocks/article-1.astro",
12
- "content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = {\n class?: string\n badge?: string\n title: string\n description: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n image: {\n src: ImageMetadata\n alt: string\n }\n}\n\nconst {\n class: className,\n badge,\n title,\n description,\n author,\n image,\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)}>\n <SectionContainer class=\"mx-auto max-w-2xl gap-8\">\n <div class=\"mx-auto flex w-full max-w-2xl flex-col gap-6\">\n {\n badge && (\n <Badge variant=\"secondary\" class=\"w-fit\">\n {badge}\n </Badge>\n )\n }\n <div class=\"flex flex-col gap-4\">\n <h1\n class=\"text-4xl leading-tight font-semibold tracking-tight text-balance sm:text-5xl\"\n >\n {title}\n </h1>\n <p class=\"text-muted-foreground text-lg leading-8 text-balance\">\n {description}\n </p>\n </div>\n <div class=\"flex items-center gap-3\">\n <Avatar size=\"lg\">\n <AvatarImage src={author.image} alt={author.name} />\n <AvatarFallback>{author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{author.name}</p>\n <p class=\"text-muted-foreground text-xs\">{author.date}</p>\n </div>\n </div>\n </div>\n\n <Image\n src={image.src}\n alt={image.alt}\n class=\"aspect-[16/10] w-full rounded-xl object-cover\"\n widths={[640, 960]}\n sizes=\"(min-width: 42rem) 42rem, 100vw\"\n />\n\n <article\n class=\"mx-auto flex w-full max-w-2xl flex-col gap-6 text-base leading-8\"\n >\n <slot />\n </article>\n </SectionContainer>\n</Section>\n",
14
+ "content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = HTMLAttributes<\"section\"> & {\n badge?: string\n title: string\n description: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n image: {\n src: ImageMetadata\n alt: string\n }\n}\n\nconst {\n class: className,\n badge,\n title,\n description,\n author,\n image,\n ...props\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)} {...props}>\n <SectionContainer class=\"mx-auto max-w-2xl gap-8\">\n <div class=\"mx-auto flex w-full max-w-2xl flex-col gap-6\">\n {\n badge && (\n <Badge variant=\"secondary\" class=\"w-fit\">\n {badge}\n </Badge>\n )\n }\n <div class=\"flex flex-col gap-4\">\n <h1\n class=\"text-4xl leading-tight font-semibold tracking-tight text-balance sm:text-5xl\"\n >\n {title}\n </h1>\n <p class=\"text-muted-foreground text-lg leading-8 text-balance\">\n {description}\n </p>\n </div>\n <div class=\"flex items-center gap-3\">\n <Avatar size=\"lg\">\n <AvatarImage src={author.image} alt={author.name} />\n <AvatarFallback>{author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{author.name}</p>\n <p class=\"text-muted-foreground text-xs\">{author.date}</p>\n </div>\n </div>\n </div>\n\n <Image\n src={image.src}\n alt={image.alt}\n class=\"aspect-[16/10] w-full rounded-xl object-cover\"\n widths={[640, 960]}\n sizes=\"(min-width: 42rem) 42rem, 100vw\"\n />\n\n <article\n class=\"mx-auto flex w-full max-w-2xl flex-col gap-6 text-base leading-8\"\n >\n <slot />\n </article>\n </SectionContainer>\n</Section>\n",
13
15
  "type": "registry:block"
14
16
  }
15
17
  ],
18
+ "docs": "https://ui.full.dev/blocks/article/",
19
+ "categories": [
20
+ "article"
21
+ ],
16
22
  "type": "registry:block"
17
23
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "article-2",
4
+ "title": "Article 2",
5
+ "description": "Editorial article layouts for long-form stories, interviews, and analysis.",
4
6
  "registryDependencies": [
5
7
  "@fulldev/avatar",
6
8
  "@fulldev/badge",
@@ -9,9 +11,13 @@
9
11
  "files": [
10
12
  {
11
13
  "path": "src/components/blocks/article-2.astro",
12
- "content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = {\n class?: string\n badge?: string\n title: string\n description: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n readingTime: string\n }\n image: {\n src: ImageMetadata\n alt: string\n }\n}\n\nconst {\n class: className,\n badge,\n title,\n description,\n author,\n image,\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)}>\n <SectionContainer class=\"mx-auto max-w-2xl items-center gap-8 text-center\">\n <div class=\"mx-auto flex w-full max-w-2xl flex-col items-center gap-6\">\n {badge && <Badge variant=\"secondary\">{badge}</Badge>}\n <div class=\"flex flex-col gap-4\">\n <h1\n class=\"text-4xl leading-tight font-semibold tracking-tight text-balance sm:text-5xl\"\n >\n {title}\n </h1>\n <p class=\"text-muted-foreground text-lg leading-8 text-balance\">\n {description}\n </p>\n </div>\n <div class=\"flex items-center gap-3\">\n <Avatar size=\"lg\">\n <AvatarImage src={author.image} alt={author.name} />\n <AvatarFallback>{author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col text-left\">\n <p class=\"text-sm font-medium\">\n {author.name}\n <span class=\"text-muted-foreground font-normal\">\n &middot; {author.date}\n </span>\n </p>\n <p class=\"text-muted-foreground text-xs\">{author.readingTime}</p>\n </div>\n </div>\n </div>\n\n <Image\n src={image.src}\n alt={image.alt}\n class=\"aspect-[16/10] w-full rounded-xl object-cover\"\n widths={[640, 960]}\n sizes=\"(min-width: 42rem) 42rem, 100vw\"\n />\n\n <article\n class=\"mx-auto flex w-full max-w-2xl flex-col gap-6 text-left text-base leading-8\"\n >\n <slot />\n </article>\n </SectionContainer>\n</Section>\n",
14
+ "content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = HTMLAttributes<\"section\"> & {\n badge?: string\n title: string\n description: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n readingTime: string\n }\n image: {\n src: ImageMetadata\n alt: string\n }\n}\n\nconst {\n class: className,\n badge,\n title,\n description,\n author,\n image,\n ...props\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)} {...props}>\n <SectionContainer class=\"mx-auto max-w-2xl items-center gap-8 text-center\">\n <div class=\"mx-auto flex w-full max-w-2xl flex-col items-center gap-6\">\n {badge && <Badge variant=\"secondary\">{badge}</Badge>}\n <div class=\"flex flex-col gap-4\">\n <h1\n class=\"text-4xl leading-tight font-semibold tracking-tight text-balance sm:text-5xl\"\n >\n {title}\n </h1>\n <p class=\"text-muted-foreground text-lg leading-8 text-balance\">\n {description}\n </p>\n </div>\n <div class=\"flex items-center gap-3\">\n <Avatar size=\"lg\">\n <AvatarImage src={author.image} alt={author.name} />\n <AvatarFallback>{author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col text-left\">\n <p class=\"text-sm font-medium\">\n {author.name}\n <span class=\"text-muted-foreground font-normal\">\n &middot; {author.date}\n </span>\n </p>\n <p class=\"text-muted-foreground text-xs\">{author.readingTime}</p>\n </div>\n </div>\n </div>\n\n <Image\n src={image.src}\n alt={image.alt}\n class=\"aspect-[16/10] w-full rounded-xl object-cover\"\n widths={[640, 960]}\n sizes=\"(min-width: 42rem) 42rem, 100vw\"\n />\n\n <article\n class=\"mx-auto flex w-full max-w-2xl flex-col gap-6 text-left text-base leading-8\"\n >\n <slot />\n </article>\n </SectionContainer>\n</Section>\n",
13
15
  "type": "registry:block"
14
16
  }
15
17
  ],
18
+ "docs": "https://ui.full.dev/blocks/article/",
19
+ "categories": [
20
+ "article"
21
+ ],
16
22
  "type": "registry:block"
17
23
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "articles-1",
4
+ "title": "Articles 1",
5
+ "description": "Collection and listing layouts for journals, magazines, and editorial feeds.",
4
6
  "registryDependencies": [
5
7
  "@fulldev/avatar",
6
8
  "@fulldev/badge",
@@ -9,9 +11,13 @@
9
11
  "files": [
10
12
  {
11
13
  "path": "src/components/blocks/articles-1.astro",
12
- "content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = {\n class?: string\n badge?: string\n title: string\n description: string\n articles: {\n image: {\n src: ImageMetadata\n alt: string\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n }[]\n}\n\nconst { class: className, badge, title, description, articles } = Astro.props\n---\n\n<Section class={cn(\"\", className)}>\n <SectionContainer class=\"gap-8\">\n <div class=\"flex max-w-2xl flex-col gap-4\">\n {\n badge && (\n <Badge variant=\"secondary\" class=\"w-fit\">\n {badge}\n </Badge>\n )\n }\n <h2\n class=\"text-3xl font-semibold tracking-tight text-balance sm:text-4xl\"\n >\n {title}\n </h2>\n <p class=\"text-muted-foreground text-base leading-7\">\n {description}\n </p>\n </div>\n\n <div class=\"grid gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {\n articles.map((article) => (\n <a\n href={article.href ?? \"#\"}\n class=\"group hover:bg-muted/50 focus-visible:ring-ring/50 flex h-full flex-col gap-4 rounded-xl p-4 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n >\n <Image\n src={article.image.src}\n alt={article.image.alt}\n class=\"-mx-4 -mt-4 aspect-[16/9] w-[calc(100%+2rem)] max-w-none rounded-lg object-cover transition-opacity group-hover:opacity-85\"\n widths={[480, 720, 960]}\n sizes=\"(min-width: 64rem) 26rem, (min-width: 48rem) 50vw, 100vw\"\n />\n <div class=\"flex flex-col gap-2\">\n <p class=\"text-muted-foreground text-sm font-medium\">\n {article.category}\n </p>\n <h3 class=\"text-foreground line-clamp-2 text-xl leading-snug font-semibold\">\n {article.title}\n </h3>\n <p class=\"text-muted-foreground line-clamp-2 text-sm leading-6\">\n {article.description}\n </p>\n </div>\n <div class=\"mt-auto flex items-center gap-3\">\n <Avatar>\n <AvatarImage\n src={article.author.image}\n alt={article.author.name}\n />\n <AvatarFallback>{article.author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{article.author.name}</p>\n <p class=\"text-muted-foreground text-xs\">\n {article.author.date}\n </p>\n </div>\n </div>\n </a>\n ))\n }\n </div>\n </SectionContainer>\n</Section>\n",
14
+ "content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\ntype Props = HTMLAttributes<\"section\"> & {\n badge?: string\n title: string\n description: string\n articles: {\n image: {\n src: ImageMetadata\n alt: string\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n }[]\n}\n\nconst {\n class: className,\n badge,\n title,\n description,\n articles,\n ...props\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)} {...props}>\n <SectionContainer class=\"gap-8\">\n <div class=\"flex max-w-2xl flex-col gap-4\">\n {\n badge && (\n <Badge variant=\"secondary\" class=\"w-fit\">\n {badge}\n </Badge>\n )\n }\n <SectionTitle>\n {title}\n </SectionTitle>\n <p class=\"text-muted-foreground text-base leading-7\">\n {description}\n </p>\n </div>\n\n <div class=\"grid gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {\n articles.map((article) => (\n <a\n href={article.href ?? \"#\"}\n class=\"group hover:bg-muted/50 focus-visible:ring-ring/50 flex h-full flex-col gap-4 rounded-xl p-4 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n >\n <Image\n src={article.image.src}\n alt={article.image.alt}\n class=\"-mx-4 -mt-4 aspect-[16/9] w-[calc(100%+2rem)] max-w-none rounded-lg object-cover transition-opacity group-hover:opacity-85\"\n widths={[480, 720, 960]}\n sizes=\"(min-width: 64rem) 26rem, (min-width: 48rem) 50vw, 100vw\"\n />\n <div class=\"flex flex-col gap-2\">\n <p class=\"text-muted-foreground text-sm font-medium\">\n {article.category}\n </p>\n <h3 class=\"text-foreground line-clamp-2 text-xl leading-snug font-semibold\">\n {article.title}\n </h3>\n <p class=\"text-muted-foreground line-clamp-2 text-sm leading-6\">\n {article.description}\n </p>\n </div>\n <div class=\"mt-auto flex items-center gap-3\">\n <Avatar>\n <AvatarImage\n src={article.author.image}\n alt={article.author.name}\n />\n <AvatarFallback>{article.author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{article.author.name}</p>\n <p class=\"text-muted-foreground text-xs\">\n {article.author.date}\n </p>\n </div>\n </div>\n </a>\n ))\n }\n </div>\n </SectionContainer>\n</Section>\n",
13
15
  "type": "registry:block"
14
16
  }
15
17
  ],
18
+ "docs": "https://ui.full.dev/blocks/articles/",
19
+ "categories": [
20
+ "articles"
21
+ ],
16
22
  "type": "registry:block"
17
23
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "articles-2",
4
+ "title": "Articles 2",
5
+ "description": "Collection and listing layouts for journals, magazines, and editorial feeds.",
4
6
  "registryDependencies": [
5
7
  "@fulldev/avatar",
6
8
  "@fulldev/badge",
@@ -9,9 +11,13 @@
9
11
  "files": [
10
12
  {
11
13
  "path": "src/components/blocks/articles-2.astro",
12
- "content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = {\n class?: string\n badge?: string\n title: string\n description: string\n featured: {\n image: {\n src: ImageMetadata\n alt: string\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n }\n articles: {\n image: {\n src: ImageMetadata\n alt: string\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n }[]\n}\n\nconst {\n class: className,\n badge,\n title,\n description,\n featured,\n articles,\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)}>\n <SectionContainer class=\"gap-8\">\n <div class=\"mx-auto max-w-2xl text-center\">\n {badge && <Badge variant=\"secondary\">{badge}</Badge>}\n <h2\n class={cn(\n \"text-3xl font-semibold tracking-tight text-balance sm:text-4xl\",\n badge && \"mt-4\"\n )}\n >\n {title}\n </h2>\n <p class=\"text-muted-foreground mt-2 text-base leading-7 text-balance\">\n {description}\n </p>\n </div>\n\n <a\n href={featured.href ?? \"#\"}\n class=\"group hover:bg-muted/50 focus-visible:ring-ring/50 grid gap-6 rounded-xl transition-colors focus-visible:ring-2 focus-visible:outline-none lg:grid-cols-2 lg:items-center lg:pr-4\"\n >\n <Image\n src={featured.image.src}\n alt={featured.image.alt}\n class=\"aspect-[4/3] rounded-lg object-cover transition-opacity group-hover:opacity-85\"\n widths={[640, 960, 1280]}\n sizes=\"(min-width: 64rem) 50vw, 100vw\"\n />\n <div class=\"flex flex-col gap-4\">\n <Badge variant=\"outline\" class=\"w-fit\">{featured.category}</Badge>\n <h3\n class=\"text-foreground text-2xl leading-tight font-semibold sm:text-3xl\"\n >\n {featured.title}\n </h3>\n <p class=\"text-muted-foreground text-base leading-7\">\n {featured.description}\n </p>\n <div class=\"flex items-center gap-3\">\n <Avatar>\n <AvatarImage\n src={featured.author.image}\n alt={featured.author.name}\n />\n <AvatarFallback>{featured.author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{featured.author.name}</p>\n <p class=\"text-muted-foreground text-xs\">{featured.author.date}</p>\n </div>\n </div>\n </div>\n </a>\n\n <div class=\"grid gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {\n articles.map((article) => (\n <a\n href={article.href ?? \"#\"}\n class=\"group hover:bg-muted/50 focus-visible:ring-ring/50 flex h-full flex-col gap-4 rounded-xl p-4 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n >\n <Image\n src={article.image.src}\n alt={article.image.alt}\n class=\"-mx-4 -mt-4 aspect-[16/9] w-[calc(100%+2rem)] max-w-none rounded-lg object-cover transition-opacity group-hover:opacity-85\"\n widths={[480, 720]}\n sizes=\"(min-width: 64rem) 22rem, (min-width: 48rem) 50vw, 100vw\"\n />\n <div class=\"flex flex-col gap-2\">\n <p class=\"text-muted-foreground text-sm font-medium\">\n {article.category}\n </p>\n <h3 class=\"text-foreground line-clamp-2 text-lg leading-snug font-semibold\">\n {article.title}\n </h3>\n <p class=\"text-muted-foreground line-clamp-2 text-sm leading-6\">\n {article.description}\n </p>\n </div>\n <div class=\"mt-auto flex items-center gap-3\">\n <Avatar>\n <AvatarImage\n src={article.author.image}\n alt={article.author.name}\n />\n <AvatarFallback>{article.author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{article.author.name}</p>\n <p class=\"text-muted-foreground text-xs\">\n {article.author.date}\n </p>\n </div>\n </div>\n </a>\n ))\n }\n </div>\n </SectionContainer>\n</Section>\n",
14
+ "content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = HTMLAttributes<\"section\"> & {\n badge?: string\n title: string\n description: string\n featured: {\n image: {\n src: ImageMetadata\n alt: string\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n }\n articles: {\n image: {\n src: ImageMetadata\n alt: string\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n }[]\n}\n\nconst {\n class: className,\n badge,\n title,\n description,\n featured,\n articles,\n ...props\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)} {...props}>\n <SectionContainer class=\"gap-8\">\n <div class=\"mx-auto max-w-2xl text-center\">\n {badge && <Badge variant=\"secondary\">{badge}</Badge>}\n <h2\n class={cn(\n \"text-3xl font-semibold tracking-tight text-balance sm:text-4xl\",\n badge && \"mt-4\"\n )}\n >\n {title}\n </h2>\n <p class=\"text-muted-foreground mt-2 text-base leading-7 text-balance\">\n {description}\n </p>\n </div>\n\n <a\n href={featured.href ?? \"#\"}\n class=\"group hover:bg-muted/50 focus-visible:ring-ring/50 grid gap-6 rounded-xl transition-colors focus-visible:ring-2 focus-visible:outline-none lg:grid-cols-2 lg:items-center lg:pr-4\"\n >\n <Image\n src={featured.image.src}\n alt={featured.image.alt}\n class=\"aspect-[4/3] rounded-lg object-cover transition-opacity group-hover:opacity-85\"\n widths={[640, 960, 1280]}\n sizes=\"(min-width: 64rem) 50vw, 100vw\"\n />\n <div class=\"flex flex-col gap-4\">\n <Badge variant=\"outline\" class=\"w-fit\">{featured.category}</Badge>\n <h3\n class=\"text-foreground text-2xl leading-tight font-semibold sm:text-3xl\"\n >\n {featured.title}\n </h3>\n <p class=\"text-muted-foreground text-base leading-7\">\n {featured.description}\n </p>\n <div class=\"flex items-center gap-3\">\n <Avatar>\n <AvatarImage\n src={featured.author.image}\n alt={featured.author.name}\n />\n <AvatarFallback>{featured.author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{featured.author.name}</p>\n <p class=\"text-muted-foreground text-xs\">{featured.author.date}</p>\n </div>\n </div>\n </div>\n </a>\n\n <div class=\"grid gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {\n articles.map((article) => (\n <a\n href={article.href ?? \"#\"}\n class=\"group hover:bg-muted/50 focus-visible:ring-ring/50 flex h-full flex-col gap-4 rounded-xl p-4 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n >\n <Image\n src={article.image.src}\n alt={article.image.alt}\n class=\"-mx-4 -mt-4 aspect-[16/9] w-[calc(100%+2rem)] max-w-none rounded-lg object-cover transition-opacity group-hover:opacity-85\"\n widths={[480, 720]}\n sizes=\"(min-width: 64rem) 22rem, (min-width: 48rem) 50vw, 100vw\"\n />\n <div class=\"flex flex-col gap-2\">\n <p class=\"text-muted-foreground text-sm font-medium\">\n {article.category}\n </p>\n <h3 class=\"text-foreground line-clamp-2 text-lg leading-snug font-semibold\">\n {article.title}\n </h3>\n <p class=\"text-muted-foreground line-clamp-2 text-sm leading-6\">\n {article.description}\n </p>\n </div>\n <div class=\"mt-auto flex items-center gap-3\">\n <Avatar>\n <AvatarImage\n src={article.author.image}\n alt={article.author.name}\n />\n <AvatarFallback>{article.author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{article.author.name}</p>\n <p class=\"text-muted-foreground text-xs\">\n {article.author.date}\n </p>\n </div>\n </div>\n </a>\n ))\n }\n </div>\n </SectionContainer>\n</Section>\n",
13
15
  "type": "registry:block"
14
16
  }
15
17
  ],
18
+ "docs": "https://ui.full.dev/blocks/articles/",
19
+ "categories": [
20
+ "articles"
21
+ ],
16
22
  "type": "registry:block"
17
23
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "articles-3",
4
+ "title": "Articles 3",
5
+ "description": "Collection and listing layouts for journals, magazines, and editorial feeds.",
4
6
  "registryDependencies": [
5
7
  "@fulldev/avatar",
6
8
  "@fulldev/badge",
@@ -9,9 +11,13 @@
9
11
  "files": [
10
12
  {
11
13
  "path": "src/components/blocks/articles-3.astro",
12
- "content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = {\n class?: string\n badge?: string\n title: string\n articles: {\n image: {\n src: ImageMetadata\n alt: string\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n }[]\n}\n\nconst { class: className, badge, title, articles } = Astro.props\n---\n\n<Section class={cn(\"\", className)}>\n <SectionContainer class=\"gap-8\">\n <div class=\"flex flex-wrap items-end justify-between gap-4\">\n <div class=\"flex flex-col gap-4\">\n {\n badge && (\n <Badge variant=\"secondary\" class=\"w-fit\">\n {badge}\n </Badge>\n )\n }\n <h2\n class=\"text-3xl font-semibold tracking-tight text-balance sm:text-4xl\"\n >\n {title}\n </h2>\n </div>\n </div>\n\n <div class=\"grid gap-6 md:grid-cols-2 lg:grid-cols-4\">\n {\n articles.map((article) => (\n <a\n href={article.href ?? \"#\"}\n class=\"group bg-muted/50 hover:bg-muted focus-visible:ring-ring/50 flex h-full flex-col gap-4 rounded-xl p-4 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n >\n <Image\n src={article.image.src}\n alt={article.image.alt}\n class=\"-mx-4 -mt-4 aspect-[16/9] w-[calc(100%+2rem)] max-w-none rounded-lg object-cover transition-opacity group-hover:opacity-85\"\n widths={[480, 720]}\n sizes=\"(min-width: 64rem) 18rem, (min-width: 48rem) 50vw, 100vw\"\n />\n <div class=\"flex flex-col gap-2\">\n <p class=\"text-muted-foreground text-sm font-medium\">\n {article.category}\n </p>\n <h3 class=\"text-foreground line-clamp-2 text-lg leading-snug font-semibold\">\n {article.title}\n </h3>\n <p class=\"text-muted-foreground line-clamp-2 text-sm leading-6\">\n {article.description}\n </p>\n </div>\n <div class=\"mt-auto flex items-center gap-3\">\n <Avatar>\n <AvatarImage\n src={article.author.image}\n alt={article.author.name}\n />\n <AvatarFallback>{article.author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{article.author.name}</p>\n <p class=\"text-muted-foreground text-xs\">\n {article.author.date}\n </p>\n </div>\n </div>\n </a>\n ))\n }\n </div>\n </SectionContainer>\n</Section>\n",
14
+ "content": "---\nimport type { ImageMetadata } from \"astro\"\nimport { Image } from \"astro:assets\"\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport {\n Section,\n SectionContainer,\n SectionTitle,\n} from \"@/components/ui/section\"\n\ntype Props = HTMLAttributes<\"section\"> & {\n badge?: string\n title: string\n articles: {\n image: {\n src: ImageMetadata\n alt: string\n }\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n }[]\n}\n\nconst { class: className, badge, title, articles, ...props } = Astro.props\n---\n\n<Section class={cn(\"\", className)} {...props}>\n <SectionContainer class=\"gap-8\">\n <div class=\"flex flex-wrap items-end justify-between gap-4\">\n <div class=\"flex flex-col gap-4\">\n {\n badge && (\n <Badge variant=\"secondary\" class=\"w-fit\">\n {badge}\n </Badge>\n )\n }\n <SectionTitle>\n {title}\n </SectionTitle>\n </div>\n </div>\n\n <div class=\"grid gap-6 md:grid-cols-2 lg:grid-cols-4\">\n {\n articles.map((article) => (\n <a\n href={article.href ?? \"#\"}\n class=\"group bg-muted/50 hover:bg-muted focus-visible:ring-ring/50 flex h-full flex-col gap-4 rounded-xl p-4 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n >\n <Image\n src={article.image.src}\n alt={article.image.alt}\n class=\"-mx-4 -mt-4 aspect-[16/9] w-[calc(100%+2rem)] max-w-none rounded-lg object-cover transition-opacity group-hover:opacity-85\"\n widths={[480, 720]}\n sizes=\"(min-width: 64rem) 18rem, (min-width: 48rem) 50vw, 100vw\"\n />\n <div class=\"flex flex-col gap-2\">\n <p class=\"text-muted-foreground text-sm font-medium\">\n {article.category}\n </p>\n <h3 class=\"text-foreground line-clamp-2 text-lg leading-snug font-semibold\">\n {article.title}\n </h3>\n <p class=\"text-muted-foreground line-clamp-2 text-sm leading-6\">\n {article.description}\n </p>\n </div>\n <div class=\"mt-auto flex items-center gap-3\">\n <Avatar>\n <AvatarImage\n src={article.author.image}\n alt={article.author.name}\n />\n <AvatarFallback>{article.author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{article.author.name}</p>\n <p class=\"text-muted-foreground text-xs\">\n {article.author.date}\n </p>\n </div>\n </div>\n </a>\n ))\n }\n </div>\n </SectionContainer>\n</Section>\n",
13
15
  "type": "registry:block"
14
16
  }
15
17
  ],
18
+ "docs": "https://ui.full.dev/blocks/articles/",
19
+ "categories": [
20
+ "articles"
21
+ ],
16
22
  "type": "registry:block"
17
23
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "articles-4",
4
+ "title": "Articles 4",
5
+ "description": "Collection and listing layouts for journals, magazines, and editorial feeds.",
4
6
  "registryDependencies": [
5
7
  "@fulldev/avatar",
6
8
  "@fulldev/badge",
@@ -9,9 +11,13 @@
9
11
  "files": [
10
12
  {
11
13
  "path": "src/components/blocks/articles-4.astro",
12
- "content": "---\nimport type { ImageMetadata } from \"astro\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = {\n class?: string\n badge?: string\n title: string\n description: string\n articles: {\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n }[]\n}\n\nconst { class: className, badge, title, description, articles } = Astro.props\n---\n\n<Section class={cn(\"\", className)}>\n <SectionContainer class=\"gap-8\">\n <div class=\"mx-auto max-w-2xl text-center\">\n {badge && <Badge variant=\"secondary\">{badge}</Badge>}\n <h2\n class={cn(\n \"text-3xl font-semibold tracking-tight text-balance sm:text-4xl\",\n badge && \"mt-4\"\n )}\n >\n {title}\n </h2>\n <p class=\"text-muted-foreground mt-2 text-base leading-7 text-balance\">\n {description}\n </p>\n </div>\n\n <div class=\"grid gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {\n articles.map((article) => (\n <a\n href={article.href ?? \"#\"}\n class=\"group hover:bg-muted/50 focus-visible:ring-ring/50 flex h-full flex-col gap-4 rounded-xl border p-6 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n >\n <div class=\"flex flex-col gap-2\">\n <p class=\"text-muted-foreground text-sm font-medium\">\n {article.category}\n </p>\n <h3 class=\"text-foreground line-clamp-2 text-xl leading-snug font-semibold\">\n {article.title}\n </h3>\n <p class=\"text-muted-foreground line-clamp-2 text-sm leading-6\">\n {article.description}\n </p>\n </div>\n <div class=\"mt-auto flex items-center gap-3\">\n <Avatar>\n <AvatarImage\n src={article.author.image}\n alt={article.author.name}\n />\n <AvatarFallback>{article.author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{article.author.name}</p>\n <p class=\"text-muted-foreground text-xs\">\n {article.author.date}\n </p>\n </div>\n </div>\n </a>\n ))\n }\n </div>\n </SectionContainer>\n</Section>\n",
14
+ "content": "---\nimport type { ImageMetadata } from \"astro\"\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Section, SectionContainer } from \"@/components/ui/section\"\n\ntype Props = HTMLAttributes<\"section\"> & {\n badge?: string\n title: string\n description: string\n articles: {\n category: string\n title: string\n description: string\n href?: string\n author: {\n image?: ImageMetadata\n initials: string\n name: string\n date: string\n }\n }[]\n}\n\nconst {\n class: className,\n badge,\n title,\n description,\n articles,\n ...props\n} = Astro.props\n---\n\n<Section class={cn(\"\", className)} {...props}>\n <SectionContainer class=\"gap-8\">\n <div class=\"mx-auto max-w-2xl text-center\">\n {badge && <Badge variant=\"secondary\">{badge}</Badge>}\n <h2\n class={cn(\n \"text-3xl font-semibold tracking-tight text-balance sm:text-4xl\",\n badge && \"mt-4\"\n )}\n >\n {title}\n </h2>\n <p class=\"text-muted-foreground mt-2 text-base leading-7 text-balance\">\n {description}\n </p>\n </div>\n\n <div class=\"grid gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {\n articles.map((article) => (\n <a\n href={article.href ?? \"#\"}\n class=\"group hover:bg-muted/50 focus-visible:ring-ring/50 flex h-full flex-col gap-4 rounded-xl border p-6 transition-colors focus-visible:ring-2 focus-visible:outline-none\"\n >\n <div class=\"flex flex-col gap-2\">\n <p class=\"text-muted-foreground text-sm font-medium\">\n {article.category}\n </p>\n <h3 class=\"text-foreground line-clamp-2 text-xl leading-snug font-semibold\">\n {article.title}\n </h3>\n <p class=\"text-muted-foreground line-clamp-2 text-sm leading-6\">\n {article.description}\n </p>\n </div>\n <div class=\"mt-auto flex items-center gap-3\">\n <Avatar>\n <AvatarImage\n src={article.author.image}\n alt={article.author.name}\n />\n <AvatarFallback>{article.author.initials}</AvatarFallback>\n </Avatar>\n <div class=\"flex flex-col\">\n <p class=\"text-sm font-medium\">{article.author.name}</p>\n <p class=\"text-muted-foreground text-xs\">\n {article.author.date}\n </p>\n </div>\n </div>\n </a>\n ))\n }\n </div>\n </SectionContainer>\n</Section>\n",
13
15
  "type": "registry:block"
14
16
  }
15
17
  ],
18
+ "docs": "https://ui.full.dev/blocks/articles/",
19
+ "categories": [
20
+ "articles"
21
+ ],
16
22
  "type": "registry:block"
17
23
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "avatar",
4
+ "title": "Avatar",
5
+ "description": "An image element with a fallback for representing the user.",
4
6
  "files": [
5
7
  {
6
8
  "path": "src/components/ui/avatar/avatar.astro",
@@ -23,5 +25,9 @@
23
25
  "type": "registry:ui"
24
26
  }
25
27
  ],
28
+ "docs": "https://ui.full.dev/components/avatar/",
29
+ "categories": [
30
+ "ui"
31
+ ],
26
32
  "type": "registry:ui"
27
33
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "badge",
4
+ "title": "Badge",
5
+ "description": "Displays a badge or a component that looks like a badge.",
4
6
  "files": [
5
7
  {
6
8
  "path": "src/components/ui/badge/badge-variants.ts",
@@ -18,5 +20,9 @@
18
20
  "type": "registry:ui"
19
21
  }
20
22
  ],
23
+ "docs": "https://ui.full.dev/components/badge/",
24
+ "categories": [
25
+ "ui"
26
+ ],
21
27
  "type": "registry:ui"
22
28
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "banner-1",
4
+ "title": "Banner 1",
5
+ "description": "Announcement and promo bars that sit above or inside page content.",
4
6
  "dependencies": [
5
7
  "@lucide/astro"
6
8
  ],
@@ -10,9 +12,13 @@
10
12
  "files": [
11
13
  {
12
14
  "path": "src/components/blocks/banner-1.astro",
13
- "content": "---\nimport ArrowRightIcon from \"@lucide/astro/icons/arrow-right\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Banner, BannerContainer } from \"@/components/ui/banner\"\n\ntype Props = {\n class?: string\n title: string\n description: string\n link?: {\n label: string\n href: string\n }\n}\n\nconst { class: className, title, description, link } = Astro.props\n---\n\n<Banner\n storageKey=\"banner-1\"\n class={cn(\"dark bg-background text-foreground\", className)}\n>\n <BannerContainer class=\"flex-row items-center gap-x-4 gap-y-1\">\n <p class=\"text-sm leading-relaxed\">\n <span class=\"font-semibold\">{title}</span>\n <span class=\"mx-1.5 hidden opacity-50 sm:inline\">&mdash;</span>\n <span class=\"opacity-80\">{description}</span>\n </p>\n {\n link && (\n <a\n href={link.href}\n class=\"group/link inline-flex shrink-0 items-center gap-1 text-sm font-medium underline underline-offset-4 transition-opacity hover:opacity-80\"\n >\n {link.label}\n <ArrowRightIcon class=\"size-3.5 transition-transform group-hover/link:translate-x-0.5\" />\n </a>\n )\n }\n </BannerContainer>\n</Banner>\n",
15
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport ArrowRightIcon from \"@lucide/astro/icons/arrow-right\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Banner, BannerContainer } from \"@/components/ui/banner\"\n\ntype Props = HTMLAttributes<\"aside\"> & {\n title: string\n description: string\n link?: {\n label: string\n href: string\n }\n}\n\nconst { class: className, title, description, link, ...props } = Astro.props\n---\n\n<Banner\n storageKey=\"banner-1\"\n class={cn(\"dark bg-background text-foreground\", className)}\n {...props}\n>\n <BannerContainer class=\"flex-row items-center gap-x-4 gap-y-1\">\n <p class=\"text-sm leading-relaxed\">\n <span class=\"font-semibold\">{title}</span>\n <span class=\"mx-1.5 hidden opacity-50 sm:inline\">&mdash;</span>\n <span class=\"opacity-80\">{description}</span>\n </p>\n {\n link && (\n <a\n href={link.href}\n class=\"group/link inline-flex shrink-0 items-center gap-1 text-sm font-medium underline underline-offset-4 transition-opacity hover:opacity-80\"\n >\n {link.label}\n <ArrowRightIcon class=\"size-3.5 transition-transform group-hover/link:translate-x-0.5\" />\n </a>\n )\n }\n </BannerContainer>\n</Banner>\n",
14
16
  "type": "registry:block"
15
17
  }
16
18
  ],
19
+ "docs": "https://ui.full.dev/blocks/banner/",
20
+ "categories": [
21
+ "banner"
22
+ ],
17
23
  "type": "registry:block"
18
24
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "banner-2",
4
+ "title": "Banner 2",
5
+ "description": "Announcement and promo bars that sit above or inside page content.",
4
6
  "registryDependencies": [
5
7
  "@fulldev/banner",
6
8
  "@fulldev/button"
@@ -8,9 +10,13 @@
8
10
  "files": [
9
11
  {
10
12
  "path": "src/components/blocks/banner-2.astro",
11
- "content": "---\nimport { cn } from \"@/lib/utils\"\nimport { Banner, BannerContainer } from \"@/components/ui/banner\"\nimport { Button } from \"@/components/ui/button\"\n\ntype Props = {\n class?: string\n title: string\n description: string\n buttons?: {\n label: string\n href: string\n variant?: \"default\" | \"outline\" | \"secondary\" | \"ghost\"\n }[]\n}\n\nconst { class: className, title, description, buttons } = Astro.props\n---\n\n<Banner variant=\"floating\" storageKey=\"banner-2\" class={cn(\"\", className)}>\n <BannerContainer class=\"gap-4 py-1\" showClose={false}>\n <div\n class=\"flex flex-1 flex-col gap-0.5 @5xl:flex-row @5xl:items-center @5xl:gap-x-4\"\n >\n <p class=\"text-sm font-semibold\">{title}</p>\n <p class=\"text-muted-foreground text-sm\">{description}</p>\n </div>\n {\n buttons?.length && (\n <div class=\"flex shrink-0 items-center gap-2\">\n {buttons.map(({ href, label, ...button }, index) => (\n <Button\n as=\"a\"\n href={href}\n size=\"sm\"\n variant={button.variant ?? (index === 0 ? \"default\" : \"outline\")}\n {...button}\n >\n {label}\n </Button>\n ))}\n </div>\n )\n }\n </BannerContainer>\n</Banner>\n",
13
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Banner, BannerContainer } from \"@/components/ui/banner\"\nimport { Button } from \"@/components/ui/button\"\n\ntype Props = HTMLAttributes<\"aside\"> & {\n title: string\n description: string\n buttons?: {\n label: string\n href: string\n variant?: \"default\" | \"outline\" | \"secondary\" | \"ghost\"\n }[]\n}\n\nconst { class: className, title, description, buttons, ...props } = Astro.props\n---\n\n<Banner\n variant=\"floating\"\n storageKey=\"banner-2\"\n class={cn(\"\", className)}\n {...props}\n>\n <BannerContainer class=\"gap-4 py-1\" showClose={false}>\n <div\n class=\"flex flex-1 flex-col gap-0.5 @5xl:flex-row @5xl:items-center @5xl:gap-x-4\"\n >\n <p class=\"text-sm font-semibold\">{title}</p>\n <p class=\"text-muted-foreground text-sm\">{description}</p>\n </div>\n {\n buttons?.length && (\n <div class=\"flex shrink-0 items-center gap-2\">\n {buttons.map(({ href, label, ...button }, index) => (\n <Button\n as=\"a\"\n href={href}\n size=\"sm\"\n variant={button.variant ?? (index === 0 ? \"default\" : \"outline\")}\n {...button}\n >\n {label}\n </Button>\n ))}\n </div>\n )\n }\n </BannerContainer>\n</Banner>\n",
12
14
  "type": "registry:block"
13
15
  }
14
16
  ],
17
+ "docs": "https://ui.full.dev/blocks/banner/",
18
+ "categories": [
19
+ "banner"
20
+ ],
15
21
  "type": "registry:block"
16
22
  }
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "banner",
4
+ "title": "Banner",
5
+ "description": "A full-width container for important messages or announcements.",
4
6
  "dependencies": [
5
7
  "@lucide/astro"
6
8
  ],
@@ -25,5 +27,9 @@
25
27
  "type": "registry:ui"
26
28
  }
27
29
  ],
30
+ "docs": "https://ui.full.dev/components/banner/",
31
+ "categories": [
32
+ "ui"
33
+ ],
28
34
  "type": "registry:ui"
29
35
  }
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "blocks-1",
4
+ "title": "Blocks 1",
4
5
  "dependencies": [
5
6
  "@lucide/astro",
6
7
  "simple-icons-astro"
@@ -14,9 +15,13 @@
14
15
  "files": [
15
16
  {
16
17
  "path": "src/components/blocks/blocks-1.astro",
17
- "content": "---\nimport ArrowLeft from \"@lucide/astro/icons/arrow-left\"\nimport ArrowRight from \"@lucide/astro/icons/arrow-right\"\nimport Check from \"@lucide/astro/icons/check\"\nimport ChevronDown from \"@lucide/astro/icons/chevron-down\"\nimport Copy from \"@lucide/astro/icons/copy\"\nimport ExternalLink from \"@lucide/astro/icons/external-link\"\nimport Claude from \"simple-icons-astro/Claude\"\nimport Cursor from \"simple-icons-astro/Cursor\"\nimport Markdown from \"simple-icons-astro/Markdown\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { buttonVariants } from \"@/components/ui/button/button-variants\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { SectionContainer } from \"@/components/ui/section\"\nimport {\n Typography,\n TypographyH1,\n TypographyLead,\n} from \"@/components/ui/typography\"\n\ntype Props = {\n class?: string\n title: string\n description?: string\n copyButton?: {\n id: string\n source: string\n }\n markdownUrl?: string\n previousPage?: {\n href: string\n title: string\n }\n nextPage?: {\n href: string\n title: string\n }\n labels: {\n copyMarkdown: string\n openIn: string\n openInMarkdown: string\n openInChatGPT: string\n openInClaude: string\n openInCursor: string\n pagination: {\n previous: string\n next: string\n ariaLabel: string\n }\n }\n}\n\nconst {\n class: className,\n title,\n description,\n copyButton,\n markdownUrl,\n previousPage,\n nextPage,\n labels,\n} = Astro.props\nconst showCopyButton = Boolean(copyButton)\nconst showOpenButton = Boolean(markdownUrl)\nconst showPagination = Boolean(previousPage || nextPage)\nconst assistantPrompt = markdownUrl\n ? `Read ${markdownUrl}, I want to ask questions about it.`\n : \"\"\nconst openLinks = markdownUrl\n ? [\n {\n label: labels.openInMarkdown,\n href: markdownUrl,\n icon: \"markdown\",\n },\n {\n label: labels.openInChatGPT,\n href: `https://chatgpt.com/?hints=search&q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"chatgpt\",\n },\n {\n label: labels.openInClaude,\n href: `https://claude.ai/new?q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"claude\",\n },\n {\n label: labels.openInCursor,\n href: `https://cursor.com/link/prompt?text=${encodeURIComponent(assistantPrompt)}`,\n icon: \"cursor\",\n },\n ]\n : []\n---\n\n<SectionContainer\n data-slot=\"blocks-page\"\n class={cn(\"gap-10 pt-10 pb-10 sm:pt-12 sm:pb-12\", className)}\n>\n <div class=\"mx-auto flex w-full max-w-[84rem] flex-col gap-10\">\n <header\n class=\"flex flex-col gap-4 border-b pb-8 sm:flex-row sm:items-start sm:justify-between\"\n >\n <div class=\"flex max-w-3xl min-w-0 flex-1 flex-col gap-2\">\n <TypographyH1\n class=\"text-foreground text-left text-3xl tracking-tight sm:text-4xl\"\n >\n {title}\n </TypographyH1>\n {\n description && (\n <TypographyLead class=\"max-w-2xl text-base leading-7\">\n {description}\n </TypographyLead>\n )\n }\n </div>\n <div class=\"flex shrink-0 items-center gap-2 self-start\">\n {\n showCopyButton && (\n <Button\n id={copyButton?.id}\n type=\"button\"\n variant=\"outline\"\n size=\"xs\"\n data-source={copyButton?.source}\n aria-label={labels.copyMarkdown}\n >\n <Copy class=\"blocks-copy-icon size-3.5\" />\n <Check class=\"blocks-check-icon hidden size-3.5\" />\n <span>{labels.copyMarkdown}</span>\n </Button>\n )\n }\n {\n showOpenButton && (\n <DropdownMenu>\n <DropdownMenuTrigger\n class={buttonVariants({ variant: \"outline\", size: \"xs\" })}\n >\n <span>{labels.openIn}</span>\n <ChevronDown class=\"size-3.5 opacity-70\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" sideOffset={6} class=\"w-56\">\n {openLinks.map((link) => (\n <a\n href={link.href}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n class=\"hover:bg-accent hover:text-accent-foreground flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm transition-colors outline-none\"\n >\n {link.icon === \"markdown\" && <Markdown class=\"size-4\" />}\n {link.icon === \"chatgpt\" && (\n <svg\n role=\"img\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"size-4\"\n aria-hidden=\"true\"\n >\n <path d=\"M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.182a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .511 4.91 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.989 5.989 0 0 0 3.998-2.9 6.056 6.056 0 0 0-.748-7.073ZM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.142-.081 4.778-2.758a.795.795 0 0 0 .393-.681v-6.737l2.02 1.169a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.495 4.494Zm-9.66-4.125a4.471 4.471 0 0 1-.535-3.014l.142.085 4.783 2.758a.771.771 0 0 0 .781 0l5.843-3.368v2.332a.08.08 0 0 1-.034.062L9.74 19.95a4.499 4.499 0 0 1-6.14-1.646ZM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.677l5.814 3.354-2.02 1.169a.076.076 0 0 1-.071 0l-4.83-2.787A4.504 4.504 0 0 1 2.34 7.872Zm16.596 3.856-5.833-3.388L15.12 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.104v-5.677a.79.79 0 0 0-.407-.667Zm2.011-3.024-.142-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.499 4.499 0 0 1 6.68 4.66ZM8.307 12.863l-2.02-1.164a.08.08 0 0 1-.038-.057V6.074a4.499 4.499 0 0 1 7.376-3.453l-.142.08-4.778 2.758a.795.795 0 0 0-.393.681Zm1.097-2.365 2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5Z\" />\n </svg>\n )}\n {link.icon === \"claude\" && <Claude class=\"size-4\" />}\n {link.icon === \"cursor\" && <Cursor class=\"size-4\" />}\n <span>{link.label}</span>\n <ExternalLink class=\"text-muted-foreground ml-auto size-3.5\" />\n </a>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n }\n </div>\n </header>\n\n <Typography as=\"article\" class=\"w-full max-w-none\">\n <slot />\n </Typography>\n\n {\n showPagination && (\n <nav\n class=\"flex items-center justify-between gap-3\"\n aria-label={labels.pagination.ariaLabel}\n >\n {previousPage ? (\n <Button\n as=\"a\"\n href={previousPage.href}\n variant=\"outline\"\n class=\"h-auto min-w-0 items-center justify-start gap-2 px-3 py-2 whitespace-normal\"\n >\n <ArrowLeft class=\"size-4\" />\n <span class=\"truncate text-sm font-medium\">\n {previousPage.title}\n </span>\n </Button>\n ) : (\n <div aria-hidden=\"true\" />\n )}\n\n {nextPage ? (\n <Button\n as=\"a\"\n href={nextPage.href}\n variant=\"outline\"\n class=\"h-auto min-w-0 items-center justify-end gap-2 px-3 py-2 text-right whitespace-normal\"\n >\n <span class=\"truncate text-sm font-medium\">{nextPage.title}</span>\n <ArrowRight class=\"size-4\" />\n </Button>\n ) : (\n <div aria-hidden=\"true\" />\n )}\n </nav>\n )\n }\n </div>\n</SectionContainer>\n\n<script is:inline define:vars={{ copyButtonId: copyButton?.id }}>\n const button = copyButtonId ? document.getElementById(copyButtonId) : null\n\n if (button instanceof HTMLButtonElement) {\n button.addEventListener(\"click\", async () => {\n const source = button.dataset.source\n\n if (!source) return\n\n try {\n await navigator.clipboard.writeText(source)\n button.querySelector(\".blocks-copy-icon\")?.classList.add(\"hidden\")\n button.querySelector(\".blocks-check-icon\")?.classList.remove(\"hidden\")\n\n window.setTimeout(() => {\n button.querySelector(\".blocks-copy-icon\")?.classList.remove(\"hidden\")\n button.querySelector(\".blocks-check-icon\")?.classList.add(\"hidden\")\n }, 1200)\n } catch {\n // Ignore clipboard failures; the button remains available for retry.\n }\n })\n }\n</script>\n",
18
+ "content": "---\nimport ArrowLeft from \"@lucide/astro/icons/arrow-left\"\nimport ArrowRight from \"@lucide/astro/icons/arrow-right\"\nimport Check from \"@lucide/astro/icons/check\"\nimport ChevronDown from \"@lucide/astro/icons/chevron-down\"\nimport Copy from \"@lucide/astro/icons/copy\"\nimport ExternalLink from \"@lucide/astro/icons/external-link\"\nimport Claude from \"simple-icons-astro/Claude\"\nimport Cursor from \"simple-icons-astro/Cursor\"\nimport Markdown from \"simple-icons-astro/Markdown\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { buttonVariants } from \"@/components/ui/button/button-variants\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { SectionContainer } from \"@/components/ui/section\"\nimport {\n Typography,\n TypographyH1,\n TypographyLead,\n} from \"@/components/ui/typography\"\n\ntype Props = {\n class?: string\n title: string\n description?: string\n copyButton?: {\n id: string\n source: string\n }\n markdownUrl?: string\n previousPage?: {\n href: string\n title: string\n }\n nextPage?: {\n href: string\n title: string\n }\n labels: {\n copyMarkdown: string\n openIn: string\n openInMarkdown: string\n openInChatGPT: string\n openInClaude: string\n openInCursor: string\n pagination: {\n previous: string\n next: string\n ariaLabel: string\n }\n }\n}\n\nconst {\n class: className,\n title,\n description,\n copyButton,\n markdownUrl,\n previousPage,\n nextPage,\n labels,\n} = Astro.props\nconst showCopyButton = Boolean(copyButton)\nconst showOpenButton = Boolean(markdownUrl)\nconst showPagination = Boolean(previousPage || nextPage)\nconst assistantPrompt = markdownUrl\n ? `Read ${new URL(markdownUrl, Astro.site ?? Astro.url.origin).href}, I want to ask questions about it.`\n : \"\"\nconst openLinks = markdownUrl\n ? [\n {\n label: labels.openInMarkdown,\n href: markdownUrl,\n icon: \"markdown\",\n },\n {\n label: labels.openInChatGPT,\n href: `https://chatgpt.com/?hints=search&q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"chatgpt\",\n },\n {\n label: labels.openInClaude,\n href: `https://claude.ai/new?q=${encodeURIComponent(assistantPrompt)}`,\n icon: \"claude\",\n },\n {\n label: labels.openInCursor,\n href: `https://cursor.com/link/prompt?text=${encodeURIComponent(assistantPrompt)}`,\n icon: \"cursor\",\n },\n ]\n : []\n---\n\n<SectionContainer\n data-slot=\"blocks-page\"\n class={cn(\"gap-10 pt-10 pb-10 sm:pt-12 sm:pb-12\", className)}\n>\n <div class=\"mx-auto flex w-full max-w-[84rem] flex-col gap-10\">\n <header\n class=\"flex flex-col gap-4 border-b pb-8 sm:flex-row sm:items-start sm:justify-between\"\n >\n <div class=\"flex max-w-3xl min-w-0 flex-1 flex-col gap-2\">\n <TypographyH1\n class=\"text-foreground text-left text-3xl tracking-tight sm:text-4xl\"\n >\n {title}\n </TypographyH1>\n {\n description && (\n <TypographyLead class=\"max-w-2xl text-base leading-7\">\n {description}\n </TypographyLead>\n )\n }\n </div>\n <div class=\"flex shrink-0 items-center gap-2 self-start\">\n {\n showCopyButton && (\n <Button\n id={copyButton?.id}\n type=\"button\"\n variant=\"outline\"\n size=\"xs\"\n data-source={copyButton?.source}\n aria-label={labels.copyMarkdown}\n >\n <Copy class=\"blocks-copy-icon size-3.5\" />\n <Check class=\"blocks-check-icon hidden size-3.5\" />\n <span>{labels.copyMarkdown}</span>\n </Button>\n )\n }\n {\n showOpenButton && (\n <DropdownMenu>\n <DropdownMenuTrigger\n class={buttonVariants({ variant: \"outline\", size: \"xs\" })}\n >\n <span>{labels.openIn}</span>\n <ChevronDown class=\"size-3.5 opacity-70\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" sideOffset={6} class=\"w-56\">\n {openLinks.map((link) => (\n <a\n href={link.href}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n class=\"hover:bg-accent hover:text-accent-foreground flex items-center gap-2 rounded-sm px-2 py-1.5 text-sm transition-colors outline-none\"\n >\n {link.icon === \"markdown\" && <Markdown class=\"size-4\" />}\n {link.icon === \"chatgpt\" && (\n <svg\n role=\"img\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n class=\"size-4\"\n aria-hidden=\"true\"\n >\n <path d=\"M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.182a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .511 4.91 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.989 5.989 0 0 0 3.998-2.9 6.056 6.056 0 0 0-.748-7.073ZM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.142-.081 4.778-2.758a.795.795 0 0 0 .393-.681v-6.737l2.02 1.169a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.495 4.494Zm-9.66-4.125a4.471 4.471 0 0 1-.535-3.014l.142.085 4.783 2.758a.771.771 0 0 0 .781 0l5.843-3.368v2.332a.08.08 0 0 1-.034.062L9.74 19.95a4.499 4.499 0 0 1-6.14-1.646ZM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.677l5.814 3.354-2.02 1.169a.076.076 0 0 1-.071 0l-4.83-2.787A4.504 4.504 0 0 1 2.34 7.872Zm16.596 3.856-5.833-3.388L15.12 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.104v-5.677a.79.79 0 0 0-.407-.667Zm2.011-3.024-.142-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.499 4.499 0 0 1 6.68 4.66ZM8.307 12.863l-2.02-1.164a.08.08 0 0 1-.038-.057V6.074a4.499 4.499 0 0 1 7.376-3.453l-.142.08-4.778 2.758a.795.795 0 0 0-.393.681Zm1.097-2.365 2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5Z\" />\n </svg>\n )}\n {link.icon === \"claude\" && <Claude class=\"size-4\" />}\n {link.icon === \"cursor\" && <Cursor class=\"size-4\" />}\n <span>{link.label}</span>\n <ExternalLink class=\"text-muted-foreground ml-auto size-3.5\" />\n </a>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n }\n </div>\n </header>\n\n <Typography as=\"article\" class=\"w-full max-w-none\">\n <slot />\n </Typography>\n\n {\n showPagination && (\n <nav\n class=\"flex items-center justify-between gap-3\"\n aria-label={labels.pagination.ariaLabel}\n >\n {previousPage ? (\n <Button\n as=\"a\"\n href={previousPage.href}\n variant=\"outline\"\n class=\"h-auto min-w-0 items-center justify-start gap-2 px-3 py-2 whitespace-normal\"\n >\n <ArrowLeft class=\"size-4\" />\n <span class=\"truncate text-sm font-medium\">\n {previousPage.title}\n </span>\n </Button>\n ) : (\n <div aria-hidden=\"true\" />\n )}\n\n {nextPage ? (\n <Button\n as=\"a\"\n href={nextPage.href}\n variant=\"outline\"\n class=\"h-auto min-w-0 items-center justify-end gap-2 px-3 py-2 text-right whitespace-normal\"\n >\n <span class=\"truncate text-sm font-medium\">{nextPage.title}</span>\n <ArrowRight class=\"size-4\" />\n </Button>\n ) : (\n <div aria-hidden=\"true\" />\n )}\n </nav>\n )\n }\n </div>\n</SectionContainer>\n\n<script is:inline define:vars={{ copyButtonId: copyButton?.id }}>\n const button = copyButtonId ? document.getElementById(copyButtonId) : null\n\n if (button instanceof HTMLButtonElement) {\n button.addEventListener(\"click\", async () => {\n const source = button.dataset.source\n\n if (!source) return\n\n try {\n await navigator.clipboard.writeText(source)\n button.querySelector(\".blocks-copy-icon\")?.classList.add(\"hidden\")\n button.querySelector(\".blocks-check-icon\")?.classList.remove(\"hidden\")\n\n window.setTimeout(() => {\n button.querySelector(\".blocks-copy-icon\")?.classList.remove(\"hidden\")\n button.querySelector(\".blocks-check-icon\")?.classList.add(\"hidden\")\n }, 1200)\n } catch {\n // Ignore clipboard failures; the button remains available for retry.\n }\n })\n }\n</script>\n",
18
19
  "type": "registry:block"
19
20
  }
20
21
  ],
22
+ "docs": "https://ui.full.dev/blocks/",
23
+ "categories": [
24
+ "blocks"
25
+ ],
21
26
  "type": "registry:block"
22
27
  }