fulldev-ui 0.11.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/package.json +29 -21
  3. package/public/r/accordion.json +2 -2
  4. package/public/r/alert-dialog.json +2 -2
  5. package/public/r/aspect-ratio.json +23 -0
  6. package/public/r/attachment.json +66 -0
  7. package/public/r/banner.json +0 -4
  8. package/public/r/blocks-1.json +1 -1
  9. package/public/r/button-group.json +41 -0
  10. package/public/r/button.json +1 -1
  11. package/public/r/carousel.json +8 -8
  12. package/public/r/collapsible.json +2 -2
  13. package/public/r/combobox.json +6 -5
  14. package/public/r/command.json +5 -4
  15. package/public/r/components.json +8 -0
  16. package/public/r/dialog.json +2 -2
  17. package/public/r/doc-1.json +1 -1
  18. package/public/r/drawer.json +109 -0
  19. package/public/r/dropdown-menu.json +4 -4
  20. package/public/r/hover-card.json +4 -4
  21. package/public/r/init.json +1 -1
  22. package/public/r/input-group.json +0 -1
  23. package/public/r/layout.json +3 -0
  24. package/public/r/navigation-menu.json +3 -3
  25. package/public/r/pagination.json +59 -0
  26. package/public/r/popover.json +3 -3
  27. package/public/r/radio-group.json +2 -2
  28. package/public/r/registry.json +418 -28
  29. package/public/r/resizable.json +36 -0
  30. package/public/r/reviews-3.json +1 -1
  31. package/public/r/select.json +3 -3
  32. package/public/r/sheet.json +2 -2
  33. package/public/r/sidebar-1.json +1 -1
  34. package/public/r/sidebar.json +1 -1
  35. package/public/r/slider.json +2 -2
  36. package/public/r/switch.json +2 -2
  37. package/public/r/tabs.json +4 -4
  38. package/public/r/toast.json +80 -0
  39. package/public/r/toggle-group.json +34 -0
  40. package/public/r/toggle.json +2 -2
  41. package/public/r/tooltip.json +3 -3
  42. package/public/r/typography.json +21 -16
  43. package/registry/init/global.css +2 -0
  44. package/registry.json +384 -23
  45. package/src/components/blocks/blocks-1.astro +23 -23
  46. package/src/components/blocks/doc-1.astro +116 -26
  47. package/src/components/blocks/reviews-3.astro +1 -1
  48. package/src/components/blocks/sidebar-1.astro +46 -44
  49. package/src/components/ui/accordion/accordion.astro +8 -2
  50. package/src/components/ui/alert-dialog/alert-dialog.astro +8 -2
  51. package/src/components/ui/aspect-ratio/aspect-ratio.astro +25 -0
  52. package/src/components/ui/aspect-ratio/index.ts +1 -0
  53. package/src/components/ui/attachment/attachment-action.astro +20 -0
  54. package/src/components/ui/attachment/attachment-actions.astro +20 -0
  55. package/src/components/ui/attachment/attachment-content.astro +20 -0
  56. package/src/components/ui/attachment/attachment-description.astro +20 -0
  57. package/src/components/ui/attachment/attachment-group.astro +20 -0
  58. package/src/components/ui/attachment/attachment-media.astro +36 -0
  59. package/src/components/ui/attachment/attachment-title.astro +20 -0
  60. package/src/components/ui/attachment/attachment-trigger.astro +24 -0
  61. package/src/components/ui/attachment/attachment.astro +52 -0
  62. package/src/components/ui/attachment/index.ts +9 -0
  63. package/src/components/ui/button/button.astro +4 -1
  64. package/src/components/ui/button-group/button-group-separator.astro +29 -0
  65. package/src/components/ui/button-group/button-group-text.astro +20 -0
  66. package/src/components/ui/button-group/button-group-variants.ts +20 -0
  67. package/src/components/ui/button-group/button-group.astro +30 -0
  68. package/src/components/ui/button-group/index.ts +7 -0
  69. package/src/components/ui/carousel/carousel-content.astro +11 -13
  70. package/src/components/ui/carousel/carousel-item.astro +2 -5
  71. package/src/components/ui/carousel/carousel-next.astro +0 -3
  72. package/src/components/ui/carousel/carousel-previous.astro +0 -3
  73. package/src/components/ui/carousel/carousel.astro +19 -219
  74. package/src/components/ui/carousel/index.ts +1 -5
  75. package/src/components/ui/collapsible/collapsible.astro +8 -2
  76. package/src/components/ui/combobox/combobox-content.astro +1 -1
  77. package/src/components/ui/combobox/combobox-input.astro +11 -4
  78. package/src/components/ui/combobox/combobox-trigger.astro +7 -7
  79. package/src/components/ui/combobox/combobox.astro +9 -17
  80. package/src/components/ui/command/command-dialog.astro +1 -0
  81. package/src/components/ui/command/command.astro +40 -25
  82. package/src/components/ui/dialog/dialog.astro +8 -2
  83. package/src/components/ui/drawer/drawer-close.astro +13 -0
  84. package/src/components/ui/drawer/drawer-content.astro +43 -0
  85. package/src/components/ui/drawer/drawer-description.astro +17 -0
  86. package/src/components/ui/drawer/drawer-footer.astro +17 -0
  87. package/src/components/ui/drawer/drawer-header.astro +17 -0
  88. package/src/components/ui/drawer/drawer-indent-background.astro +11 -0
  89. package/src/components/ui/drawer/drawer-indent.astro +11 -0
  90. package/src/components/ui/drawer/drawer-overlay.astro +21 -0
  91. package/src/components/ui/drawer/drawer-popup.astro +36 -0
  92. package/src/components/ui/drawer/drawer-portal.astro +27 -0
  93. package/src/components/ui/drawer/drawer-provider.astro +11 -0
  94. package/src/components/ui/drawer/drawer-swipe-handle.astro +20 -0
  95. package/src/components/ui/drawer/drawer-title.astro +17 -0
  96. package/src/components/ui/drawer/drawer-trigger.astro +21 -0
  97. package/src/components/ui/drawer/drawer-viewport.astro +21 -0
  98. package/src/components/ui/drawer/drawer-virtual-keyboard-provider.astro +11 -0
  99. package/src/components/ui/drawer/drawer.astro +60 -0
  100. package/src/components/ui/drawer/index.ts +28 -0
  101. package/src/components/ui/dropdown-menu/dropdown-menu-content.astro +1 -1
  102. package/src/components/ui/dropdown-menu/dropdown-menu-item.astro +40 -9
  103. package/src/components/ui/dropdown-menu/dropdown-menu.astro +8 -2
  104. package/src/components/ui/hover-card/hover-card-content.astro +1 -1
  105. package/src/components/ui/hover-card/hover-card.astro +15 -4
  106. package/src/components/ui/navigation-menu/navigation-menu-positioner.astro +1 -1
  107. package/src/components/ui/navigation-menu/navigation-menu.astro +13 -4
  108. package/src/components/ui/pagination/index.ts +7 -0
  109. package/src/components/ui/pagination/pagination-content.astro +17 -0
  110. package/src/components/ui/pagination/pagination-ellipsis.astro +22 -0
  111. package/src/components/ui/pagination/pagination-item.astro +11 -0
  112. package/src/components/ui/pagination/pagination-link.astro +41 -0
  113. package/src/components/ui/pagination/pagination-next.astro +27 -0
  114. package/src/components/ui/pagination/pagination-previous.astro +27 -0
  115. package/src/components/ui/pagination/pagination.astro +19 -0
  116. package/src/components/ui/popover/popover-content.astro +2 -1
  117. package/src/components/ui/popover/popover.astro +9 -2
  118. package/src/components/ui/radio-group/radio-group.astro +8 -2
  119. package/src/components/ui/resizable/index.ts +4 -0
  120. package/src/components/ui/resizable/resizable-handle.astro +32 -0
  121. package/src/components/ui/resizable/resizable-panel.astro +36 -0
  122. package/src/components/ui/resizable/resizable.astro +43 -0
  123. package/src/components/ui/select/select-content.astro +2 -2
  124. package/src/components/ui/select/select.astro +11 -7
  125. package/src/components/ui/sheet/sheet.astro +8 -2
  126. package/src/components/ui/slider/slider.astro +9 -3
  127. package/src/components/ui/switch/switch.astro +8 -2
  128. package/src/components/ui/tabs/tabs-content.astro +1 -1
  129. package/src/components/ui/tabs/tabs-trigger.astro +3 -2
  130. package/src/components/ui/tabs/tabs.astro +8 -2
  131. package/src/components/ui/toast/index.ts +26 -0
  132. package/src/components/ui/toast/toast-action.astro +25 -0
  133. package/src/components/ui/toast/toast-close.astro +27 -0
  134. package/src/components/ui/toast/toast-content.astro +20 -0
  135. package/src/components/ui/toast/toast-description.astro +18 -0
  136. package/src/components/ui/toast/toast-icon.astro +37 -0
  137. package/src/components/ui/toast/toast-item.astro +28 -0
  138. package/src/components/ui/toast/toast-template.astro +11 -0
  139. package/src/components/ui/toast/toast-title.astro +17 -0
  140. package/src/components/ui/toast/toast-viewport.astro +20 -0
  141. package/src/components/ui/toast/toast.astro +51 -0
  142. package/src/components/ui/toast/toaster.astro +37 -0
  143. package/src/components/ui/toggle/toggle.astro +8 -2
  144. package/src/components/ui/toggle-group/index.ts +2 -0
  145. package/src/components/ui/toggle-group/toggle-group-item.astro +44 -0
  146. package/src/components/ui/toggle-group/toggle-group.astro +74 -0
  147. package/src/components/ui/tooltip/tooltip-content.astro +1 -1
  148. package/src/components/ui/tooltip/tooltip.astro +11 -2
  149. package/src/components/ui/typography/typeset.css +441 -0
  150. package/src/components/ui/typography/typography-a.astro +13 -22
  151. package/src/components/ui/typography/typography-blockquote.astro +4 -23
  152. package/src/components/ui/typography/typography-h1.astro +13 -26
  153. package/src/components/ui/typography/typography-h2.astro +13 -31
  154. package/src/components/ui/typography/typography-h3.astro +9 -26
  155. package/src/components/ui/typography/typography-h4.astro +9 -26
  156. package/src/components/ui/typography/typography-inline-code.astro +8 -27
  157. package/src/components/ui/typography/typography-lead.astro +4 -26
  158. package/src/components/ui/typography/typography-list-item.astro +4 -24
  159. package/src/components/ui/typography/typography-list.astro +10 -40
  160. package/src/components/ui/typography/typography-p.astro +9 -28
  161. package/src/components/ui/typography/typography-table-cell.astro +9 -40
  162. package/src/components/ui/typography/typography-table-head.astro +9 -35
  163. package/src/components/ui/typography/typography-table-row.astro +4 -23
  164. package/src/components/ui/typography/typography-table.astro +8 -28
  165. package/src/components/ui/typography/typography.astro +10 -283
  166. package/src/styles/global.css +2 -0
@@ -4,8 +4,9 @@
4
4
  "title": "Command",
5
5
  "description": "Command menu for search and quick actions.",
6
6
  "dependencies": [
7
- "@data-slot/command",
8
- "@lucide/astro"
7
+ "@data-slot/command@^1.0.2",
8
+ "@lucide/astro",
9
+ "@data-slot/core@^1.0.2"
9
10
  ],
