@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.
- package/package.json +38 -0
- package/src/accordion/Accordion.astro +38 -0
- package/src/accordion/AccordionContent.astro +25 -0
- package/src/accordion/AccordionItem.astro +26 -0
- package/src/accordion/AccordionTrigger.astro +38 -0
- package/src/accordion/accordion.ts +189 -0
- package/src/accordion/index.ts +4 -0
- package/src/alert/Alert.astro +69 -0
- package/src/alert/AlertDescription.astro +17 -0
- package/src/alert/AlertTitle.astro +21 -0
- package/src/alert/CollapsibleAlert.astro +103 -0
- package/src/alert/icon.ts +32 -0
- package/src/alert/index.ts +4 -0
- package/src/alert/variants.ts +29 -0
- package/src/alert-dialog/AlertDialog.astro +16 -0
- package/src/alert-dialog/AlertDialogAction.astro +23 -0
- package/src/alert-dialog/AlertDialogCancel.astro +23 -0
- package/src/alert-dialog/AlertDialogContent.astro +37 -0
- package/src/alert-dialog/AlertDialogDescription.astro +18 -0
- package/src/alert-dialog/AlertDialogFooter.astro +18 -0
- package/src/alert-dialog/AlertDialogHeader.astro +18 -0
- package/src/alert-dialog/AlertDialogTitle.astro +18 -0
- package/src/alert-dialog/AlertDialogTrigger.astro +24 -0
- package/src/alert-dialog/alert-dialog.ts +154 -0
- package/src/alert-dialog/index.ts +9 -0
- package/src/api-doc/ApiDoc.astro +52 -0
- package/src/api-doc/index.ts +1 -0
- package/src/api-layout/ApiCodePanel.astro +21 -0
- package/src/api-layout/ApiLayout.astro +29 -0
- package/src/api-layout/ExampleBlock.astro +63 -0
- package/src/api-params/ApiParams.astro +96 -0
- package/src/api-params/index.ts +1 -0
- package/src/api-source/ApiSource.astro +20 -0
- package/src/api-source/api-source.css +32 -0
- package/src/api-source/index.ts +1 -0
- package/src/api-symbol/ApiSymbol.astro +48 -0
- package/src/api-symbol/api-symbol.css +89 -0
- package/src/api-symbol/index.ts +1 -0
- package/src/api-url-bar/ApiUrlBar.astro +63 -0
- package/src/avatar/Avatar.astro +57 -0
- package/src/avatar/index.ts +1 -0
- package/src/badge/Badge.astro +37 -0
- package/src/badge/index.ts +1 -0
- package/src/breadcrumb/Breadcrumb.astro +32 -0
- package/src/breadcrumb/BreadcrumbEllipsis.astro +32 -0
- package/src/breadcrumb/BreadcrumbItem.astro +41 -0
- package/src/breadcrumb/BreadcrumbSeparator.astro +33 -0
- package/src/breadcrumb/index.ts +4 -0
- package/src/button/Button.astro +70 -0
- package/src/button/index.ts +1 -0
- package/src/card/Card.astro +17 -0
- package/src/card/CardContent.astro +17 -0
- package/src/card/CardDescription.astro +17 -0
- package/src/card/CardFooter.astro +17 -0
- package/src/card/CardHeader.astro +17 -0
- package/src/card/CardTitle.astro +17 -0
- package/src/card/index.ts +6 -0
- package/src/checkbox/Checkbox.astro +70 -0
- package/src/checkbox/index.ts +1 -0
- package/src/checkbox-group/CheckboxGroup.astro +38 -0
- package/src/checkbox-group/checkbox-group.ts +53 -0
- package/src/checkbox-group/index.ts +1 -0
- package/src/code-block/CodeBlock.astro +160 -0
- package/src/code-rich/CodeRich.astro +267 -0
- package/src/code-rich/code-rich.css +68 -0
- package/src/code-rich/index.ts +1 -0
- package/src/code-samples/CodeSamples.astro +59 -0
- package/src/collapsible/Collapsible.astro +35 -0
- package/src/collapsible/CollapsibleContent.astro +24 -0
- package/src/collapsible/CollapsibleTrigger.astro +23 -0
- package/src/collapsible/collapsible.ts +42 -0
- package/src/collapsible/index.ts +3 -0
- package/src/combobox/Combobox.astro +53 -0
- package/src/combobox/ComboboxEmpty.astro +18 -0
- package/src/combobox/ComboboxItem.astro +28 -0
- package/src/combobox/combobox.ts +179 -0
- package/src/combobox/index.ts +3 -0
- package/src/command/Command.astro +22 -0
- package/src/command/CommandEmpty.astro +18 -0
- package/src/command/CommandGroup.astro +24 -0
- package/src/command/CommandInput.astro +49 -0
- package/src/command/CommandItem.astro +26 -0
- package/src/command/CommandList.astro +19 -0
- package/src/command/CommandSeparator.astro +16 -0
- package/src/command/CommandShortcut.astro +18 -0
- package/src/command/command.ts +212 -0
- package/src/command/index.ts +8 -0
- package/src/content-renderer/ContentRenderer.astro +410 -0
- package/src/content-renderer/InlineRenderer.astro +149 -0
- package/src/context-menu/ContextMenu.astro +22 -0
- package/src/context-menu/ContextMenuContent.astro +24 -0
- package/src/context-menu/ContextMenuItem.astro +49 -0
- package/src/context-menu/ContextMenuSeparator.astro +14 -0
- package/src/context-menu/ContextMenuShortcut.astro +14 -0
- package/src/context-menu/ContextMenuTrigger.astro +22 -0
- package/src/context-menu/context-menu.ts +238 -0
- package/src/context-menu/index.ts +6 -0
- package/src/copy-button/CopyButton.astro +88 -0
- package/src/copy-button/index.ts +1 -0
- package/src/diagram/Diagram.astro +15 -0
- package/src/diagram/index.ts +1 -0
- package/src/dialog/Dialog.astro +22 -0
- package/src/dialog/DialogClose.astro +32 -0
- package/src/dialog/DialogContent.astro +37 -0
- package/src/dialog/DialogDescription.astro +22 -0
- package/src/dialog/DialogFooter.astro +18 -0
- package/src/dialog/DialogHeader.astro +18 -0
- package/src/dialog/DialogTitle.astro +18 -0
- package/src/dialog/DialogTrigger.astro +33 -0
- package/src/dialog/dialog.ts +291 -0
- package/src/dialog/index.ts +8 -0
- package/src/docs-footer/DocsFooter.astro +50 -0
- package/src/docs-header/DocsHeader.astro +32 -0
- package/src/docs-layout/DocsLayout.astro +187 -0
- package/src/docs-layout/index.ts +1 -0
- package/src/drawer/Drawer.astro +12 -0
- package/src/drawer/DrawerClose.astro +12 -0
- package/src/drawer/DrawerContent.astro +46 -0
- package/src/drawer/DrawerDescription.astro +10 -0
- package/src/drawer/DrawerFooter.astro +10 -0
- package/src/drawer/DrawerHandle.astro +16 -0
- package/src/drawer/DrawerHeader.astro +10 -0
- package/src/drawer/DrawerTitle.astro +10 -0
- package/src/drawer/DrawerTrigger.astro +25 -0
- package/src/drawer/drawer.ts +262 -0
- package/src/drawer/index.ts +9 -0
- package/src/dropdown-menu/DropdownMenu.astro +22 -0
- package/src/dropdown-menu/DropdownMenuContent.astro +33 -0
- package/src/dropdown-menu/DropdownMenuGroup.astro +17 -0
- package/src/dropdown-menu/DropdownMenuItem.astro +48 -0
- package/src/dropdown-menu/DropdownMenuLabel.astro +28 -0
- package/src/dropdown-menu/DropdownMenuSeparator.astro +21 -0
- package/src/dropdown-menu/DropdownMenuShortcut.astro +18 -0
- package/src/dropdown-menu/DropdownMenuTrigger.astro +34 -0
- package/src/dropdown-menu/dropdown-menu.ts +348 -0
- package/src/dropdown-menu/index.ts +8 -0
- package/src/endpoint-card/EndpointCard.astro +60 -0
- package/src/endpoint-card/EndpointCardSection.astro +22 -0
- package/src/endpoint-card/EndpointSection.astro +35 -0
- package/src/field/Field.astro +31 -0
- package/src/field/FieldDescription.astro +22 -0
- package/src/field/FieldLabel.astro +24 -0
- package/src/field/field.ts +61 -0
- package/src/field/index.ts +3 -0
- package/src/fieldset/Fieldset.astro +24 -0
- package/src/fieldset/FieldsetLegend.astro +18 -0
- package/src/fieldset/index.ts +2 -0
- package/src/footnote/Footnote.astro +37 -0
- package/src/footnote/footnote.ts +79 -0
- package/src/footnote/index.ts +1 -0
- package/src/form/Form.astro +27 -0
- package/src/form/form.ts +160 -0
- package/src/form/index.ts +1 -0
- package/src/grid/Grid.astro +117 -0
- package/src/grid/GridItem.astro +95 -0
- package/src/grid/index.ts +2 -0
- package/src/image/Image.astro +115 -0
- package/src/image/index.ts +1 -0
- package/src/input/Input.astro +34 -0
- package/src/input/index.ts +1 -0
- package/src/kbd/Kbd.astro +17 -0
- package/src/kbd/index.ts +1 -0
- package/src/label/Label.astro +17 -0
- package/src/label/index.ts +1 -0
- package/src/link-card/LinkCard.astro +47 -0
- package/src/link-card/index.ts +1 -0
- package/src/map-view/MapView.astro +88 -0
- package/src/map-view/index.ts +1 -0
- package/src/map-view/map-view.ts +194 -0
- package/src/markdown-example/MarkdownExample.astro +138 -0
- package/src/markdown-example/index.ts +1 -0
- package/src/math/MathKatex.astro +35 -0
- package/src/math/index.ts +1 -0
- package/src/menubar/Menubar.astro +25 -0
- package/src/menubar/MenubarContent.astro +24 -0
- package/src/menubar/MenubarItem.astro +26 -0
- package/src/menubar/MenubarMenu.astro +12 -0
- package/src/menubar/MenubarSeparator.astro +11 -0
- package/src/menubar/MenubarShortcut.astro +11 -0
- package/src/menubar/MenubarTrigger.astro +27 -0
- package/src/menubar/index.ts +7 -0
- package/src/menubar/menubar.ts +258 -0
- package/src/meter/Meter.astro +75 -0
- package/src/meter/index.ts +1 -0
- package/src/method-badge/MethodBadge.astro +32 -0
- package/src/navigation-menu/NavigationMenu.astro +24 -0
- package/src/navigation-menu/NavigationMenuContent.astro +24 -0
- package/src/navigation-menu/NavigationMenuItem.astro +22 -0
- package/src/navigation-menu/NavigationMenuLink.astro +26 -0
- package/src/navigation-menu/NavigationMenuList.astro +22 -0
- package/src/navigation-menu/NavigationMenuTrigger.astro +40 -0
- package/src/navigation-menu/index.ts +6 -0
- package/src/navigation-menu/navigation-menu.ts +192 -0
- package/src/number-field/NumberField.astro +84 -0
- package/src/number-field/index.ts +1 -0
- package/src/number-field/number-field.ts +68 -0
- package/src/pagination/Pagination.astro +59 -0
- package/src/pagination/index.ts +1 -0
- package/src/parameter-table/ParameterTable.astro +75 -0
- package/src/popover/Popover.astro +21 -0
- package/src/popover/PopoverContent.astro +31 -0
- package/src/popover/PopoverTrigger.astro +31 -0
- package/src/popover/index.ts +3 -0
- package/src/popover/popover.ts +144 -0
- package/src/preview-card/PreviewCard.astro +24 -0
- package/src/preview-card/PreviewCardContent.astro +24 -0
- package/src/preview-card/PreviewCardTrigger.astro +23 -0
- package/src/preview-card/index.ts +3 -0
- package/src/preview-card/preview-card.ts +91 -0
- package/src/progress/Progress.astro +61 -0
- package/src/progress/index.ts +1 -0
- package/src/property-item/PropertyItem.astro +183 -0
- package/src/property-list/PropertyList.astro +68 -0
- package/src/radio-group/RadioGroup.astro +41 -0
- package/src/radio-group/RadioGroupItem.astro +36 -0
- package/src/radio-group/index.ts +2 -0
- package/src/radio-group/radio-group.ts +126 -0
- package/src/response-tabs/ResponseTabs.astro +60 -0
- package/src/schema-viewer/SchemaViewer.astro +42 -0
- package/src/scroll-area/ScrollArea.astro +44 -0
- package/src/scroll-area/index.ts +1 -0
- package/src/scroll-area/scroll-area.ts +176 -0
- package/src/select/Select.astro +34 -0
- package/src/select/SelectContent.astro +24 -0
- package/src/select/SelectGroup.astro +23 -0
- package/src/select/SelectItem.astro +28 -0
- package/src/select/SelectLabel.astro +18 -0
- package/src/select/SelectSeparator.astro +22 -0
- package/src/select/SelectTrigger.astro +28 -0
- package/src/select/SelectValue.astro +18 -0
- package/src/select/index.ts +8 -0
- package/src/select/select.ts +381 -0
- package/src/separator/Separator.astro +35 -0
- package/src/separator/index.ts +1 -0
- package/src/sheet/Sheet.astro +12 -0
- package/src/sheet/SheetClose.astro +35 -0
- package/src/sheet/SheetContent.astro +52 -0
- package/src/sheet/SheetDescription.astro +18 -0
- package/src/sheet/SheetFooter.astro +18 -0
- package/src/sheet/SheetHeader.astro +18 -0
- package/src/sheet/SheetTitle.astro +18 -0
- package/src/sheet/SheetTrigger.astro +32 -0
- package/src/sheet/index.ts +8 -0
- package/src/sheet/sheet.ts +173 -0
- package/src/sidebar/Sidebar.astro +113 -0
- package/src/sidebar/SidebarContent.astro +18 -0
- package/src/sidebar/SidebarFooter.astro +18 -0
- package/src/sidebar/SidebarGroup.astro +18 -0
- package/src/sidebar/SidebarGroupContent.astro +18 -0
- package/src/sidebar/SidebarGroupLabel.astro +18 -0
- package/src/sidebar/SidebarHeader.astro +18 -0
- package/src/sidebar/SidebarInset.astro +18 -0
- package/src/sidebar/SidebarMenu.astro +18 -0
- package/src/sidebar/SidebarMenuBadge.astro +18 -0
- package/src/sidebar/SidebarMenuButton.astro +71 -0
- package/src/sidebar/SidebarMenuItem.astro +18 -0
- package/src/sidebar/SidebarMenuSub.astro +18 -0
- package/src/sidebar/SidebarMenuSubButton.astro +45 -0
- package/src/sidebar/SidebarMenuSubItem.astro +12 -0
- package/src/sidebar/SidebarNavTree.astro +106 -0
- package/src/sidebar/SidebarProvider.astro +23 -0
- package/src/sidebar/SidebarRail.astro +25 -0
- package/src/sidebar/SidebarSeparator.astro +21 -0
- package/src/sidebar/SidebarTrigger.astro +40 -0
- package/src/sidebar/index.ts +19 -0
- package/src/sidebar/sidebar.ts +265 -0
- package/src/skeleton/Skeleton.astro +16 -0
- package/src/skeleton/index.ts +1 -0
- package/src/skip-link/SkipLink.astro +24 -0
- package/src/slider/Slider.astro +61 -0
- package/src/slider/index.ts +1 -0
- package/src/slider/slider.ts +111 -0
- package/src/spinner/Spinner.astro +54 -0
- package/src/spinner/index.ts +1 -0
- package/src/steps/Step.astro +16 -0
- package/src/steps/Steps.astro +122 -0
- package/src/steps/SubSteps.astro +73 -0
- package/src/switch/Switch.astro +52 -0
- package/src/switch/index.ts +1 -0
- package/src/switch/switch.ts +109 -0
- package/src/table/Table.astro +24 -0
- package/src/table/TableBody.astro +18 -0
- package/src/table/TableCaption.astro +18 -0
- package/src/table/TableCell.astro +18 -0
- package/src/table/TableFooter.astro +18 -0
- package/src/table/TableHead.astro +18 -0
- package/src/table/TableHeader.astro +18 -0
- package/src/table/TableRow.astro +18 -0
- package/src/table/index.ts +8 -0
- package/src/tabs/Tabs.astro +37 -0
- package/src/tabs/TabsContent.astro +32 -0
- package/src/tabs/TabsList.astro +23 -0
- package/src/tabs/TabsTrigger.astro +29 -0
- package/src/tabs/index.ts +4 -0
- package/src/tabs/tabs.ts +220 -0
- package/src/textarea/Textarea.astro +25 -0
- package/src/textarea/index.ts +1 -0
- package/src/theme-toggle/ThemeToggle.astro +67 -0
- package/src/theme-toggle/index.ts +1 -0
- package/src/toast/Toaster.astro +39 -0
- package/src/toast/index.ts +3 -0
- package/src/toast/toast.ts +104 -0
- package/src/toc/TableOfContents.astro +225 -0
- package/src/toggle/Toggle.astro +56 -0
- package/src/toggle/index.ts +1 -0
- package/src/toggle/toggle.ts +38 -0
- package/src/toggle-group/ToggleGroup.astro +39 -0
- package/src/toggle-group/ToggleGroupItem.astro +56 -0
- package/src/toggle-group/index.ts +2 -0
- package/src/toggle-group/toggle-group.ts +121 -0
- package/src/toolbar/Toolbar.astro +26 -0
- package/src/toolbar/ToolbarButton.astro +29 -0
- package/src/toolbar/ToolbarSeparator.astro +14 -0
- package/src/toolbar/index.ts +3 -0
- package/src/toolbar/toolbar.ts +65 -0
- package/src/tooltip/Tooltip.astro +21 -0
- package/src/tooltip/TooltipContent.astro +25 -0
- package/src/tooltip/TooltipTrigger.astro +31 -0
- package/src/tooltip/index.ts +3 -0
- package/src/tooltip/tooltip.ts +156 -0
- package/src/youtube/YouTube.astro +119 -0
- package/src/youtube/index.ts +1 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
|
|
4
|
+
const dialogClose = tv({
|
|
5
|
+
base: "inline-flex items-center justify-center gap-2 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
|
+
asChild?: boolean;
|
|
10
|
+
class?: string;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { asChild = false, class: className, ...rest } = Astro.props;
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
asChild ? (
|
|
19
|
+
<span data-part="close" data-as-child>
|
|
20
|
+
<slot />
|
|
21
|
+
</span>
|
|
22
|
+
) : (
|
|
23
|
+
<button
|
|
24
|
+
class={dialogClose({ class: className })}
|
|
25
|
+
data-part="close"
|
|
26
|
+
type="button"
|
|
27
|
+
{...rest}
|
|
28
|
+
>
|
|
29
|
+
<slot />
|
|
30
|
+
</button>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
|
|
4
|
+
const dialogBackdrop = tv({
|
|
5
|
+
base: "fixed inset-0 z-50 bg-black/80",
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
const dialogContent = 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={dialogBackdrop()}
|
|
22
|
+
data-part="backdrop"
|
|
23
|
+
data-state="closed"
|
|
24
|
+
hidden
|
|
25
|
+
>
|
|
26
|
+
</div>
|
|
27
|
+
<div
|
|
28
|
+
class={dialogContent({ class: className })}
|
|
29
|
+
data-part="content"
|
|
30
|
+
role="dialog"
|
|
31
|
+
aria-modal="true"
|
|
32
|
+
data-state="closed"
|
|
33
|
+
hidden
|
|
34
|
+
{...rest}
|
|
35
|
+
>
|
|
36
|
+
<slot />
|
|
37
|
+
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
|
|
4
|
+
const dialogDescription = 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
|
|
17
|
+
class={dialogDescription({ class: className })}
|
|
18
|
+
data-part="description"
|
|
19
|
+
{...rest}
|
|
20
|
+
>
|
|
21
|
+
<slot />
|
|
22
|
+
</p>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
|
|
4
|
+
const dialogFooter = 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={dialogFooter({ class: className })} {...rest}>
|
|
17
|
+
<slot />
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
|
|
4
|
+
const dialogHeader = tv({
|
|
5
|
+
base: "flex flex-col space-y-1.5 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={dialogHeader({ class: className })} {...rest}>
|
|
17
|
+
<slot />
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
|
|
4
|
+
const dialogTitle = tv({
|
|
5
|
+
base: "text-lg font-semibold leading-none tracking-tight",
|
|
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={dialogTitle({ class: className })} data-part="title" {...rest}>
|
|
17
|
+
<slot />
|
|
18
|
+
</h2>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
|
|
4
|
+
const dialogTrigger = 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
|
+
asChild?: boolean;
|
|
10
|
+
class?: string;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { asChild = false, class: className, ...rest } = Astro.props;
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
asChild ? (
|
|
19
|
+
<span data-part="trigger" data-as-child>
|
|
20
|
+
<slot />
|
|
21
|
+
</span>
|
|
22
|
+
) : (
|
|
23
|
+
<button
|
|
24
|
+
class={dialogTrigger({ class: className })}
|
|
25
|
+
data-part="trigger"
|
|
26
|
+
type="button"
|
|
27
|
+
aria-haspopup="dialog"
|
|
28
|
+
{...rest}
|
|
29
|
+
>
|
|
30
|
+
<slot />
|
|
31
|
+
</button>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { FocusTrap } from "@dogsbay/primitives/focus-trap";
|
|
2
|
+
import { ScrollLock } from "@dogsbay/primitives/scroll-lock";
|
|
3
|
+
import { DismissController } from "@dogsbay/primitives/dismiss";
|
|
4
|
+
import { markOthersInert } from "@dogsbay/primitives/inert";
|
|
5
|
+
import { createPortal } from "@dogsbay/primitives/portal";
|
|
6
|
+
|
|
7
|
+
interface DialogInstance {
|
|
8
|
+
root: HTMLElement;
|
|
9
|
+
trigger: HTMLElement | null;
|
|
10
|
+
content: HTMLElement;
|
|
11
|
+
backdrop: HTMLElement;
|
|
12
|
+
focusTrap: FocusTrap;
|
|
13
|
+
dismiss: DismissController;
|
|
14
|
+
cleanupPortal: (() => void) | null;
|
|
15
|
+
cleanupInert: (() => void) | null;
|
|
16
|
+
open: boolean;
|
|
17
|
+
/** The element that opened the dialog (may differ from trigger if opened externally). */
|
|
18
|
+
openedBy: HTMLElement | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Map from dialog content ID to its root element, for external trigger lookup. */
|
|
22
|
+
const dialogById = new Map<string, HTMLElement>();
|
|
23
|
+
|
|
24
|
+
const instances = new WeakMap<HTMLElement, DialogInstance>();
|
|
25
|
+
|
|
26
|
+
let idCounter = 0;
|
|
27
|
+
function uniqueId(prefix: string) {
|
|
28
|
+
return `${prefix}-${++idCounter}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function resolveAsChild(wrapper: HTMLElement): HTMLElement {
|
|
32
|
+
// When asChild is used, the wrapper is a <span data-as-child>.
|
|
33
|
+
// Find the first element child and forward the data-part attribute to it.
|
|
34
|
+
const child = wrapper.firstElementChild as HTMLElement | null;
|
|
35
|
+
if (child) {
|
|
36
|
+
const part = wrapper.getAttribute("data-part");
|
|
37
|
+
if (part) child.setAttribute("data-part", part);
|
|
38
|
+
return child;
|
|
39
|
+
}
|
|
40
|
+
return wrapper;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function initDialog(root: HTMLElement) {
|
|
44
|
+
if (instances.has(root)) return;
|
|
45
|
+
|
|
46
|
+
// Find parts that belong to THIS dialog root, not nested ones.
|
|
47
|
+
// A part belongs to us if its closest dialog root ancestor is this root.
|
|
48
|
+
const ownParts = (selector: string) => {
|
|
49
|
+
const all = root.querySelectorAll(selector);
|
|
50
|
+
for (let i = 0; i < all.length; i++) {
|
|
51
|
+
const el = all[i] as HTMLElement;
|
|
52
|
+
if (el.closest("[data-component='dialog']") === root) return el;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const content = ownParts("[data-part='content']");
|
|
58
|
+
const backdrop = ownParts("[data-part='backdrop']");
|
|
59
|
+
if (!content || !backdrop) return;
|
|
60
|
+
|
|
61
|
+
// Resolve trigger — handle asChild
|
|
62
|
+
const triggerWrapper = ownParts("[data-part='trigger']");
|
|
63
|
+
let trigger = triggerWrapper;
|
|
64
|
+
if (triggerWrapper?.hasAttribute("data-as-child")) {
|
|
65
|
+
trigger = resolveAsChild(triggerWrapper);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Generate unique IDs for ARIA linkage
|
|
69
|
+
const dialogId = content.id || uniqueId("base-dialog");
|
|
70
|
+
content.id = dialogId;
|
|
71
|
+
|
|
72
|
+
if (trigger) {
|
|
73
|
+
trigger.setAttribute("aria-controls", dialogId);
|
|
74
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
75
|
+
if (!trigger.hasAttribute("aria-haspopup")) {
|
|
76
|
+
trigger.setAttribute("aria-haspopup", "dialog");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Link title and description
|
|
81
|
+
const title = content.querySelector(
|
|
82
|
+
"[data-part='title']",
|
|
83
|
+
) as HTMLElement | null;
|
|
84
|
+
const description = content.querySelector(
|
|
85
|
+
"[data-part='description']",
|
|
86
|
+
) as HTMLElement | null;
|
|
87
|
+
|
|
88
|
+
if (title) {
|
|
89
|
+
const titleId = title.id || uniqueId("base-dialog-title");
|
|
90
|
+
title.id = titleId;
|
|
91
|
+
content.setAttribute("aria-labelledby", titleId);
|
|
92
|
+
}
|
|
93
|
+
if (description) {
|
|
94
|
+
const descId = description.id || uniqueId("base-dialog-desc");
|
|
95
|
+
description.id = descId;
|
|
96
|
+
content.setAttribute("aria-describedby", descId);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const instance: DialogInstance = {
|
|
100
|
+
root,
|
|
101
|
+
trigger,
|
|
102
|
+
content,
|
|
103
|
+
backdrop,
|
|
104
|
+
focusTrap: new FocusTrap(content),
|
|
105
|
+
dismiss: new DismissController(content, {
|
|
106
|
+
onDismiss: (reason) => closeDialog(root, reason),
|
|
107
|
+
}),
|
|
108
|
+
cleanupPortal: null,
|
|
109
|
+
cleanupInert: null,
|
|
110
|
+
open: false,
|
|
111
|
+
openedBy: null,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
instances.set(root, instance);
|
|
115
|
+
dialogById.set(dialogId, root);
|
|
116
|
+
|
|
117
|
+
// Trigger click
|
|
118
|
+
if (trigger) {
|
|
119
|
+
trigger.addEventListener("click", () => {
|
|
120
|
+
if (instance.open) {
|
|
121
|
+
closeDialog(root, "trigger-press");
|
|
122
|
+
} else {
|
|
123
|
+
openDialog(root, trigger);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Close button handlers — only bind buttons that belong to THIS dialog,
|
|
129
|
+
// not close buttons inside nested dialogs
|
|
130
|
+
content.querySelectorAll("[data-part='close']").forEach((el) => {
|
|
131
|
+
// Skip if this close button is inside a nested dialog's content
|
|
132
|
+
const parentContent = el.closest("[data-part='content']");
|
|
133
|
+
if (parentContent !== content) return;
|
|
134
|
+
|
|
135
|
+
let closeEl = el as HTMLElement;
|
|
136
|
+
if (closeEl.hasAttribute("data-as-child")) {
|
|
137
|
+
closeEl = resolveAsChild(closeEl);
|
|
138
|
+
}
|
|
139
|
+
closeEl.addEventListener("click", () => {
|
|
140
|
+
closeDialog(root, "close-press");
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function openDialog(root: HTMLElement, opener?: HTMLElement) {
|
|
146
|
+
const instance = instances.get(root);
|
|
147
|
+
if (!instance || instance.open) return;
|
|
148
|
+
instance.open = true;
|
|
149
|
+
instance.openedBy = opener ?? instance.trigger;
|
|
150
|
+
|
|
151
|
+
// Portal: move content and backdrop to body
|
|
152
|
+
const contentPortalCleanup = createPortal(
|
|
153
|
+
instance.content,
|
|
154
|
+
instance.content.id,
|
|
155
|
+
);
|
|
156
|
+
const backdropPortalCleanup = createPortal(
|
|
157
|
+
instance.backdrop,
|
|
158
|
+
`${instance.content.id}-backdrop`,
|
|
159
|
+
);
|
|
160
|
+
instance.cleanupPortal = () => {
|
|
161
|
+
contentPortalCleanup();
|
|
162
|
+
backdropPortalCleanup();
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// Show
|
|
166
|
+
instance.content.hidden = false;
|
|
167
|
+
instance.backdrop.hidden = false;
|
|
168
|
+
instance.content.setAttribute("data-state", "open");
|
|
169
|
+
instance.backdrop.setAttribute("data-state", "open");
|
|
170
|
+
if (instance.openedBy) {
|
|
171
|
+
instance.openedBy.setAttribute("aria-expanded", "true");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Scroll lock
|
|
175
|
+
ScrollLock.activate();
|
|
176
|
+
|
|
177
|
+
// Inert siblings
|
|
178
|
+
instance.cleanupInert = markOthersInert(instance.content);
|
|
179
|
+
|
|
180
|
+
// Focus trap
|
|
181
|
+
instance.focusTrap.activate();
|
|
182
|
+
|
|
183
|
+
// Dismiss
|
|
184
|
+
instance.dismiss.activate();
|
|
185
|
+
|
|
186
|
+
// Dispatch open event
|
|
187
|
+
root.dispatchEvent(new CustomEvent("base-dialog:open", { bubbles: true }));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function closeDialog(root: HTMLElement, reason: string) {
|
|
191
|
+
const instance = instances.get(root);
|
|
192
|
+
if (!instance || !instance.open) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
instance.open = false;
|
|
196
|
+
|
|
197
|
+
// Deactivate in reverse order
|
|
198
|
+
instance.dismiss.deactivate();
|
|
199
|
+
instance.focusTrap.deactivate();
|
|
200
|
+
|
|
201
|
+
if (instance.cleanupInert) {
|
|
202
|
+
instance.cleanupInert();
|
|
203
|
+
instance.cleanupInert = null;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
ScrollLock.deactivate();
|
|
207
|
+
|
|
208
|
+
// Update state attributes
|
|
209
|
+
instance.content.setAttribute("data-state", "closed");
|
|
210
|
+
instance.backdrop.setAttribute("data-state", "closed");
|
|
211
|
+
if (instance.openedBy) {
|
|
212
|
+
instance.openedBy.setAttribute("aria-expanded", "false");
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Wait for exit animations before hiding/removing portals
|
|
216
|
+
const animations = instance.content.getAnimations?.() ?? [];
|
|
217
|
+
const cleanup = () => {
|
|
218
|
+
instance.content.hidden = true;
|
|
219
|
+
instance.backdrop.hidden = true;
|
|
220
|
+
if (instance.cleanupPortal) {
|
|
221
|
+
instance.cleanupPortal();
|
|
222
|
+
instance.cleanupPortal = null;
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
if (animations.length > 0) {
|
|
227
|
+
Promise.all(animations.map((a) => a.finished))
|
|
228
|
+
.then(cleanup)
|
|
229
|
+
.catch(cleanup);
|
|
230
|
+
} else {
|
|
231
|
+
cleanup();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Dispatch close event
|
|
235
|
+
root.dispatchEvent(
|
|
236
|
+
new CustomEvent("base-dialog:close", {
|
|
237
|
+
detail: { reason },
|
|
238
|
+
bubbles: true,
|
|
239
|
+
}),
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Bind external triggers — elements with `data-dialog-for="dialogId"` anywhere
|
|
245
|
+
* on the page can open a dialog without being inside its component tree.
|
|
246
|
+
*/
|
|
247
|
+
function bindExternalTriggers() {
|
|
248
|
+
document.querySelectorAll("[data-dialog-for]").forEach((el) => {
|
|
249
|
+
const btn = el as HTMLElement;
|
|
250
|
+
// Skip if already bound
|
|
251
|
+
if (btn.hasAttribute("data-dialog-external-bound")) return;
|
|
252
|
+
btn.setAttribute("data-dialog-external-bound", "");
|
|
253
|
+
|
|
254
|
+
const targetId = btn.getAttribute("data-dialog-for")!;
|
|
255
|
+
// Set ARIA attributes on the external trigger
|
|
256
|
+
btn.setAttribute("aria-haspopup", "dialog");
|
|
257
|
+
btn.setAttribute("aria-controls", targetId);
|
|
258
|
+
btn.setAttribute("aria-expanded", "false");
|
|
259
|
+
|
|
260
|
+
btn.addEventListener("click", () => {
|
|
261
|
+
const root = dialogById.get(targetId);
|
|
262
|
+
if (!root) return;
|
|
263
|
+
const instance = instances.get(root);
|
|
264
|
+
if (!instance) return;
|
|
265
|
+
|
|
266
|
+
if (instance.open) {
|
|
267
|
+
closeDialog(root, "trigger-press");
|
|
268
|
+
} else {
|
|
269
|
+
openDialog(root, btn);
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Auto-initialize all dialog roots on the page
|
|
276
|
+
function init() {
|
|
277
|
+
document.querySelectorAll("[data-component='dialog']").forEach((el) => {
|
|
278
|
+
initDialog(el as HTMLElement);
|
|
279
|
+
});
|
|
280
|
+
bindExternalTriggers();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Run on load and after Astro View Transitions
|
|
284
|
+
if (document.readyState === "loading") {
|
|
285
|
+
document.addEventListener("DOMContentLoaded", init);
|
|
286
|
+
} else {
|
|
287
|
+
init();
|
|
288
|
+
}
|
|
289
|
+
document.addEventListener("astro:page-load", init);
|
|
290
|
+
|
|
291
|
+
export { initDialog, openDialog, closeDialog };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { default as Dialog } from "./Dialog.astro";
|
|
2
|
+
export { default as DialogTrigger } from "./DialogTrigger.astro";
|
|
3
|
+
export { default as DialogContent } from "./DialogContent.astro";
|
|
4
|
+
export { default as DialogHeader } from "./DialogHeader.astro";
|
|
5
|
+
export { default as DialogTitle } from "./DialogTitle.astro";
|
|
6
|
+
export { default as DialogDescription } from "./DialogDescription.astro";
|
|
7
|
+
export { default as DialogFooter } from "./DialogFooter.astro";
|
|
8
|
+
export { default as DialogClose } from "./DialogClose.astro";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
|
|
4
|
+
const docsFooter = tv({
|
|
5
|
+
base: "mt-12 border-t pt-6",
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
const footerMeta = tv({
|
|
9
|
+
base: "mb-6 flex flex-wrap items-center gap-4 text-sm text-muted-foreground",
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
interface Props {
|
|
13
|
+
/** URL to edit this page on GitHub */
|
|
14
|
+
editUrl?: string;
|
|
15
|
+
/** Last updated date string */
|
|
16
|
+
lastUpdated?: string;
|
|
17
|
+
class?: string;
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const { editUrl, lastUpdated, class: className, ...rest } = Astro.props;
|
|
22
|
+
|
|
23
|
+
const showMeta = !!editUrl || !!lastUpdated;
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
<footer
|
|
27
|
+
class={docsFooter({ class: className })}
|
|
28
|
+
data-component="docs-footer"
|
|
29
|
+
{...rest}
|
|
30
|
+
>
|
|
31
|
+
{showMeta && (
|
|
32
|
+
<div class={footerMeta()}>
|
|
33
|
+
{editUrl && (
|
|
34
|
+
<a
|
|
35
|
+
href={editUrl}
|
|
36
|
+
target="_blank"
|
|
37
|
+
rel="noopener noreferrer"
|
|
38
|
+
class="inline-flex items-center gap-1 hover:text-foreground"
|
|
39
|
+
>
|
|
40
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
|
|
41
|
+
Edit this page
|
|
42
|
+
</a>
|
|
43
|
+
)}
|
|
44
|
+
{lastUpdated && (
|
|
45
|
+
<span>Last updated: {lastUpdated}</span>
|
|
46
|
+
)}
|
|
47
|
+
</div>
|
|
48
|
+
)}
|
|
49
|
+
<slot />
|
|
50
|
+
</footer>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
|
|
4
|
+
const docsHeader = tv({
|
|
5
|
+
base: "z-40 flex h-14 items-center gap-4 border-b bg-background/95 px-4 backdrop-blur supports-[backdrop-filter]:bg-background/60",
|
|
6
|
+
variants: {
|
|
7
|
+
sticky: {
|
|
8
|
+
true: "sticky top-0",
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
defaultVariants: {
|
|
12
|
+
sticky: true,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
interface Props {
|
|
17
|
+
/** Stick to top of viewport while scrolling (default: true) */
|
|
18
|
+
sticky?: boolean;
|
|
19
|
+
class?: string;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const { sticky = true, class: className, ...rest } = Astro.props;
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
<header
|
|
27
|
+
class={docsHeader({ sticky, class: className })}
|
|
28
|
+
data-component="docs-header"
|
|
29
|
+
{...rest}
|
|
30
|
+
>
|
|
31
|
+
<slot />
|
|
32
|
+
</header>
|