@kirchdev/duxt 0.1.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/LICENSE +21 -0
- package/README.md +151 -0
- package/app/app.config.ts +13 -0
- package/app/app.vue +122 -0
- package/app/assets/css/duxt.css +555 -0
- package/app/assets/css/typeset.css +498 -0
- package/app/components/DuxtBrand.vue +53 -0
- package/app/components/DuxtBreadcrumb.vue +37 -0
- package/app/components/DuxtCodeBlock.vue +143 -0
- package/app/components/DuxtCopyPage.vue +117 -0
- package/app/components/DuxtFooter.vue +86 -0
- package/app/components/DuxtHeader.vue +496 -0
- package/app/components/DuxtJsonEditor.vue +359 -0
- package/app/components/DuxtLandingProse.vue +90 -0
- package/app/components/DuxtLandingShowcase.vue +295 -0
- package/app/components/DuxtLiveWindow.vue +343 -0
- package/app/components/DuxtLocale.vue +86 -0
- package/app/components/DuxtMetaList.vue +76 -0
- package/app/components/DuxtNavigation.vue +94 -0
- package/app/components/DuxtNavigationLink.vue +41 -0
- package/app/components/DuxtOpenApiCallbacks.vue +92 -0
- package/app/components/DuxtOpenApiClient.vue +1339 -0
- package/app/components/DuxtOpenApiMedia.vue +108 -0
- package/app/components/DuxtOpenApiMethod.vue +59 -0
- package/app/components/DuxtOpenApiParameters.vue +114 -0
- package/app/components/DuxtOpenApiResponses.vue +109 -0
- package/app/components/DuxtOpenApiSchema.vue +365 -0
- package/app/components/DuxtOpenApiSecurity.vue +115 -0
- package/app/components/DuxtPageFeedback.vue +56 -0
- package/app/components/DuxtPageInfo.vue +194 -0
- package/app/components/DuxtPageNav.vue +93 -0
- package/app/components/DuxtPreviewSkeleton.vue +262 -0
- package/app/components/DuxtProgress.vue +45 -0
- package/app/components/DuxtSearch.vue +271 -0
- package/app/components/DuxtSections.vue +65 -0
- package/app/components/DuxtShortcuts.vue +46 -0
- package/app/components/DuxtSkipLink.vue +34 -0
- package/app/components/DuxtToc.vue +86 -0
- package/app/components/DuxtTranslationBanner.vue +64 -0
- package/app/components/DuxtVersion.vue +168 -0
- package/app/components/DuxtVersionBanner.vue +109 -0
- package/app/components/OgImage/Duxt.satori.vue +82 -0
- package/app/components/content/Accordion.vue +37 -0
- package/app/components/content/AccordionItem.vue +46 -0
- package/app/components/content/Callout.vue +58 -0
- package/app/components/content/ChangelogGroup.vue +91 -0
- package/app/components/content/ChangelogReleases.vue +520 -0
- package/app/components/content/CodeGroup.vue +183 -0
- package/app/components/content/DevtoolsPanel.vue +107 -0
- package/app/components/content/Field.vue +50 -0
- package/app/components/content/FieldGroup.vue +8 -0
- package/app/components/content/FileTree.vue +92 -0
- package/app/components/content/Mermaid.vue +70 -0
- package/app/components/content/OpenApiOperation.vue +185 -0
- package/app/components/content/OpenApiOperations.vue +72 -0
- package/app/components/content/OpenApiOverview.vue +302 -0
- package/app/components/content/PackageManagers.vue +187 -0
- package/app/components/content/PageCards.vue +48 -0
- package/app/components/content/Partial.vue +65 -0
- package/app/components/content/Preview.vue +173 -0
- package/app/components/content/ProseA.vue +55 -0
- package/app/components/content/ProseH2.vue +53 -0
- package/app/components/content/ProseH3.vue +53 -0
- package/app/components/content/ProseH4.vue +53 -0
- package/app/components/content/ProseImg.vue +87 -0
- package/app/components/content/ProsePre.vue +58 -0
- package/app/components/content/ProseTable.vue +11 -0
- package/app/components/content/Since.vue +21 -0
- package/app/components/content/Steps.vue +20 -0
- package/app/components/content/Tab.vue +23 -0
- package/app/components/content/TabGroup.vue +58 -0
- package/app/components/ui/alert/Alert.vue +21 -0
- package/app/components/ui/alert/AlertDescription.vue +22 -0
- package/app/components/ui/alert/AlertTitle.vue +22 -0
- package/app/components/ui/alert/index.ts +24 -0
- package/app/components/ui/badge/Badge.vue +28 -0
- package/app/components/ui/badge/index.ts +52 -0
- package/app/components/ui/breadcrumb/Breadcrumb.vue +13 -0
- package/app/components/ui/breadcrumb/BreadcrumbEllipsis.vue +22 -0
- package/app/components/ui/breadcrumb/BreadcrumbItem.vue +17 -0
- package/app/components/ui/breadcrumb/BreadcrumbLink.vue +24 -0
- package/app/components/ui/breadcrumb/BreadcrumbList.vue +22 -0
- package/app/components/ui/breadcrumb/BreadcrumbPage.vue +20 -0
- package/app/components/ui/breadcrumb/BreadcrumbSeparator.vue +21 -0
- package/app/components/ui/breadcrumb/index.ts +7 -0
- package/app/components/ui/button/Button.vue +31 -0
- package/app/components/ui/button/index.ts +39 -0
- package/app/components/ui/card/Card.vue +22 -0
- package/app/components/ui/card/CardAction.vue +22 -0
- package/app/components/ui/card/CardContent.vue +14 -0
- package/app/components/ui/card/CardDescription.vue +17 -0
- package/app/components/ui/card/CardFooter.vue +17 -0
- package/app/components/ui/card/CardHeader.vue +22 -0
- package/app/components/ui/card/CardTitle.vue +17 -0
- package/app/components/ui/card/index.ts +7 -0
- package/app/components/ui/collapsible/Collapsible.vue +19 -0
- package/app/components/ui/collapsible/CollapsibleContent.vue +12 -0
- package/app/components/ui/collapsible/CollapsibleTrigger.vue +12 -0
- package/app/components/ui/collapsible/index.ts +3 -0
- package/app/components/ui/command/Command.vue +98 -0
- package/app/components/ui/command/CommandDialog.vue +42 -0
- package/app/components/ui/command/CommandEmpty.vue +31 -0
- package/app/components/ui/command/CommandGroup.vue +52 -0
- package/app/components/ui/command/CommandInput.vue +45 -0
- package/app/components/ui/command/CommandItem.vue +85 -0
- package/app/components/ui/command/CommandList.vue +32 -0
- package/app/components/ui/command/CommandSeparator.vue +23 -0
- package/app/components/ui/command/CommandShortcut.vue +19 -0
- package/app/components/ui/command/index.ts +29 -0
- package/app/components/ui/dialog/Dialog.vue +15 -0
- package/app/components/ui/dialog/DialogClose.vue +12 -0
- package/app/components/ui/dialog/DialogContent.vue +61 -0
- package/app/components/ui/dialog/DialogDescription.vue +25 -0
- package/app/components/ui/dialog/DialogFooter.vue +30 -0
- package/app/components/ui/dialog/DialogHeader.vue +17 -0
- package/app/components/ui/dialog/DialogOverlay.vue +28 -0
- package/app/components/ui/dialog/DialogScrollContent.vue +65 -0
- package/app/components/ui/dialog/DialogTitle.vue +25 -0
- package/app/components/ui/dialog/DialogTrigger.vue +12 -0
- package/app/components/ui/dialog/index.ts +10 -0
- package/app/components/ui/dropdown-menu/DropdownMenu.vue +19 -0
- package/app/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +47 -0
- package/app/components/ui/dropdown-menu/DropdownMenuContent.vue +47 -0
- package/app/components/ui/dropdown-menu/DropdownMenuGroup.vue +12 -0
- package/app/components/ui/dropdown-menu/DropdownMenuItem.vue +41 -0
- package/app/components/ui/dropdown-menu/DropdownMenuLabel.vue +27 -0
- package/app/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +21 -0
- package/app/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +48 -0
- package/app/components/ui/dropdown-menu/DropdownMenuSeparator.vue +23 -0
- package/app/components/ui/dropdown-menu/DropdownMenuShortcut.vue +19 -0
- package/app/components/ui/dropdown-menu/DropdownMenuSub.vue +19 -0
- package/app/components/ui/dropdown-menu/DropdownMenuSubContent.vue +34 -0
- package/app/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +34 -0
- package/app/components/ui/dropdown-menu/DropdownMenuTrigger.vue +17 -0
- package/app/components/ui/dropdown-menu/index.ts +16 -0
- package/app/components/ui/input/Input.vue +35 -0
- package/app/components/ui/input/index.ts +1 -0
- package/app/components/ui/navigation-menu/NavigationMenu.vue +42 -0
- package/app/components/ui/navigation-menu/NavigationMenuContent.vue +35 -0
- package/app/components/ui/navigation-menu/NavigationMenuIndicator.vue +32 -0
- package/app/components/ui/navigation-menu/NavigationMenuItem.vue +23 -0
- package/app/components/ui/navigation-menu/NavigationMenuLink.vue +30 -0
- package/app/components/ui/navigation-menu/NavigationMenuList.vue +30 -0
- package/app/components/ui/navigation-menu/NavigationMenuTrigger.vue +31 -0
- package/app/components/ui/navigation-menu/NavigationMenuViewport.vue +30 -0
- package/app/components/ui/navigation-menu/index.ts +14 -0
- package/app/components/ui/scroll-area/ScrollArea.vue +31 -0
- package/app/components/ui/scroll-area/ScrollBar.vue +38 -0
- package/app/components/ui/scroll-area/index.ts +2 -0
- package/app/components/ui/select/Select.vue +15 -0
- package/app/components/ui/select/SelectContent.vue +59 -0
- package/app/components/ui/select/SelectGroup.vue +19 -0
- package/app/components/ui/select/SelectItem.vue +42 -0
- package/app/components/ui/select/SelectItemText.vue +12 -0
- package/app/components/ui/select/SelectLabel.vue +16 -0
- package/app/components/ui/select/SelectScrollDownButton.vue +28 -0
- package/app/components/ui/select/SelectScrollUpButton.vue +28 -0
- package/app/components/ui/select/SelectSeparator.vue +20 -0
- package/app/components/ui/select/SelectTrigger.vue +32 -0
- package/app/components/ui/select/SelectValue.vue +12 -0
- package/app/components/ui/select/index.ts +11 -0
- package/app/components/ui/separator/Separator.vue +30 -0
- package/app/components/ui/separator/index.ts +1 -0
- package/app/components/ui/sheet/Sheet.vue +15 -0
- package/app/components/ui/sheet/SheetClose.vue +12 -0
- package/app/components/ui/sheet/SheetContent.vue +68 -0
- package/app/components/ui/sheet/SheetDescription.vue +23 -0
- package/app/components/ui/sheet/SheetFooter.vue +15 -0
- package/app/components/ui/sheet/SheetHeader.vue +15 -0
- package/app/components/ui/sheet/SheetOverlay.vue +28 -0
- package/app/components/ui/sheet/SheetTitle.vue +23 -0
- package/app/components/ui/sheet/SheetTrigger.vue +12 -0
- package/app/components/ui/sheet/index.ts +8 -0
- package/app/components/ui/sidebar/Sidebar.vue +110 -0
- package/app/components/ui/sidebar/SidebarContent.vue +23 -0
- package/app/components/ui/sidebar/SidebarFooter.vue +18 -0
- package/app/components/ui/sidebar/SidebarGroup.vue +18 -0
- package/app/components/ui/sidebar/SidebarGroupAction.vue +31 -0
- package/app/components/ui/sidebar/SidebarGroupContent.vue +18 -0
- package/app/components/ui/sidebar/SidebarGroupLabel.vue +30 -0
- package/app/components/ui/sidebar/SidebarHeader.vue +18 -0
- package/app/components/ui/sidebar/SidebarInput.vue +19 -0
- package/app/components/ui/sidebar/SidebarInset.vue +23 -0
- package/app/components/ui/sidebar/SidebarMenu.vue +18 -0
- package/app/components/ui/sidebar/SidebarMenuAction.vue +42 -0
- package/app/components/ui/sidebar/SidebarMenuBadge.vue +28 -0
- package/app/components/ui/sidebar/SidebarMenuButton.vue +60 -0
- package/app/components/ui/sidebar/SidebarMenuButtonChild.vue +36 -0
- package/app/components/ui/sidebar/SidebarMenuItem.vue +18 -0
- package/app/components/ui/sidebar/SidebarMenuSkeleton.vue +35 -0
- package/app/components/ui/sidebar/SidebarMenuSub.vue +24 -0
- package/app/components/ui/sidebar/SidebarMenuSubButton.vue +43 -0
- package/app/components/ui/sidebar/SidebarMenuSubItem.vue +18 -0
- package/app/components/ui/sidebar/SidebarProvider.vue +109 -0
- package/app/components/ui/sidebar/SidebarRail.vue +35 -0
- package/app/components/ui/sidebar/SidebarSeparator.vue +19 -0
- package/app/components/ui/sidebar/SidebarTrigger.vue +26 -0
- package/app/components/ui/sidebar/index.ts +62 -0
- package/app/components/ui/sidebar/utils.ts +19 -0
- package/app/components/ui/skeleton/Skeleton.vue +17 -0
- package/app/components/ui/skeleton/index.ts +1 -0
- package/app/components/ui/sonner/Sonner.vue +67 -0
- package/app/components/ui/sonner/index.ts +1 -0
- package/app/components/ui/tabs/Tabs.vue +26 -0
- package/app/components/ui/tabs/TabsContent.vue +23 -0
- package/app/components/ui/tabs/TabsList.vue +28 -0
- package/app/components/ui/tabs/TabsTrigger.vue +30 -0
- package/app/components/ui/tabs/index.ts +4 -0
- package/app/components/ui/textarea/Textarea.vue +32 -0
- package/app/components/ui/textarea/index.ts +1 -0
- package/app/components/ui/tooltip/Tooltip.vue +15 -0
- package/app/components/ui/tooltip/TooltipContent.vue +49 -0
- package/app/components/ui/tooltip/TooltipProvider.vue +14 -0
- package/app/components/ui/tooltip/TooltipTrigger.vue +12 -0
- package/app/components/ui/tooltip/index.ts +4 -0
- package/app/composables/useActiveHeading.ts +90 -0
- package/app/composables/useDuxtAnimatedHeight.ts +155 -0
- package/app/composables/useDuxtBreadcrumb.ts +60 -0
- package/app/composables/useDuxtChoice.ts +28 -0
- package/app/composables/useDuxtCollection.ts +89 -0
- package/app/composables/useDuxtConfig.ts +47 -0
- package/app/composables/useDuxtNavigation.ts +87 -0
- package/app/composables/useDuxtPageFocus.ts +30 -0
- package/app/composables/useDuxtPath.ts +42 -0
- package/app/composables/useDuxtSearch.ts +208 -0
- package/app/composables/useDuxtSection.ts +44 -0
- package/app/composables/useDuxtSectionRow.ts +49 -0
- package/app/composables/useDuxtShortcuts.ts +58 -0
- package/app/composables/useDuxtSiteUrl.ts +27 -0
- package/app/composables/useDuxtToast.ts +25 -0
- package/app/composables/useDuxtVersion.ts +138 -0
- package/app/composables/useFuzzySearch.ts +83 -0
- package/app/composables/usePackageManager.ts +4 -0
- package/app/composables/useRecentPages.ts +52 -0
- package/app/error.vue +133 -0
- package/app/layouts/changelog.vue +85 -0
- package/app/layouts/default.vue +23 -0
- package/app/layouts/docs.vue +62 -0
- package/app/layouts/reference.vue +85 -0
- package/app/lib/utils.ts +7 -0
- package/app/middleware/duxt-section-layout.global.ts +57 -0
- package/app/pages/[...slug].vue +441 -0
- package/app/pages/index.vue +479 -0
- package/app/types/duxt.d.ts +955 -0
- package/app/utils/aside.ts +16 -0
- package/app/utils/changelog.ts +182 -0
- package/app/utils/code-highlight.ts +116 -0
- package/app/utils/duxt-config.ts +185 -0
- package/app/utils/duxt-text.ts +135 -0
- package/app/utils/file-icons.ts +62 -0
- package/app/utils/generated-sections.ts +190 -0
- package/app/utils/generated-toc.ts +216 -0
- package/app/utils/heading-link.ts +32 -0
- package/app/utils/locale-path.ts +45 -0
- package/app/utils/navigation-tree.ts +206 -0
- package/app/utils/nearest-page.ts +72 -0
- package/app/utils/openapi.ts +1028 -0
- package/app/utils/package-command.ts +162 -0
- package/app/utils/request-samples.ts +635 -0
- package/app/utils/section-scope.ts +97 -0
- package/app/utils/sheet-navigation.ts +100 -0
- package/app/utils/source-file.ts +84 -0
- package/app/utils/version-choices.ts +68 -0
- package/app/utils/version-paths.ts +65 -0
- package/bin/duxt-report.mjs +45 -0
- package/components.json +19 -0
- package/content-cache.ts +193 -0
- package/content.config.ts +38 -0
- package/duxt-app-config.ts +124 -0
- package/highlight-langs.ts +68 -0
- package/i18n/i18n.config.ts +16 -0
- package/i18n/locales/de/duxt/changelog.json +17 -0
- package/i18n/locales/de/duxt/code.json +13 -0
- package/i18n/locales/de/duxt/defaults.json +22 -0
- package/i18n/locales/de/duxt/devtools.json +7 -0
- package/i18n/locales/de/duxt/error.json +10 -0
- package/i18n/locales/de/duxt/footer.json +7 -0
- package/i18n/locales/de/duxt/locale.json +7 -0
- package/i18n/locales/de/duxt/nav.json +17 -0
- package/i18n/locales/de/duxt/openapi.json +89 -0
- package/i18n/locales/de/duxt/page.json +34 -0
- package/i18n/locales/de/duxt/search.json +12 -0
- package/i18n/locales/de/duxt/shortcuts.json +11 -0
- package/i18n/locales/de/duxt/theme.json +7 -0
- package/i18n/locales/de/duxt/toc.json +7 -0
- package/i18n/locales/de/duxt/version.json +25 -0
- package/i18n/locales/en/duxt/changelog.json +17 -0
- package/i18n/locales/en/duxt/code.json +13 -0
- package/i18n/locales/en/duxt/defaults.json +22 -0
- package/i18n/locales/en/duxt/devtools.json +7 -0
- package/i18n/locales/en/duxt/error.json +10 -0
- package/i18n/locales/en/duxt/footer.json +7 -0
- package/i18n/locales/en/duxt/locale.json +7 -0
- package/i18n/locales/en/duxt/nav.json +17 -0
- package/i18n/locales/en/duxt/openapi.json +89 -0
- package/i18n/locales/en/duxt/page.json +34 -0
- package/i18n/locales/en/duxt/search.json +12 -0
- package/i18n/locales/en/duxt/shortcuts.json +11 -0
- package/i18n/locales/en/duxt/theme.json +7 -0
- package/i18n/locales/en/duxt/toc.json +7 -0
- package/i18n/locales/en/duxt/version.json +25 -0
- package/i18n/locales/es/duxt/changelog.json +17 -0
- package/i18n/locales/es/duxt/code.json +13 -0
- package/i18n/locales/es/duxt/defaults.json +22 -0
- package/i18n/locales/es/duxt/devtools.json +7 -0
- package/i18n/locales/es/duxt/error.json +10 -0
- package/i18n/locales/es/duxt/footer.json +7 -0
- package/i18n/locales/es/duxt/locale.json +7 -0
- package/i18n/locales/es/duxt/nav.json +17 -0
- package/i18n/locales/es/duxt/openapi.json +89 -0
- package/i18n/locales/es/duxt/page.json +34 -0
- package/i18n/locales/es/duxt/search.json +12 -0
- package/i18n/locales/es/duxt/shortcuts.json +11 -0
- package/i18n/locales/es/duxt/theme.json +7 -0
- package/i18n/locales/es/duxt/toc.json +7 -0
- package/i18n/locales/es/duxt/version.json +25 -0
- package/i18n/locales/fr/duxt/changelog.json +17 -0
- package/i18n/locales/fr/duxt/code.json +13 -0
- package/i18n/locales/fr/duxt/defaults.json +22 -0
- package/i18n/locales/fr/duxt/devtools.json +7 -0
- package/i18n/locales/fr/duxt/error.json +10 -0
- package/i18n/locales/fr/duxt/footer.json +7 -0
- package/i18n/locales/fr/duxt/locale.json +7 -0
- package/i18n/locales/fr/duxt/nav.json +17 -0
- package/i18n/locales/fr/duxt/openapi.json +89 -0
- package/i18n/locales/fr/duxt/page.json +34 -0
- package/i18n/locales/fr/duxt/search.json +12 -0
- package/i18n/locales/fr/duxt/shortcuts.json +11 -0
- package/i18n/locales/fr/duxt/theme.json +7 -0
- package/i18n/locales/fr/duxt/toc.json +7 -0
- package/i18n/locales/fr/duxt/version.json +25 -0
- package/i18n/locales/pt/duxt/changelog.json +17 -0
- package/i18n/locales/pt/duxt/code.json +13 -0
- package/i18n/locales/pt/duxt/defaults.json +22 -0
- package/i18n/locales/pt/duxt/devtools.json +7 -0
- package/i18n/locales/pt/duxt/error.json +10 -0
- package/i18n/locales/pt/duxt/footer.json +7 -0
- package/i18n/locales/pt/duxt/locale.json +7 -0
- package/i18n/locales/pt/duxt/nav.json +17 -0
- package/i18n/locales/pt/duxt/openapi.json +89 -0
- package/i18n/locales/pt/duxt/page.json +34 -0
- package/i18n/locales/pt/duxt/search.json +12 -0
- package/i18n/locales/pt/duxt/shortcuts.json +11 -0
- package/i18n/locales/pt/duxt/theme.json +7 -0
- package/i18n/locales/pt/duxt/toc.json +7 -0
- package/i18n/locales/pt/duxt/version.json +25 -0
- package/i18n/locales/pt-BR/duxt/error.json +8 -0
- package/i18n/locales/pt-BR/duxt/nav.json +10 -0
- package/i18n/locales/pt-BR/duxt/page.json +10 -0
- package/i18n/locales/pt-BR/duxt/search.json +11 -0
- package/i18n/locales/pt-BR/duxt/version.json +13 -0
- package/mdc.config.ts +28 -0
- package/modules/config.ts +440 -0
- package/modules/devtools.ts +126 -0
- package/modules/git-meta.ts +349 -0
- package/modules/redirects.ts +152 -0
- package/modules/validate.ts +137 -0
- package/nuxt.config.ts +530 -0
- package/openapi-model.ts +358 -0
- package/openapi-parse.ts +1052 -0
- package/package.json +161 -0
- package/public/devtools/cache.html +318 -0
- package/public/devtools/checks.html +309 -0
- package/public/devtools/config.html +461 -0
- package/public/devtools/i18n.html +309 -0
- package/public/devtools/pages.html +348 -0
- package/public/devtools/paths.html +315 -0
- package/public/devtools/redirects.html +309 -0
- package/public/devtools/search.html +324 -0
- package/public/devtools/sources.html +309 -0
- package/public/devtools/versions.html +318 -0
- package/report.ts +303 -0
- package/repository-root.ts +26 -0
- package/section-reports.ts +55 -0
- package/sections-changelog.ts +644 -0
- package/sections-openapi.ts +450 -0
- package/sections-resolve.ts +711 -0
- package/sections.ts +157 -0
- package/server/devtools/content.ts +120 -0
- package/server/devtools/context.ts +38 -0
- package/server/devtools/entry-path.ts +30 -0
- package/server/devtools/handler.ts +104 -0
- package/server/devtools/preview.ts +461 -0
- package/server/devtools/render/content.ts +233 -0
- package/server/devtools/render/sources.ts +414 -0
- package/server/devtools/render/system.ts +352 -0
- package/server/devtools/shell.ts +611 -0
- package/server/devtools/sources.ts +122 -0
- package/server/devtools/system.ts +178 -0
- package/server/mcp/tools/list-pages.ts +52 -0
- package/server/mcp/tools/read-page.ts +57 -0
- package/server/mcp/tools/search-docs.ts +74 -0
- package/server/middleware/raw-markdown.ts +86 -0
- package/server/routes/llms-full.txt.get.ts +75 -0
- package/server/routes/llms.txt.get.ts +63 -0
- package/server/routes/rss.xml.get.ts +125 -0
- package/server/utils/duxt-server-text.ts +46 -0
- package/sources-git.ts +113 -0
- package/sources-resolve.ts +908 -0
- package/sources.ts +287 -0
- package/validate-report.ts +494 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* An image in a page: theme-aware, and zoomable.
|
|
4
|
+
*
|
|
5
|
+
* TWO VARIANTS. A screenshot of a dark editor on a white page — or the reverse
|
|
6
|
+
* — is the most common ugly thing in documentation, and CSS cannot fix it
|
|
7
|
+
* because the pixels are wrong, not the frame. So a page may name a second
|
|
8
|
+
* file:
|
|
9
|
+
*
|
|
10
|
+
* {dark="/shots/sidebar-dark.png"}
|
|
11
|
+
*
|
|
12
|
+
* Named explicitly rather than guessed by convention. Deriving `-dark.png` from
|
|
13
|
+
* the light path would 404 on every image that has no dark twin, and a broken
|
|
14
|
+
* image is worse than a mismatched one. Both are rendered and CSS picks: a
|
|
15
|
+
* `<picture>` with `prefers-color-scheme` would ignore the site's own toggle,
|
|
16
|
+
* which is a class on `<html>` and not a media query.
|
|
17
|
+
*
|
|
18
|
+
* ZOOM. A screenshot scaled to a 48rem column is often unreadable, and the
|
|
19
|
+
* browser's own zoom is not the answer when the image is 2400px wide. Clicking
|
|
20
|
+
* opens it at full size; Escape and a click outside close it, both from the
|
|
21
|
+
* Dialog primitive rather than hand-rolled.
|
|
22
|
+
*/
|
|
23
|
+
const props = defineProps<{
|
|
24
|
+
src?: string;
|
|
25
|
+
alt?: string;
|
|
26
|
+
width?: string | number;
|
|
27
|
+
height?: string | number;
|
|
28
|
+
/** A second file for dark mode. */
|
|
29
|
+
dark?: string;
|
|
30
|
+
/** `false` turns the zoom off for a decorative image. */
|
|
31
|
+
zoom?: boolean | string;
|
|
32
|
+
}>();
|
|
33
|
+
|
|
34
|
+
const open = ref(false);
|
|
35
|
+
|
|
36
|
+
const zoomable = computed(() => props.zoom !== false && props.zoom !== 'false');
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<template>
|
|
40
|
+
<span class="my-6 block">
|
|
41
|
+
<component
|
|
42
|
+
:is="zoomable ? 'button' : 'span'"
|
|
43
|
+
:type="zoomable ? 'button' : undefined"
|
|
44
|
+
class="block w-full"
|
|
45
|
+
:class="zoomable ? 'cursor-zoom-in' : undefined"
|
|
46
|
+
:aria-label="zoomable ? alt : undefined"
|
|
47
|
+
@click="zoomable && (open = true)"
|
|
48
|
+
>
|
|
49
|
+
<NuxtImg
|
|
50
|
+
:src="src"
|
|
51
|
+
:alt="alt"
|
|
52
|
+
:width="width"
|
|
53
|
+
:height="height"
|
|
54
|
+
loading="lazy"
|
|
55
|
+
class="rounded-lg border"
|
|
56
|
+
:class="dark ? 'block dark:hidden' : undefined"
|
|
57
|
+
/>
|
|
58
|
+
<NuxtImg
|
|
59
|
+
v-if="dark"
|
|
60
|
+
:src="dark"
|
|
61
|
+
:alt="alt"
|
|
62
|
+
:width="width"
|
|
63
|
+
:height="height"
|
|
64
|
+
loading="lazy"
|
|
65
|
+
class="hidden rounded-lg border dark:block"
|
|
66
|
+
/>
|
|
67
|
+
</component>
|
|
68
|
+
|
|
69
|
+
<UiDialog v-if="zoomable" v-model:open="open">
|
|
70
|
+
<UiDialogContent class="max-w-[min(96vw,80rem)] p-2">
|
|
71
|
+
<UiDialogTitle class="sr-only">{{ alt }}</UiDialogTitle>
|
|
72
|
+
<NuxtImg
|
|
73
|
+
:src="src"
|
|
74
|
+
:alt="alt"
|
|
75
|
+
class="max-h-[85vh] w-full rounded-md object-contain"
|
|
76
|
+
:class="dark ? 'block dark:hidden' : undefined"
|
|
77
|
+
/>
|
|
78
|
+
<NuxtImg
|
|
79
|
+
v-if="dark"
|
|
80
|
+
:src="dark"
|
|
81
|
+
:alt="alt"
|
|
82
|
+
class="hidden max-h-[85vh] w-full rounded-md object-contain dark:block"
|
|
83
|
+
/>
|
|
84
|
+
</UiDialogContent>
|
|
85
|
+
</UiDialog>
|
|
86
|
+
</span>
|
|
87
|
+
</template>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// Content styles its tokens with `html pre.shiki code .<token>` selectors, so
|
|
3
|
+
// the shiki classes have to land on the <pre> itself. Passed through to the
|
|
4
|
+
// wrapper instead — the default when attributes fall through — every token
|
|
5
|
+
// keeps its class and loses its colour, which reads as "highlighting is off".
|
|
6
|
+
defineOptions({ inheritAttrs: false });
|
|
7
|
+
|
|
8
|
+
const props = defineProps<{
|
|
9
|
+
code?: string;
|
|
10
|
+
language?: string;
|
|
11
|
+
filename?: string;
|
|
12
|
+
highlights?: number[];
|
|
13
|
+
meta?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The block's own header bar. Passed through rather than left to fall into
|
|
16
|
+
* `$attrs`, which `inheritAttrs: false` binds to the <pre> — where it would
|
|
17
|
+
* become an HTML attribute nobody reads instead of a prop.
|
|
18
|
+
*
|
|
19
|
+
* `::code-group` switches it off: the tab already names the file.
|
|
20
|
+
*/
|
|
21
|
+
header?: boolean;
|
|
22
|
+
}>();
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Line numbers are opt-in per fence, written in its meta:
|
|
26
|
+
*
|
|
27
|
+
* ```ts line-numbers
|
|
28
|
+
*
|
|
29
|
+
* Not on by default: most snippets in documentation are four lines long and a
|
|
30
|
+
* gutter of numbers next to them is noise. The numbers themselves are drawn by
|
|
31
|
+
* a CSS counter — see `duxt.css` — so a reader copying the block gets the code
|
|
32
|
+
* and not the numbering.
|
|
33
|
+
*/
|
|
34
|
+
const lineNumbers = computed(() =>
|
|
35
|
+
Boolean(props.meta && /\bline-numbers\b/.test(props.meta))
|
|
36
|
+
);
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<template>
|
|
40
|
+
<!-- A ```mermaid fence is a diagram, not a snippet. Mapped here rather than
|
|
41
|
+
through an MDC component map, because this is the component Content
|
|
42
|
+
already hands every fence to and the language is already a prop. -->
|
|
43
|
+
<Mermaid v-if="language === 'mermaid'" :code="code" />
|
|
44
|
+
|
|
45
|
+
<DuxtCodeBlock
|
|
46
|
+
v-else
|
|
47
|
+
:code="code"
|
|
48
|
+
:language="language"
|
|
49
|
+
:filename="filename"
|
|
50
|
+
:header="header ?? true"
|
|
51
|
+
>
|
|
52
|
+
<pre
|
|
53
|
+
v-bind="$attrs"
|
|
54
|
+
class="overflow-x-auto p-4 text-sm"
|
|
55
|
+
:class="{ 'duxt-line-numbers': lineNumbers }"
|
|
56
|
+
><slot /></pre>
|
|
57
|
+
</DuxtCodeBlock>
|
|
58
|
+
</template>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- typeset gives a wide block horizontal scroll through `.typeset-scroll`,
|
|
3
|
+
but Content renders a bare <table> and never wraps one — so a reference
|
|
4
|
+
table with long code spans pushed the whole page sideways on a phone.
|
|
5
|
+
The wrapper is what typeset expects; it also owns the flow margin. -->
|
|
6
|
+
<div class="typeset-scroll">
|
|
7
|
+
<table>
|
|
8
|
+
<slot />
|
|
9
|
+
</table>
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* `:since{version="v2.1"}` beside a heading.
|
|
4
|
+
*
|
|
5
|
+
* Hangs off the version model rather than repeating it: what the badge says is
|
|
6
|
+
* the version a thing ARRIVED in, which is a fact about the API and not about
|
|
7
|
+
* the page it is documented on — so it stays correct in every version of the
|
|
8
|
+
* docs that carries the sentence.
|
|
9
|
+
*
|
|
10
|
+
* For anything else, `:badge[…]` calls the theme's own Badge directly; MDC
|
|
11
|
+
* resolves any globally registered component by name, so a badge with arbitrary
|
|
12
|
+
* text needs no component of its own.
|
|
13
|
+
*/
|
|
14
|
+
defineProps<{ version?: string }>();
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<UiBadge variant="secondary" class="ml-2 align-middle font-mono text-[10px]">
|
|
19
|
+
{{ $t('duxt.page.since', { version }) }}
|
|
20
|
+
</UiBadge>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- Wraps an ordered list in Markdown into a stepped layout:
|
|
3
|
+
`::steps` … `::` around the list.
|
|
4
|
+
|
|
5
|
+
Two things are load-bearing here. The variant ORDER:
|
|
6
|
+
`[&>ol>li]:before:absolute` compiles to `… > ol > li::before`, while the
|
|
7
|
+
reverse spelling compiles to the container's own `::before` and the items
|
|
8
|
+
get no marker at all. And the list PADDING: typeset gives every `ol` a
|
|
9
|
+
`padding-inline-start` and every `li` one of its own, which pushed the
|
|
10
|
+
items — and with them the markers, positioned relative to each item —
|
|
11
|
+
clear of the rail they are supposed to sit on. `pl-0` on both puts the
|
|
12
|
+
item's edge back at the container's own padding, which is what
|
|
13
|
+
`-left-9` is measured against: 1.5rem in, 2.25rem back out, half a
|
|
14
|
+
marker wide — centred on the line. -->
|
|
15
|
+
<div
|
|
16
|
+
class="my-6 border-l pl-6 [counter-reset:step] [&>ol]:ml-0 [&>ol]:list-none [&>ol]:pl-0 [&>ol>li]:relative [&>ol>li]:my-6 [&>ol>li]:pl-0 [&>ol>li]:[counter-increment:step] [&>ol>li]:before:absolute [&>ol>li]:before:-left-9 [&>ol>li]:before:flex [&>ol>li]:before:size-6 [&>ol>li]:before:items-center [&>ol>li]:before:justify-center [&>ol>li]:before:rounded-full [&>ol>li]:before:bg-muted [&>ol>li]:before:text-xs [&>ol>li]:before:font-medium [&>ol>li]:before:text-foreground [&>ol>li]:before:content-[counter(step)]"
|
|
17
|
+
>
|
|
18
|
+
<slot />
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { TabsContent } from 'reka-ui';
|
|
3
|
+
import type { DuxtTabGroupContext } from './TabGroup.vue';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* One panel of a `::tab-group` block. Registers its own label with the parent on
|
|
7
|
+
* setup, which is what lets the list of triggers be built from children MDC
|
|
8
|
+
* has not rendered yet.
|
|
9
|
+
*/
|
|
10
|
+
const props = defineProps<{ label?: string }>();
|
|
11
|
+
|
|
12
|
+
const parent = inject<DuxtTabGroupContext | undefined>('duxt-tabs', undefined);
|
|
13
|
+
const value = parent?.register(props.label ?? '') ?? 'tab-0';
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<TabsContent
|
|
18
|
+
:value="value"
|
|
19
|
+
class="pt-2 focus-visible:outline-none [&>*:last-child]:mb-0"
|
|
20
|
+
>
|
|
21
|
+
<slot />
|
|
22
|
+
</TabsContent>
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { TabsList, TabsRoot, TabsTrigger } from 'reka-ui';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* `::tab-group` with `:::tab{label="…"}` children.
|
|
6
|
+
*
|
|
7
|
+
* NOT `::tabs`. The theme's own UI kit already registers a `Tabs` — shadcn's —
|
|
8
|
+
* and two components of one name is not an override a build resolves in your
|
|
9
|
+
* favour: Nuxt warns and keeps one of them, and the one it kept was shadcn's,
|
|
10
|
+
* so `::tabs` in a page rendered a primitive with no triggers and no state.
|
|
11
|
+
* A content component may not take a name the UI kit owns. `::code-group` next
|
|
12
|
+
* to it reads the same way, which is the consolation.
|
|
13
|
+
*
|
|
14
|
+
* Built on reka-ui's primitives directly rather than on the shadcn `Tabs`
|
|
15
|
+
* wrapper, because the labels are not known until the children have registered
|
|
16
|
+
* themselves: MDC hands them in as slot content, not as a prop. A provide/inject
|
|
17
|
+
* pair collects them, which is also what makes a `:::tab` work at any depth
|
|
18
|
+
* inside the block.
|
|
19
|
+
*
|
|
20
|
+
* Keyboard navigation, roving focus and the ARIA roles come from reka-ui — the
|
|
21
|
+
* reason not to hand-roll this out of divs.
|
|
22
|
+
*/
|
|
23
|
+
export interface DuxtTabGroupContext {
|
|
24
|
+
register: (label: string) => string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const tabs = ref<{ value: string; label: string }[]>([]);
|
|
28
|
+
const active = ref<string>();
|
|
29
|
+
|
|
30
|
+
provide<DuxtTabGroupContext>('duxt-tabs', {
|
|
31
|
+
register(label: string) {
|
|
32
|
+
const value = `tab-${tabs.value.length}`;
|
|
33
|
+
tabs.value.push({ value, label });
|
|
34
|
+
active.value ??= value;
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<template>
|
|
41
|
+
<TabsRoot v-model="active" class="my-6">
|
|
42
|
+
<TabsList
|
|
43
|
+
class="flex gap-1 border-b"
|
|
44
|
+
:aria-label="$t('duxt.page.tabs') as string"
|
|
45
|
+
>
|
|
46
|
+
<TabsTrigger
|
|
47
|
+
v-for="tab in tabs"
|
|
48
|
+
:key="tab.value"
|
|
49
|
+
:value="tab.value"
|
|
50
|
+
class="-mb-px cursor-pointer border-b-2 border-transparent px-3 py-1.5 text-sm text-muted-foreground transition-colors hover:text-foreground data-[state=active]:border-primary data-[state=active]:text-foreground"
|
|
51
|
+
>
|
|
52
|
+
{{ tab.label }}
|
|
53
|
+
</TabsTrigger>
|
|
54
|
+
</TabsList>
|
|
55
|
+
|
|
56
|
+
<slot />
|
|
57
|
+
</TabsRoot>
|
|
58
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import type { AlertVariants } from '.';
|
|
4
|
+
import { cn } from '@duxt/lib/utils';
|
|
5
|
+
import { alertVariants } from '.';
|
|
6
|
+
|
|
7
|
+
const props = defineProps<{
|
|
8
|
+
class?: HTMLAttributes['class'];
|
|
9
|
+
variant?: AlertVariants['variant'];
|
|
10
|
+
}>();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<div
|
|
15
|
+
data-slot="alert"
|
|
16
|
+
:class="cn(alertVariants({ variant }), props.class)"
|
|
17
|
+
role="alert"
|
|
18
|
+
>
|
|
19
|
+
<slot />
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { cn } from '@duxt/lib/utils';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div
|
|
12
|
+
data-slot="alert-description"
|
|
13
|
+
:class="
|
|
14
|
+
cn(
|
|
15
|
+
'text-muted-foreground col-start-2 text-sm [&_p]:leading-relaxed',
|
|
16
|
+
props.class
|
|
17
|
+
)
|
|
18
|
+
"
|
|
19
|
+
>
|
|
20
|
+
<slot />
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { cn } from '@duxt/lib/utils';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div
|
|
12
|
+
data-slot="alert-title"
|
|
13
|
+
:class="
|
|
14
|
+
cn(
|
|
15
|
+
'col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight',
|
|
16
|
+
props.class
|
|
17
|
+
)
|
|
18
|
+
"
|
|
19
|
+
>
|
|
20
|
+
<slot />
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { VariantProps } from 'class-variance-authority';
|
|
2
|
+
import { cva } from 'class-variance-authority';
|
|
3
|
+
|
|
4
|
+
export { default as Alert } from './Alert.vue';
|
|
5
|
+
export { default as AlertDescription } from './AlertDescription.vue';
|
|
6
|
+
export { default as AlertTitle } from './AlertTitle.vue';
|
|
7
|
+
|
|
8
|
+
export const alertVariants = cva(
|
|
9
|
+
'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current',
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
default: 'bg-card text-card-foreground',
|
|
14
|
+
destructive:
|
|
15
|
+
'text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90'
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
variant: 'default'
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export type AlertVariants = VariantProps<typeof alertVariants>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { PrimitiveProps } from 'reka-ui';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
import type { BadgeVariants } from '.';
|
|
5
|
+
import { reactiveOmit } from '@vueuse/core';
|
|
6
|
+
import { Primitive } from 'reka-ui';
|
|
7
|
+
import { cn } from '@duxt/lib/utils';
|
|
8
|
+
import { badgeVariants } from '.';
|
|
9
|
+
|
|
10
|
+
const props = defineProps<
|
|
11
|
+
PrimitiveProps & {
|
|
12
|
+
variant?: BadgeVariants['variant'];
|
|
13
|
+
class?: HTMLAttributes['class'];
|
|
14
|
+
}
|
|
15
|
+
>();
|
|
16
|
+
|
|
17
|
+
const delegatedProps = reactiveOmit(props, 'class');
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<Primitive
|
|
22
|
+
data-slot="badge"
|
|
23
|
+
:class="cn(badgeVariants({ variant }), props.class)"
|
|
24
|
+
v-bind="delegatedProps"
|
|
25
|
+
>
|
|
26
|
+
<slot />
|
|
27
|
+
</Primitive>
|
|
28
|
+
</template>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { VariantProps } from 'class-variance-authority';
|
|
2
|
+
import { cva } from 'class-variance-authority';
|
|
3
|
+
|
|
4
|
+
export { default as Badge } from './Badge.vue';
|
|
5
|
+
|
|
6
|
+
export const badgeVariants = cva(
|
|
7
|
+
'inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
/**
|
|
12
|
+
* TINTED, NOT FILLED — and that is a deliberate departure from shadcn's
|
|
13
|
+
* own set, which fills this one with solid `--primary`.
|
|
14
|
+
*
|
|
15
|
+
* A badge marks something small: a release that is current, a page that
|
|
16
|
+
* is new, an endpoint that is a webhook. A solid pill in the accent
|
|
17
|
+
* colour is the loudest object on a page of grey text, and it was
|
|
18
|
+
* louder than the changelog's filter chips sitting next to it — which
|
|
19
|
+
* are built exactly this way and read better. So the chips won.
|
|
20
|
+
*
|
|
21
|
+
* The construction is theirs: a tenth of the colour as surface, a fifth
|
|
22
|
+
* as border, the colour itself as text. `--primary` is measured as text
|
|
23
|
+
* in `tests/contrast.test.ts`, because that is a use it did not have
|
|
24
|
+
* before.
|
|
25
|
+
*/
|
|
26
|
+
default:
|
|
27
|
+
'border-primary/20 bg-primary/10 text-primary [a&]:hover:bg-primary/15',
|
|
28
|
+
secondary:
|
|
29
|
+
'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
|
|
30
|
+
/**
|
|
31
|
+
* The same tint, in the one other colour that survives being text: at
|
|
32
|
+
* 4.91 on white it clears AA, where `--success` (3.26) and `--warning`
|
|
33
|
+
* (2.29) do not — those are fill colours with a paired foreground and
|
|
34
|
+
* are measured as such.
|
|
35
|
+
*/
|
|
36
|
+
destructive:
|
|
37
|
+
'border-destructive/20 bg-destructive/10 text-destructive [a&]:hover:bg-destructive/15',
|
|
38
|
+
// Solid, because the palette carries `--success` and its paired
|
|
39
|
+
// foreground and the pair is what clears contrast — see `destructive`
|
|
40
|
+
// above for why this one cannot follow it.
|
|
41
|
+
success:
|
|
42
|
+
'border-transparent bg-success text-success-foreground [a&]:hover:bg-success/90',
|
|
43
|
+
outline:
|
|
44
|
+
'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground'
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
defaultVariants: {
|
|
48
|
+
variant: 'default'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
export type BadgeVariants = VariantProps<typeof badgeVariants>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
class?: HTMLAttributes['class'];
|
|
6
|
+
}>();
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<nav aria-label="breadcrumb" data-slot="breadcrumb" :class="props.class">
|
|
11
|
+
<slot />
|
|
12
|
+
</nav>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { cn } from '@duxt/lib/utils';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<span
|
|
12
|
+
data-slot="breadcrumb-ellipsis"
|
|
13
|
+
role="presentation"
|
|
14
|
+
aria-hidden="true"
|
|
15
|
+
:class="cn('flex size-9 items-center justify-center', props.class)"
|
|
16
|
+
>
|
|
17
|
+
<slot>
|
|
18
|
+
<Icon name="lucide:ellipsis" class="size-4" />
|
|
19
|
+
</slot>
|
|
20
|
+
<span class="sr-only">More</span>
|
|
21
|
+
</span>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { cn } from '@duxt/lib/utils';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<li
|
|
12
|
+
data-slot="breadcrumb-item"
|
|
13
|
+
:class="cn('inline-flex items-center gap-1.5', props.class)"
|
|
14
|
+
>
|
|
15
|
+
<slot />
|
|
16
|
+
</li>
|
|
17
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { PrimitiveProps } from 'reka-ui';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
import { Primitive } from 'reka-ui';
|
|
5
|
+
import { cn } from '@duxt/lib/utils';
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(
|
|
8
|
+
defineProps<PrimitiveProps & { class?: HTMLAttributes['class'] }>(),
|
|
9
|
+
{
|
|
10
|
+
as: 'a'
|
|
11
|
+
}
|
|
12
|
+
);
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<Primitive
|
|
17
|
+
data-slot="breadcrumb-link"
|
|
18
|
+
:as="as"
|
|
19
|
+
:as-child="asChild"
|
|
20
|
+
:class="cn('hover:text-foreground transition-colors', props.class)"
|
|
21
|
+
>
|
|
22
|
+
<slot />
|
|
23
|
+
</Primitive>
|
|
24
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { cn } from '@duxt/lib/utils';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<ol
|
|
12
|
+
data-slot="breadcrumb-list"
|
|
13
|
+
:class="
|
|
14
|
+
cn(
|
|
15
|
+
'text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5',
|
|
16
|
+
props.class
|
|
17
|
+
)
|
|
18
|
+
"
|
|
19
|
+
>
|
|
20
|
+
<slot />
|
|
21
|
+
</ol>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { cn } from '@duxt/lib/utils';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<span
|
|
12
|
+
data-slot="breadcrumb-page"
|
|
13
|
+
role="link"
|
|
14
|
+
aria-disabled="true"
|
|
15
|
+
aria-current="page"
|
|
16
|
+
:class="cn('text-foreground font-normal', props.class)"
|
|
17
|
+
>
|
|
18
|
+
<slot />
|
|
19
|
+
</span>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { HTMLAttributes } from 'vue';
|
|
3
|
+
import { cn } from '@duxt/lib/utils';
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
class?: HTMLAttributes['class'];
|
|
7
|
+
}>();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<li
|
|
12
|
+
data-slot="breadcrumb-separator"
|
|
13
|
+
role="presentation"
|
|
14
|
+
aria-hidden="true"
|
|
15
|
+
:class="cn('[&>svg]:size-3.5', props.class)"
|
|
16
|
+
>
|
|
17
|
+
<slot>
|
|
18
|
+
<Icon name="lucide:chevron-right" />
|
|
19
|
+
</slot>
|
|
20
|
+
</li>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as Breadcrumb } from './Breadcrumb.vue';
|
|
2
|
+
export { default as BreadcrumbEllipsis } from './BreadcrumbEllipsis.vue';
|
|
3
|
+
export { default as BreadcrumbItem } from './BreadcrumbItem.vue';
|
|
4
|
+
export { default as BreadcrumbLink } from './BreadcrumbLink.vue';
|
|
5
|
+
export { default as BreadcrumbList } from './BreadcrumbList.vue';
|
|
6
|
+
export { default as BreadcrumbPage } from './BreadcrumbPage.vue';
|
|
7
|
+
export { default as BreadcrumbSeparator } from './BreadcrumbSeparator.vue';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { PrimitiveProps } from 'reka-ui';
|
|
3
|
+
import type { HTMLAttributes } from 'vue';
|
|
4
|
+
import type { ButtonVariants } from '.';
|
|
5
|
+
import { Primitive } from 'reka-ui';
|
|
6
|
+
import { cn } from '@duxt/lib/utils';
|
|
7
|
+
import { buttonVariants } from '.';
|
|
8
|
+
|
|
9
|
+
interface Props extends PrimitiveProps {
|
|
10
|
+
variant?: ButtonVariants['variant'];
|
|
11
|
+
size?: ButtonVariants['size'];
|
|
12
|
+
class?: HTMLAttributes['class'];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
16
|
+
as: 'button'
|
|
17
|
+
});
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<Primitive
|
|
22
|
+
data-slot="button"
|
|
23
|
+
:data-variant="variant"
|
|
24
|
+
:data-size="size"
|
|
25
|
+
:as="as"
|
|
26
|
+
:as-child="asChild"
|
|
27
|
+
:class="cn(buttonVariants({ variant, size }), props.class)"
|
|
28
|
+
>
|
|
29
|
+
<slot />
|
|
30
|
+
</Primitive>
|
|
31
|
+
</template>
|