10
11
  "registryDependencies": [
11
12
  "@fulldev/dialog"
@@ -13,12 +14,12 @@
13
14
  "files": [
14
15
  {
15
16
  "path": "src/components/ui/command/command.astro",
16
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n label?: string\n defaultValue?: string\n defaultSearch?: string\n shouldFilter?: boolean\n loop?: boolean\n disablePointerSelection?: boolean\n vimBindings?: boolean\n}\n\nconst {\n class: className,\n label,\n defaultValue,\n defaultSearch,\n shouldFilter,\n loop,\n disablePointerSelection,\n vimBindings,\n ...props\n} = Astro.props\n---\n\n<div\n data-slot=\"command\"\n data-label={label}\n data-default-value={defaultValue}\n data-default-search={defaultSearch}\n data-should-filter={shouldFilter}\n data-loop={loop}\n data-disable-pointer-selection={disablePointerSelection}\n data-vim-bindings={vimBindings}\n class={cn(\n \"bg-popover text-popover-foreground flex size-full flex-col overflow-hidden rounded-xl! p-1\",\n className\n )}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { create } from \"@data-slot/command\"\n\n const initCommand = () => {\n create()\n\n document.querySelectorAll(\"[data-slot=command]\").forEach((command) => {\n if (!(command instanceof HTMLElement)) return\n if (command.dataset.linkNavigation === \"true\") return\n\n command.dataset.linkNavigation = \"true\"\n command.addEventListener(\"command:select\", (event) => {\n const { detail } = event as CustomEvent<{ value?: unknown }>\n const value = detail?.value\n if (typeof value !== \"string\") return\n\n const item = Array.from(\n command.querySelectorAll(\"[data-slot=command-item][href]\")\n ).find((item) => item.getAttribute(\"data-value\") === value)\n const href = item?.getAttribute(\"href\")\n\n if (href) window.location.href = href\n })\n })\n }\n\n initCommand()\n\n document.addEventListener(\"astro:page-load\", initCommand)\n</script>\n",
17
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n label?: string\n defaultValue?: string\n defaultSearch?: string\n shouldFilter?: boolean\n loop?: boolean\n disablePointerSelection?: boolean\n vimBindings?: boolean\n}\n\nconst {\n class: className,\n label,\n defaultValue,\n defaultSearch,\n shouldFilter,\n loop,\n disablePointerSelection,\n vimBindings,\n ...props\n} = Astro.props\n---\n\n<div\n data-slot=\"command\"\n data-label={label}\n data-default-value={defaultValue}\n data-default-search={defaultSearch}\n data-should-filter={shouldFilter}\n data-loop={loop}\n data-disable-pointer-selection={disablePointerSelection}\n data-vim-bindings={vimBindings}\n class={cn(\n \"bg-popover text-popover-foreground flex size-full flex-col overflow-hidden rounded-xl! p-1\",\n className\n )}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { create } from \"@data-slot/command\"\n import { getParts } from \"@data-slot/core\"\n\n const controllers: ReturnType<typeof create> = []\n const initialize = () => controllers.push(...create())\n initialize()\n document.addEventListener(\"astro:page-load\", initialize)\n document.addEventListener(\"astro:before-swap\", () => {\n for (const controller of controllers) controller.destroy()\n controllers.length = 0\n })\n\n // Data Slot selection does not activate links. Preserve native navigation.\n document.addEventListener(\n \"keydown\",\n (event) => {\n if (\n event.key !== \"Enter\" ||\n event.defaultPrevented ||\n event.isComposing ||\n event.keyCode === 229\n )\n return\n const input = event.target\n if (\n !(input instanceof HTMLInputElement) ||\n input.dataset.slot !== \"command-input\"\n )\n return\n const root = input.closest('[data-slot=\"command\"]')\n if (!root) return\n const item = getParts<HTMLAnchorElement>(root, \"command-item\").find(\n (item) =>\n item.hasAttribute(\"data-selected\") &&\n item.hasAttribute(\"href\") &&\n item.getAttribute(\"aria-disabled\") !== \"true\"\n )\n if (!item) return\n event.preventDefault()\n item.click()\n },\n true\n )\n</script>\n",
17
18
  "type": "registry:ui"
18
19
  },
19
20
  {
20
21
  "path": "src/components/ui/command/command-dialog.astro",
21
- "content": "---\nimport type { ComponentProps } from \"astro/types\"\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogTitle,\n} from \"@/components/ui/dialog\"\n\ntype Props = ComponentProps<typeof Dialog> & {\n title?: string\n description?: string\n contentClass?: string\n showCloseButton?: boolean\n}\n\nconst {\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n contentClass,\n showCloseButton = false,\n ...props\n} = Astro.props\n---\n\n<Dialog {...props}>\n <DialogContent\n class:list={[\n \"top-1/3 translate-y-0 overflow-hidden rounded-xl! p-0\",\n \"[&_[data-slot=command]]:border-0\",\n \"[&_[data-slot=command]]:bg-transparent\",\n \"[&_[data-slot=command-input-wrapper]]:h-12\",\n \"[&_[data-slot=command-input-wrapper]_svg]:size-5\",\n \"[&_[data-slot=command-input]]:h-12\",\n \"[&_[data-slot=command-item]]:px-2\",\n \"[&_[data-slot=command-item]]:py-3\",\n \"[&_[data-slot=command-item]_svg]:size-5\",\n \"[&_[data-slot=command-group-heading]]:text-muted-foreground\",\n \"[&_[data-slot=command-group-heading]]:px-2\",\n \"[&_[data-slot=command-group-heading]]:font-medium\",\n \"[&_[data-slot=command-group]]:px-2\",\n \"[&_[data-slot=command-group]:not([hidden])_~[data-slot=command-group]]:pt-0\",\n contentClass,\n ]}\n showCloseButton={showCloseButton}\n >\n <div class=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </div>\n <slot />\n </DialogContent>\n</Dialog>\n",
22
+ "content": "---\nimport type { ComponentProps } from \"astro/types\"\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogTitle,\n} from \"@/components/ui/dialog\"\n\ntype Props = ComponentProps<typeof Dialog> & {\n title?: string\n description?: string\n contentClass?: string\n showCloseButton?: boolean\n}\n\nconst {\n title = \"Command Palette\",\n description = \"Search for a command to run...\",\n contentClass,\n showCloseButton = false,\n ...props\n} = Astro.props\n---\n\n<Dialog {...props}>\n <slot name=\"trigger\" />\n <DialogContent\n class:list={[\n \"top-1/3 translate-y-0 overflow-hidden rounded-xl! p-0\",\n \"[&_[data-slot=command]]:border-0\",\n \"[&_[data-slot=command]]:bg-transparent\",\n \"[&_[data-slot=command-input-wrapper]]:h-12\",\n \"[&_[data-slot=command-input-wrapper]_svg]:size-5\",\n \"[&_[data-slot=command-input]]:h-12\",\n \"[&_[data-slot=command-item]]:px-2\",\n \"[&_[data-slot=command-item]]:py-3\",\n \"[&_[data-slot=command-item]_svg]:size-5\",\n \"[&_[data-slot=command-group-heading]]:text-muted-foreground\",\n \"[&_[data-slot=command-group-heading]]:px-2\",\n \"[&_[data-slot=command-group-heading]]:font-medium\",\n \"[&_[data-slot=command-group]]:px-2\",\n \"[&_[data-slot=command-group]:not([hidden])_~[data-slot=command-group]]:pt-0\",\n contentClass,\n ]}\n showCloseButton={showCloseButton}\n >\n <div class=\"sr-only\">\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription>{description}</DialogDescription>\n </div>\n <slot />\n </DialogContent>\n</Dialog>\n",
22
23
  "type": "registry:ui"
23
24
  },
