@lupinum/ginko-docs 0.4.0-rc.9 → 0.5.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 (304) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/LICENSE +1 -1
  3. package/README.md +300 -53
  4. package/app/app.config.ts +44 -55
  5. package/app/assets/docs.css +619 -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 +113 -0
  10. package/app/components/DocsIcon.vue +12 -0
  11. package/app/components/DocsLanding.vue +58 -0
  12. package/app/components/DocsLanguage.vue +40 -0
  13. package/app/components/DocsNavSheet.vue +37 -0
  14. package/app/components/DocsNavTree.vue +38 -0
  15. package/app/components/DocsPage.vue +88 -0
  16. package/app/components/DocsPageActions.vue +47 -0
  17. package/app/components/DocsPageEnd.ts +12 -0
  18. package/app/components/DocsPost.vue +58 -0
  19. package/app/components/DocsSearch.vue +136 -0
  20. package/app/components/DocsShell.vue +36 -0
  21. package/app/components/DocsSidebar.vue +19 -0
  22. package/app/components/DocsSidebarEnd.ts +4 -0
  23. package/app/components/DocsTable.vue +11 -0
  24. package/app/components/DocsThemeToggle.vue +45 -0
  25. package/app/components/DocsToc.vue +73 -0
  26. package/app/composables/useDocs.ts +53 -0
  27. package/app/composables/useDocsBlog.ts +33 -0
  28. package/app/composables/useDocsCopy.ts +17 -0
  29. package/app/composables/useDocsFrame.ts +11 -0
  30. package/app/composables/useDocsPopover.ts +36 -0
  31. package/app/composables/useDocsSite.ts +31 -0
  32. package/app/docs-pages/blog.vue +55 -0
  33. package/app/docs-pages/changelog.vue +35 -0
  34. package/app/docs-pages/doc.vue +16 -0
  35. package/app/docs-pages/docs.vue +9 -0
  36. package/app/docs-pages/index.vue +12 -0
  37. package/app/docs-pages/post.vue +8 -0
  38. package/app/error.vue +38 -115
  39. package/app/layouts/default.vue +29 -7
  40. package/app/lib/blogTypes.ts +8 -0
  41. package/app/lib/docsFirst.ts +11 -0
  42. package/app/lib/docsInit.ts +18 -0
  43. package/app/lib/docsNav.ts +36 -0
  44. package/app/lib/docsPage.ts +84 -0
  45. package/app/lib/markdownComponents.ts +15 -0
  46. package/app/lib/previewToc.ts +18 -0
  47. package/dist/config.d.mts +252 -0
  48. package/dist/config.d.ts +252 -0
  49. package/dist/config.mjs +83 -0
  50. package/dist/icons.d.mts +38 -0
  51. package/dist/icons.d.ts +38 -0
  52. package/dist/icons.mjs +175 -0
  53. package/dist/pages.d.mts +5 -0
  54. package/dist/pages.d.ts +5 -0
  55. package/dist/pages.mjs +68 -0
  56. package/i18n/de.json +1 -0
  57. package/i18n/en.json +1 -0
  58. package/i18n/fr.json +1 -0
  59. package/icons/README.md +2 -0
  60. package/icons/bluesky.svg +1 -0
  61. package/icons/claude.svg +1 -0
  62. package/icons/discord.svg +1 -0
  63. package/icons/github.svg +1 -0
  64. package/icons/linkedin.svg +1 -0
  65. package/icons/mastodon.svg +1 -0
  66. package/icons/openai.svg +1 -0
  67. package/icons/x.svg +1 -0
  68. package/icons/youtube.svg +1 -0
  69. package/nuxt.config.ts +22 -212
  70. package/package.json +44 -76
  71. package/public/_docs/fonts/LICENSE +188 -0
  72. package/public/_docs/fonts/inter-latin-wght-normal.woff2 +0 -0
  73. package/public/_docs/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
  74. package/public/_docs/fonts/jetbrains-mono-latin-500-normal.woff2 +0 -0
  75. package/server/feeds/blog-locale.get.ts +9 -0
  76. package/server/feeds/blog.get.ts +4 -0
  77. package/server/lib/blogFeed.ts +35 -0
  78. package/server/mcp/handler.ts +108 -0
  79. package/server/routes/__ginko/docs-mcp.ts +35 -0
  80. package/shared/layerRoutes.ts +66 -0
  81. package/shared/paths.ts +4 -0
  82. package/app/app.vue +0 -98
  83. package/app/assets/css/prose.css +0 -3240
  84. package/app/assets/css/tailwind.css +0 -394
  85. package/app/assets/css/theme-palettes.css +0 -309
  86. package/app/assets/css/theme-presets.css +0 -141
  87. package/app/components/OgImage/GinkoDocs.satori.vue +0 -238
  88. package/app/components/content/DocumentPageShell.vue +0 -55
  89. package/app/components/content/Feedback.vue +0 -102
  90. package/app/components/content/ImageZoomDialog.vue +0 -84
  91. package/app/components/content/PageMarkdownCopy.vue +0 -104
  92. package/app/components/content/imageZoom.ts +0 -25
  93. package/app/components/mdc/MdcAccordion.vue +0 -67
  94. package/app/components/mdc/MdcAccordionItem.vue +0 -42
  95. package/app/components/mdc/MdcApi.vue +0 -159
  96. package/app/components/mdc/MdcAside.vue +0 -23
  97. package/app/components/mdc/MdcCallout.vue +0 -61
  98. package/app/components/mdc/MdcCard.vue +0 -175
  99. package/app/components/mdc/MdcCards.vue +0 -30
  100. package/app/components/mdc/MdcCenter.vue +0 -71
  101. package/app/components/mdc/MdcCodeGroup.vue +0 -197
  102. package/app/components/mdc/MdcCodeTree.vue +0 -234
  103. package/app/components/mdc/MdcCollapse.vue +0 -61
  104. package/app/components/mdc/MdcColumn.vue +0 -70
  105. package/app/components/mdc/MdcDropcap.vue +0 -84
  106. package/app/components/mdc/MdcError.vue +0 -23
  107. package/app/components/mdc/MdcExcerpt.vue +0 -26
  108. package/app/components/mdc/MdcFigure.vue +0 -85
  109. package/app/components/mdc/MdcFiles.vue +0 -120
  110. package/app/components/mdc/MdcIdea.vue +0 -17
  111. package/app/components/mdc/MdcInfo.vue +0 -17
  112. package/app/components/mdc/MdcInlineToc.vue +0 -51
  113. package/app/components/mdc/MdcKbd.vue +0 -10
  114. package/app/components/mdc/MdcLayout.vue +0 -57
  115. package/app/components/mdc/MdcNote.vue +0 -17
  116. package/app/components/mdc/MdcQuiz.vue +0 -241
  117. package/app/components/mdc/MdcQuizQuestion.vue +0 -221
  118. package/app/components/mdc/MdcReadMore.vue +0 -70
  119. package/app/components/mdc/MdcSteps.vue +0 -59
  120. package/app/components/mdc/MdcSuccess.vue +0 -23
  121. package/app/components/mdc/MdcTab.vue +0 -17
  122. package/app/components/mdc/MdcTabs.vue +0 -150
  123. package/app/components/mdc/MdcTimeline.vue +0 -17
  124. package/app/components/mdc/MdcTimelineItem.vue +0 -40
  125. package/app/components/mdc/MdcWarning.vue +0 -23
  126. package/app/components/mdc/api.utils.ts +0 -132
  127. package/app/components/mdc/code-tree.utils.ts +0 -22
  128. package/app/components/mdc/icons.ts +0 -10
  129. package/app/components/mdc/quiz.utils.ts +0 -38
  130. package/app/components/prose/ProseA.vue +0 -27
  131. package/app/components/prose/ProseBlockquote.vue +0 -30
  132. package/app/components/prose/ProseCode.vue +0 -14
  133. package/app/components/prose/ProseEm.vue +0 -14
  134. package/app/components/prose/ProseH1.vue +0 -18
  135. package/app/components/prose/ProseH2.vue +0 -29
  136. package/app/components/prose/ProseH3.vue +0 -29
  137. package/app/components/prose/ProseH4.vue +0 -29
  138. package/app/components/prose/ProseH5.vue +0 -15
  139. package/app/components/prose/ProseH6.vue +0 -15
  140. package/app/components/prose/ProseHr.vue +0 -12
  141. package/app/components/prose/ProseImg.vue +0 -55
  142. package/app/components/prose/ProseLi.vue +0 -14
  143. package/app/components/prose/ProseOl.vue +0 -14
  144. package/app/components/prose/ProseP.vue +0 -14
  145. package/app/components/prose/ProsePre.vue +0 -180
  146. package/app/components/prose/ProseStrong.vue +0 -14
  147. package/app/components/prose/ProseTable.vue +0 -18
  148. package/app/components/prose/ProseTbody.vue +0 -14
  149. package/app/components/prose/ProseTd.vue +0 -14
  150. package/app/components/prose/ProseTh.vue +0 -14
  151. package/app/components/prose/ProseThead.vue +0 -14
  152. package/app/components/prose/ProseTr.vue +0 -14
  153. package/app/components/prose/ProseUl.vue +0 -14
  154. package/app/components/site/ModeToggle.vue +0 -81
  155. package/app/components/site/SiteBanner.vue +0 -97
  156. package/app/components/site/SiteFooter.vue +0 -90
  157. package/app/components/site/SiteHeader.vue +0 -371
  158. package/app/components/site/SiteHeroCode.vue +0 -173
  159. package/app/components/site/SiteInteractionLayer.vue +0 -42
  160. package/app/components/site/SiteLocaleSwitcher.vue +0 -190
  161. package/app/components/site/SiteLogoMark.vue +0 -12
  162. package/app/components/site/SiteSkipLink.vue +0 -14
  163. package/app/components/site/SiteSocialLinks.vue +0 -33
  164. package/app/components/site/header-utils.ts +0 -3
  165. package/app/components/site/mode-toggle.utils.ts +0 -18
  166. package/app/components/ui/badge/Badge.vue +0 -28
  167. package/app/components/ui/badge/index.ts +0 -24
  168. package/app/components/ui/button/Button.vue +0 -31
  169. package/app/components/ui/button/index.ts +0 -35
  170. package/app/components/ui/collapsible/Collapsible.vue +0 -15
  171. package/app/components/ui/collapsible/CollapsibleContent.vue +0 -25
  172. package/app/components/ui/collapsible/CollapsibleTrigger.vue +0 -12
  173. package/app/components/ui/collapsible/index.ts +0 -3
  174. package/app/components/ui/dropdown-menu/DropdownMenu.vue +0 -15
  175. package/app/components/ui/dropdown-menu/DropdownMenuContent.vue +0 -50
  176. package/app/components/ui/dropdown-menu/DropdownMenuItem.vue +0 -41
  177. package/app/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue +0 -15
  178. package/app/components/ui/dropdown-menu/DropdownMenuRadioItem.vue +0 -37
  179. package/app/components/ui/dropdown-menu/DropdownMenuSeparator.vue +0 -23
  180. package/app/components/ui/dropdown-menu/DropdownMenuTrigger.vue +0 -14
  181. package/app/components/ui/dropdown-menu/index.ts +0 -7
  182. package/app/components/ui/kbd/Kbd.vue +0 -23
  183. package/app/components/ui/kbd/index.ts +0 -21
  184. package/app/components/ui/scroll-area/ScrollArea.vue +0 -39
  185. package/app/components/ui/scroll-area/ScrollBar.vue +0 -33
  186. package/app/components/ui/scroll-area/index.ts +0 -2
  187. package/app/components/ui/separator/Separator.vue +0 -27
  188. package/app/components/ui/separator/index.ts +0 -1
  189. package/app/components/ui/sheet/Sheet.vue +0 -15
  190. package/app/components/ui/sheet/SheetContent.vue +0 -59
  191. package/app/components/ui/sheet/SheetDescription.vue +0 -21
  192. package/app/components/ui/sheet/SheetOverlay.vue +0 -26
  193. package/app/components/ui/sheet/SheetTitle.vue +0 -21
  194. package/app/components/ui/sheet/SheetTrigger.vue +0 -12
  195. package/app/components/ui/sheet/index.ts +0 -5
  196. package/app/components/ui/tabs/Tabs.vue +0 -24
  197. package/app/components/ui/tabs/TabsList.vue +0 -26
  198. package/app/components/ui/tabs/TabsTrigger.vue +0 -28
  199. package/app/components/ui/tabs/index.ts +0 -3
  200. package/app/composables/site-navigation.utils.ts +0 -133
  201. package/app/composables/useCanonicalUrl.ts +0 -9
  202. package/app/composables/useContentRouteAlternates.ts +0 -35
  203. package/app/composables/useGinkoAnalytics.ts +0 -52
  204. package/app/composables/useGinkoDocsConfig.ts +0 -6
  205. package/app/composables/useGinkoOgImage.ts +0 -20
  206. package/app/composables/useLocalizedPath.ts +0 -12
  207. package/app/composables/useLocalizedRouteSwitch.ts +0 -31
  208. package/app/composables/useMetaKey.ts +0 -18
  209. package/app/composables/usePageMarkdownActions.ts +0 -79
  210. package/app/composables/useProseAppearance.ts +0 -24
  211. package/app/composables/useSchemaJsonLd.ts +0 -25
  212. package/app/composables/useSiteNavigation.ts +0 -64
  213. package/app/config/site.utils.ts +0 -36
  214. package/app/features/docs/components/DocsBreadcrumb.vue +0 -37
  215. package/app/features/docs/components/DocsContributeLinks.vue +0 -75
  216. package/app/features/docs/components/DocsMobileToc.vue +0 -108
  217. package/app/features/docs/components/DocsPageContent.vue +0 -234
  218. package/app/features/docs/components/DocsPageNav.vue +0 -57
  219. package/app/features/docs/components/DocsSidebar.vue +0 -145
  220. package/app/features/docs/components/DocsSidebarDropdown.vue +0 -70
  221. package/app/features/docs/components/DocsSidebarItem.vue +0 -122
  222. package/app/features/docs/components/DocsSidebarList.vue +0 -35
  223. package/app/features/docs/components/DocsSidebarRow.vue +0 -27
  224. package/app/features/docs/components/DocsSidebarTabs.vue +0 -59
  225. package/app/features/docs/components/DocsToc.vue +0 -106
  226. package/app/features/docs/composables/useDocsNavigation.ts +0 -29
  227. package/app/features/docs/composables/useDocsNavigationData.ts +0 -18
  228. package/app/features/docs/composables/useRevealActive.ts +0 -58
  229. package/app/features/docs/composables/useScrollspy.ts +0 -135
  230. package/app/features/docs/docs-navigation.ts +0 -157
  231. package/app/features/docs/toc-context.ts +0 -6
  232. package/app/features/search/command-center.ts +0 -110
  233. package/app/features/search/components/SiteCommandCenter.vue +0 -359
  234. package/app/features/search/components/SiteSearchPageHighlight.vue +0 -126
  235. package/app/features/search/useCommandCenter.ts +0 -292
  236. package/app/layouts/blog.vue +0 -15
  237. package/app/layouts/docs.vue +0 -20
  238. package/app/lib/errors.ts +0 -37
  239. package/app/lib/schema-org.ts +0 -38
  240. package/app/pages/blog/[slug].vue +0 -228
  241. package/app/pages/blog/index.vue +0 -130
  242. package/app/pages/docs/[...slug].vue +0 -10
  243. package/app/pages/docs/index.vue +0 -19
  244. package/app/pages/index.vue +0 -278
  245. package/app/plugins/ginko-docs-theme.ts +0 -14
  246. package/app/plugins/ssr-width.ts +0 -6
  247. package/app/utils/content.ts +0 -67
  248. package/app/utils/file-icons.ts +0 -90
  249. package/app/utils/index.ts +0 -7
  250. package/app/utils/repository.ts +0 -20
  251. package/components.ts +0 -9
  252. package/content-collections.ts +0 -89
  253. package/content.js +0 -200
  254. package/content.ts +0 -104
  255. package/i18n/i18n.config.ts +0 -10
  256. package/i18n/locales.ts +0 -81
  257. package/i18n/messages/global/banner.ts +0 -8
  258. package/i18n/messages/global/blog.ts +0 -18
  259. package/i18n/messages/global/command.ts +0 -49
  260. package/i18n/messages/global/docs.ts +0 -36
  261. package/i18n/messages/global/errors.ts +0 -36
  262. package/i18n/messages/global/feedback.ts +0 -11
  263. package/i18n/messages/global/index.ts +0 -21
  264. package/i18n/messages/global/nav.ts +0 -26
  265. package/i18n/messages/global/site.ts +0 -4
  266. package/i18n/messages/global/theme.ts +0 -9
  267. package/i18n/messages/index.ts +0 -20
  268. package/i18n/messages/localize.ts +0 -35
  269. package/i18n/routes.ts +0 -33
  270. package/icon-bundle.ts +0 -116
  271. package/index.d.ts +0 -37
  272. package/modules/analytics-boundary.ts +0 -23
  273. package/modules/feature-routing.ts +0 -68
  274. package/modules/syntax-highlighting.ts +0 -120
  275. package/public/fonts/public-sans/LICENSE +0 -93
  276. package/public/fonts/public-sans/README.md +0 -12
  277. package/public/fonts/public-sans/public-sans-400-normal-latin.woff +0 -0
  278. package/public/fonts/public-sans/public-sans-500-normal-latin.woff +0 -0
  279. package/public/fonts/public-sans/public-sans-600-normal-latin.woff +0 -0
  280. package/public/fonts/public-sans/public-sans-700-normal-latin.woff +0 -0
  281. package/runtime/generate-favicons.mjs +0 -124
  282. package/runtime/server/agent-markdown.ts +0 -19
  283. package/server/api/_ginko-docs/redirects.get.ts +0 -28
  284. package/server/mcp/tools/get-page.ts +0 -14
  285. package/server/mcp/tools/list-pages.ts +0 -10
  286. package/server/middleware/redirects.ts +0 -22
  287. package/server/plugins/agent-markdown.ts +0 -6
  288. package/server/plugins/sitemap-policy.ts +0 -12
  289. package/server/routes/.well-known/ai-catalog.json.get.ts +0 -10
  290. package/server/routes/[locale]/blog/rss.xml.get.ts +0 -13
  291. package/server/routes/blog/rss.xml.get.ts +0 -5
  292. package/server/routes/mcp/server-card.get.ts +0 -14
  293. package/server/utils/blog-feed.ts +0 -51
  294. package/server/utils/feed.ts +0 -70
  295. package/server/utils/mcp-server-card.ts +0 -45
  296. package/server/utils/redirects.ts +0 -38
  297. package/server/utils/redirects.utils.ts +0 -58
  298. package/server/utils/sitemap.ts +0 -45
  299. package/shared/route-slugs.ts +0 -5
  300. package/shared/theme-palettes.ts +0 -37
  301. package/shared/theme-presets.ts +0 -3
  302. package/shared/types/app-config.ts +0 -172
  303. package/shared/types/nuxt-config.ts +0 -14
  304. package/tags.ts +0 -192
