@lupinum/ginko-docs 0.4.0-rc.8 → 0.4.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 (296) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/LICENSE +1 -1
  3. package/README.md +206 -54
  4. package/app/app.config.ts +42 -55
  5. package/app/assets/docs.css +555 -0
  6. package/app/components/DocsBanner.vue +29 -0
  7. package/app/components/DocsExample.vue +43 -0
  8. package/app/components/DocsFooter.vue +19 -0
  9. package/app/components/DocsHeader.vue +112 -0
  10. package/app/components/DocsLanding.vue +55 -0
  11. package/app/components/DocsLanguage.vue +29 -0
  12. package/app/components/DocsNavTree.vue +38 -0
  13. package/app/components/DocsPage.vue +84 -0
  14. package/app/components/DocsPageActions.vue +47 -0
  15. package/app/components/DocsPost.vue +58 -0
  16. package/app/components/DocsSearch.vue +134 -0
  17. package/app/components/DocsShell.vue +20 -0
  18. package/app/components/DocsSidebar.vue +18 -0
  19. package/app/components/DocsTable.vue +11 -0
  20. package/app/components/DocsThemeToggle.vue +45 -0
  21. package/app/components/DocsToc.vue +73 -0
  22. package/app/composables/useDocs.ts +52 -0
  23. package/app/composables/useDocsBlog.ts +32 -0
  24. package/app/composables/useDocsCopy.ts +17 -0
  25. package/app/composables/useDocsPopover.ts +36 -0
  26. package/app/composables/useDocsSite.ts +10 -0
  27. package/app/docs-pages/blog.vue +47 -0
  28. package/app/docs-pages/changelog.vue +27 -0
  29. package/app/docs-pages/doc.vue +14 -0
  30. package/app/docs-pages/docs.vue +9 -0
  31. package/app/docs-pages/index.vue +12 -0
  32. package/app/docs-pages/post.vue +8 -0
  33. package/app/error.vue +23 -115
  34. package/app/layouts/default.vue +25 -7
  35. package/app/lib/blogTypes.ts +8 -0
  36. package/app/lib/docsFirst.ts +11 -0
  37. package/app/lib/docsInit.ts +18 -0
  38. package/app/lib/docsNav.ts +36 -0
  39. package/app/lib/docsPage.ts +44 -0
  40. package/app/lib/markdownComponents.ts +16 -0
  41. package/app/lib/previewToc.ts +18 -0
  42. package/dist/config.d.mts +232 -0
  43. package/dist/config.d.ts +232 -0
  44. package/dist/config.mjs +114 -0
  45. package/dist/pages.d.mts +5 -0
  46. package/dist/pages.d.ts +5 -0
  47. package/dist/pages.mjs +36 -0
  48. package/dist/shared/ginko-docs.BwbF7JBR.mjs +4 -0
  49. package/i18n/de.json +1 -0
  50. package/i18n/en.json +1 -0
  51. package/icons/README.md +2 -0
  52. package/icons/bluesky.svg +1 -0
  53. package/icons/claude.svg +1 -0
  54. package/icons/discord.svg +1 -0
  55. package/icons/github.svg +1 -0
  56. package/icons/linkedin.svg +1 -0
  57. package/icons/mastodon.svg +1 -0
  58. package/icons/openai.svg +1 -0
  59. package/icons/x.svg +1 -0
  60. package/icons/youtube.svg +1 -0
  61. package/nuxt.config.ts +34 -209
  62. package/package.json +43 -76
  63. package/public/_docs/fonts/LICENSE +188 -0
  64. package/public/_docs/fonts/inter-latin-wght-normal.woff2 +0 -0
  65. package/public/_docs/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
  66. package/public/_docs/fonts/jetbrains-mono-latin-500-normal.woff2 +0 -0
  67. package/server/feeds/blog-locale.get.ts +9 -0
  68. package/server/feeds/blog.get.ts +4 -0
  69. package/server/lib/blogFeed.ts +35 -0
  70. package/server/lib/rss.ts +57 -0
  71. package/server/mcp/handler.ts +108 -0
  72. package/server/routes/__ginko/docs-mcp.ts +35 -0
  73. package/shared/paths.ts +4 -0
  74. package/app/app.vue +0 -98
  75. package/app/assets/css/prose.css +0 -3240
  76. package/app/assets/css/tailwind.css +0 -394
  77. package/app/assets/css/theme-palettes.css +0 -309
  78. package/app/assets/css/theme-presets.css +0 -141
  79. package/app/components/OgImage/GinkoDocs.satori.vue +0 -238
  80. package/app/components/content/DocumentPageShell.vue +0 -55
  81. package/app/components/content/Feedback.vue +0 -102
  82. package/app/components/content/ImageZoomDialog.vue +0 -84
  83. package/app/components/content/PageMarkdownCopy.vue +0 -104
  84. package/app/components/content/imageZoom.ts +0 -25
  85. package/app/components/mdc/MdcAccordion.vue +0 -67
  86. package/app/components/mdc/MdcAccordionItem.vue +0 -42
  87. package/app/components/mdc/MdcApi.vue +0 -159
  88. package/app/components/mdc/MdcAside.vue +0 -23
  89. package/app/components/mdc/MdcCallout.vue +0 -61
  90. package/app/components/mdc/MdcCard.vue +0 -175
  91. package/app/components/mdc/MdcCards.vue +0 -30
  92. package/app/components/mdc/MdcCenter.vue +0 -71
  93. package/app/components/mdc/MdcCodeGroup.vue +0 -197
  94. package/app/components/mdc/MdcCodeTree.vue +0 -234
  95. package/app/components/mdc/MdcCollapse.vue +0 -61
  96. package/app/components/mdc/MdcColumn.vue +0 -70
  97. package/app/components/mdc/MdcDropcap.vue +0 -84
  98. package/app/components/mdc/MdcError.vue +0 -23
  99. package/app/components/mdc/MdcExcerpt.vue +0 -26
  100. package/app/components/mdc/MdcFigure.vue +0 -85
  101. package/app/components/mdc/MdcFiles.vue +0 -120
  102. package/app/components/mdc/MdcIdea.vue +0 -17
  103. package/app/components/mdc/MdcInfo.vue +0 -17
  104. package/app/components/mdc/MdcInlineToc.vue +0 -51
  105. package/app/components/mdc/MdcKbd.vue +0 -10
  106. package/app/components/mdc/MdcLayout.vue +0 -57
  107. package/app/components/mdc/MdcNote.vue +0 -17
  108. package/app/components/mdc/MdcQuiz.vue +0 -241
  109. package/app/components/mdc/MdcQuizQuestion.vue +0 -221
  110. package/app/components/mdc/MdcReadMore.vue +0 -70
  111. package/app/components/mdc/MdcSteps.vue +0 -59
  112. package/app/components/mdc/MdcSuccess.vue +0 -23
  113. package/app/components/mdc/MdcTab.vue +0 -17
  114. package/app/components/mdc/MdcTabs.vue +0 -150
  115. package/app/components/mdc/MdcTimeline.vue +0 -17
  116. package/app/components/mdc/MdcTimelineItem.vue +0 -40
  117. package/app/components/mdc/MdcWarning.vue +0 -23
  118. package/app/components/mdc/api.utils.ts +0 -132
  119. package/app/components/mdc/code-tree.utils.ts +0 -22
  120. package/app/components/mdc/icons.ts +0 -10
  121. package/app/components/mdc/quiz.utils.ts +0 -38
  122. package/app/components/prose/ProseA.vue +0 -27
  123. package/app/components/prose/ProseBlockquote.vue +0 -30
  124. package/app/components/prose/ProseCode.vue +0 -14
  125. package/app/components/prose/ProseEm.vue +0 -14
  126. package/app/components/prose/ProseH1.vue +0 -18
  127. package/app/components/prose/ProseH2.vue +0 -29
  128. package/app/components/prose/ProseH3.vue +0 -29
  129. package/app/components/prose/ProseH4.vue +0 -29
  130. package/app/components/prose/ProseH5.vue +0 -15
  131. package/app/components/prose/ProseH6.vue +0 -15
  132. package/app/components/prose/ProseHr.vue +0 -12
  133. package/app/components/prose/ProseImg.vue +0 -55
  134. package/app/components/prose/ProseLi.vue +0 -14
  135. package/app/components/prose/ProseOl.vue +0 -14
  136. package/app/components/prose/ProseP.vue +0 -14
  137. package/app/components/prose/ProsePre.vue +0 -180
  138. package/app/components/prose/ProseStrong.vue +0 -14
  139. package/app/components/prose/ProseTable.vue +0 -18
  140. package/app/components/prose/ProseTbody.vue +0 -14
  141. package/app/components/prose/ProseTd.vue +0 -14
  142. package/app/components/prose/ProseTh.vue +0 -14
  143. package/app/components/prose/ProseThead.vue +0 -14
  144. package/app/components/prose/ProseTr.vue +0 -14
  145. package/app/components/prose/ProseUl.vue +0 -14
  146. package/app/components/site/ModeToggle.vue +0 -81
  147. package/app/components/site/SiteBanner.vue +0 -97
  148. package/app/components/site/SiteFooter.vue +0 -90
  149. package/app/components/site/SiteHeader.vue +0 -371
  150. package/app/components/site/SiteHeroCode.vue +0 -173
  151. package/app/components/site/SiteInteractionLayer.vue +0 -42
  152. package/app/components/site/SiteLocaleSwitcher.vue +0 -190
  153. package/app/components/site/SiteLogoMark.vue +0 -12
  154. package/app/components/site/SiteSkipLink.vue +0 -14
  155. package/app/components/site/SiteSocialLinks.vue +0 -33
  156. package/app/components/site/header-utils.ts +0 -3
  157. package/app/components/site/mode-toggle.utils.ts +0 -18
  158. package/app/components/ui/badge/Badge.vue +0 -28
  159. package/app/components/ui/badge/index.ts +0 -24
  160. package/app/components/ui/button/Button.vue +0 -31
  161. package/app/components/ui/button/index.ts +0 -35
  162. package/app/components/ui/collapsible/Collapsible.vue +0 -15
  163. package/app/components/ui/collapsible/CollapsibleContent.vue +0 -25
  164. package/app/components/ui/collapsible/CollapsibleTrigger.vue +0 -12
  165. package/app/components/ui/collapsible/index.ts +0 -3
  166. package/app/components/ui/dropdown-menu/DropdownMenu.vue +0 -15
  167. package/app/components/ui/dropdown-menu/DropdownMenuContent.vue +0 -50
  168. package/app/components/ui/dropdown-menu/DropdownMenuItem.vue +0 -41
  169. package/app/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +0 -15
  170. package/app/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +0 -37
  171. package/app/components/ui/dropdown-menu/DropdownMenuSeparator.vue +0 -23
  172. package/app/components/ui/dropdown-menu/DropdownMenuTrigger.vue +0 -14
  173. package/app/components/ui/dropdown-menu/index.ts +0 -7
  174. package/app/components/ui/kbd/Kbd.vue +0 -23
  175. package/app/components/ui/kbd/index.ts +0 -21
  176. package/app/components/ui/scroll-area/ScrollArea.vue +0 -39
  177. package/app/components/ui/scroll-area/ScrollBar.vue +0 -33
  178. package/app/components/ui/scroll-area/index.ts +0 -2
  179. package/app/components/ui/separator/Separator.vue +0 -27
  180. package/app/components/ui/separator/index.ts +0 -1
  181. package/app/components/ui/sheet/Sheet.vue +0 -15
  182. package/app/components/ui/sheet/SheetContent.vue +0 -59
  183. package/app/components/ui/sheet/SheetDescription.vue +0 -21
  184. package/app/components/ui/sheet/SheetOverlay.vue +0 -26
  185. package/app/components/ui/sheet/SheetTitle.vue +0 -21
  186. package/app/components/ui/sheet/SheetTrigger.vue +0 -12
  187. package/app/components/ui/sheet/index.ts +0 -5
  188. package/app/components/ui/tabs/Tabs.vue +0 -24
  189. package/app/components/ui/tabs/TabsList.vue +0 -26
  190. package/app/components/ui/tabs/TabsTrigger.vue +0 -28
  191. package/app/components/ui/tabs/index.ts +0 -3
  192. package/app/composables/site-navigation.utils.ts +0 -133
  193. package/app/composables/useCanonicalUrl.ts +0 -9
  194. package/app/composables/useContentRouteAlternates.ts +0 -35
  195. package/app/composables/useGinkoAnalytics.ts +0 -52
  196. package/app/composables/useGinkoDocsConfig.ts +0 -6
  197. package/app/composables/useGinkoOgImage.ts +0 -20
  198. package/app/composables/useLocalizedPath.ts +0 -12
  199. package/app/composables/useLocalizedRouteSwitch.ts +0 -31
  200. package/app/composables/useMetaKey.ts +0 -18
  201. package/app/composables/usePageMarkdownActions.ts +0 -79
  202. package/app/composables/useProseAppearance.ts +0 -24
  203. package/app/composables/useSchemaJsonLd.ts +0 -25
  204. package/app/composables/useSiteNavigation.ts +0 -64
  205. package/app/config/site.utils.ts +0 -36
  206. package/app/features/docs/components/DocsBreadcrumb.vue +0 -37
  207. package/app/features/docs/components/DocsContributeLinks.vue +0 -75
  208. package/app/features/docs/components/DocsMobileToc.vue +0 -108
  209. package/app/features/docs/components/DocsPageContent.vue +0 -234
  210. package/app/features/docs/components/DocsPageNav.vue +0 -57
  211. package/app/features/docs/components/DocsSidebar.vue +0 -145
  212. package/app/features/docs/components/DocsSidebarDropdown.vue +0 -70
  213. package/app/features/docs/components/DocsSidebarItem.vue +0 -122
  214. package/app/features/docs/components/DocsSidebarList.vue +0 -35
  215. package/app/features/docs/components/DocsSidebarRow.vue +0 -27
  216. package/app/features/docs/components/DocsSidebarTabs.vue +0 -59
  217. package/app/features/docs/components/DocsToc.vue +0 -106
  218. package/app/features/docs/composables/useDocsNavigation.ts +0 -29
  219. package/app/features/docs/composables/useDocsNavigationData.ts +0 -18
  220. package/app/features/docs/composables/useRevealActive.ts +0 -58
  221. package/app/features/docs/composables/useScrollspy.ts +0 -135
  222. package/app/features/docs/docs-navigation.ts +0 -157
  223. package/app/features/docs/toc-context.ts +0 -6
  224. package/app/features/search/command-center.ts +0 -110
  225. package/app/features/search/components/SiteCommandCenter.vue +0 -359
  226. package/app/features/search/components/SiteSearchPageHighlight.vue +0 -126
  227. package/app/features/search/useCommandCenter.ts +0 -292
  228. package/app/layouts/blog.vue +0 -15
  229. package/app/layouts/docs.vue +0 -20
  230. package/app/lib/errors.ts +0 -37
  231. package/app/lib/schema-org.ts +0 -38
  232. package/app/pages/blog/[slug].vue +0 -228
  233. package/app/pages/blog/index.vue +0 -130
  234. package/app/pages/docs/[...slug].vue +0 -10
  235. package/app/pages/docs/index.vue +0 -19
  236. package/app/pages/index.vue +0 -278
  237. package/app/plugins/ginko-docs-theme.ts +0 -14
  238. package/app/plugins/ssr-width.ts +0 -6
  239. package/app/utils/content.ts +0 -67
  240. package/app/utils/file-icons.ts +0 -90
  241. package/app/utils/index.ts +0 -7
  242. package/app/utils/repository.ts +0 -20
  243. package/components.ts +0 -9
  244. package/content-collections.ts +0 -89
  245. package/content.js +0 -200
  246. package/content.ts +0 -104
  247. package/i18n/i18n.config.ts +0 -10
  248. package/i18n/locales.ts +0 -81
  249. package/i18n/messages/global/banner.ts +0 -8
  250. package/i18n/messages/global/blog.ts +0 -18
  251. package/i18n/messages/global/command.ts +0 -49
  252. package/i18n/messages/global/docs.ts +0 -36
  253. package/i18n/messages/global/errors.ts +0 -36
  254. package/i18n/messages/global/feedback.ts +0 -11
  255. package/i18n/messages/global/index.ts +0 -21
  256. package/i18n/messages/global/nav.ts +0 -26
  257. package/i18n/messages/global/site.ts +0 -4
  258. package/i18n/messages/global/theme.ts +0 -9
  259. package/i18n/messages/index.ts +0 -20
  260. package/i18n/messages/localize.ts +0 -35
  261. package/i18n/routes.ts +0 -33
  262. package/icon-bundle.ts +0 -116
  263. package/index.d.ts +0 -37
  264. package/modules/analytics-boundary.ts +0 -23
  265. package/modules/feature-routing.ts +0 -68
  266. package/modules/syntax-highlighting.ts +0 -120
  267. package/public/fonts/public-sans/LICENSE +0 -93
  268. package/public/fonts/public-sans/README.md +0 -12
  269. package/public/fonts/public-sans/public-sans-400-normal-latin.woff +0 -0
  270. package/public/fonts/public-sans/public-sans-500-normal-latin.woff +0 -0
  271. package/public/fonts/public-sans/public-sans-600-normal-latin.woff +0 -0
  272. package/public/fonts/public-sans/public-sans-700-normal-latin.woff +0 -0
  273. package/runtime/generate-favicons.mjs +0 -124
  274. package/runtime/server/agent-markdown.ts +0 -19
  275. package/server/api/_ginko-docs/redirects.get.ts +0 -28
  276. package/server/mcp/tools/get-page.ts +0 -14
  277. package/server/mcp/tools/list-pages.ts +0 -10
  278. package/server/middleware/redirects.ts +0 -22
  279. package/server/plugins/agent-markdown.ts +0 -6
  280. package/server/plugins/sitemap-policy.ts +0 -12
  281. package/server/routes/.well-known/ai-catalog.json.get.ts +0 -10
  282. package/server/routes/[locale]/blog/rss.xml.get.ts +0 -13
  283. package/server/routes/blog/rss.xml.get.ts +0 -5
  284. package/server/routes/mcp/server-card.get.ts +0 -14
  285. package/server/utils/blog-feed.ts +0 -51
  286. package/server/utils/feed.ts +0 -70
  287. package/server/utils/mcp-server-card.ts +0 -45
  288. package/server/utils/redirects.ts +0 -38
  289. package/server/utils/redirects.utils.ts +0 -58
  290. package/server/utils/sitemap.ts +0 -45
  291. package/shared/route-slugs.ts +0 -5
  292. package/shared/theme-palettes.ts +0 -37
  293. package/shared/theme-presets.ts +0 -3
  294. package/shared/types/app-config.ts +0 -172
  295. package/shared/types/nuxt-config.ts +0 -14
  296. package/tags.ts +0 -192