24
25
  {
@@ -7,11 +7,14 @@
7
7
  "@fulldev/accordion",
8
8
  "@fulldev/alert",
9
9
  "@fulldev/alert-dialog",
10
+ "@fulldev/aspect-ratio",
11
+ "@fulldev/attachment",
10
12
  "@fulldev/avatar",
11
13
  "@fulldev/badge",
12
14
  "@fulldev/banner",
13
15
  "@fulldev/breadcrumb",
14
16
  "@fulldev/button",
17
+ "@fulldev/button-group",
15
18
  "@fulldev/card",
16
19
  "@fulldev/carousel",
17
20
  "@fulldev/checkbox",
@@ -19,6 +22,7 @@
19
22
  "@fulldev/combobox",
20
23
  "@fulldev/command",
21
24
  "@fulldev/dialog",
25
+ "@fulldev/drawer",
22
26
  "@fulldev/dropdown-menu",
23
27
  "@fulldev/empty",
24
28
  "@fulldev/field",
@@ -36,10 +40,12 @@
36
40
  "@fulldev/marquee",
37
41
  "@fulldev/native-select",
38
42
  "@fulldev/navigation-menu",
43
+ "@fulldev/pagination",
39
44
  "@fulldev/popover",
40
45
  "@fulldev/price",
41
46
  "@fulldev/radio-group",
42
47
  "@fulldev/rating",
48
+ "@fulldev/resizable",
43
49
  "@fulldev/section",
44
50
  "@fulldev/select",
45
51
  "@fulldev/separator",
@@ -53,8 +59,10 @@
53
59
  "@fulldev/tabs",
54
60
  "@fulldev/textarea",
55
61
  "@fulldev/theme-toggle",
62
+ "@fulldev/toast",
56
63
  "@fulldev/toc",
57
64
  "@fulldev/toggle",
65
+ "@fulldev/toggle-group",
58
66
  "@fulldev/tooltip",
59
67
  "@fulldev/typography",
60
68
  "@fulldev/video"
@@ -4,7 +4,7 @@
4
4
  "title": "Dialog",
5
5
  "description": "A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.",
6
6
  "dependencies": [
7
- "@data-slot/dialog",
7
+ "@data-slot/dialog@^1.0.2",
8
8
  "@lucide/astro"
9
9
  ],
10
10
  "registryDependencies": [
@@ -13,7 +13,7 @@
13
13
  "files": [
14
14
  {
15
15
  "path": "src/components/ui/dialog/dialog.astro",
16
- "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 alertDialog?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n closeOnClickOutside,\n closeOnEscape,\n lockScroll,\n alertDialog,\n ...props\n} = Astro.props\n---\n\n<div\n data-slot=\"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 data-alert-dialog={alertDialog}\n class={className}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { create } from \"@data-slot/dialog\"\n\n create()\n document.addEventListener(\"astro:page-load\", () => create())\n</script>\n",
16
+ "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 alertDialog?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n closeOnClickOutside,\n closeOnEscape,\n lockScroll,\n alertDialog,\n ...props\n} = Astro.props\n---\n\n<div\n data-slot=\"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 data-alert-dialog={alertDialog}\n class={className}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { create } from \"@data-slot/dialog\"\n\n const controllers: ReturnType<typeof create> = []\n const initialize = () => controllers.push(...create())\n initialize()\n document.addEventListener(\"astro:page-load\", initialize)\n document.addEventListener(\"astro:before-swap\", () => {\n for (const controller of controllers) controller.destroy()\n controllers.length = 0\n })\n</script>\n",
17
17
  "type": "registry:ui"
18
18
  },
19
19
  {
@@ -18,7 +18,7 @@
18
18
  "files": [
19
19
  {
20
20
  "path": "src/components/blocks/doc-1.astro",
21
- "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 Card,\n CardDescription,\n CardFooter,\n CardHeader,\n} from \"@/components/ui/card\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { SectionContainer } from \"@/components/ui/section\"\nimport {\n Toc,\n TocMenu,\n TocMenuItem,\n TocMenuLink,\n TocTitle,\n} from \"@/components/ui/toc\"\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 tocItems: {\n depth: number\n href: string\n label: string\n }[]\n callout?: {\n description: string\n button: {\n label: string\n href: string\n variant?: \"default\" | \"outline\" | \"secondary\" | \"ghost\"\n }\n }\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 toc: string\n }\n}\n\nconst {\n class: className,\n title,\n description,\n copyButton,\n markdownUrl,\n tocItems,\n callout,\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 class={cn(\n \"gap-10 pt-10 pb-8 sm:pt-12 sm:pb-10 xl:grid xl:grid-cols-[minmax(0,1fr)_16rem] xl:items-start xl:gap-x-16\",\n className\n )}\n>\n <div class=\"mx-auto flex w-full max-w-3xl min-w-0 flex-col gap-10\">\n <header\n class=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\"\n >\n <div class=\"flex min-w-0 flex-1 flex-col gap-2\">\n <TypographyH1\n size=\"sm\"\n class=\"text-foreground text-left tracking-tight\"\n >\n {title}\n </TypographyH1>\n {\n description && (\n <TypographyLead size=\"sm\" class=\"max-w-2xl 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 data-copy-icon class=\"docs-copy-icon size-3.5\" />\n <Check data-check-icon class=\"docs-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\" size=\"sm\">\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\n {\n (tocItems.length > 0 || callout) && (\n <aside class=\"hidden w-64 xl:sticky xl:top-12 xl:mr-0 xl:ml-auto xl:block xl:self-start\">\n <div class=\"flex flex-col gap-6\">\n {tocItems.length > 0 && (\n <Toc aria-label={labels.toc}>\n <TocTitle>{labels.toc}</TocTitle>\n <TocMenu>\n {tocItems.map((item) => (\n <TocMenuItem>\n <TocMenuLink href={item.href} depth={item.depth}>\n {item.label}\n </TocMenuLink>\n </TocMenuItem>\n ))}\n </TocMenu>\n </Toc>\n )}\n\n {callout && (\n <Card size=\"sm\">\n <CardHeader>\n <CardDescription>{callout.description}</CardDescription>\n </CardHeader>\n <CardFooter>\n <Button\n as=\"a\"\n href={callout.button.href}\n variant={callout.button.variant}\n size=\"sm\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {callout.button.label}\n </Button>\n </CardFooter>\n </Card>\n )}\n </div>\n </aside>\n )\n }\n</SectionContainer>\n\n<script is:inline>\n const copyIcon = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"></rect><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"></path></svg>`\n const checkIcon = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"></path></svg>`\n document.querySelectorAll(\"[data-slot='typography'] > pre\").forEach((pre) => {\n if (pre.closest(\".docs-code-block\")) return\n const wrapper = document.createElement(\"div\")\n const button = document.createElement(\"button\")\n wrapper.className = \"docs-code-block\"\n button.type = \"button\"\n button.className = \"docs-code-copy\"\n button.ariaLabel = \"Copy code\"\n button.innerHTML = `<span data-copy-icon>${copyIcon}</span><span data-check-icon class=\"hidden\">${checkIcon}</span>`\n pre.before(wrapper)\n wrapper.append(pre, button)\n })\n document.addEventListener(\"click\", (event) => {\n const button = event.target?.closest?.(\n \"[id^='docs-copy-page-'], .docs-code-copy\"\n )\n if (!button) return\n const source =\n button.dataset.source ??\n button\n .closest(\".docs-code-block\")\n ?.querySelector(\"pre\")\n ?.textContent?.replace(/\\n$/, \"\")\n button.querySelector(\"[data-copy-icon]\")?.classList.add(\"hidden\")\n button.querySelector(\"[data-check-icon]\")?.classList.remove(\"hidden\")\n navigator.clipboard?.writeText(source ?? \"\")\n setTimeout(() => {\n button.querySelector(\"[data-copy-icon]\")?.classList.remove(\"hidden\")\n button.querySelector(\"[data-check-icon]\")?.classList.add(\"hidden\")\n }, 1200)\n })\n</script>\n",
21
+ "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 Card,\n CardDescription,\n CardFooter,\n CardHeader,\n} from \"@/components/ui/card\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\"\nimport { SectionContainer } from \"@/components/ui/section\"\nimport {\n Toc,\n TocMenu,\n TocMenuItem,\n TocMenuLink,\n TocTitle,\n} from \"@/components/ui/toc\"\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 tocItems: {\n depth: number\n href: string\n label: string\n }[]\n callout?: {\n description: string\n button: {\n label: string\n href: string\n variant?: \"default\" | \"outline\" | \"secondary\" | \"ghost\"\n }\n }\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 toc: string\n }\n}\n\nconst {\n class: className,\n title,\n description,\n copyButton,\n markdownUrl,\n tocItems,\n callout,\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 class={cn(\n \"gap-10 pt-10 pb-8 sm:pt-12 sm:pb-10 xl:grid xl:grid-cols-[minmax(0,1fr)_16rem] xl:items-start xl:gap-x-16\",\n className\n )}\n>\n <div class=\"mx-auto flex w-full max-w-3xl min-w-0 flex-col gap-10\">\n <header\n class=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\"\n >\n <div class=\"flex min-w-0 flex-1 flex-col gap-2\">\n <TypographyH1\n size=\"sm\"\n class=\"text-foreground text-left tracking-tight\"\n >\n {title}\n </TypographyH1>\n {\n description && (\n <TypographyLead size=\"sm\" class=\"max-w-2xl 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 data-copy-icon class=\"docs-copy-icon size-3.5\" />\n <Check data-check-icon class=\"docs-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 <DropdownMenuItem\n href={link.href}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\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 </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n }\n </div>\n </header>\n\n <Typography as=\"article\" size=\"sm\">\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\n {\n (tocItems.length > 0 || callout) && (\n <aside class=\"hidden w-64 xl:sticky xl:top-12 xl:mr-0 xl:ml-auto xl:block xl:self-start\">\n <div class=\"flex flex-col gap-6\">\n {tocItems.length > 0 && (\n <Toc aria-label={labels.toc}>\n <TocTitle>{labels.toc}</TocTitle>\n <TocMenu>\n {tocItems.map((item) => (\n <TocMenuItem>\n <TocMenuLink href={item.href} depth={item.depth}>\n {item.label}\n </TocMenuLink>\n </TocMenuItem>\n ))}\n </TocMenu>\n </Toc>\n )}\n\n {callout && (\n <Card size=\"sm\">\n <CardHeader>\n <CardDescription>{callout.description}</CardDescription>\n </CardHeader>\n <CardFooter>\n <Button\n as=\"a\"\n href={callout.button.href}\n variant={callout.button.variant}\n size=\"sm\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {callout.button.label}\n </Button>\n </CardFooter>\n </Card>\n )}\n </div>\n </aside>\n )\n }\n</SectionContainer>\n\n<style is:global>\n .docs-code-block {\n position: relative;\n overflow: hidden;\n margin-block-start: var(--typeset-flow);\n border: 1px solid var(--color-border);\n border-radius: var(--radius-xl);\n background: color-mix(in oklab, var(--color-muted) 60%, transparent);\n }\n\n .docs-code-block > pre,\n .docs-code-block > pre.astro-code {\n margin: 0;\n overflow-x: auto;\n border: 0;\n border-radius: 0;\n background: transparent !important;\n padding: 1rem 3.5rem 1rem 1rem;\n font-family: var(--font-mono);\n font-size: var(--text-sm);\n line-height: var(--text-sm--line-height);\n }\n\n .docs-code-block > pre.astro-code code {\n color: var(--shiki-light, var(--color-foreground)) !important;\n font: inherit;\n }\n\n .dark .docs-code-block > pre.astro-code code {\n color: var(--shiki-dark, var(--color-foreground)) !important;\n }\n\n .dark .docs-code-block > pre.astro-code span[style*=\"--shiki-dark\"] {\n color: var(--shiki-dark) !important;\n font-style: var(--shiki-dark-font-style, inherit) !important;\n font-weight: var(--shiki-dark-font-weight, inherit) !important;\n text-decoration: var(--shiki-dark-text-decoration, inherit) !important;\n }\n\n .docs-code-copy {\n position: absolute;\n z-index: 10;\n top: 0.75rem;\n right: 0.75rem;\n display: inline-flex;\n width: 2rem;\n height: 2rem;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n background: var(--color-background);\n color: var(--color-muted-foreground);\n box-shadow: var(--shadow-sm);\n transition:\n color 150ms,\n background-color 150ms;\n }\n\n .docs-code-copy:hover {\n background: var(--color-accent);\n color: var(--color-accent-foreground);\n }\n\n .docs-code-copy:focus-visible {\n outline: 2px solid var(--color-ring);\n outline-offset: 2px;\n }\n\n .docs-code-copy svg {\n width: 1rem;\n height: 1rem;\n }\n</style>\n\n<script>\n const copyIcon = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"></rect><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"></path></svg>`\n const checkIcon = `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 6 9 17l-5-5\"></path></svg>`\n const initializeCodeBlocks = () => {\n document\n .querySelectorAll(\"[data-slot='typography'] > pre\")\n .forEach((pre) => {\n if (pre.closest(\".docs-code-block\")) return\n const wrapper = document.createElement(\"div\")\n const button = document.createElement(\"button\")\n wrapper.className = \"docs-code-block\"\n wrapper.dataset.notTypeset = \"\"\n button.type = \"button\"\n button.className = \"docs-code-copy\"\n button.ariaLabel = \"Copy code\"\n button.innerHTML = `<span data-copy-icon>${copyIcon}</span><span data-check-icon class=\"hidden\">${checkIcon}</span>`\n pre.before(wrapper)\n wrapper.append(pre, button)\n })\n }\n\n initializeCodeBlocks()\n document.addEventListener(\"astro:page-load\", initializeCodeBlocks)\n\n document.addEventListener(\"click\", async (event) => {\n if (!(event.target instanceof Element)) return\n const button = event.target.closest(\n \"[id^='docs-copy-page-'], .docs-code-copy\"\n )\n if (!(button instanceof HTMLButtonElement)) return\n const source =\n button.dataset.source ??\n button\n .closest(\".docs-code-block\")\n ?.querySelector(\"pre\")\n ?.textContent?.replace(/\\n$/, \"\")\n\n try {\n await navigator.clipboard.writeText(source ?? \"\")\n button.querySelector(\"[data-copy-icon]\")?.classList.add(\"hidden\")\n button.querySelector(\"[data-check-icon]\")?.classList.remove(\"hidden\")\n setTimeout(() => {\n button.querySelector(\"[data-copy-icon]\")?.classList.remove(\"hidden\")\n button.querySelector(\"[data-check-icon]\")?.classList.add(\"hidden\")\n }, 1200)\n } catch {\n // Keep the copy state unchanged so the action can be retried.\n }\n })\n</script>\n",
22
22
  "type": "registry:block"
23
23
  }
24
24
  ],
@@ -0,0 +1,109 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
+ "name": "drawer",
4
+ "title": "Drawer",
5
+ "description": "A swipeable panel that opens from an edge of the screen.",
6
+ "dependencies": [
7
+ "@data-slot/drawer@^1.0.2"
8
+ ],
9
+ "registryDependencies": [
10
+ "@fulldev/button"
11
+ ],
12
+ "files": [
13
+ {
14
+ "path": "src/components/ui/drawer/drawer-close.astro",
15
+ "content": "---\nimport type { ComponentProps } from \"astro/types\"\n\nimport { Button } from \"@/components/ui/button\"\n\ntype Props = ComponentProps<typeof Button>\n\nconst { ...props } = Astro.props\n---\n\n<Button data-slot=\"drawer-close\" {...props}>\n <slot />\n</Button>\n",
16
+ "type": "registry:ui"
17
+ },
18
+ {
19
+ "path": "src/components/ui/drawer/drawer-content.astro",
20
+ "content": "---\nimport type { ComponentProps } from \"astro/types\"\n\nimport DrawerOverlay from \"./drawer-overlay.astro\"\nimport DrawerPopup from \"./drawer-popup.astro\"\nimport DrawerPortal from \"./drawer-portal.astro\"\nimport DrawerSwipeHandle from \"./drawer-swipe-handle.astro\"\nimport DrawerViewport from \"./drawer-viewport.astro\"\n\ntype Props = ComponentProps<typeof DrawerPopup> & {\n showOverlay?: boolean\n showSwipeHandle?: boolean\n container?: string\n keepMounted?: boolean\n overlayClass?: string\n viewportClass?: string\n}\n\nconst {\n showOverlay = true,\n showSwipeHandle = false,\n container,\n keepMounted,\n overlayClass,\n viewportClass,\n ...props\n} = Astro.props\n---\n\n<DrawerPortal container={container} keepMounted={keepMounted}>\n {showOverlay && <DrawerOverlay class={overlayClass} />}\n <DrawerViewport class={viewportClass}>\n <DrawerPopup {...props}>\n {showSwipeHandle && <DrawerSwipeHandle />}\n <div\n data-slot=\"drawer-content\"\n class=\"flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-contain rounded-[inherit] transition-opacity duration-300 select-text group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-swiping/drawer-popup:opacity-100 group-data-swiping/drawer-popup:select-none\"\n >\n <slot />\n </div>\n </DrawerPopup>\n </DrawerViewport>\n</DrawerPortal>\n",
21
+ "type": "registry:ui"
22
+ },
23
+ {
24
+ "path": "src/components/ui/drawer/drawer-description.astro",
25
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"p\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<p\n data-slot=\"drawer-description\"\n class={cn(\"text-muted-foreground text-sm text-balance\", className)}\n {...props}\n>\n <slot />\n</p>\n",
26
+ "type": "registry:ui"
27
+ },
28
+ {
29
+ "path": "src/components/ui/drawer/drawer-footer.astro",
30
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<div\n data-slot=\"drawer-footer\"\n class={cn(\"mt-auto flex shrink-0 flex-col gap-2 p-4 pt-0\", className)}\n {...props}\n>\n <slot />\n</div>\n",
31
+ "type": "registry:ui"
32
+ },
33
+ {
34
+ "path": "src/components/ui/drawer/drawer-header.astro",
35
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<div\n data-slot=\"drawer-header\"\n class={cn(\"flex shrink-0 flex-col gap-1.5 p-4 pb-0\", className)}\n {...props}\n>\n <slot />\n</div>\n",
36
+ "type": "registry:ui"
37
+ },
38
+ {
39
+ "path": "src/components/ui/drawer/drawer-indent-background.astro",
40
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<div data-slot=\"drawer-indent-background\" class={className} {...props}>\n <slot />\n</div>\n",
41
+ "type": "registry:ui"
42
+ },
43
+ {
44
+ "path": "src/components/ui/drawer/drawer-indent.astro",
45
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<div data-slot=\"drawer-indent\" class={className} {...props}>\n <slot />\n</div>\n",
46
+ "type": "registry:ui"
47
+ },
48
+ {
49
+ "path": "src/components/ui/drawer/drawer-overlay.astro",
50
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\">\n\nconst { class: className, hidden = true, ...props } = Astro.props\n---\n\n<div\n data-slot=\"drawer-backdrop\"\n hidden={hidden}\n class={cn(\n \"fixed inset-0 z-50 min-h-dvh bg-black/10 opacity-[calc(1-var(--drawer-swipe-progress,0))] transition-opacity duration-300 ease-[cubic-bezier(0.32,0.72,0,1)] select-none data-ending-style:pointer-events-none data-ending-style:opacity-0 data-starting-style:opacity-0 data-swiping:duration-0 supports-backdrop-filter:backdrop-blur-xs\",\n className\n )}\n {...props}\n>\n <slot />\n</div>\n",
51
+ "type": "registry:ui"
52
+ },
53
+ {
54
+ "path": "src/components/ui/drawer/drawer-popup.astro",
55
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n initialFocus?: boolean | string\n finalFocus?: boolean | string\n}\n\nconst {\n class: className,\n initialFocus,\n finalFocus,\n hidden = true,\n ...props\n} = Astro.props\n---\n\n<div\n data-slot=\"drawer-popup\"\n data-initial-focus={initialFocus}\n data-final-focus={finalFocus}\n hidden={hidden}\n class={cn(\n \"group/drawer-popup bg-popover text-popover-foreground pointer-events-auto fixed z-50 flex min-h-0 transform-gpu flex-col text-sm shadow-lg transition-[transform,height,opacity,filter] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] will-change-transform outline-none select-none data-ending-style:duration-[calc(var(--drawer-swipe-strength,1)*400ms)] data-nested-drawer-open:overflow-hidden data-nested-drawer-open:brightness-95 data-swiping:duration-0\",\n \"data-[swipe-direction=down]:inset-x-0 data-[swipe-direction=down]:bottom-0 data-[swipe-direction=down]:max-h-[calc(100dvh-3rem)] data-[swipe-direction=down]:[transform:translate3d(0,calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-amount-y,0px)),0)] data-[swipe-direction=down]:rounded-t-xl data-[swipe-direction=down]:border-t data-[swipe-direction=down]:data-ending-style:[transform:translate3d(0,calc(100%+2px),0)] data-[swipe-direction=down]:data-starting-style:[transform:translate3d(0,calc(100%+2px),0)]\",\n \"data-[swipe-direction=up]:inset-x-0 data-[swipe-direction=up]:top-0 data-[swipe-direction=up]:max-h-[calc(100dvh-3rem)] data-[swipe-direction=up]:[transform:translate3d(0,calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-amount-y,0px)),0)] data-[swipe-direction=up]:rounded-b-xl data-[swipe-direction=up]:border-b data-[swipe-direction=up]:data-ending-style:[transform:translate3d(0,calc(-100%-2px),0)] data-[swipe-direction=up]:data-starting-style:[transform:translate3d(0,calc(-100%-2px),0)]\",\n \"data-[swipe-direction=left]:inset-y-0 data-[swipe-direction=left]:left-0 data-[swipe-direction=left]:h-full data-[swipe-direction=left]:w-3/4 data-[swipe-direction=left]:max-w-sm data-[swipe-direction=left]:[transform:translate3d(calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-amount-x,0px)),0,0)] data-[swipe-direction=left]:flex-row data-[swipe-direction=left]:rounded-r-xl data-[swipe-direction=left]:border-r data-[swipe-direction=left]:data-ending-style:[transform:translate3d(calc(-100%-2px),0,0)] data-[swipe-direction=left]:data-starting-style:[transform:translate3d(calc(-100%-2px),0,0)]\",\n \"data-[swipe-direction=right]:inset-y-0 data-[swipe-direction=right]:right-0 data-[swipe-direction=right]:h-full data-[swipe-direction=right]:w-3/4 data-[swipe-direction=right]:max-w-sm data-[swipe-direction=right]:[transform:translate3d(calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-amount-x,0px)),0,0)] data-[swipe-direction=right]:flex-row data-[swipe-direction=right]:rounded-l-xl data-[swipe-direction=right]:border-l data-[swipe-direction=right]:data-ending-style:[transform:translate3d(calc(100%+2px),0,0)] data-[swipe-direction=right]:data-starting-style:[transform:translate3d(calc(100%+2px),0,0)]\",\n className\n )}\n {...props}\n>\n <slot />\n</div>\n",
56
+ "type": "registry:ui"
57
+ },
58
+ {
59
+ "path": "src/components/ui/drawer/drawer-portal.astro",
60
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n container?: string\n keepMounted?: boolean\n}\n\nconst {\n class: className,\n container,\n keepMounted,\n hidden = true,\n ...props\n} = Astro.props\n---\n\n<div\n data-slot=\"drawer-portal\"\n data-container={container}\n data-keep-mounted={keepMounted}\n class={className}\n hidden={hidden}\n {...props}\n>\n <slot />\n</div>\n",
61
+ "type": "registry:ui"
62
+ },
63
+ {
64
+ "path": "src/components/ui/drawer/drawer-provider.astro",
65
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<div data-slot=\"drawer-provider\" class={className} {...props}>\n <slot />\n</div>\n",
66
+ "type": "registry:ui"
67
+ },
68
+ {
69
+ "path": "src/components/ui/drawer/drawer-swipe-handle.astro",
70
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<div\n data-slot=\"drawer-handle\"\n aria-hidden=\"true\"\n class={cn(\n \"after:bg-muted relative z-10 flex shrink-0 cursor-grab transition-opacity duration-200 group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-swiping/drawer-popup:opacity-100 group-data-[swipe-direction=down]/drawer-popup:h-3 group-data-[swipe-direction=down]/drawer-popup:w-full group-data-[swipe-direction=down]/drawer-popup:items-end group-data-[swipe-direction=down]/drawer-popup:justify-center group-data-[swipe-direction=left]/drawer-popup:order-last group-data-[swipe-direction=left]/drawer-popup:h-full group-data-[swipe-direction=left]/drawer-popup:w-3 group-data-[swipe-direction=left]/drawer-popup:items-center group-data-[swipe-direction=left]/drawer-popup:justify-start group-data-[swipe-direction=right]/drawer-popup:h-full group-data-[swipe-direction=right]/drawer-popup:w-3 group-data-[swipe-direction=right]/drawer-popup:items-center group-data-[swipe-direction=right]/drawer-popup:justify-end group-data-[swipe-direction=up]/drawer-popup:order-last group-data-[swipe-direction=up]/drawer-popup:h-3 group-data-[swipe-direction=up]/drawer-popup:w-full group-data-[swipe-direction=up]/drawer-popup:items-start group-data-[swipe-direction=up]/drawer-popup:justify-center after:block after:shrink-0 after:rounded-full group-data-[swipe-direction=down]/drawer-popup:after:h-1.5 group-data-[swipe-direction=down]/drawer-popup:after:w-24 group-data-[swipe-direction=left]/drawer-popup:after:h-24 group-data-[swipe-direction=left]/drawer-popup:after:w-1.5 group-data-[swipe-direction=right]/drawer-popup:after:h-24 group-data-[swipe-direction=right]/drawer-popup:after:w-1.5 group-data-[swipe-direction=up]/drawer-popup:after:h-1.5 group-data-[swipe-direction=up]/drawer-popup:after:w-24 active:cursor-grabbing\",\n className\n )}\n {...props}\n>\n</div>\n",
71
+ "type": "registry:ui"
72
+ },
73
+ {
74
+ "path": "src/components/ui/drawer/drawer-title.astro",
75
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"h2\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<h2\n data-slot=\"drawer-title\"\n class={cn(\"text-foreground font-medium\", className)}\n {...props}\n>\n <slot />\n</h2>\n",
76
+ "type": "registry:ui"
77
+ },
78
+ {
79
+ "path": "src/components/ui/drawer/drawer-trigger.astro",
80
+ "content": "---\nimport type { ComponentProps } from \"astro/types\"\n\nimport { Button } from \"@/components/ui/button\"\n\ntype Props = ComponentProps<typeof Button> & {\n drawerTarget?: string\n payload?: string\n}\n\nconst { drawerTarget, payload, ...props } = Astro.props\n---\n\n<Button\n data-slot=\"drawer-trigger\"\n data-drawer-target={drawerTarget}\n data-payload={payload}\n {...props}\n>\n <slot />\n</Button>\n",
81
+ "type": "registry:ui"
82
+ },
83
+ {
84
+ "path": "src/components/ui/drawer/drawer-viewport.astro",
85
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\">\n\nconst { class: className, hidden = true, ...props } = Astro.props\n---\n\n<div\n data-slot=\"drawer-viewport\"\n hidden={hidden}\n class={cn(\n \"pointer-events-none fixed inset-0 z-50 min-h-dvh select-none\",\n className\n )}\n {...props}\n>\n <slot />\n</div>\n",
86
+ "type": "registry:ui"
87
+ },
88
+ {
89
+ "path": "src/components/ui/drawer/drawer-virtual-keyboard-provider.astro",
90
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"div\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<div data-slot=\"drawer-virtual-keyboard-provider\" class={className} {...props}>\n <slot />\n</div>\n",
91
+ "type": "registry:ui"
92
+ },
93
+ {
94
+ "path": "src/components/ui/drawer/drawer.astro",
95
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { DrawerSnapPoint, DrawerSwipeDirection } from \"@data-slot/drawer\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n modal?: boolean | \"trap-focus\"\n disablePointerDismissal?: boolean\n closeOnEscape?: boolean\n swipeDirection?: DrawerSwipeDirection\n snapPoint?: DrawerSnapPoint | null\n defaultSnapPoint?: DrawerSnapPoint | null\n triggerId?: string | null\n defaultTriggerId?: string | null\n}\n\nconst {\n class: className,\n defaultOpen,\n modal,\n disablePointerDismissal,\n closeOnEscape,\n swipeDirection,\n snapPoint,\n defaultSnapPoint,\n triggerId,\n defaultTriggerId,\n ...props\n} = Astro.props\n---\n\n<div\n data-slot=\"drawer\"\n data-default-open={defaultOpen}\n data-modal={modal}\n data-disable-pointer-dismissal={disablePointerDismissal}\n data-close-on-escape={closeOnEscape}\n data-swipe-direction={swipeDirection}\n data-snap-point={snapPoint}\n data-default-snap-point={defaultSnapPoint}\n data-trigger-id={triggerId}\n data-default-trigger-id={defaultTriggerId}\n class={className}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { create } from \"@data-slot/drawer\"\n\n const controllers: ReturnType<typeof create> = []\n const initialize = () => controllers.push(...create())\n initialize()\n document.addEventListener(\"astro:page-load\", initialize)\n document.addEventListener(\"astro:before-swap\", () => {\n for (const controller of controllers) controller.destroy()\n controllers.length = 0\n })\n</script>\n",
96
+ "type": "registry:ui"
97
+ },
98
+ {
99
+ "path": "src/components/ui/drawer/index.ts",
100
+ "content": "export { default as Drawer } from \"./drawer.astro\"\nexport { default as DrawerTrigger } from \"./drawer-trigger.astro\"\nexport { default as DrawerClose } from \"./drawer-close.astro\"\nexport { default as DrawerPortal } from \"./drawer-portal.astro\"\nexport { default as DrawerOverlay } from \"./drawer-overlay.astro\"\nexport { default as DrawerBackdrop } from \"./drawer-overlay.astro\"\nexport { default as DrawerViewport } from \"./drawer-viewport.astro\"\nexport { default as DrawerPopup } from \"./drawer-popup.astro\"\nexport { default as DrawerContent } from \"./drawer-content.astro\"\nexport { default as DrawerSwipeHandle } from \"./drawer-swipe-handle.astro\"\nexport { default as DrawerHeader } from \"./drawer-header.astro\"\nexport { default as DrawerFooter } from \"./drawer-footer.astro\"\nexport { default as DrawerTitle } from \"./drawer-title.astro\"\nexport { default as DrawerDescription } from \"./drawer-description.astro\"\nexport { default as DrawerProvider } from \"./drawer-provider.astro\"\nexport { default as DrawerIndent } from \"./drawer-indent.astro\"\nexport { default as DrawerIndentBackground } from \"./drawer-indent-background.astro\"\nexport { default as DrawerVirtualKeyboardProvider } from \"./drawer-virtual-keyboard-provider.astro\"\n\nexport type {\n DrawerChangeDetails,\n DrawerChangeReason,\n DrawerController,\n DrawerOptions,\n DrawerSnapChangeDetails,\n DrawerSnapPoint,\n DrawerSwipeDirection,\n} from \"@data-slot/drawer\"\n",
101
+ "type": "registry:ui"
102
+ }
103
+ ],
104
+ "docs": "https://ui.full.dev/components/drawer/",
105
+ "categories": [
106
+ "ui"
107
+ ],
108
+ "type": "registry:ui"
109
+ }
@@ -4,13 +4,13 @@
4
4
  "title": "Dropdown Menu",
5
5
  "description": "Displays a menu to the user, such as a set of actions or functions, triggered by a button.",
6
6
  "dependencies": [
7
- "@data-slot/dropdown-menu",
7
+ "@data-slot/dropdown-menu@^1.0.2",
8
8
  "@lucide/astro"
9
9
  ],
10
10
  "files": [
11
11
  {
12
12
  "path": "src/components/ui/dropdown-menu/dropdown-menu.astro",
13
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Side } from \"@data-slot/dropdown-menu\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n defaultValue?: string | null\n defaultValues?: string[]\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n closeOnSelect?: boolean\n highlightItemOnHover?: boolean\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n lockScroll?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n defaultValue,\n defaultValues,\n closeOnClickOutside,\n closeOnEscape,\n closeOnSelect,\n highlightItemOnHover,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n lockScroll,\n ...props\n} = Astro.props\n\nconst defaultValuesAttr =\n defaultValues === undefined ? undefined : JSON.stringify(defaultValues)\n---\n\n<div\n data-slot=\"dropdown-menu\"\n data-default-open={defaultOpen}\n data-default-value={defaultValue}\n data-default-values={defaultValuesAttr}\n data-close-on-click-outside={closeOnClickOutside}\n data-close-on-escape={closeOnEscape}\n data-close-on-select={closeOnSelect}\n data-highlight-item-on-hover={highlightItemOnHover}\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-avoid-collisions={avoidCollisions}\n data-collision-padding={collisionPadding}\n data-lock-scroll={lockScroll}\n class={className}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { create } from \"@data-slot/dropdown-menu\"\n\n create()\n document.addEventListener(\"astro:page-load\", () => create())\n</script>\n",
13
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Side } from \"@data-slot/dropdown-menu\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n defaultValue?: string | null\n defaultValues?: string[]\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n closeOnSelect?: boolean\n highlightItemOnHover?: boolean\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n lockScroll?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n defaultValue,\n defaultValues,\n closeOnClickOutside,\n closeOnEscape,\n closeOnSelect,\n highlightItemOnHover,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n lockScroll,\n ...props\n} = Astro.props\n\nconst defaultValuesAttr =\n defaultValues === undefined ? undefined : JSON.stringify(defaultValues)\n---\n\n<div\n data-slot=\"dropdown-menu\"\n data-default-open={defaultOpen}\n data-default-value={defaultValue}\n data-default-values={defaultValuesAttr}\n data-close-on-click-outside={closeOnClickOutside}\n data-close-on-escape={closeOnEscape}\n data-close-on-select={closeOnSelect}\n data-highlight-item-on-hover={highlightItemOnHover}\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-avoid-collisions={avoidCollisions}\n data-collision-padding={collisionPadding}\n data-lock-scroll={lockScroll}\n class={className}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { create } from \"@data-slot/dropdown-menu\"\n\n const controllers: ReturnType<typeof create> = []\n const initialize = () => controllers.push(...create())\n initialize()\n document.addEventListener(\"astro:page-load\", initialize)\n document.addEventListener(\"astro:before-swap\", () => {\n for (const controller of controllers) controller.destroy()\n controllers.length = 0\n })\n</script>\n",
14
14
  "type": "registry:ui"
15
15
  },