@@ -1,7 +0,0 @@
1
- export { default as DropdownMenu } from "./DropdownMenu.vue";
2
- export { default as DropdownMenuContent } from "./DropdownMenuContent.vue";
3
- export { default as DropdownMenuItem } from "./DropdownMenuItem.vue";
4
- export { default as DropdownMenuRadioGroup } from "./DropdownMenuRadioGroup.vue";
5
- export { default as DropdownMenuRadioItem } from "./DropdownMenuRadioItem.vue";
6
- export { default as DropdownMenuSeparator } from "./DropdownMenuSeparator.vue";
7
- export { default as DropdownMenuTrigger } from "./DropdownMenuTrigger.vue";
@@ -1,23 +0,0 @@
1
- <script setup lang="ts">
2
- import type { HTMLAttributes } from "vue";
3
- import { cn } from "#ginko-docs/utils";
4
-
5
- const props = defineProps<{
6
- class?: HTMLAttributes["class"];
7
- }>();
8
- </script>
9
-
10
- <template>
11
- <kbd
12
- :class="
13
- cn(
14
- 'pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none',
15
- '[&_svg:not([class*=\'size-\'])]:size-3',
16
- '[[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10',
17
- props.class,
18
- )
19
- "
20
- >
21
- <slot />
22
- </kbd>
23
- </template>
@@ -1,21 +0,0 @@
1
- import type { VariantProps } from "class-variance-authority";
2
- import { cva } from "class-variance-authority";
3
-
4
- export { default as Kbd } from "./Kbd.vue";
5
-
6
- export const kbdVariants = cva(
7
- "bg-muted text-muted-foreground ring-1 ring-border pointer-events-none inline-flex w-fit items-center justify-center gap-1 rounded-sm font-sans font-medium select-none [&_svg:not([class*='size-'])]:size-3 [[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10",
8
- {
9
- variants: {
10
- size: {
11
- sm: "h-5 min-w-5 px-1 text-xs",
12
- md: "h-7 min-w-7 px-1.5 text-sm",
13
- },
14
- },
15
- defaultVariants: {
16
- size: "sm",
17
- },
18
- },
19
- );
20
-
21
- export type KbdVariants = VariantProps<typeof kbdVariants>;
@@ -1,39 +0,0 @@
1
- <script setup lang="ts">
2
- import type { ScrollAreaRootProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { ScrollAreaCorner, ScrollAreaRoot, ScrollAreaViewport } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
- import ScrollBar from "./ScrollBar.vue";
8
-
9
- const props = defineProps<
10
- ScrollAreaRootProps & {
11
- class?: HTMLAttributes["class"];
12
- viewportClass?: HTMLAttributes["class"];
13
- }
14
- >();
15
-
16
- const delegatedProps = reactiveOmit(props, "class", "viewportClass");
17
- </script>
18
-
19
- <template>
20
- <ScrollAreaRoot
21
- data-slot="scroll-area"
22
- v-bind="delegatedProps"
23
- :class="cn('relative', props.class)"
24
- >
25
- <ScrollAreaViewport
26
- data-slot="scroll-area-viewport"
27
- :class="
28
- cn(
29
- 'size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1',
30
- props.viewportClass,
31
- )
32
- "
33
- >
34
- <slot />
35
- </ScrollAreaViewport>
36
- <ScrollBar />
37
- <ScrollAreaCorner />
38
- </ScrollAreaRoot>
39
- </template>
@@ -1,33 +0,0 @@
1
- <script setup lang="ts">
2
- import type { ScrollAreaScrollbarProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { ScrollAreaScrollbar, ScrollAreaThumb } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = withDefaults(
9
- defineProps<ScrollAreaScrollbarProps & { class?: HTMLAttributes["class"] }>(),
10
- {
11
- orientation: "vertical",
12
- },
13
- );
14
-
15
- const delegatedProps = reactiveOmit(props, "class");
16
- </script>
17
-
18
- <template>
19
- <ScrollAreaScrollbar
20
- data-slot="scroll-area-scrollbar"
21
- v-bind="delegatedProps"
22
- :class="
23
- cn(
24
- 'flex touch-none p-px transition-colors select-none',
25
- orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent',
26
- orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent',
27
- props.class,
28
- )
29
- "
30
- >
31
- <ScrollAreaThumb data-slot="scroll-area-thumb" class="relative flex-1 rounded-full bg-border" />
32
- </ScrollAreaScrollbar>
33
- </template>
@@ -1,2 +0,0 @@
1
- export { default as ScrollArea } from "./ScrollArea.vue";
2
- export { default as ScrollBar } from "./ScrollBar.vue";
@@ -1,27 +0,0 @@
1
- <script setup lang="ts">
2
- import type { SeparatorProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { Separator } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = withDefaults(defineProps<SeparatorProps & { class?: HTMLAttributes["class"] }>(), {
9
- orientation: "horizontal",
10
- decorative: true,
11
- });
12
-
13
- const delegatedProps = reactiveOmit(props, "class");
14
- </script>
15
-
16
- <template>
17
- <Separator
18
- data-slot="separator"
19
- v-bind="delegatedProps"
20
- :class="
21
- cn(
22
- 'shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px',
23
- props.class,
24
- )
25
- "
26
- />
27
- </template>
@@ -1 +0,0 @@
1
- export { default as Separator } from "./Separator.vue";
@@ -1,15 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DialogRootEmits, DialogRootProps } from "reka-ui";
3
- import { DialogRoot, useForwardPropsEmits } from "reka-ui";
4
-
5
- const props = defineProps<DialogRootProps>();
6
- const emits = defineEmits<DialogRootEmits>();
7
-
8
- const forwarded = useForwardPropsEmits(props, emits);
9
- </script>
10
-
11
- <template>
12
- <DialogRoot v-slot="slotProps" data-slot="sheet" v-bind="forwarded">
13
- <slot v-bind="slotProps" />
14
- </DialogRoot>
15
- </template>
@@ -1,59 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DialogContentEmits, DialogContentProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { DialogClose, DialogContent, DialogPortal, useForwardPropsEmits } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
- import SheetOverlay from "./SheetOverlay.vue";
8
-
9
- interface SheetContentProps extends DialogContentProps {
10
- class?: HTMLAttributes["class"];
11
- side?: "top" | "right" | "bottom" | "left";
12
- }
13
-
14
- defineOptions({
15
- inheritAttrs: false,
16
- });
17
-
18
- const props = withDefaults(defineProps<SheetContentProps>(), {
19
- side: "right",
20
- });
21
- const emits = defineEmits<DialogContentEmits>();
22
-
23
- const delegatedProps = reactiveOmit(props, "class", "side");
24
-
25
- const forwarded = useForwardPropsEmits(delegatedProps, emits);
26
- </script>
27
-
28
- <template>
29
- <DialogPortal>
30
- <SheetOverlay />
31
- <DialogContent
32
- data-slot="sheet-content"
33
- :class="
34
- cn(
35
- 'fixed z-[70] flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-200 data-[state=open]:animate-in data-[state=open]:duration-200',
36
- side === 'right' &&
37
- 'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',
38
- side === 'left' &&
39
- 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',
40
- side === 'top' &&
41
- 'inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',
42
- side === 'bottom' &&
43
- 'inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',
44
- props.class,
45
- )
46
- "
47
- v-bind="{ ...$attrs, ...forwarded }"
48
- >
49
- <slot />
50
-
51
- <DialogClose
52
- class="absolute top-4 right-4 inline-flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none"
53
- >
54
- <Icon name="lucide:x" class="size-4" aria-hidden="true" />
55
- <span class="sr-only">Close</span>
56
- </DialogClose>
57
- </DialogContent>
58
- </DialogPortal>
59
- </template>
@@ -1,21 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DialogDescriptionProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { DialogDescription } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = defineProps<DialogDescriptionProps & { class?: HTMLAttributes["class"] }>();
9
-
10
- const delegatedProps = reactiveOmit(props, "class");
11
- </script>
12
-
13
- <template>
14
- <DialogDescription
15
- data-slot="sheet-description"
16
- :class="cn('text-sm text-muted-foreground', props.class)"
17
- v-bind="delegatedProps"
18
- >
19
- <slot />
20
- </DialogDescription>
21
- </template>
@@ -1,26 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DialogOverlayProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { DialogOverlay } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = defineProps<DialogOverlayProps & { class?: HTMLAttributes["class"] }>();
9
-
10
- const delegatedProps = reactiveOmit(props, "class");
11
- </script>
12
-
13
- <template>
14
- <DialogOverlay
15
- data-slot="sheet-overlay"
16
- :class="
17
- cn(
18
- 'fixed inset-0 z-[60] bg-overlay data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0',
19
- props.class,
20
- )
21
- "
22
- v-bind="delegatedProps"
23
- >
24
- <slot />
25
- </DialogOverlay>
26
- </template>
@@ -1,21 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DialogTitleProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { DialogTitle } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = defineProps<DialogTitleProps & { class?: HTMLAttributes["class"] }>();
9
-
10
- const delegatedProps = reactiveOmit(props, "class");
11
- </script>
12
-
13
- <template>
14
- <DialogTitle
15
- data-slot="sheet-title"
16
- :class="cn('font-semibold text-foreground', props.class)"
17
- v-bind="delegatedProps"
18
- >
19
- <slot />
20
- </DialogTitle>
21
- </template>
@@ -1,12 +0,0 @@
1
- <script setup lang="ts">
2
- import type { DialogTriggerProps } from "reka-ui";
3
- import { DialogTrigger } from "reka-ui";
4
-
5
- const props = defineProps<DialogTriggerProps>();
6
- </script>
7
-
8
- <template>
9
- <DialogTrigger data-slot="sheet-trigger" v-bind="props">
10
- <slot />
11
- </DialogTrigger>
12
- </template>
@@ -1,5 +0,0 @@
1
- export { default as Sheet } from "./Sheet.vue";
2
- export { default as SheetContent } from "./SheetContent.vue";
3
- export { default as SheetDescription } from "./SheetDescription.vue";
4
- export { default as SheetTitle } from "./SheetTitle.vue";
5
- export { default as SheetTrigger } from "./SheetTrigger.vue";
@@ -1,24 +0,0 @@
1
- <script setup lang="ts">
2
- import type { TabsRootEmits, TabsRootProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { TabsRoot, useForwardPropsEmits } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = defineProps<TabsRootProps & { class?: HTMLAttributes["class"] }>();
9
- const emits = defineEmits<TabsRootEmits>();
10
-
11
- const delegatedProps = reactiveOmit(props, "class");
12
- const forwarded = useForwardPropsEmits(delegatedProps, emits);
13
- </script>
14
-
15
- <template>
16
- <TabsRoot
17
- v-slot="slotProps"
18
- data-slot="tabs"
19
- v-bind="forwarded"
20
- :class="cn('flex flex-col gap-2', props.class)"
21
- >
22
- <slot v-bind="slotProps" />
23
- </TabsRoot>
24
- </template>
@@ -1,26 +0,0 @@
1
- <script setup lang="ts">
2
- import type { TabsListProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { TabsList } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = defineProps<TabsListProps & { class?: HTMLAttributes["class"] }>();
9
-
10
- const delegatedProps = reactiveOmit(props, "class");
11
- </script>
12
-
13
- <template>
14
- <TabsList
15
- data-slot="tabs-list"
16
- v-bind="delegatedProps"
17
- :class="
18
- cn(
19
- 'inline-flex h-9 w-fit items-center justify-center rounded-lg bg-muted p-[3px] text-muted-foreground',
20
- props.class,
21
- )
22
- "
23
- >
24
- <slot />
25
- </TabsList>
26
- </template>
@@ -1,28 +0,0 @@
1
- <script setup lang="ts">
2
- import type { TabsTriggerProps } from "reka-ui";
3
- import type { HTMLAttributes } from "vue";
4
- import { reactiveOmit } from "@vueuse/core";
5
- import { TabsTrigger, useForwardProps } from "reka-ui";
6
- import { cn } from "#ginko-docs/utils";
7
-
8
- const props = defineProps<TabsTriggerProps & { class?: HTMLAttributes["class"] }>();
9
-
10
- const delegatedProps = reactiveOmit(props, "class");
11
-
12
- const forwardedProps = useForwardProps(delegatedProps);
13
- </script>
14
-
15
- <template>
16
- <TabsTrigger
17
- data-slot="tabs-trigger"
18
- :class="
19
- cn(
20
- 'inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:shadow-sm dark:text-muted-foreground dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 dark:data-[state=active]:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
21
- props.class,
22
- )
23
- "
24
- v-bind="forwardedProps"
25
- >
26
- <slot />
27
- </TabsTrigger>
28
- </template>
@@ -1,3 +0,0 @@
1
- export { default as Tabs } from "./Tabs.vue";
2
- export { default as TabsList } from "./TabsList.vue";
3
- export { default as TabsTrigger } from "./TabsTrigger.vue";
@@ -1,133 +0,0 @@
1
- import type {
2
- GinkoDocsAppConfig,
3
- GinkoDocsLink,
4
- GinkoDocsSocialPlatform,
5
- } from "../../shared/types/app-config";
6
- import { getLocalizedSiteText } from "../config/site.utils";
7
-
8
- export interface NavItem {
9
- label: string;
10
- href: string;
11
- external?: boolean;
12
- icon?: string;
13
- description?: string;
14
- /** Set on social links so features can find a platform without matching its icon. */
15
- platform?: GinkoDocsSocialPlatform;
16
- }
17
-
18
- export interface MainNavContext {
19
- locale: string;
20
- docsPath: string;
21
- blogPath: string;
22
- blogExists: boolean;
23
- docsLabel: string;
24
- blogLabel: string;
25
- docsDescription?: string;
26
- blogDescription?: string;
27
- }
28
-
29
- const isExternalHref = (href: string) => /^https?:\/\//.test(href);
30
-
31
- export function resolveMainNav(
32
- links: GinkoDocsAppConfig["nav"]["links"],
33
- ctx: MainNavContext,
34
- ): NavItem[] {
35
- if (Array.isArray(links)) {
36
- return links.map((link: GinkoDocsLink) => {
37
- const href = getLocalizedSiteText(link.to, ctx.locale);
38
- return {
39
- label: getLocalizedSiteText(link.label, ctx.locale),
40
- href,
41
- external: isExternalHref(href),
42
- icon: link.icon,
43
- description: link.description
44
- ? getLocalizedSiteText(link.description, ctx.locale)
45
- : undefined,
46
- };
47
- });
48
- }
49
-
50
- const items: NavItem[] = [
51
- {
52
- label: ctx.docsLabel,
53
- href: ctx.docsPath,
54
- icon: "lucide:book-open",
55
- description: ctx.docsDescription,
56
- },
57
- ];
58
- if (ctx.blogExists) {
59
- items.push({
60
- label: ctx.blogLabel,
61
- href: ctx.blogPath,
62
- icon: "lucide:file-text",
63
- description: ctx.blogDescription,
64
- });
65
- }
66
- return items;
67
- }
68
-
69
- /** Brand names are not translated, so the labels are literals. */
70
- const socialDefaults: Record<GinkoDocsSocialPlatform, { label: string; icon: string }> = {
71
- github: { label: "GitHub", icon: "ginko-social:github" },
72
- discord: { label: "Discord", icon: "ginko-social:discord" },
73
- linkedin: { label: "LinkedIn", icon: "lucide:linkedin" },
74
- };
75
-
76
- export function resolveSocialLinks(social: GinkoDocsAppConfig["social"]): NavItem[] {
77
- // Config order is render order, so a site can list Discord ahead of GitHub.
78
- return Object.entries(social).flatMap<NavItem>(([key, entry]) => {
79
- const platform = key as GinkoDocsSocialPlatform;
80
- const defaults = socialDefaults[platform];
81
- if (!defaults || !entry) return [];
82
-
83
- const link = typeof entry === "string" ? { href: entry } : entry;
84
- if (!link.href) return [];
85
-
86
- return [
87
- {
88
- label: link.label ?? defaults.label,
89
- href: link.href,
90
- external: true,
91
- icon: link.icon ?? defaults.icon,
92
- platform,
93
- },
94
- ];
95
- });
96
- }
97
-
98
- export interface BannerContext {
99
- locale: string;
100
- defaultText: string;
101
- defaultLinkLabel: string;
102
- }
103
-
104
- export interface ResolvedBanner {
105
- show: boolean;
106
- text: string;
107
- linkLabel: string;
108
- linkHref?: string;
109
- storageKey: string;
110
- }
111
-
112
- export function bannerStorageKey(id: string) {
113
- return `ginko-docs:banner:${id}`;
114
- }
115
-
116
- export function resolveBanner(
117
- config: GinkoDocsAppConfig["banner"],
118
- ctx: BannerContext,
119
- ): ResolvedBanner {
120
- const text = config.text ? getLocalizedSiteText(config.text, ctx.locale) : ctx.defaultText;
121
- const linkHref = config.link?.to ? getLocalizedSiteText(config.link.to, ctx.locale) : undefined;
122
- const linkLabel = config.link?.label
123
- ? getLocalizedSiteText(config.link.label, ctx.locale)
124
- : ctx.defaultLinkLabel;
125
-
126
- return {
127
- show: config.enabled,
128
- text,
129
- linkLabel,
130
- linkHref,
131
- storageKey: bannerStorageKey(config.id),
132
- };
133
- }
@@ -1,9 +0,0 @@
1
- import { computed } from "vue";
2
- import { useAppConfig, useRoute } from "#imports";
3
-
4
- export function useCanonicalUrl() {
5
- const route = useRoute();
6
- const config = useAppConfig().ginkoDocs;
7
-
8
- return computed(() => new URL(route.path, config.site.url).toString());
9
- }
@@ -1,35 +0,0 @@
1
- import type { ContentAlternate } from "@lupinum/ginko-content/client";
2
- import { computed, watch, type Ref } from "vue";
3
- import { useRoute, useState } from "#imports";
4
-
5
- type ContentRouteAlternatesState = {
6
- sourcePath: string;
7
- alternates: ContentAlternate[];
8
- };
9
-
10
- export function useContentRouteAlternates() {
11
- const route = useRoute();
12
- const state = useState<ContentRouteAlternatesState>("content-route-alternates", () => ({
13
- sourcePath: "",
14
- alternates: [],
15
- }));
16
-
17
- const current = computed(() =>
18
- state.value.sourcePath === route.path ? state.value.alternates : [],
19
- );
20
-
21
- function sync(page: Ref<{ route?: { alternates?: ContentAlternate[] } } | null | undefined>) {
22
- watch(
23
- page,
24
- (document) => {
25
- state.value = {
26
- sourcePath: route.path,
27
- alternates: document?.route?.alternates ?? [],
28
- };
29
- },
30
- { immediate: true },
31
- );
32
- }
33
-
34
- return { current, sync };
35
- }
@@ -1,52 +0,0 @@
1
- import { useScriptPlausibleAnalytics } from "#imports";
2
- import { useGinkoDocsConfig } from "./useGinkoDocsConfig";
3
-
4
- const PLAUSIBLE_INITIALIZER =
5
- "window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};plausible.init()";
6
-
7
- export type AnalyticsProps = Record<string, string>;
8
-
9
- export interface GinkoAnalytics {
10
- enabled: boolean;
11
- track: (event: string, props?: AnalyticsProps) => void;
12
- }
13
-
14
- /**
15
- * Plausible analytics via the Nuxt Scripts registry script. Fully disabled
16
- * unless `ginkoDocs.analytics.plausible.scriptId` is configured. Without an
17
- * ID, no script loads and `track()` is a no-op, so callers never guard.
18
- */
19
- export function useGinkoAnalytics(): GinkoAnalytics {
20
- const config = useGinkoDocsConfig();
21
- const scriptId = config.analytics?.plausible?.scriptId?.trim();
22
-
23
- if (!scriptId) {
24
- return { enabled: false, track: () => {} };
25
- }
26
-
27
- const src = `https://plausible.io/js/pa-${scriptId}.js`;
28
- useHead({
29
- script: [
30
- { key: "plausibleAnalytics", src, async: true },
31
- { key: "plausibleAnalyticsInit", innerHTML: PLAUSIBLE_INITIALIZER },
32
- ],
33
- });
34
-
35
- const script = useScriptPlausibleAnalytics({
36
- scriptId,
37
- // Plausible verifies its exact snippet in server-rendered HTML. The head
38
- // entry above provides it; Nuxt Scripts reuses the same keyed script for
39
- // its typed proxy and lifecycle instead of adding a second tracker.
40
- scriptOptions: { bundle: false },
41
- });
42
-
43
- return {
44
- enabled: true,
45
- track: (event, props) => {
46
- if (!import.meta.client) return;
47
- const plausible = script.proxy.plausible;
48
- if (typeof plausible !== "function") return;
49
- plausible(event, props ? { props } : undefined);
50
- },
51
- };
52
- }
@@ -1,6 +0,0 @@
1
- import { useAppConfig } from "#imports";
2
- import type { GinkoDocsAppConfig } from "../../shared/types/app-config";
3
-
4
- export function useGinkoDocsConfig(): GinkoDocsAppConfig {
5
- return useAppConfig().ginkoDocs as GinkoDocsAppConfig;
6
- }