@dogsbay/ui 0.2.0-beta.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 (322) hide show
  1. package/package.json +38 -0
  2. package/src/accordion/Accordion.astro +38 -0
  3. package/src/accordion/AccordionContent.astro +25 -0
  4. package/src/accordion/AccordionItem.astro +26 -0
  5. package/src/accordion/AccordionTrigger.astro +38 -0
  6. package/src/accordion/accordion.ts +189 -0
  7. package/src/accordion/index.ts +4 -0
  8. package/src/alert/Alert.astro +69 -0
  9. package/src/alert/AlertDescription.astro +17 -0
  10. package/src/alert/AlertTitle.astro +21 -0
  11. package/src/alert/CollapsibleAlert.astro +103 -0
  12. package/src/alert/icon.ts +32 -0
  13. package/src/alert/index.ts +4 -0
  14. package/src/alert/variants.ts +29 -0
  15. package/src/alert-dialog/AlertDialog.astro +16 -0
  16. package/src/alert-dialog/AlertDialogAction.astro +23 -0
  17. package/src/alert-dialog/AlertDialogCancel.astro +23 -0
  18. package/src/alert-dialog/AlertDialogContent.astro +37 -0
  19. package/src/alert-dialog/AlertDialogDescription.astro +18 -0
  20. package/src/alert-dialog/AlertDialogFooter.astro +18 -0
  21. package/src/alert-dialog/AlertDialogHeader.astro +18 -0
  22. package/src/alert-dialog/AlertDialogTitle.astro +18 -0
  23. package/src/alert-dialog/AlertDialogTrigger.astro +24 -0
  24. package/src/alert-dialog/alert-dialog.ts +154 -0
  25. package/src/alert-dialog/index.ts +9 -0
  26. package/src/api-doc/ApiDoc.astro +52 -0
  27. package/src/api-doc/index.ts +1 -0
  28. package/src/api-layout/ApiCodePanel.astro +21 -0
  29. package/src/api-layout/ApiLayout.astro +29 -0
  30. package/src/api-layout/ExampleBlock.astro +63 -0
  31. package/src/api-params/ApiParams.astro +96 -0
  32. package/src/api-params/index.ts +1 -0
  33. package/src/api-source/ApiSource.astro +20 -0
  34. package/src/api-source/api-source.css +32 -0
  35. package/src/api-source/index.ts +1 -0
  36. package/src/api-symbol/ApiSymbol.astro +48 -0
  37. package/src/api-symbol/api-symbol.css +89 -0
  38. package/src/api-symbol/index.ts +1 -0
  39. package/src/api-url-bar/ApiUrlBar.astro +63 -0
  40. package/src/avatar/Avatar.astro +57 -0
  41. package/src/avatar/index.ts +1 -0
  42. package/src/badge/Badge.astro +37 -0
  43. package/src/badge/index.ts +1 -0
  44. package/src/breadcrumb/Breadcrumb.astro +32 -0
  45. package/src/breadcrumb/BreadcrumbEllipsis.astro +32 -0
  46. package/src/breadcrumb/BreadcrumbItem.astro +41 -0
  47. package/src/breadcrumb/BreadcrumbSeparator.astro +33 -0
  48. package/src/breadcrumb/index.ts +4 -0
  49. package/src/button/Button.astro +70 -0
  50. package/src/button/index.ts +1 -0
  51. package/src/card/Card.astro +17 -0
  52. package/src/card/CardContent.astro +17 -0
  53. package/src/card/CardDescription.astro +17 -0
  54. package/src/card/CardFooter.astro +17 -0
  55. package/src/card/CardHeader.astro +17 -0
  56. package/src/card/CardTitle.astro +17 -0
  57. package/src/card/index.ts +6 -0
  58. package/src/checkbox/Checkbox.astro +70 -0
  59. package/src/checkbox/index.ts +1 -0
  60. package/src/checkbox-group/CheckboxGroup.astro +38 -0
  61. package/src/checkbox-group/checkbox-group.ts +53 -0
  62. package/src/checkbox-group/index.ts +1 -0
  63. package/src/code-block/CodeBlock.astro +160 -0
  64. package/src/code-rich/CodeRich.astro +267 -0
  65. package/src/code-rich/code-rich.css +68 -0
  66. package/src/code-rich/index.ts +1 -0
  67. package/src/code-samples/CodeSamples.astro +59 -0
  68. package/src/collapsible/Collapsible.astro +35 -0
  69. package/src/collapsible/CollapsibleContent.astro +24 -0
  70. package/src/collapsible/CollapsibleTrigger.astro +23 -0
  71. package/src/collapsible/collapsible.ts +42 -0
  72. package/src/collapsible/index.ts +3 -0
  73. package/src/combobox/Combobox.astro +53 -0
  74. package/src/combobox/ComboboxEmpty.astro +18 -0
  75. package/src/combobox/ComboboxItem.astro +28 -0
  76. package/src/combobox/combobox.ts +179 -0
  77. package/src/combobox/index.ts +3 -0
  78. package/src/command/Command.astro +22 -0
  79. package/src/command/CommandEmpty.astro +18 -0
  80. package/src/command/CommandGroup.astro +24 -0
  81. package/src/command/CommandInput.astro +49 -0
  82. package/src/command/CommandItem.astro +26 -0
  83. package/src/command/CommandList.astro +19 -0
  84. package/src/command/CommandSeparator.astro +16 -0
  85. package/src/command/CommandShortcut.astro +18 -0
  86. package/src/command/command.ts +212 -0
  87. package/src/command/index.ts +8 -0
  88. package/src/content-renderer/ContentRenderer.astro +410 -0
  89. package/src/content-renderer/InlineRenderer.astro +149 -0
  90. package/src/context-menu/ContextMenu.astro +22 -0
  91. package/src/context-menu/ContextMenuContent.astro +24 -0
  92. package/src/context-menu/ContextMenuItem.astro +49 -0
  93. package/src/context-menu/ContextMenuSeparator.astro +14 -0
  94. package/src/context-menu/ContextMenuShortcut.astro +14 -0
  95. package/src/context-menu/ContextMenuTrigger.astro +22 -0
  96. package/src/context-menu/context-menu.ts +238 -0
  97. package/src/context-menu/index.ts +6 -0
  98. package/src/copy-button/CopyButton.astro +88 -0
  99. package/src/copy-button/index.ts +1 -0
  100. package/src/diagram/Diagram.astro +15 -0
  101. package/src/diagram/index.ts +1 -0
  102. package/src/dialog/Dialog.astro +22 -0
  103. package/src/dialog/DialogClose.astro +32 -0
  104. package/src/dialog/DialogContent.astro +37 -0
  105. package/src/dialog/DialogDescription.astro +22 -0
  106. package/src/dialog/DialogFooter.astro +18 -0
  107. package/src/dialog/DialogHeader.astro +18 -0
  108. package/src/dialog/DialogTitle.astro +18 -0
  109. package/src/dialog/DialogTrigger.astro +33 -0
  110. package/src/dialog/dialog.ts +291 -0
  111. package/src/dialog/index.ts +8 -0
  112. package/src/docs-footer/DocsFooter.astro +50 -0
  113. package/src/docs-header/DocsHeader.astro +32 -0
  114. package/src/docs-layout/DocsLayout.astro +187 -0
  115. package/src/docs-layout/index.ts +1 -0
  116. package/src/drawer/Drawer.astro +12 -0
  117. package/src/drawer/DrawerClose.astro +12 -0
  118. package/src/drawer/DrawerContent.astro +46 -0
  119. package/src/drawer/DrawerDescription.astro +10 -0
  120. package/src/drawer/DrawerFooter.astro +10 -0
  121. package/src/drawer/DrawerHandle.astro +16 -0
  122. package/src/drawer/DrawerHeader.astro +10 -0
  123. package/src/drawer/DrawerTitle.astro +10 -0
  124. package/src/drawer/DrawerTrigger.astro +25 -0
  125. package/src/drawer/drawer.ts +262 -0
  126. package/src/drawer/index.ts +9 -0
  127. package/src/dropdown-menu/DropdownMenu.astro +22 -0
  128. package/src/dropdown-menu/DropdownMenuContent.astro +33 -0
  129. package/src/dropdown-menu/DropdownMenuGroup.astro +17 -0
  130. package/src/dropdown-menu/DropdownMenuItem.astro +48 -0
  131. package/src/dropdown-menu/DropdownMenuLabel.astro +28 -0
  132. package/src/dropdown-menu/DropdownMenuSeparator.astro +21 -0
  133. package/src/dropdown-menu/DropdownMenuShortcut.astro +18 -0
  134. package/src/dropdown-menu/DropdownMenuTrigger.astro +34 -0
  135. package/src/dropdown-menu/dropdown-menu.ts +348 -0
  136. package/src/dropdown-menu/index.ts +8 -0
  137. package/src/endpoint-card/EndpointCard.astro +60 -0
  138. package/src/endpoint-card/EndpointCardSection.astro +22 -0
  139. package/src/endpoint-card/EndpointSection.astro +35 -0
  140. package/src/field/Field.astro +31 -0
  141. package/src/field/FieldDescription.astro +22 -0
  142. package/src/field/FieldLabel.astro +24 -0
  143. package/src/field/field.ts +61 -0
  144. package/src/field/index.ts +3 -0
  145. package/src/fieldset/Fieldset.astro +24 -0
  146. package/src/fieldset/FieldsetLegend.astro +18 -0
  147. package/src/fieldset/index.ts +2 -0
  148. package/src/footnote/Footnote.astro +37 -0
  149. package/src/footnote/footnote.ts +79 -0
  150. package/src/footnote/index.ts +1 -0
  151. package/src/form/Form.astro +27 -0
  152. package/src/form/form.ts +160 -0
  153. package/src/form/index.ts +1 -0
  154. package/src/grid/Grid.astro +117 -0
  155. package/src/grid/GridItem.astro +95 -0
  156. package/src/grid/index.ts +2 -0
  157. package/src/image/Image.astro +115 -0
  158. package/src/image/index.ts +1 -0
  159. package/src/input/Input.astro +34 -0
  160. package/src/input/index.ts +1 -0
  161. package/src/kbd/Kbd.astro +17 -0
  162. package/src/kbd/index.ts +1 -0
  163. package/src/label/Label.astro +17 -0
  164. package/src/label/index.ts +1 -0
  165. package/src/link-card/LinkCard.astro +47 -0
  166. package/src/link-card/index.ts +1 -0
  167. package/src/map-view/MapView.astro +88 -0
  168. package/src/map-view/index.ts +1 -0
  169. package/src/map-view/map-view.ts +194 -0
  170. package/src/markdown-example/MarkdownExample.astro +138 -0
  171. package/src/markdown-example/index.ts +1 -0
  172. package/src/math/MathKatex.astro +35 -0
  173. package/src/math/index.ts +1 -0
  174. package/src/menubar/Menubar.astro +25 -0
  175. package/src/menubar/MenubarContent.astro +24 -0
  176. package/src/menubar/MenubarItem.astro +26 -0
  177. package/src/menubar/MenubarMenu.astro +12 -0
  178. package/src/menubar/MenubarSeparator.astro +11 -0
  179. package/src/menubar/MenubarShortcut.astro +11 -0
  180. package/src/menubar/MenubarTrigger.astro +27 -0
  181. package/src/menubar/index.ts +7 -0
  182. package/src/menubar/menubar.ts +258 -0
  183. package/src/meter/Meter.astro +75 -0
  184. package/src/meter/index.ts +1 -0
  185. package/src/method-badge/MethodBadge.astro +32 -0
  186. package/src/navigation-menu/NavigationMenu.astro +24 -0
  187. package/src/navigation-menu/NavigationMenuContent.astro +24 -0
  188. package/src/navigation-menu/NavigationMenuItem.astro +22 -0
  189. package/src/navigation-menu/NavigationMenuLink.astro +26 -0
  190. package/src/navigation-menu/NavigationMenuList.astro +22 -0
  191. package/src/navigation-menu/NavigationMenuTrigger.astro +40 -0
  192. package/src/navigation-menu/index.ts +6 -0
  193. package/src/navigation-menu/navigation-menu.ts +192 -0
  194. package/src/number-field/NumberField.astro +84 -0
  195. package/src/number-field/index.ts +1 -0
  196. package/src/number-field/number-field.ts +68 -0
  197. package/src/pagination/Pagination.astro +59 -0
  198. package/src/pagination/index.ts +1 -0
  199. package/src/parameter-table/ParameterTable.astro +75 -0
  200. package/src/popover/Popover.astro +21 -0
  201. package/src/popover/PopoverContent.astro +31 -0
  202. package/src/popover/PopoverTrigger.astro +31 -0
  203. package/src/popover/index.ts +3 -0
  204. package/src/popover/popover.ts +144 -0
  205. package/src/preview-card/PreviewCard.astro +24 -0
  206. package/src/preview-card/PreviewCardContent.astro +24 -0
  207. package/src/preview-card/PreviewCardTrigger.astro +23 -0
  208. package/src/preview-card/index.ts +3 -0
  209. package/src/preview-card/preview-card.ts +91 -0
  210. package/src/progress/Progress.astro +61 -0
  211. package/src/progress/index.ts +1 -0
  212. package/src/property-item/PropertyItem.astro +183 -0
  213. package/src/property-list/PropertyList.astro +68 -0
  214. package/src/radio-group/RadioGroup.astro +41 -0
  215. package/src/radio-group/RadioGroupItem.astro +36 -0
  216. package/src/radio-group/index.ts +2 -0
  217. package/src/radio-group/radio-group.ts +126 -0
  218. package/src/response-tabs/ResponseTabs.astro +60 -0
  219. package/src/schema-viewer/SchemaViewer.astro +42 -0
  220. package/src/scroll-area/ScrollArea.astro +44 -0
  221. package/src/scroll-area/index.ts +1 -0
  222. package/src/scroll-area/scroll-area.ts +176 -0
  223. package/src/select/Select.astro +34 -0
  224. package/src/select/SelectContent.astro +24 -0
  225. package/src/select/SelectGroup.astro +23 -0
  226. package/src/select/SelectItem.astro +28 -0
  227. package/src/select/SelectLabel.astro +18 -0
  228. package/src/select/SelectSeparator.astro +22 -0
  229. package/src/select/SelectTrigger.astro +28 -0
  230. package/src/select/SelectValue.astro +18 -0
  231. package/src/select/index.ts +8 -0
  232. package/src/select/select.ts +381 -0
  233. package/src/separator/Separator.astro +35 -0
  234. package/src/separator/index.ts +1 -0
  235. package/src/sheet/Sheet.astro +12 -0
  236. package/src/sheet/SheetClose.astro +35 -0
  237. package/src/sheet/SheetContent.astro +52 -0
  238. package/src/sheet/SheetDescription.astro +18 -0
  239. package/src/sheet/SheetFooter.astro +18 -0
  240. package/src/sheet/SheetHeader.astro +18 -0
  241. package/src/sheet/SheetTitle.astro +18 -0
  242. package/src/sheet/SheetTrigger.astro +32 -0
  243. package/src/sheet/index.ts +8 -0
  244. package/src/sheet/sheet.ts +173 -0
  245. package/src/sidebar/Sidebar.astro +113 -0
  246. package/src/sidebar/SidebarContent.astro +18 -0
  247. package/src/sidebar/SidebarFooter.astro +18 -0
  248. package/src/sidebar/SidebarGroup.astro +18 -0
  249. package/src/sidebar/SidebarGroupContent.astro +18 -0
  250. package/src/sidebar/SidebarGroupLabel.astro +18 -0
  251. package/src/sidebar/SidebarHeader.astro +18 -0
  252. package/src/sidebar/SidebarInset.astro +18 -0
  253. package/src/sidebar/SidebarMenu.astro +18 -0
  254. package/src/sidebar/SidebarMenuBadge.astro +18 -0
  255. package/src/sidebar/SidebarMenuButton.astro +71 -0
  256. package/src/sidebar/SidebarMenuItem.astro +18 -0
  257. package/src/sidebar/SidebarMenuSub.astro +18 -0
  258. package/src/sidebar/SidebarMenuSubButton.astro +45 -0
  259. package/src/sidebar/SidebarMenuSubItem.astro +12 -0
  260. package/src/sidebar/SidebarNavTree.astro +106 -0
  261. package/src/sidebar/SidebarProvider.astro +23 -0
  262. package/src/sidebar/SidebarRail.astro +25 -0
  263. package/src/sidebar/SidebarSeparator.astro +21 -0
  264. package/src/sidebar/SidebarTrigger.astro +40 -0
  265. package/src/sidebar/index.ts +19 -0
  266. package/src/sidebar/sidebar.ts +265 -0
  267. package/src/skeleton/Skeleton.astro +16 -0
  268. package/src/skeleton/index.ts +1 -0
  269. package/src/skip-link/SkipLink.astro +24 -0
  270. package/src/slider/Slider.astro +61 -0
  271. package/src/slider/index.ts +1 -0
  272. package/src/slider/slider.ts +111 -0
  273. package/src/spinner/Spinner.astro +54 -0
  274. package/src/spinner/index.ts +1 -0
  275. package/src/steps/Step.astro +16 -0
  276. package/src/steps/Steps.astro +122 -0
  277. package/src/steps/SubSteps.astro +73 -0
  278. package/src/switch/Switch.astro +52 -0
  279. package/src/switch/index.ts +1 -0
  280. package/src/switch/switch.ts +109 -0
  281. package/src/table/Table.astro +24 -0
  282. package/src/table/TableBody.astro +18 -0
  283. package/src/table/TableCaption.astro +18 -0
  284. package/src/table/TableCell.astro +18 -0
  285. package/src/table/TableFooter.astro +18 -0
  286. package/src/table/TableHead.astro +18 -0
  287. package/src/table/TableHeader.astro +18 -0
  288. package/src/table/TableRow.astro +18 -0
  289. package/src/table/index.ts +8 -0
  290. package/src/tabs/Tabs.astro +37 -0
  291. package/src/tabs/TabsContent.astro +32 -0
  292. package/src/tabs/TabsList.astro +23 -0
  293. package/src/tabs/TabsTrigger.astro +29 -0
  294. package/src/tabs/index.ts +4 -0
  295. package/src/tabs/tabs.ts +220 -0
  296. package/src/textarea/Textarea.astro +25 -0
  297. package/src/textarea/index.ts +1 -0
  298. package/src/theme-toggle/ThemeToggle.astro +67 -0
  299. package/src/theme-toggle/index.ts +1 -0
  300. package/src/toast/Toaster.astro +39 -0
  301. package/src/toast/index.ts +3 -0
  302. package/src/toast/toast.ts +104 -0
  303. package/src/toc/TableOfContents.astro +225 -0
  304. package/src/toggle/Toggle.astro +56 -0
  305. package/src/toggle/index.ts +1 -0
  306. package/src/toggle/toggle.ts +38 -0
  307. package/src/toggle-group/ToggleGroup.astro +39 -0
  308. package/src/toggle-group/ToggleGroupItem.astro +56 -0
  309. package/src/toggle-group/index.ts +2 -0
  310. package/src/toggle-group/toggle-group.ts +121 -0
  311. package/src/toolbar/Toolbar.astro +26 -0
  312. package/src/toolbar/ToolbarButton.astro +29 -0
  313. package/src/toolbar/ToolbarSeparator.astro +14 -0
  314. package/src/toolbar/index.ts +3 -0
  315. package/src/toolbar/toolbar.ts +65 -0
  316. package/src/tooltip/Tooltip.astro +21 -0
  317. package/src/tooltip/TooltipContent.astro +25 -0
  318. package/src/tooltip/TooltipTrigger.astro +31 -0
  319. package/src/tooltip/index.ts +3 -0
  320. package/src/tooltip/tooltip.ts +156 -0
  321. package/src/youtube/YouTube.astro +119 -0
  322. package/src/youtube/index.ts +1 -0