16
16
  {
@@ -20,12 +20,12 @@
20
20
  },
21
21
  {
22
22
  "path": "src/components/ui/dropdown-menu/dropdown-menu-content.astro",
23
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Side } from \"@data-slot/dropdown-menu\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n<div data-slot=\"dropdown-menu-portal\">\n <div\n data-slot=\"dropdown-menu-positioner\"\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-avoid-collisions={avoidCollisions}\n data-collision-padding={collisionPadding}\n class=\"isolate z-50 outline-none\"\n >\n <div\n data-slot=\"dropdown-menu-content\"\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-avoid-collisions={avoidCollisions}\n data-collision-padding={collisionPadding}\n hidden={hidden}\n class={cn(\n \"bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md p-1 shadow-md ring-1 duration-100 outline-none data-closed:overflow-hidden\",\n className\n )}\n {...props}\n >\n <slot />\n </div>\n </div>\n</div>\n",
23
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport type { Align, Side } from \"@data-slot/dropdown-menu\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: Side\n align?: Align\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n<div data-slot=\"dropdown-menu-portal\">\n <div\n data-slot=\"dropdown-menu-positioner\"\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-avoid-collisions={avoidCollisions}\n data-collision-padding={collisionPadding}\n class=\"isolate z-[1000] outline-none\"\n >\n <div\n data-slot=\"dropdown-menu-content\"\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-avoid-collisions={avoidCollisions}\n data-collision-padding={collisionPadding}\n hidden={hidden}\n class={cn(\n \"bg-popover text-popover-foreground ring-foreground/10 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md p-1 shadow-md ring-1 duration-100 outline-none data-closed:overflow-hidden\",\n className\n )}\n {...props}\n >\n <slot />\n </div>\n </div>\n</div>\n",
24
24
  "type": "registry:ui"