@@ -1,190 +0,0 @@
1
- <script setup lang="ts">
2
- import type { HTMLAttributes } from "vue";
3
- import { Button } from "#ginko-docs/components/ui/button";
4
- import {
5
- DropdownMenu,
6
- DropdownMenuContent,
7
- DropdownMenuItem,
8
- DropdownMenuTrigger,
9
- } from "#ginko-docs/components/ui/dropdown-menu";
10
- import { cn } from "#ginko-docs/utils";
11
- import { computed } from "vue";
12
- import { useI18n } from "#imports";
13
- import { useLocalizedRouteSwitch } from "#ginko-docs/composables/useLocalizedRouteSwitch";
14
- import { headerUtilityButtonClass } from "#ginko-docs/components/site/header-utils";
15
- import { locales as configuredLocales } from "../../../i18n/locales";
16
-
17
- type LocaleSwitcherVariant = "dropdown" | "menu-row";
18
-
19
- type LocaleEntry = {
20
- code: string;
21
- language?: string;
22
- name?: string;
23
- nativeName?: string;
24
- shortLabel?: string;
25
- };
26
-
27
- const props = withDefaults(
28
- defineProps<{
29
- variant?: LocaleSwitcherVariant;
30
- class?: HTMLAttributes["class"];
31
- }>(),
32
- {
33
- variant: "dropdown",
34
- },
35
- );
36
-
37
- const emit = defineEmits<{
38
- navigate: [];
39
- }>();
40
-
41
- const { locale, locales, t } = useI18n();
42
- const { switchPath } = useLocalizedRouteSwitch();
43
-
44
- type ConfiguredLocale = (typeof configuredLocales)[number];
45
-
46
- const configuredLocaleMap: ReadonlyMap<string, ConfiguredLocale> = new Map(
47
- configuredLocales.map((entry) => [entry.code, entry]),
48
- );
49
-
50
- function normalizeLocale(entry: string | LocaleEntry) {
51
- if (typeof entry === "string") {
52
- const configured: LocaleEntry | undefined = configuredLocaleMap.get(entry);
53
- return {
54
- code: entry,
55
- language: configured?.language ?? entry,
56
- name: configured?.name ?? entry.toUpperCase(),
57
- nativeName: configured?.nativeName ?? configured?.name ?? entry.toUpperCase(),
58
- shortLabel: configured?.shortLabel ?? entry.toUpperCase(),
59
- };
60
- }
61
-
62
- const configured: LocaleEntry | undefined = configuredLocaleMap.get(entry.code);
63
- return {
64
- code: entry.code,
65
- language: entry.language ?? configured?.language ?? entry.code,
66
- name: entry.name ?? configured?.name ?? entry.code.toUpperCase(),
67
- nativeName:
68
- entry.nativeName ?? entry.name ?? configured?.nativeName ?? entry.code.toUpperCase(),
69
- shortLabel: entry.shortLabel ?? configured?.shortLabel ?? entry.code.toUpperCase(),
70
- };
71
- }
72
-
73
- const localeLinks = computed(() =>
74
- locales.value.map((entry) => {
75
- const normalized = normalizeLocale(entry as string | LocaleEntry);
76
- return {
77
- ...normalized,
78
- to: switchPath(normalized.code) || "/",
79
- current: locale.value === normalized.code,
80
- };
81
- }),
82
- );
83
-
84
- const currentLocale = computed(
85
- () => localeLinks.value.find((entry) => entry.current) ?? localeLinks.value[0],
86
- );
87
-
88
- function trackLocaleNavigation(_entry: { code: string; current: boolean; to: unknown }) {
89
- emit("navigate");
90
- }
91
- </script>
92
-
93
- <template>
94
- <div
95
- v-if="localeLinks.length > 1 && variant === 'dropdown'"
96
- :class="cn('items-center', props.class)"
97
- >
98
- <ClientOnly>
99
- <DropdownMenu>
100
- <DropdownMenuTrigger as-child>
101
- <button type="button" :class="headerUtilityButtonClass" :aria-label="t('nav.language')">
102
- <Icon name="lucide:languages" class="size-[18px]" aria-hidden="true" />
103
- </button>
104
- </DropdownMenuTrigger>
105
- <DropdownMenuContent align="end" class="w-52">
106
- <DropdownMenuItem v-for="entry in localeLinks" :key="entry.code" as-child>
107
- <NuxtLink
108
- :to="entry.to"
109
- :hreflang="entry.language"
110
- :lang="entry.code"
111
- :aria-label="entry.name"
112
- :aria-current="entry.current ? 'page' : undefined"
113
- class="flex w-full items-center gap-3"
114
- @click="trackLocaleNavigation(entry)"
115
- >
116
- <span class="w-7 text-xs font-semibold tracking-wide text-muted-foreground">{{
117
- entry.shortLabel
118
- }}</span>
119
- <span class="flex-1">{{ entry.nativeName }}</span>
120
- <Icon
121
- v-if="entry.current"
122
- name="lucide:check"
123
- class="size-4 text-foreground"
124
- aria-hidden="true"
125
- />
126
- </NuxtLink>
127
- </DropdownMenuItem>
128
- </DropdownMenuContent>
129
- </DropdownMenu>
130
-
131
- <template #fallback>
132
- <span class="inline-flex size-9 shrink-0 rounded-lg" aria-hidden="true" />
133
- </template>
134
- </ClientOnly>
135
- </div>
136
-
137
- <div
138
- v-else-if="localeLinks.length > 1 && variant === 'menu-row'"
139
- :class="cn('items-center', props.class)"
140
- >
141
- <DropdownMenu>
142
- <DropdownMenuTrigger as-child>
143
- <Button
144
- variant="ghost"
145
- class="h-14 w-full justify-between rounded-none px-5 text-base font-semibold hover:bg-transparent"
146
- :aria-label="t('nav.language')"
147
- >
148
- <span class="flex min-w-0 items-center gap-4">
149
- <span
150
- class="flex size-11 shrink-0 items-center justify-center rounded-lg bg-muted/60 text-foreground"
151
- >
152
- <Icon name="lucide:languages" class="size-5" aria-hidden="true" />
153
- </span>
154
- <span class="truncate">{{ t("nav.languageLabel") }}</span>
155
- </span>
156
- <span class="flex items-center gap-2 text-muted-foreground">
157
- <span class="text-sm font-semibold text-foreground">{{
158
- currentLocale?.nativeName
159
- }}</span>
160
- <Icon name="lucide:chevron-down" class="size-5" aria-hidden="true" />
161
- </span>
162
- </Button>
163
- </DropdownMenuTrigger>
164
- <DropdownMenuContent align="end" class="w-52" portal-disabled>
165
- <DropdownMenuItem v-for="entry in localeLinks" :key="entry.code" as-child>
166
- <NuxtLink
167
- :to="entry.to"
168
- :hreflang="entry.language"
169
- :lang="entry.code"
170
- :aria-label="entry.name"
171
- :aria-current="entry.current ? 'page' : undefined"
172
- class="flex w-full items-center gap-3"
173
- @click="trackLocaleNavigation(entry)"
174
- >
175
- <span class="w-7 text-xs font-semibold tracking-wide text-muted-foreground">{{
176
- entry.shortLabel
177
- }}</span>
178
- <span class="flex-1">{{ entry.nativeName }}</span>
179
- <Icon
180
- v-if="entry.current"
181
- name="lucide:check"
182
- class="size-4 text-foreground"
183
- aria-hidden="true"
184
- />
185
- </NuxtLink>
186
- </DropdownMenuItem>
187
- </DropdownMenuContent>
188
- </DropdownMenu>
189
- </div>
190
- </template>
@@ -1,12 +0,0 @@
1
- <script setup lang="ts">
2
- import { useSiteNavigation } from "#ginko-docs/composables/useSiteNavigation";
3
-
4
- const { site } = useSiteNavigation();
5
- </script>
6
-
7
- <template>
8
- <span class="relative inline-flex h-7 shrink-0" aria-hidden="true">
9
- <img :src="site.logo.light" alt="" class="h-7 w-auto dark:hidden" loading="eager" />
10
- <img :src="site.logo.dark" alt="" class="hidden h-7 w-auto dark:block" loading="eager" />
11
- </span>
12
- </template>
@@ -1,14 +0,0 @@
1
- <script setup lang="ts">
2
- import { useI18n } from "#imports";
3
-
4
- const { t } = useI18n();
5
- </script>
6
-
7
- <template>
8
- <a
9
- href="#main-content"
10
- class="sr-only focus:not-sr-only focus:fixed focus:top-4 focus:left-4 focus:z-100 focus:rounded-md focus:border focus:border-border focus:bg-background focus:px-4 focus:py-2 focus:text-sm focus:font-medium focus:text-foreground focus:shadow-md"
11
- >
12
- {{ t("nav.skip") }}
13
- </a>
14
- </template>
@@ -1,33 +0,0 @@
1
- <script setup lang="ts">
2
- import { useSiteNavigation } from "#ginko-docs/composables/useSiteNavigation";
3
- import { headerUtilityButtonClass } from "#ginko-docs/components/site/header-utils";
4
-
5
- const { socialLinks } = useSiteNavigation();
6
-
7
- defineEmits<{ navigate: [] }>();
8
- </script>
9
-
10
- <template>
11
- <div v-if="socialLinks.length" class="flex items-center">
12
- <NuxtLink
13
- v-for="link in socialLinks"
14
- :key="link.href"
15
- :to="link.href"
16
- target="_blank"
17
- rel="noopener noreferrer"
18
- :aria-label="link.label"
19
- :class="headerUtilityButtonClass"
20
- @click="$emit('navigate')"
21
- >
22
- <Icon :name="link.icon ?? 'lucide:link'" class="social-icon" aria-hidden="true" />
23
- </NuxtLink>
24
- </div>
25
- </template>
26
-
27
- <style scoped>
28
- .social-icon {
29
- width: 1.25rem;
30
- height: 1.25rem;
31
- flex: none;
32
- }
33
- </style>
@@ -1,3 +0,0 @@
1
- /** Shared ghost geometry for header utility controls (theme, locale, social). */
2
- export const headerUtilityButtonClass =
3
- "inline-flex size-9 shrink-0 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring outline-none";
@@ -1,18 +0,0 @@
1
- export type RenderedColorMode = "light" | "dark";
2
- /**
3
- * Next stored preference for a two-state theme toggle.
4
- *
5
- * The page follows the operating system until the first interaction. After
6
- * that interaction, the reader's explicit light or dark choice remains fixed.
7
- */
8
- export function nextColorModePreference(currentRendered: RenderedColorMode): RenderedColorMode {
9
- return currentRendered === "dark" ? "light" : "dark";
10
- }
11
-
12
- export function themeToggleIcon(isDark: boolean) {
13
- return isDark ? "lucide:moon" : "lucide:sun";
14
- }
15
-
16
- export function themeToggleLabelKey(isDark: boolean) {
17
- return isDark ? "theme.switchToLight" : "theme.switchToDark";
18
- }
@@ -1,28 +0,0 @@
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 "#ginko-docs/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.variant }), props.class)"
24
- v-bind="delegatedProps"
25
- >
26
- <slot />
27
- </Primitive>
28
- </template>
@@ -1,24 +0,0 @@
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-[3px] 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
- default: "border-transparent bg-brand text-brand-foreground [a&]:hover:bg-brand/90",
12
- secondary:
13
- "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
14
- destructive:
15
- "border-transparent bg-destructive text-destructive-foreground [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
16
- outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
17
- },
18
- },
19
- defaultVariants: {
20
- variant: "default",
21
- },
22
- },
23
- );
24
- export type BadgeVariants = VariantProps<typeof badgeVariants>;
@@ -1,31 +0,0 @@
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 "#ginko-docs/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>
@@ -1,35 +0,0 @@
1
- import type { VariantProps } from "class-variance-authority";
2
- import { cva } from "class-variance-authority";
3
-
4
- export { default as Button } from "./Button.vue";
5
-
6
- export const buttonVariants = cva(
7
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
8
- {
9
- variants: {
10
- variant: {
11
- default: "bg-brand text-brand-foreground hover:bg-brand/90",
12
- destructive:
13
- "bg-destructive text-destructive-foreground hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40",
14
- outline:
15
- "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
16
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
17
- ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
18
- link: "text-primary underline-offset-4 hover:underline",
19
- },
20
- size: {
21
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
22
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
23
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
24
- icon: "size-9",
25
- "icon-sm": "size-8",
26
- "icon-lg": "size-10",
27
- },
28
- },
29
- defaultVariants: {
30
- variant: "default",
31
- size: "default",
32
- },
33
- },
34
- );
35
- export type ButtonVariants = VariantProps<typeof buttonVariants>;
@@ -1,15 +0,0 @@
1
- <script setup lang="ts">
2
- import type { CollapsibleRootEmits, CollapsibleRootProps } from "reka-ui";
3
- import { CollapsibleRoot, useForwardPropsEmits } from "reka-ui";
4
-
5
- const props = defineProps<CollapsibleRootProps>();
6
- const emits = defineEmits<CollapsibleRootEmits>();
7
-
8
- const forwarded = useForwardPropsEmits(props, emits);
9
- </script>
10
-
11
- <template>
12
- <CollapsibleRoot v-bind="forwarded">
13
- <slot />
14
- </CollapsibleRoot>
15
- </template>
@@ -1,25 +0,0 @@
1
- <script setup lang="ts">
2
- import type { CollapsibleContentProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { CollapsibleContent } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = defineProps<CollapsibleContentProps & { class?: HTMLAttributes["class"] }>();
9
-
10
- const delegatedProps = reactiveOmit(props, "class");
11
- </script>
12
-
13
- <template>
14
- <CollapsibleContent
15
- v-bind="delegatedProps"
16
- :class="
17
- cn(
18
- 'overflow-hidden data-[state=closed]:animate-collapsible-up data-[state=open]:animate-collapsible-down',
19
- props.class,
20
- )
21
- "
22
- >
23
- <slot />
24
- </CollapsibleContent>
25
- </template>
@@ -1,12 +0,0 @@
1
- <script setup lang="ts">
2
- import type { CollapsibleTriggerProps } from "reka-ui";
3
- import { CollapsibleTrigger } from "reka-ui";
4
-
5
- const props = defineProps<CollapsibleTriggerProps>();
6
- </script>
7
-
8
- <template>
9
- <CollapsibleTrigger v-bind="props">
10
- <slot />
11
- </CollapsibleTrigger>
12
- </template>
@@ -1,3 +0,0 @@
1
- export { default as Collapsible } from "./Collapsible.vue";
2
- export { default as CollapsibleTrigger } from "./CollapsibleTrigger.vue";
3
- export { default as CollapsibleContent } from "./CollapsibleContent.vue";
@@ -1,15 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DropdownMenuRootEmits, DropdownMenuRootProps } from "reka-ui";
3
- import { DropdownMenuRoot, useForwardPropsEmits } from "reka-ui";
4
-
5
- const props = defineProps<DropdownMenuRootProps>();
6
- const emits = defineEmits<DropdownMenuRootEmits>();
7
-
8
- const forwarded = useForwardPropsEmits(props, emits);
9
- </script>
10
-
11
- <template>
12
- <DropdownMenuRoot v-slot="slotProps" data-slot="dropdown-menu" v-bind="forwarded">
13
- <slot v-bind="slotProps" />
14
- </DropdownMenuRoot>
15
- </template>
@@ -1,50 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DropdownMenuContentEmits, DropdownMenuContentProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { DropdownMenuContent, DropdownMenuPortal, useForwardPropsEmits } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- defineOptions({
9
- inheritAttrs: false,
10
- });
11
-
12
- const props = withDefaults(
13
- defineProps<
14
- DropdownMenuContentProps & {
15
- class?: HTMLAttributes["class"];
16
- /**
17
- * Render in place instead of teleporting to body. Required inside modal
18
- * dialogs (e.g. the mobile menu sheet), where body-level portals are
19
- * blocked by the dialog's pointer-events lock.
20
- */
21
- portalDisabled?: boolean;
22
- }
23
- >(),
24
- {
25
- sideOffset: 4,
26
- },
27
- );
28
- const emits = defineEmits<DropdownMenuContentEmits>();
29
-
30
- const delegatedProps = reactiveOmit(props, "class", "portalDisabled");
31
-
32
- const forwarded = useForwardPropsEmits(delegatedProps, emits);
33
- </script>
34
-
35
- <template>
36
- <DropdownMenuPortal :disabled="props.portalDisabled">
37
- <DropdownMenuContent
38
- data-slot="dropdown-menu-content"
39
- v-bind="{ ...$attrs, ...forwarded }"
40
- :class="
41
- cn(
42
- 'z-50 max-h-(--reka-dropdown-menu-content-available-height) min-w-[8rem] origin-(--reka-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
43
- props.class,
44
- )
45
- "
46
- >
47
- <slot />
48
- </DropdownMenuContent>
49
- </DropdownMenuPortal>
50
- </template>
@@ -1,41 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DropdownMenuItemProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { DropdownMenuItem, useForwardProps } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = withDefaults(
9
- defineProps<
10
- DropdownMenuItemProps & {
11
- class?: HTMLAttributes["class"];
12
- inset?: boolean;
13
- variant?: "default" | "destructive";
14
- }
15
- >(),
16
- {
17
- variant: "default",
18
- },
19
- );
20
-
21
- const delegatedProps = reactiveOmit(props, "inset", "variant", "class");
22
-
23
- const forwardedProps = useForwardProps(delegatedProps);
24
- </script>
25
-
26
- <template>
27
- <DropdownMenuItem
28
- data-slot="dropdown-menu-item"
29
- :data-inset="inset ? '' : undefined"
30
- :data-variant="variant"
31
- v-bind="forwardedProps"
32
- :class="
33
- cn(
34
- 'relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4 [&_svg:not([class*=\'text-\'])]:text-muted-foreground data-[variant=destructive]:*:[svg]:!text-destructive',
35
- props.class,
36
- )
37
- "
38
- >
39
- <slot />
40
- </DropdownMenuItem>
41
- </template>
@@ -1,15 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DropdownMenuRadioGroupEmits, DropdownMenuRadioGroupProps } from "reka-ui";
3
- import { DropdownMenuRadioGroup, useForwardPropsEmits } from "reka-ui";
4
-
5
- const props = defineProps<DropdownMenuRadioGroupProps>();
6
- const emits = defineEmits<DropdownMenuRadioGroupEmits>();
7
-
8
- const forwarded = useForwardPropsEmits(props, emits);
9
- </script>
10
-
11
- <template>
12
- <DropdownMenuRadioGroup data-slot="dropdown-menu-radio-group" v-bind="forwarded">
13
- <slot />
14
- </DropdownMenuRadioGroup>
15
- </template>
@@ -1,37 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DropdownMenuRadioItemEmits, DropdownMenuRadioItemProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { DropdownMenuItemIndicator, DropdownMenuRadioItem, useForwardPropsEmits } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = defineProps<DropdownMenuRadioItemProps & { class?: HTMLAttributes["class"] }>();
9
-
10
- const emits = defineEmits<DropdownMenuRadioItemEmits>();
11
-
12
- const delegatedProps = reactiveOmit(props, "class");
13
-
14
- const forwarded = useForwardPropsEmits(delegatedProps, emits);
15
- </script>
16
-
17
- <template>
18
- <DropdownMenuRadioItem
19
- data-slot="dropdown-menu-radio-item"
20
- v-bind="forwarded"
21
- :class="
22
- cn(
23
- 'relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
24
- props.class,
25
- )
26
- "
27
- >
28
- <span class="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
29
- <DropdownMenuItemIndicator>
30
- <slot name="indicator-icon">
31
- <Icon name="lucide:circle" class="size-2 fill-current" aria-hidden="true" />
32
- </slot>
33
- </DropdownMenuItemIndicator>
34
- </span>
35
- <slot />
36
- </DropdownMenuRadioItem>
37
- </template>
@@ -1,23 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DropdownMenuSeparatorProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { DropdownMenuSeparator } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = defineProps<
9
- DropdownMenuSeparatorProps & {
10
- class?: HTMLAttributes["class"];
11
- }
12
- >();
13
-
14
- const delegatedProps = reactiveOmit(props, "class");
15
- </script>
16
-
17
- <template>
18
- <DropdownMenuSeparator
19
- data-slot="dropdown-menu-separator"
20
- v-bind="delegatedProps"
21
- :class="cn('-mx-1 my-1 h-px bg-border', props.class)"
22
- />
23
- </template>
@@ -1,14 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DropdownMenuTriggerProps } from "reka-ui";
3
- import { DropdownMenuTrigger, useForwardProps } from "reka-ui";
4
-
5
- const props = defineProps<DropdownMenuTriggerProps>();
6
-
7
- const forwardedProps = useForwardProps(props);
8
- </script>
9
-
10
- <template>
11
- <DropdownMenuTrigger data-slot="dropdown-menu-trigger" v-bind="forwardedProps">
12
- <slot />
13
- </DropdownMenuTrigger>
14
- </template>