@@ -0,0 +1,23 @@
1
+ ---
2
+ import { tv } from "tailwind-variants";
3
+
4
+ const alertDialogAction = tv({
5
+ base: "inline-flex items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
6
+ });
7
+
8
+ interface Props {
9
+ class?: string;
10
+ [key: string]: unknown;
11
+ }
12
+
13
+ const { class: className, ...rest } = Astro.props;
14
+ ---
15
+
16
+ <button
17
+ class={alertDialogAction({ class: className })}
18
+ data-part="action"
19
+ type="button"
20
+ {...rest}
21
+ >
22
+ <slot />
23
+ </button>
@@ -0,0 +1,23 @@
1
+ ---
2
+ import { tv } from "tailwind-variants";
3
+
4
+ const alertDialogCancel = tv({
5
+ base: "inline-flex items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
6
+ });
7
+
8
+ interface Props {
9
+ class?: string;
10
+ [key: string]: unknown;
11
+ }
12
+
13
+ const { class: className, ...rest } = Astro.props;
14
+ ---
15
+
16
+ <button
17
+ class={alertDialogCancel({ class: className })}
18
+ data-part="cancel"
19
+ type="button"
20
+ {...rest}
21
+ >
22
+ <slot />
23
+ </button>
@@ -0,0 +1,37 @@
1
+ ---
2
+ import { tv } from "tailwind-variants";
3
+
4
+ const alertDialogBackdrop = tv({
5
+ base: "fixed inset-0 z-50 bg-black/80",
6
+ });
7
+
8
+ const alertDialogContent = tv({
9
+ base: "fixed left-1/2 top-1/2 z-[51] grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg sm:rounded-lg",
10
+ });
11
+
12
+ interface Props {
13
+ class?: string;
14
+ [key: string]: unknown;
15
+ }
16
+
17
+ const { class: className, ...rest } = Astro.props;
18
+ ---
19
+
20
+ <div
21
+ class={alertDialogBackdrop()}
22
+ data-part="backdrop"
23
+ data-state="closed"
24
+ hidden
25
+ >
26
+ </div>
27
+ <div
28
+ class={alertDialogContent({ class: className })}
29
+ data-part="content"
30
+ role="alertdialog"
31
+ aria-modal="true"
32
+ data-state="closed"
33
+ hidden
34
+ {...rest}
35
+ >
36
+ <slot />
37
+ </div>
@@ -0,0 +1,18 @@
1
+ ---
2
+ import { tv } from "tailwind-variants";
3
+
4
+ const alertDialogDescription = tv({
5
+ base: "text-sm text-muted-foreground",
6
+ });
7
+
8
+ interface Props {
9
+ class?: string;
10
+ [key: string]: unknown;
11
+ }
12
+
13
+ const { class: className, ...rest } = Astro.props;
14
+ ---
15
+
16
+ <p class={alertDialogDescription({ class: className })} data-part="description" {...rest}>
17
+ <slot />
18
+ </p>
@@ -0,0 +1,18 @@
1
+ ---
2
+ import { tv } from "tailwind-variants";
3
+
4
+ const alertDialogFooter = tv({
5
+ base: "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
6
+ });
7
+
8
+ interface Props {
9
+ class?: string;
10
+ [key: string]: unknown;
11
+ }
12
+
13
+ const { class: className, ...rest } = Astro.props;
14
+ ---
15
+
16
+ <div class={alertDialogFooter({ class: className })} {...rest}>
17
+ <slot />
18
+ </div>
@@ -0,0 +1,18 @@
1
+ ---
2
+ import { tv } from "tailwind-variants";
3
+
4
+ const alertDialogHeader = tv({
5
+ base: "flex flex-col space-y-2 text-center sm:text-left",
6
+ });
7
+
8
+ interface Props {
9
+ class?: string;
10
+ [key: string]: unknown;
11
+ }
12
+
13
+ const { class: className, ...rest } = Astro.props;
14
+ ---
15
+
16
+ <div class={alertDialogHeader({ class: className })} {...rest}>
17
+ <slot />
18
+ </div>
@@ -0,0 +1,18 @@
1
+ ---
2
+ import { tv } from "tailwind-variants";
3
+
4
+ const alertDialogTitle = tv({
5
+ base: "text-lg font-semibold",
6
+ });
7
+
8
+ interface Props {
9
+ class?: string;
10
+ [key: string]: unknown;
11
+ }
12
+
13
+ const { class: className, ...rest } = Astro.props;
14
+ ---
15
+
16
+ <h2 class={alertDialogTitle({ class: className })} data-part="title" {...rest}>
17
+ <slot />
18
+ </h2>
@@ -0,0 +1,24 @@
1
+ ---
2
+ import { tv } from "tailwind-variants";
3
+
4
+ const alertDialogTrigger = tv({
5
+ base: "inline-flex items-center justify-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
6
+ });
7
+
8
+ interface Props {
9
+ class?: string;
10
+ [key: string]: unknown;
11
+ }
12
+
13
+ const { class: className, ...rest } = Astro.props;
14
+ ---
15
+
16
+ <button
17
+ class={alertDialogTrigger({ class: className })}
18
+ data-part="trigger"
19
+ type="button"
20
+ aria-haspopup="dialog"
21
+ {...rest}
22
+ >
23
+ <slot />
24
+ </button>
@@ -0,0 +1,154 @@
1
+ import { FocusTrap } from "@dogsbay/primitives/focus-trap";
2
+ import { ScrollLock } from "@dogsbay/primitives/scroll-lock";
3
+ import { markOthersInert } from "@dogsbay/primitives/inert";
4
+ import { createPortal } from "@dogsbay/primitives/portal";
5
+
6
+ interface AlertDialogInstance {
7
+ root: HTMLElement;
8
+ trigger: HTMLElement | null;
9
+ content: HTMLElement;
10
+ backdrop: HTMLElement;
11
+ focusTrap: FocusTrap;
12
+ cleanupPortal: (() => void) | null;
13
+ cleanupInert: (() => void) | null;
14
+ open: boolean;
15
+ }
16
+
17
+ const instances = new WeakMap<HTMLElement, AlertDialogInstance>();
18
+
19
+ let idCounter = 0;
20
+ function uniqueId(prefix: string) {
21
+ return `${prefix}-${++idCounter}`;
22
+ }
23
+
24
+ function init(root: HTMLElement) {
25
+ if (root.hasAttribute("data-initialized")) return;
26
+ root.setAttribute("data-initialized", "");
27
+
28
+ const ownPart = (selector: string) => {
29
+ const all = root.querySelectorAll(selector);
30
+ for (let i = 0; i < all.length; i++) {
31
+ const el = all[i] as HTMLElement;
32
+ if (el.closest("[data-component='alert-dialog']") === root) return el;
33
+ }
34
+ return null;
35
+ };
36
+
37
+ const content = ownPart("[data-part='content']");
38
+ const backdrop = ownPart("[data-part='backdrop']");
39
+ const trigger = ownPart("[data-part='trigger']");
40
+ if (!content || !backdrop) return;
41
+
42
+ const dialogId = content.id || uniqueId("base-alert-dialog");
43
+ content.id = dialogId;
44
+
45
+ if (trigger) {
46
+ trigger.setAttribute("aria-controls", dialogId);
47
+ trigger.setAttribute("aria-expanded", "false");
48
+ }
49
+
50
+ const title = content.querySelector("[data-part='title']") as HTMLElement | null;
51
+ const description = content.querySelector("[data-part='description']") as HTMLElement | null;
52
+
53
+ if (title) {
54
+ const titleId = title.id || uniqueId("base-alert-dialog-title");
55
+ title.id = titleId;
56
+ content.setAttribute("aria-labelledby", titleId);
57
+ }
58
+ if (description) {
59
+ const descId = description.id || uniqueId("base-alert-dialog-desc");
60
+ description.id = descId;
61
+ content.setAttribute("aria-describedby", descId);
62
+ }
63
+
64
+ const instance: AlertDialogInstance = {
65
+ root,
66
+ trigger,
67
+ content,
68
+ backdrop,
69
+ focusTrap: new FocusTrap(content),
70
+ cleanupPortal: null,
71
+ cleanupInert: null,
72
+ open: false,
73
+ };
74
+
75
+ instances.set(root, instance);
76
+
77
+ // Trigger click — bound directly since trigger stays in DOM
78
+ if (trigger) {
79
+ trigger.addEventListener("click", () => {
80
+ openAlertDialog(root);
81
+ });
82
+ }
83
+
84
+ // Action/Cancel clicks — bound to content since it gets portaled
85
+ content.addEventListener("click", (e) => {
86
+ const target = e.target as HTMLElement;
87
+ if (target.closest("[data-part='action']")) {
88
+ root.dispatchEvent(new CustomEvent("base-alert-dialog:action", { bubbles: true }));
89
+ closeAlertDialog(root);
90
+ } else if (target.closest("[data-part='cancel']")) {
91
+ root.dispatchEvent(new CustomEvent("base-alert-dialog:cancel", { bubbles: true }));
92
+ closeAlertDialog(root);
93
+ }
94
+ });
95
+
96
+ // No Escape key dismiss — alert dialogs require explicit action
97
+ content.addEventListener("keydown", (e) => {
98
+ if (e.key === "Escape") {
99
+ e.preventDefault();
100
+ e.stopPropagation();
101
+ }
102
+ });
103
+ }
104
+
105
+ function openAlertDialog(root: HTMLElement) {
106
+ const instance = instances.get(root);
107
+ if (!instance || instance.open) return;
108
+ instance.open = true;
109
+
110
+ const contentPortal = createPortal(instance.content, instance.content.id);
111
+ const backdropPortal = createPortal(instance.backdrop, `${instance.content.id}-backdrop`);
112
+ instance.cleanupPortal = () => { contentPortal(); backdropPortal(); };
113
+
114
+ instance.content.hidden = false;
115
+ instance.backdrop.hidden = false;
116
+ instance.content.setAttribute("data-state", "open");
117
+ instance.backdrop.setAttribute("data-state", "open");
118
+ instance.trigger?.setAttribute("aria-expanded", "true");
119
+
120
+ ScrollLock.activate();
121
+ instance.cleanupInert = markOthersInert(instance.content);
122
+ instance.focusTrap.activate();
123
+ }
124
+
125
+ function closeAlertDialog(root: HTMLElement) {
126
+ const instance = instances.get(root);
127
+ if (!instance || !instance.open) return;
128
+ instance.open = false;
129
+
130
+ instance.focusTrap.deactivate();
131
+ instance.cleanupInert?.();
132
+ instance.cleanupInert = null;
133
+ ScrollLock.deactivate();
134
+
135
+ instance.content.setAttribute("data-state", "closed");
136
+ instance.backdrop.setAttribute("data-state", "closed");
137
+ instance.trigger?.setAttribute("aria-expanded", "false");
138
+
139
+ instance.content.hidden = true;
140
+ instance.backdrop.hidden = true;
141
+ instance.cleanupPortal?.();
142
+ instance.cleanupPortal = null;
143
+ }
144
+
145
+ function initAll() {
146
+ document.querySelectorAll<HTMLElement>("[data-component='alert-dialog']").forEach(init);
147
+ }
148
+
149
+ if (document.readyState === "loading") {
150
+ document.addEventListener("DOMContentLoaded", initAll);
151
+ } else {
152
+ initAll();
153
+ }
154
+ document.addEventListener("astro:page-load", initAll);
@@ -0,0 +1,9 @@
1
+ export { default as AlertDialog } from "./AlertDialog.astro";
2
+ export { default as AlertDialogTrigger } from "./AlertDialogTrigger.astro";
3
+ export { default as AlertDialogContent } from "./AlertDialogContent.astro";
4
+ export { default as AlertDialogHeader } from "./AlertDialogHeader.astro";
5
+ export { default as AlertDialogTitle } from "./AlertDialogTitle.astro";
6
+ export { default as AlertDialogDescription } from "./AlertDialogDescription.astro";
7
+ export { default as AlertDialogFooter } from "./AlertDialogFooter.astro";
8
+ export { default as AlertDialogAction } from "./AlertDialogAction.astro";
9
+ export { default as AlertDialogCancel } from "./AlertDialogCancel.astro";
@@ -0,0 +1,52 @@
1
+ ---
2
+ import CodeBlock from "../code-block/CodeBlock.astro";
3
+
4
+ interface Props {
5
+ html: string;
6
+ }
7
+
8
+ const { html } = Astro.props;
9
+
10
+ interface Segment {
11
+ type: "html" | "code";
12
+ content: string;
13
+ lang?: string;
14
+ }
15
+
16
+ function splitCodeBlocks(src: string): Segment[] {
17
+ const segments: Segment[] = [];
18
+ const re = /<pre><code(?:\s+class="language-(\w+)")?>([\s\S]*?)<\/code><\/pre>/g;
19
+ let lastIndex = 0;
20
+ let match;
21
+
22
+ while ((match = re.exec(src)) !== null) {
23
+ if (match.index > lastIndex) {
24
+ segments.push({ type: "html", content: src.slice(lastIndex, match.index) });
25
+ }
26
+ const lang = match[1] || "python";
27
+ const code = match[2]
28
+ .replace(/&amp;/g, "&")
29
+ .replace(/&lt;/g, "<")
30
+ .replace(/&gt;/g, ">")
31
+ .replace(/&quot;/g, '"');
32
+ segments.push({ type: "code", content: code, lang });
33
+ lastIndex = match.index + match[0].length;
34
+ }
35
+
36
+ if (lastIndex < src.length) {
37
+ segments.push({ type: "html", content: src.slice(lastIndex) });
38
+ }
39
+
40
+ return segments;
41
+ }
42
+
43
+ const segments = splitCodeBlocks(html);
44
+ ---
45
+
46
+ {segments.map((seg) =>
47
+ seg.type === "html" ? (
48
+ <div class="prose prose-sm dark:prose-invert max-w-none [&>p:first-child]:mt-0 [&>p:last-child]:mb-2" set:html={seg.content} />
49
+ ) : (
50
+ <CodeBlock code={seg.content} lang={seg.lang || "python"} />
51
+ )
52
+ )}
@@ -0,0 +1 @@
1
+ export { default as ApiDoc } from "./ApiDoc.astro";
@@ -0,0 +1,21 @@
1
+ ---
2
+ /**
3
+ * Dark-themed container for the right column of an API layout.
4
+ * Holds code samples, request/response examples.
5
+ *
6
+ * Usage:
7
+ * <ApiCodePanel>
8
+ * <CodeSamples ... />
9
+ * <ExampleBlock title="Response 200" json={data} />
10
+ * </ApiCodePanel>
11
+ */
12
+ interface Props {
13
+ class?: string;
14
+ }
15
+
16
+ const { class: className } = Astro.props;
17
+ ---
18
+
19
+ <div class:list={["space-y-8", className]}>
20
+ <slot />
21
+ </div>
@@ -0,0 +1,29 @@
1
+ ---
2
+ /**
3
+ * Two-column layout for API reference pages.
4
+ * Description/schema on the left, code/examples on the right (dark background).
5
+ * Stacks vertically on mobile.
6
+ *
7
+ * Usage:
8
+ * <ApiLayout>
9
+ * <EndpointCard slot="description" ... />
10
+ * <ApiCodePanel slot="code">...</ApiCodePanel>
11
+ * </ApiLayout>
12
+ */
13
+ interface Props {
14
+ class?: string;
15
+ }
16
+
17
+ const { class: className } = Astro.props;
18
+ ---
19
+
20
+ <div class:list={["grid grid-cols-1 lg:grid-cols-2 lg:min-h-[calc(100vh-3rem)]", className]}>
21
+ <div class="px-6 py-10 lg:border-r">
22
+ <slot name="description" />
23
+ </div>
24
+ <div class="bg-[var(--api-panel-bg)] text-[var(--api-panel-fg)]">
25
+ <div class="px-6 py-10 lg:sticky lg:top-12 lg:max-h-[calc(100vh-3rem)] lg:overflow-y-auto">
26
+ <slot name="code" />
27
+ </div>
28
+ </div>
29
+ </div>
@@ -0,0 +1,63 @@
1
+ ---
2
+ /**
3
+ * Labeled example block for API pages.
4
+ * Uses CodeBlock for syntax highlighting and copy button.
5
+ * Auto-detects language from contentType if lang is not specified.
6
+ *
7
+ * Usage:
8
+ * <ExampleBlock title="Response 200" json={responseData} />
9
+ * <ExampleBlock title="Request Body" json={requestBody} contentType="application/xml" />
10
+ * <ExampleBlock title="Custom" code={rawText} lang="yaml" />
11
+ */
12
+ import CodeBlock from "../code-block/CodeBlock.astro";
13
+
14
+ interface Props {
15
+ title: string;
16
+ json?: unknown;
17
+ code?: string;
18
+ lang?: string;
19
+ contentType?: string;
20
+ class?: string;
21
+ }
22
+
23
+ const contentTypeToLang: Record<string, string> = {
24
+ "application/json": "json",
25
+ "application/xml": "xml",
26
+ "application/x-www-form-urlencoded": "plaintext",
27
+ "text/xml": "xml",
28
+ "text/html": "html",
29
+ "text/plain": "plaintext",
30
+ "text/yaml": "yaml",
31
+ "application/yaml": "yaml",
32
+ "application/x-yaml": "yaml",
33
+ "multipart/form-data": "plaintext",
34
+ };
35
+
36
+ function detectLang(contentType?: string): string {
37
+ if (!contentType) return "json";
38
+ // Exact match
39
+ if (contentTypeToLang[contentType]) return contentTypeToLang[contentType];
40
+ // Match base type (ignore parameters like charset)
41
+ const base = contentType.split(";")[0].trim();
42
+ if (contentTypeToLang[base]) return contentTypeToLang[base];
43
+ // Fallback heuristics
44
+ if (base.includes("json")) return "json";
45
+ if (base.includes("xml")) return "xml";
46
+ if (base.includes("yaml") || base.includes("yml")) return "yaml";
47
+ return "json";
48
+ }
49
+
50
+ const { title, json, code, lang, contentType, class: className } = Astro.props;
51
+
52
+ const resolvedLang = lang || detectLang(contentType);
53
+ const content = code || (json !== undefined && json !== null ? JSON.stringify(json, null, 2) : null);
54
+ ---
55
+
56
+ {content && (
57
+ <div class={className}>
58
+ <h3 class="mb-3 text-xs font-semibold uppercase tracking-wider text-white/60">
59
+ {title}
60
+ </h3>
61
+ <CodeBlock code={content} lang={resolvedLang} copy={true} />
62
+ </div>
63
+ )}
@@ -0,0 +1,96 @@
1
+ ---
2
+ import CodeBlock from "../code-block/CodeBlock.astro";
3
+
4
+ interface Param {
5
+ name: string;
6
+ type: string | null;
7
+ default: string | null;
8
+ required: boolean;
9
+ doc: string | null;
10
+ docHtml: string | null;
11
+ }
12
+
13
+ interface Props {
14
+ params: Param[];
15
+ }
16
+
17
+ const { params } = Astro.props;
18
+
19
+ /**
20
+ * Split rendered HTML into segments: regular HTML and code blocks.
21
+ * Code blocks get rendered through our CodeBlock component with Shiki.
22
+ */
23
+ interface Segment {
24
+ type: "html" | "code";
25
+ content: string;
26
+ lang?: string;
27
+ }
28
+
29
+ function splitCodeBlocks(html: string): Segment[] {
30
+ const segments: Segment[] = [];
31
+ const codeBlockRe = /<pre><code(?:\s+class="language-(\w+)")?>([\s\S]*?)<\/code><\/pre>/g;
32
+ let lastIndex = 0;
33
+ let match;
34
+
35
+ while ((match = codeBlockRe.exec(html)) !== null) {
36
+ // HTML before the code block
37
+ if (match.index > lastIndex) {
38
+ segments.push({ type: "html", content: html.slice(lastIndex, match.index) });
39
+ }
40
+ // The code block itself
41
+ const lang = match[1] || "python";
42
+ const code = match[2]
43
+ .replace(/&amp;/g, "&")
44
+ .replace(/&lt;/g, "<")
45
+ .replace(/&gt;/g, ">")
46
+ .replace(/&quot;/g, '"');
47
+ segments.push({ type: "code", content: code, lang });
48
+ lastIndex = match.index + match[0].length;
49
+ }
50
+
51
+ // Remaining HTML after last code block
52
+ if (lastIndex < html.length) {
53
+ segments.push({ type: "html", content: html.slice(lastIndex) });
54
+ }
55
+
56
+ return segments;
57
+ }
58
+ ---
59
+
60
+ <table class="api-params w-full text-sm border-collapse not-prose">
61
+ <thead>
62
+ <tr class="border-b border-border">
63
+ <th class="py-3 px-4 text-left font-semibold text-muted-foreground uppercase tracking-wider text-xs w-[140px]">Parameter</th>
64
+ <th class="py-3 px-4 text-left font-semibold text-muted-foreground uppercase tracking-wider text-xs">Description</th>
65
+ </tr>
66
+ </thead>
67
+ <tbody>
68
+ {params.map((p) => {
69
+ const segments = p.docHtml ? splitCodeBlocks(p.docHtml) : [];
70
+ return (
71
+ <tr class="border-b border-border/50">
72
+ <td class="py-3 px-4 align-top">
73
+ <code class="text-sm font-medium">{p.name}</code>
74
+ </td>
75
+ <td class="py-3 px-4 align-top">
76
+ {segments.map((seg) =>
77
+ seg.type === "html" ? (
78
+ <div class="prose prose-sm dark:prose-invert max-w-none [&>p:first-child]:mt-0 [&>p:last-child]:mb-0" set:html={seg.content} />
79
+ ) : (
80
+ <CodeBlock code={seg.content} lang={seg.lang || "python"} />
81
+ )
82
+ )}
83
+ <div class="flex items-center gap-4 mt-2 text-xs text-muted-foreground">
84
+ {p.type && (
85
+ <span><strong>TYPE:</strong> <code class="text-xs">{p.type}</code></span>
86
+ )}
87
+ {p.default && (
88
+ <span class="ml-auto"><strong>DEFAULT:</strong> <code class="text-xs">{p.default}</code></span>
89
+ )}
90
+ </div>
91
+ </td>
92
+ </tr>
93
+ );
94
+ })}
95
+ </tbody>
96
+ </table>
@@ -0,0 +1 @@
1
+ export { default as ApiParams } from "./ApiParams.astro";
@@ -0,0 +1,20 @@
1
+ ---
2
+ import CodeBlock from "../code-block/CodeBlock.astro";
3
+ import "./api-source.css";
4
+
5
+ interface Props {
6
+ code: string;
7
+ file?: string;
8
+ line?: number;
9
+ }
10
+
11
+ const { code, file, line } = Astro.props;
12
+ const label = file
13
+ ? `Source code in ${file}${line ? `, line ${line}` : ""}`
14
+ : "Source code";
15
+ ---
16
+
17
+ <details class="api-source">
18
+ <summary>{label}</summary>
19
+ <CodeBlock code={code} lang="python" />
20
+ </details>
@@ -0,0 +1,32 @@
1
+ .api-source {
2
+ margin-top: 0.75rem;
3
+ margin-bottom: 0.75rem;
4
+ border: 1px solid var(--color-border, oklch(0.85 0 0));
5
+ border-radius: 0.375rem;
6
+ overflow: hidden;
7
+ }
8
+
9
+ .api-source summary {
10
+ cursor: pointer;
11
+ padding: 0.5rem 0.75rem;
12
+ font-size: 0.8125rem;
13
+ font-weight: 500;
14
+ color: var(--color-muted-foreground, oklch(0.55 0 0));
15
+ background: var(--color-muted, oklch(0.96 0 0));
16
+ user-select: none;
17
+ }
18
+
19
+ .api-source summary:hover {
20
+ color: var(--color-foreground, oklch(0.15 0 0));
21
+ }
22
+
23
+ .api-source[open] summary {
24
+ border-bottom: 1px solid var(--color-border, oklch(0.85 0 0));
25
+ }
26
+
27
+ /* Remove extra margin from the code block inside */
28
+ .api-source :global(pre) {
29
+ margin: 0 !important;
30
+ border-radius: 0 !important;
31
+ border: none !important;
32
+ }
@@ -0,0 +1 @@
1
+ export { default as ApiSource } from "./ApiSource.astro";