25
25
  },
26
26
  {
27
27
  "path": "src/components/ui/dropdown-menu/dropdown-menu-item.astro",
28
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"button\"> & {\n disabled?: boolean\n variant?: \"default\" | \"destructive\"\n inset?: boolean\n}\n\nconst {\n class: className,\n type = \"button\",\n disabled,\n variant,\n inset,\n ...props\n} = Astro.props\n---\n\n<button\n data-slot=\"dropdown-menu-item\"\n data-disabled={disabled}\n data-variant={variant}\n data-inset={inset}\n disabled={disabled ? true : undefined}\n type={type}\n class={cn(\n \"group/dropdown-menu-item data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground not-data-[variant=destructive]:data-[highlighted]:**:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:data-[highlighted]:bg-destructive/10 data-[variant=destructive]:data-[highlighted]:text-destructive dark:data-[variant=destructive]:data-[highlighted]:bg-destructive/20 data-[variant=destructive]:*:[svg]:text-destructive relative flex w-full cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n>\n <slot />\n</button>\n",
28
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"button\"> &\n HTMLAttributes<\"a\"> & {\n as?: \"button\" | \"a\"\n disabled?: boolean\n variant?: \"default\" | \"destructive\"\n inset?: boolean\n }\n\nconst {\n as: Tag = \"href\" in Astro.props ? \"a\" : \"button\",\n class: className,\n type = \"button\",\n disabled,\n variant,\n inset,\n ...props\n} = Astro.props\n---\n\n<Tag\n data-slot=\"dropdown-menu-item\"\n data-disabled={disabled}\n data-variant={variant}\n data-inset={inset}\n disabled={Tag === \"button\" && disabled ? true : undefined}\n type={Tag === \"button\" ? type : undefined}\n class={cn(\n \"group/dropdown-menu-item data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground not-data-[variant=destructive]:data-[highlighted]:**:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:data-[highlighted]:bg-destructive/10 data-[variant=destructive]:data-[highlighted]:text-destructive dark:data-[variant=destructive]:data-[highlighted]:bg-destructive/20 data-[variant=destructive]:*:[svg]:text-destructive relative flex w-full cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n>\n <slot />\n</Tag>\n\n<script>\n // Data Slot owns selection; links also need native keyboard activation.\n document.addEventListener(\n \"keydown\",\n (event) => {\n if (\n event.defaultPrevented ||\n event.isComposing ||\n ![\"Enter\", \" \"].includes(event.key)\n )\n return\n const item =\n event.target instanceof Element\n ? event.target.closest('[data-slot=\"dropdown-menu-item\"][href]')\n : null\n if (\n !(item instanceof HTMLAnchorElement) ||\n item.getAttribute(\"aria-disabled\") === \"true\"\n )\n return\n event.preventDefault()\n event.stopPropagation()\n item.click()\n },\n true\n )\n</script>\n",
29
29
  "type": "registry:ui"
30
30
  },
31
31
  {
@@ -4,18 +4,18 @@
4
4
  "title": "Hover Card",
5
5
  "description": "For sighted users to preview content available behind a link.",
6
6
  "dependencies": [
7
- "@data-slot/hover-card",
8
- "@data-slot/core"
7
+ "@data-slot/hover-card@^1.0.2",
8
+ "@data-slot/core@^1.0.2"
9
9
  ],
10
10
  "files": [
11
11
  {
12
12
  "path": "src/components/ui/hover-card/hover-card.astro",
13
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n delay?: number\n skipDelayDuration?: number\n closeDelay?: number\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n portal?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n}\n\nconst {\n class: className,\n defaultOpen,\n open,\n delay = 700,\n skipDelayDuration = 300,\n closeDelay = 300,\n side = \"bottom\",\n align = \"center\",\n sideOffset = 4,\n alignOffset = 0,\n avoidCollisions = true,\n collisionPadding = 8,\n portal = true,\n closeOnClickOutside = true,\n closeOnEscape = true,\n ...props\n} = Astro.props\n---\n\n<div\n data-slot=\"hover-card\"\n data-default-open={defaultOpen}\n data-controlled-open={open}\n data-delay={delay}\n data-skip-delay-duration={skipDelayDuration}\n data-close-delay={closeDelay}\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-avoid-collisions={avoidCollisions}\n data-collision-padding={collisionPadding}\n data-portal={portal}\n data-close-on-click-outside={closeOnClickOutside}\n data-close-on-escape={closeOnEscape}\n class={cn(className)}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { getDataBool } from \"@data-slot/core\"\n import { createHoverCard } from \"@data-slot/hover-card\"\n\n const initialize = () => {\n document.querySelectorAll('[data-slot=\"hover-card\"]').forEach((root) => {\n createHoverCard(root, { open: getDataBool(root, \"controlledOpen\") })\n })\n }\n initialize()\n document.addEventListener(\"astro:page-load\", initialize)\n</script>\n",
13
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n mountStrategy?: \"lazy\" | \"eager\"\n defaultOpen?: boolean\n open?: boolean\n delay?: number\n skipDelayDuration?: number\n closeDelay?: number\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n portal?: boolean\n closeOnClickOutside?: boolean\n closeOnEscape?: boolean\n}\n\nconst {\n mountStrategy,\n class: className,\n defaultOpen,\n open,\n delay = 700,\n skipDelayDuration = 300,\n closeDelay = 300,\n side = \"bottom\",\n align = \"center\",\n sideOffset = 4,\n alignOffset = 0,\n avoidCollisions = true,\n collisionPadding = 8,\n portal = true,\n closeOnClickOutside = true,\n closeOnEscape = true,\n ...props\n} = Astro.props\n---\n\n<div\n data-slot=\"hover-card\"\n data-mount-strategy={mountStrategy}\n data-default-open={defaultOpen}\n data-controlled-open={open}\n data-delay={delay}\n data-skip-delay-duration={skipDelayDuration}\n data-close-delay={closeDelay}\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-avoid-collisions={avoidCollisions}\n data-collision-padding={collisionPadding}\n data-portal={portal}\n data-close-on-click-outside={closeOnClickOutside}\n data-close-on-escape={closeOnEscape}\n class={cn(className)}\n {...props}\n>\n <slot />\n</div>\n\n<script>\n import { getDataBool, getRoots, hasRootBinding } from \"@data-slot/core\"\n import { createHoverCard } from \"@data-slot/hover-card\"\n\n const controllers: ReturnType<typeof createHoverCard>[] = []\n const initialize = () => {\n for (const root of getRoots(document, \"hover-card\")) {\n if (hasRootBinding(root, \"@data-slot/hover-card\")) continue\n controllers.push(\n createHoverCard(root, { open: getDataBool(root, \"controlledOpen\") })\n )\n }\n }\n initialize()\n document.addEventListener(\"astro:page-load\", initialize)\n document.addEventListener(\"astro:before-swap\", () => {\n for (const controller of controllers) controller.destroy()\n controllers.length = 0\n })\n</script>\n",
14
14
  "type": "registry:ui"
15
15
  },
16
16
  {
17
17
  "path": "src/components/ui/hover-card/hover-card-content.astro",
18
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n<div data-slot=\"hover-card-portal\">\n <div\n data-slot=\"hover-card-positioner\"\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-avoid-collisions={avoidCollisions}\n data-collision-padding={collisionPadding}\n class=\"isolate z-50\"\n >\n <div\n data-slot=\"hover-card-content\"\n hidden={hidden}\n class={cn(\n \"bg-popover text-popover-foreground ring-foreground/10 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 z-50 w-64 origin-(--transform-origin) rounded-lg p-4 text-sm shadow-md ring-1 outline-hidden duration-100\",\n className\n )}\n {...props}\n >\n <slot />\n </div>\n </div>\n</div>\n",
18
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n avoidCollisions?: boolean\n collisionPadding?: number\n}\n\nconst {\n class: className,\n hidden = true,\n side,\n align,\n sideOffset,\n alignOffset,\n avoidCollisions,\n collisionPadding,\n ...props\n} = Astro.props\n---\n\n<div data-slot=\"hover-card-portal\">\n <div\n data-slot=\"hover-card-positioner\"\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-avoid-collisions={avoidCollisions}\n data-collision-padding={collisionPadding}\n class=\"isolate z-[1000]\"\n >\n <div\n data-slot=\"hover-card-content\"\n hidden={hidden}\n class={cn(\n \"bg-popover text-popover-foreground ring-foreground/10 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 z-50 w-64 origin-(--transform-origin) rounded-lg p-4 text-sm shadow-md ring-1 outline-hidden duration-100\",\n className\n )}\n {...props}\n >\n <slot />\n </div>\n </div>\n</div>\n",
19
19
  "type": "registry:ui"
20
20
  },
21
21
  {
@@ -18,7 +18,7 @@
18
18
  },
19
19
  {
20
20
  "path": "registry/init/global.css",
21
- "content": "@import \"tailwindcss\";\n@import \"tw-animate-css\";\n@import \"shadcn/tailwind.css\";\n\n@custom-variant dark (&:where(.dark, .dark *));\n\n:root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0 0);\n --primary: oklch(0.5488 0.2498 261.783);\n --primary-foreground: oklch(1 0 0);\n --secondary: oklch(0.97 0 0);\n --secondary-foreground: oklch(0.205 0 0);\n --muted: oklch(0.97 0 0);\n --muted-foreground: oklch(0.556 0 0);\n --accent: oklch(0.97 0 0);\n --accent-foreground: oklch(0.205 0 0);\n --destructive: oklch(0.577 0.245 27.325);\n --destructive-foreground: oklch(1 0 0);\n --border: oklch(0.922 0 0);\n --input: oklch(0.922 0 0);\n --ring: oklch(0.708 0 0);\n --chart-1: oklch(0.81 0.1 252);\n --chart-2: oklch(0.62 0.19 260);\n --chart-3: oklch(0.55 0.22 263);\n --chart-4: oklch(0.49 0.22 264);\n --chart-5: oklch(0.42 0.18 266);\n --sidebar: oklch(0.985 0 0);\n --sidebar-foreground: oklch(0.145 0 0);\n --sidebar-primary: oklch(0.5488 0.2498 261.783);\n --sidebar-primary-foreground: oklch(1 0 0);\n --sidebar-accent: oklch(0.97 0 0);\n --sidebar-accent-foreground: oklch(0.205 0 0);\n --sidebar-border: oklch(0.922 0 0);\n --sidebar-ring: oklch(0.708 0 0);\n --radius: 0.625rem;\n --shadow-x: 0;\n --shadow-y: 1px;\n --shadow-blur: 3px;\n --shadow-spread: 0px;\n --shadow-opacity: 0.1;\n --shadow-color: oklch(0 0 0);\n --shadow-2xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);\n --shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);\n --shadow-sm:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);\n --shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);\n --shadow-md:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1);\n --shadow-lg:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1);\n --shadow-xl:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1);\n --shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25);\n --tracking-normal: 0em;\n --spacing: 0.25rem;\n}\n\n.dark {\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.205 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.269 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.686 0.2105 41.139);\n --primary-foreground: oklch(1 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.371 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --destructive-foreground: oklch(0.985 0 0);\n --border: oklch(0.275 0 0);\n --input: oklch(0.325 0 0);\n --ring: oklch(0.556 0 0);\n --chart-1: oklch(0.81 0.1 252);\n --chart-2: oklch(0.62 0.19 260);\n --chart-3: oklch(0.55 0.22 263);\n --chart-4: oklch(0.49 0.22 264);\n --chart-5: oklch(0.42 0.18 266);\n --sidebar: oklch(0.205 0 0);\n --sidebar-foreground: oklch(0.985 0 0);\n --sidebar-primary: oklch(0.686 0.2105 41.139);\n --sidebar-primary-foreground: oklch(1 0 0);\n --sidebar-accent: oklch(0.269 0 0);\n --sidebar-accent-foreground: oklch(0.985 0 0);\n --sidebar-border: oklch(0.275 0 0);\n --sidebar-ring: oklch(0.439 0 0);\n --radius: 0.625rem;\n --shadow-x: 0;\n --shadow-y: 1px;\n --shadow-blur: 3px;\n --shadow-spread: 0px;\n --shadow-opacity: 0.1;\n --shadow-color: oklch(0 0 0);\n --shadow-2xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);\n --shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);\n --shadow-sm:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);\n --shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);\n --shadow-md:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1);\n --shadow-lg:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1);\n --shadow-xl:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1);\n --shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25);\n}\n\n@theme inline {\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --color-card: var(--card);\n --color-card-foreground: var(--card-foreground);\n --color-popover: var(--popover);\n --color-popover-foreground: var(--popover-foreground);\n --color-primary: var(--primary);\n --color-primary-foreground: var(--primary-foreground);\n --color-secondary: var(--secondary);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-muted: var(--muted);\n --color-muted-foreground: var(--muted-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --color-destructive: var(--destructive);\n --color-destructive-foreground: var(--destructive-foreground);\n --color-border: var(--border);\n --color-input: var(--input);\n --color-ring: var(--ring);\n --color-chart-1: var(--chart-1);\n --color-chart-2: var(--chart-2);\n --color-chart-3: var(--chart-3);\n --color-chart-4: var(--chart-4);\n --color-chart-5: var(--chart-5);\n --color-sidebar: var(--sidebar);\n --color-sidebar-foreground: var(--sidebar-foreground);\n --color-sidebar-primary: var(--sidebar-primary);\n --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);\n --color-sidebar-accent: var(--sidebar-accent);\n --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);\n --color-sidebar-border: var(--sidebar-border);\n --color-sidebar-ring: var(--sidebar-ring);\n\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n\n --shadow-2xs: var(--shadow-2xs);\n --shadow-xs: var(--shadow-xs);\n --shadow-sm: var(--shadow-sm);\n --shadow: var(--shadow);\n --shadow-md: var(--shadow-md);\n --shadow-lg: var(--shadow-lg);\n --shadow-xl: var(--shadow-xl);\n --shadow-2xl: var(--shadow-2xl);\n}\n\n@layer base {\n * {\n @apply border-border outline-ring/50;\n }\n html {\n @apply font-sans;\n }\n body {\n @apply bg-background text-foreground font-sans;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n ::before,\n ::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n scroll-behavior: auto !important;\n }\n}\n",
21
+ "content": "@import \"tailwindcss\";\n@import \"tw-animate-css\";\n@import \"shadcn/tailwind.css\";\n\n@custom-variant dark (&:where(.dark, .dark *));\n\n:root {\n --background: oklch(1 0 0);\n --foreground: oklch(0.145 0 0);\n --card: oklch(1 0 0);\n --card-foreground: oklch(0.145 0 0);\n --popover: oklch(1 0 0);\n --popover-foreground: oklch(0.145 0 0);\n --primary: oklch(0.5488 0.2498 261.783);\n --primary-foreground: oklch(1 0 0);\n --secondary: oklch(0.97 0 0);\n --secondary-foreground: oklch(0.205 0 0);\n --muted: oklch(0.97 0 0);\n --muted-foreground: oklch(0.556 0 0);\n --accent: oklch(0.97 0 0);\n --accent-foreground: oklch(0.205 0 0);\n --destructive: oklch(0.577 0.245 27.325);\n --destructive-foreground: oklch(1 0 0);\n --border: oklch(0.922 0 0);\n --input: oklch(0.922 0 0);\n --ring: oklch(0.708 0 0);\n --chart-1: oklch(0.81 0.1 252);\n --chart-2: oklch(0.62 0.19 260);\n --chart-3: oklch(0.55 0.22 263);\n --chart-4: oklch(0.49 0.22 264);\n --chart-5: oklch(0.42 0.18 266);\n --sidebar: oklch(0.985 0 0);\n --sidebar-foreground: oklch(0.145 0 0);\n --sidebar-primary: oklch(0.5488 0.2498 261.783);\n --sidebar-primary-foreground: oklch(1 0 0);\n --sidebar-accent: oklch(0.97 0 0);\n --sidebar-accent-foreground: oklch(0.205 0 0);\n --sidebar-border: oklch(0.922 0 0);\n --sidebar-ring: oklch(0.708 0 0);\n --radius: 0.625rem;\n --shadow-x: 0;\n --shadow-y: 1px;\n --shadow-blur: 3px;\n --shadow-spread: 0px;\n --shadow-opacity: 0.1;\n --shadow-color: oklch(0 0 0);\n --shadow-2xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);\n --shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);\n --shadow-sm:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);\n --shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);\n --shadow-md:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1);\n --shadow-lg:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1);\n --shadow-xl:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1);\n --shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25);\n --tracking-normal: 0em;\n --spacing: 0.25rem;\n}\n\n.dark {\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.205 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.269 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.686 0.2105 41.139);\n --primary-foreground: oklch(1 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.371 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.704 0.191 22.216);\n --destructive-foreground: oklch(0.985 0 0);\n --border: oklch(0.275 0 0);\n --input: oklch(0.325 0 0);\n --ring: oklch(0.556 0 0);\n --chart-1: oklch(0.81 0.1 252);\n --chart-2: oklch(0.62 0.19 260);\n --chart-3: oklch(0.55 0.22 263);\n --chart-4: oklch(0.49 0.22 264);\n --chart-5: oklch(0.42 0.18 266);\n --sidebar: oklch(0.205 0 0);\n --sidebar-foreground: oklch(0.985 0 0);\n --sidebar-primary: oklch(0.686 0.2105 41.139);\n --sidebar-primary-foreground: oklch(1 0 0);\n --sidebar-accent: oklch(0.269 0 0);\n --sidebar-accent-foreground: oklch(0.985 0 0);\n --sidebar-border: oklch(0.275 0 0);\n --sidebar-ring: oklch(0.439 0 0);\n --radius: 0.625rem;\n --shadow-x: 0;\n --shadow-y: 1px;\n --shadow-blur: 3px;\n --shadow-spread: 0px;\n --shadow-opacity: 0.1;\n --shadow-color: oklch(0 0 0);\n --shadow-2xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);\n --shadow-xs: 0 1px 3px 0px hsl(0 0% 0% / 0.05);\n --shadow-sm:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);\n --shadow: 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 1px 2px -1px hsl(0 0% 0% / 0.1);\n --shadow-md:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 2px 4px -1px hsl(0 0% 0% / 0.1);\n --shadow-lg:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 4px 6px -1px hsl(0 0% 0% / 0.1);\n --shadow-xl:\n 0 1px 3px 0px hsl(0 0% 0% / 0.1), 0 8px 10px -1px hsl(0 0% 0% / 0.1);\n --shadow-2xl: 0 1px 3px 0px hsl(0 0% 0% / 0.25);\n}\n\n@theme inline {\n --font-heading: var(--font-sans);\n\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --color-card: var(--card);\n --color-card-foreground: var(--card-foreground);\n --color-popover: var(--popover);\n --color-popover-foreground: var(--popover-foreground);\n --color-primary: var(--primary);\n --color-primary-foreground: var(--primary-foreground);\n --color-secondary: var(--secondary);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-muted: var(--muted);\n --color-muted-foreground: var(--muted-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --color-destructive: var(--destructive);\n --color-destructive-foreground: var(--destructive-foreground);\n --color-border: var(--border);\n --color-input: var(--input);\n --color-ring: var(--ring);\n --color-chart-1: var(--chart-1);\n --color-chart-2: var(--chart-2);\n --color-chart-3: var(--chart-3);\n --color-chart-4: var(--chart-4);\n --color-chart-5: var(--chart-5);\n --color-sidebar: var(--sidebar);\n --color-sidebar-foreground: var(--sidebar-foreground);\n --color-sidebar-primary: var(--sidebar-primary);\n --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);\n --color-sidebar-accent: var(--sidebar-accent);\n --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);\n --color-sidebar-border: var(--sidebar-border);\n --color-sidebar-ring: var(--sidebar-ring);\n\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n\n --shadow-2xs: var(--shadow-2xs);\n --shadow-xs: var(--shadow-xs);\n --shadow-sm: var(--shadow-sm);\n --shadow: var(--shadow);\n --shadow-md: var(--shadow-md);\n --shadow-lg: var(--shadow-lg);\n --shadow-xl: var(--shadow-xl);\n --shadow-2xl: var(--shadow-2xl);\n}\n\n@layer base {\n * {\n @apply border-border outline-ring/50;\n }\n html {\n @apply font-sans;\n }\n body {\n @apply bg-background text-foreground font-sans;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n ::before,\n ::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n scroll-behavior: auto !important;\n }\n}\n",
22
22
  "type": "registry:style",
23
23
  "target": "src/styles/global.css"
24
24
  }
@@ -5,7 +5,6 @@
5
5
  "description": "Add addons, buttons, and helper content to inputs.",
6
6
  "registryDependencies": [
7
7
  "@fulldev/button",
8
- "@fulldev/dropdown-menu",
9
8
  "@fulldev/input",
10
9
  "@fulldev/textarea"
11
10
  ],
@@ -3,6 +3,9 @@
3
3
  "name": "layout",
4
4
  "title": "Layout",
5
5
  "description": "Page-shell primitives for the root html, head, body, and main structure.",
6
+ "dependencies": [
7
+ "@lexingtonthemes/seo@^0.2.0"
8
+ ],
6
9
  "files": [
7
10
  {
8
11
  "path": "src/components/ui/layout/layout.astro",
@@ -4,13 +4,13 @@
4
4
  "title": "Navigation Menu",
5
5
  "description": "A collection of links for navigating websites.",
6
6
  "dependencies": [
7
- "@data-slot/navigation-menu",
7
+ "@data-slot/navigation-menu@^1.0.2",
8
8
  "@lucide/astro"
9
9
  ],
10
10
  "files": [
11
11
  {
12
12
  "path": "src/components/ui/navigation-menu/navigation-menu.astro",
13
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\nimport NavigationMenuPositioner from \"./navigation-menu-positioner.astro\"\n\ntype Props = HTMLAttributes<\"nav\"> & {\n delayOpen?: number\n delayClose?: number\n openOnFocus?: boolean\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n positionMethod?: \"absolute\" | \"fixed\"\n safeTriangle?: boolean\n debugSafeTriangle?: boolean\n}\n\nconst {\n class: className = \"\",\n delayOpen = 0,\n delayClose = 0,\n openOnFocus,\n side = \"bottom\",\n align = \"start\",\n sideOffset = 0,\n alignOffset = 0,\n positionMethod = \"absolute\",\n safeTriangle,\n debugSafeTriangle,\n ...props\n} = Astro.props\n---\n\n<nav\n {...props}\n data-slot=\"navigation-menu\"\n data-delay-open={delayOpen}\n data-delay-close={delayClose}\n data-open-on-focus={openOnFocus}\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-position-method={positionMethod}\n data-safe-triangle={safeTriangle}\n data-debug-safe-triangle={debugSafeTriangle}\n class={cn(\n \"group/navigation-menu relative flex max-w-max flex-1 items-center justify-center\",\n className\n )}\n>\n <slot />\n <NavigationMenuPositioner align={align} />\n</nav>\n\n<script>\n import { create } from \"@data-slot/navigation-menu\"\n\n create()\n document.addEventListener(\"astro:page-load\", () => create())\n</script>\n",
13
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\nimport NavigationMenuPositioner from \"./navigation-menu-positioner.astro\"\n\ntype Props = HTMLAttributes<\"nav\"> & {\n mountStrategy?: \"lazy\" | \"eager\"\n delayOpen?: number\n delayClose?: number\n openOnFocus?: boolean\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n align?: \"start\" | \"center\" | \"end\"\n sideOffset?: number\n alignOffset?: number\n positionMethod?: \"absolute\" | \"fixed\"\n safeTriangle?: boolean\n debugSafeTriangle?: boolean\n}\n\nconst {\n mountStrategy,\n class: className = \"\",\n delayOpen = 0,\n delayClose = 0,\n openOnFocus,\n side = \"bottom\",\n align = \"start\",\n sideOffset = 8,\n alignOffset = 0,\n positionMethod = \"absolute\",\n safeTriangle,\n debugSafeTriangle,\n ...props\n} = Astro.props\n---\n\n<nav\n {...props}\n data-slot=\"navigation-menu\"\n data-mount-strategy={mountStrategy}\n data-delay-open={delayOpen}\n data-delay-close={delayClose}\n data-open-on-focus={openOnFocus}\n data-side={side}\n data-align={align}\n data-side-offset={sideOffset}\n data-align-offset={alignOffset}\n data-position-method={positionMethod}\n data-safe-triangle={safeTriangle}\n data-debug-safe-triangle={debugSafeTriangle}\n class={cn(\n \"group/navigation-menu relative flex max-w-max flex-1 items-center justify-center\",\n className\n )}\n>\n <slot />\n <NavigationMenuPositioner {side} {sideOffset} {align} {alignOffset} />\n</nav>\n\n<script>\n import { create } from \"@data-slot/navigation-menu\"\n\n const controllers: ReturnType<typeof create> = []\n const initialize = () => controllers.push(...create())\n initialize()\n document.addEventListener(\"astro:page-load\", initialize)\n document.addEventListener(\"astro:before-swap\", () => {\n for (const controller of controllers) controller.destroy()\n controllers.length = 0\n })\n</script>\n",
14
14
  "type": "registry:ui"
15
15
  },
16
16
  {
@@ -50,7 +50,7 @@
50
50
  },
51
51
  {
52
52
  "path": "src/components/ui/navigation-menu/navigation-menu-positioner.astro",
53
- "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n sideOffset?: number\n align?: \"start\" | \"center\" | \"end\"\n alignOffset?: number\n}\n\nconst {\n class: className,\n side = \"bottom\",\n sideOffset = 8,\n align = \"start\",\n alignOffset = 0,\n ...props\n} = Astro.props\n---\n\n<div data-slot=\"navigation-menu-portal\">\n <div\n {...props}\n data-slot=\"navigation-menu-positioner\"\n data-side={side}\n data-side-offset={sideOffset}\n data-align={align}\n data-align-offset={alignOffset}\n class={cn(\n \"isolate z-50 h-(--positioner-height) w-(--positioner-width) max-w-(--available-width) transition-[top,left,right,bottom] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] data-instant:transition-none data-[side=bottom]:before:top-[-10px] data-[side=bottom]:before:right-0 data-[side=bottom]:before:left-0\",\n className\n )}\n >\n <div\n data-slot=\"navigation-menu-popup\"\n hidden\n class=\"data-[ending-style]:easing-[ease] xs:w-(--popup-width) bg-popover text-popover-foreground ring-foreground/10 relative h-(--popup-height) w-(--popup-width) origin-(--transform-origin) rounded-lg shadow ring-1 transition-[opacity,transform,width,height,scale,translate] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] outline-none data-ending-style:scale-90 data-ending-style:opacity-0 data-ending-style:duration-150 data-starting-style:scale-90 data-starting-style:opacity-0\"\n >\n <div\n data-slot=\"navigation-menu-viewport\"\n hidden\n class=\"relative size-full overflow-hidden\"\n >\n </div>\n </div>\n </div>\n</div>\n",
53
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"div\"> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n sideOffset?: number\n align?: \"start\" | \"center\" | \"end\"\n alignOffset?: number\n}\n\nconst {\n class: className,\n side = \"bottom\",\n sideOffset = 8,\n align = \"start\",\n alignOffset = 0,\n ...props\n} = Astro.props\n---\n\n<div data-slot=\"navigation-menu-portal\">\n <div\n {...props}\n data-slot=\"navigation-menu-positioner\"\n data-side={side}\n data-side-offset={sideOffset}\n data-align={align}\n data-align-offset={alignOffset}\n class={cn(\n \"isolate z-[1000] h-(--positioner-height) w-(--positioner-width) max-w-(--available-width) transition-[top,left,right,bottom] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] data-instant:transition-none data-[side=bottom]:before:top-[-10px] data-[side=bottom]:before:right-0 data-[side=bottom]:before:left-0\",\n className\n )}\n >\n <div\n data-slot=\"navigation-menu-popup\"\n hidden\n class=\"data-[ending-style]:easing-[ease] xs:w-(--popup-width) bg-popover text-popover-foreground ring-foreground/10 relative h-(--popup-height) w-(--popup-width) origin-(--transform-origin) rounded-lg shadow ring-1 transition-[opacity,transform,width,height,scale,translate] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)] outline-none data-ending-style:scale-90 data-ending-style:opacity-0 data-ending-style:duration-150 data-starting-style:scale-90 data-starting-style:opacity-0\"\n >\n <div\n data-slot=\"navigation-menu-viewport\"\n hidden\n class=\"relative size-full overflow-hidden\"\n >\n </div>\n </div>\n </div>\n</div>\n",
54
54
  "type": "registry:ui"
55
55
  },
56
56
  {
@@ -0,0 +1,59 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
+ "name": "pagination",
4
+ "title": "Pagination",
5
+ "description": "Page navigation with previous, next, numbered, and overflow links.",
6
+ "dependencies": [
7
+ "@lucide/astro"
8
+ ],
9
+ "registryDependencies": [
10
+ "@fulldev/button"
11
+ ],
12
+ "files": [
13
+ {
14
+ "path": "src/components/ui/pagination/index.ts",
15
+ "content": "export { default as Pagination } from \"./pagination.astro\"\nexport { default as PaginationContent } from \"./pagination-content.astro\"\nexport { default as PaginationEllipsis } from \"./pagination-ellipsis.astro\"\nexport { default as PaginationItem } from \"./pagination-item.astro\"\nexport { default as PaginationLink } from \"./pagination-link.astro\"\nexport { default as PaginationNext } from \"./pagination-next.astro\"\nexport { default as PaginationPrevious } from \"./pagination-previous.astro\"\n",
16
+ "type": "registry:ui"
17
+ },
18
+ {
19
+ "path": "src/components/ui/pagination/pagination-content.astro",
20
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"ul\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<ul\n data-slot=\"pagination-content\"\n class={cn(\"flex items-center gap-1\", className)}\n {...props}\n>\n <slot />\n</ul>\n",
21
+ "type": "registry:ui"
22
+ },
23
+ {
24
+ "path": "src/components/ui/pagination/pagination-ellipsis.astro",
25
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport EllipsisIcon from \"@lucide/astro/icons/ellipsis\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"span\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<span\n data-slot=\"pagination-ellipsis\"\n class={cn(\n \"flex size-9 items-center justify-center [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n>\n <EllipsisIcon aria-hidden=\"true\" />\n <span class=\"sr-only\">More pages</span>\n</span>\n",
26
+ "type": "registry:ui"
27
+ },
28
+ {
29
+ "path": "src/components/ui/pagination/pagination-item.astro",
30
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\ntype Props = HTMLAttributes<\"li\">\n\nconst { ...props } = Astro.props\n---\n\n<li data-slot=\"pagination-item\" {...props}>\n <slot />\n</li>\n",
31
+ "type": "registry:ui"
32
+ },
33
+ {
34
+ "path": "src/components/ui/pagination/pagination-link.astro",
35
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button, type ButtonVariantProps } from \"@/components/ui/button\"\n\ntype Props = HTMLAttributes<\"a\"> & {\n isActive?: boolean\n disabled?: boolean\n size?: ButtonVariantProps[\"size\"]\n}\n\nconst {\n class: className,\n href,\n isActive,\n disabled,\n size = \"icon\",\n tabindex,\n ...props\n} = Astro.props\n---\n\n<Button\n as=\"a\"\n data-slot=\"pagination-link\"\n data-active={isActive ? \"true\" : undefined}\n href={disabled ? undefined : href}\n aria-current={isActive ? \"page\" : undefined}\n aria-disabled={disabled ? \"true\" : undefined}\n tabindex={disabled ? -1 : tabindex}\n variant={isActive ? \"outline\" : \"ghost\"}\n size={size}\n class={cn(\n \"aria-disabled:pointer-events-none aria-disabled:opacity-50\",\n className\n )}\n {...props}\n>\n <slot />\n</Button>\n",
36
+ "type": "registry:ui"
37
+ },
38
+ {
39
+ "path": "src/components/ui/pagination/pagination-next.astro",
40
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport ChevronRightIcon from \"@lucide/astro/icons/chevron-right\"\n\nimport { cn } from \"@/lib/utils\"\nimport type { ButtonVariantProps } from \"@/components/ui/button\"\n\nimport PaginationLink from \"./pagination-link.astro\"\n\ntype Props = HTMLAttributes<\"a\"> & {\n text?: string\n disabled?: boolean\n size?: ButtonVariantProps[\"size\"]\n}\n\nconst { class: className, text = \"Next\", ...props } = Astro.props\n---\n\n<PaginationLink\n aria-label=\"Go to next page\"\n size=\"default\"\n class={cn(\"pr-2!\", className)}\n {...props}\n>\n <span class=\"hidden sm:block\">{text}</span>\n <ChevronRightIcon data-icon=\"inline-end\" class=\"rtl:rotate-180\" />\n</PaginationLink>\n",
41
+ "type": "registry:ui"
42
+ },
43
+ {
44
+ "path": "src/components/ui/pagination/pagination-previous.astro",
45
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\nimport ChevronLeftIcon from \"@lucide/astro/icons/chevron-left\"\n\nimport { cn } from \"@/lib/utils\"\nimport type { ButtonVariantProps } from \"@/components/ui/button\"\n\nimport PaginationLink from \"./pagination-link.astro\"\n\ntype Props = HTMLAttributes<\"a\"> & {\n text?: string\n disabled?: boolean\n size?: ButtonVariantProps[\"size\"]\n}\n\nconst { class: className, text = \"Previous\", ...props } = Astro.props\n---\n\n<PaginationLink\n aria-label=\"Go to previous page\"\n size=\"default\"\n class={cn(\"pl-2!\", className)}\n {...props}\n>\n <ChevronLeftIcon data-icon=\"inline-start\" class=\"rtl:rotate-180\" />\n <span class=\"hidden sm:block\">{text}</span>\n</PaginationLink>\n",
46
+ "type": "registry:ui"
47
+ },
48
+ {
49
+ "path": "src/components/ui/pagination/pagination.astro",
50
+ "content": "---\nimport type { HTMLAttributes } from \"astro/types\"\n\nimport { cn } from \"@/lib/utils\"\n\ntype Props = HTMLAttributes<\"nav\">\n\nconst { class: className, ...props } = Astro.props\n---\n\n<nav\n role=\"navigation\"\n aria-label=\"pagination\"\n data-slot=\"pagination\"\n class={cn(\"mx-auto flex w-full justify-center\", className)}\n {...props}\n>\n <slot />\n</nav>\n",
51
+ "type": "registry:ui"
52
+ }
53
+ ],
54
+ "docs": "https://ui.full.dev/components/pagination/",
55
+ "categories": [
56
+ "ui"
57
+ ],
58
+ "type": "registry:ui"
59
+ }