@baybreezy/docd 0.0.1

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 (268) hide show
  1. package/app/app.config.ts +239 -0
  2. package/app/app.vue +19 -0
  3. package/app/assets/css/tailwind.css +335 -0
  4. package/app/assets/css/theme.css +1171 -0
  5. package/app/components/OgImage/Docs.takumi.vue +69 -0
  6. package/app/components/OgImage/Landing.takumi.vue +64 -0
  7. package/app/components/OgImage/Site.takumi.vue +32 -0
  8. package/app/components/Ui/Avatar/Avatar.vue +75 -0
  9. package/app/components/Ui/Avatar/Badge.vue +34 -0
  10. package/app/components/Ui/Avatar/Fallback.vue +30 -0
  11. package/app/components/Ui/Avatar/Group.vue +29 -0
  12. package/app/components/Ui/Avatar/GroupCount.vue +29 -0
  13. package/app/components/Ui/Avatar/Image.vue +29 -0
  14. package/app/components/Ui/Badge.vue +86 -0
  15. package/app/components/Ui/BadgeGroup.vue +314 -0
  16. package/app/components/Ui/BgPattern/Grid.vue +137 -0
  17. package/app/components/Ui/BorderBeam.vue +97 -0
  18. package/app/components/Ui/Breadcrumbs.vue +103 -0
  19. package/app/components/Ui/Button.vue +169 -0
  20. package/app/components/Ui/ButtonGroup/ButtonGroup.vue +54 -0
  21. package/app/components/Ui/ButtonGroup/Separator.vue +38 -0
  22. package/app/components/Ui/ButtonGroup/Text.vue +33 -0
  23. package/app/components/Ui/Card/Action.vue +31 -0
  24. package/app/components/Ui/Card/Card.vue +58 -0
  25. package/app/components/Ui/Card/Content.vue +34 -0
  26. package/app/components/Ui/Card/Description.vue +36 -0
  27. package/app/components/Ui/Card/Footer.vue +31 -0
  28. package/app/components/Ui/Card/Header.vue +31 -0
  29. package/app/components/Ui/Card/Title.vue +37 -0
  30. package/app/components/Ui/Collapsible/Collapsible.vue +16 -0
  31. package/app/components/Ui/Collapsible/Content.vue +27 -0
  32. package/app/components/Ui/Collapsible/Trigger.vue +13 -0
  33. package/app/components/Ui/Command/Command.vue +115 -0
  34. package/app/components/Ui/Command/Dialog.vue +65 -0
  35. package/app/components/Ui/Command/Empty.vue +32 -0
  36. package/app/components/Ui/Command/Footer.vue +40 -0
  37. package/app/components/Ui/Command/Group.vue +58 -0
  38. package/app/components/Ui/Command/Input.vue +57 -0
  39. package/app/components/Ui/Command/Item.vue +102 -0
  40. package/app/components/Ui/Command/List.vue +33 -0
  41. package/app/components/Ui/Command/Separator.vue +30 -0
  42. package/app/components/Ui/Command/Shortcut.vue +28 -0
  43. package/app/components/Ui/Container.vue +46 -0
  44. package/app/components/Ui/ContextMenu/Arrow.vue +43 -0
  45. package/app/components/Ui/ContextMenu/CheckboxItem.vue +42 -0
  46. package/app/components/Ui/ContextMenu/Content.vue +53 -0
  47. package/app/components/Ui/ContextMenu/ContextMenu.vue +14 -0
  48. package/app/components/Ui/ContextMenu/Group.vue +12 -0
  49. package/app/components/Ui/ContextMenu/Item.vue +65 -0
  50. package/app/components/Ui/ContextMenu/ItemIndicator.vue +30 -0
  51. package/app/components/Ui/ContextMenu/Label.vue +35 -0
  52. package/app/components/Ui/ContextMenu/Portal.vue +12 -0
  53. package/app/components/Ui/ContextMenu/RadioGroup.vue +16 -0
  54. package/app/components/Ui/ContextMenu/RadioItem.vue +40 -0
  55. package/app/components/Ui/ContextMenu/Separator.vue +25 -0
  56. package/app/components/Ui/ContextMenu/Shortcut.vue +30 -0
  57. package/app/components/Ui/ContextMenu/Sub.vue +15 -0
  58. package/app/components/Ui/ContextMenu/SubContent.vue +55 -0
  59. package/app/components/Ui/ContextMenu/SubTrigger.vue +42 -0
  60. package/app/components/Ui/ContextMenu/Trigger.vue +12 -0
  61. package/app/components/Ui/Dialog/Close.vue +12 -0
  62. package/app/components/Ui/Dialog/Content.vue +79 -0
  63. package/app/components/Ui/Dialog/Description.vue +29 -0
  64. package/app/components/Ui/Dialog/Dialog.vue +14 -0
  65. package/app/components/Ui/Dialog/Footer.vue +32 -0
  66. package/app/components/Ui/Dialog/Header.vue +32 -0
  67. package/app/components/Ui/Dialog/Overlay.vue +25 -0
  68. package/app/components/Ui/Dialog/Portal.vue +12 -0
  69. package/app/components/Ui/Dialog/Title.vue +29 -0
  70. package/app/components/Ui/Dialog/Trigger.vue +12 -0
  71. package/app/components/Ui/Divider.vue +102 -0
  72. package/app/components/Ui/Drawer/Close.vue +12 -0
  73. package/app/components/Ui/Drawer/Content.vue +67 -0
  74. package/app/components/Ui/Drawer/Description.vue +33 -0
  75. package/app/components/Ui/Drawer/Drawer.vue +17 -0
  76. package/app/components/Ui/Drawer/Footer.vue +35 -0
  77. package/app/components/Ui/Drawer/Header.vue +34 -0
  78. package/app/components/Ui/Drawer/Overlay.vue +20 -0
  79. package/app/components/Ui/Drawer/Portal.vue +12 -0
  80. package/app/components/Ui/Drawer/Title.vue +35 -0
  81. package/app/components/Ui/Drawer/Trigger.vue +12 -0
  82. package/app/components/Ui/DropdownMenu/Arrow.vue +43 -0
  83. package/app/components/Ui/DropdownMenu/CheckboxItem.vue +41 -0
  84. package/app/components/Ui/DropdownMenu/Content.vue +56 -0
  85. package/app/components/Ui/DropdownMenu/DropdownMenu.vue +15 -0
  86. package/app/components/Ui/DropdownMenu/Group.vue +12 -0
  87. package/app/components/Ui/DropdownMenu/Item.vue +64 -0
  88. package/app/components/Ui/DropdownMenu/ItemIndicator.vue +32 -0
  89. package/app/components/Ui/DropdownMenu/Label.vue +34 -0
  90. package/app/components/Ui/DropdownMenu/Portal.vue +12 -0
  91. package/app/components/Ui/DropdownMenu/RadioGroup.vue +16 -0
  92. package/app/components/Ui/DropdownMenu/RadioItem.vue +40 -0
  93. package/app/components/Ui/DropdownMenu/Separator.vue +25 -0
  94. package/app/components/Ui/DropdownMenu/Shortcut.vue +44 -0
  95. package/app/components/Ui/DropdownMenu/Sub.vue +14 -0
  96. package/app/components/Ui/DropdownMenu/SubContent.vue +56 -0
  97. package/app/components/Ui/DropdownMenu/SubTrigger.vue +47 -0
  98. package/app/components/Ui/DropdownMenu/Trigger.vue +12 -0
  99. package/app/components/Ui/FancyIcon.vue +243 -0
  100. package/app/components/Ui/GradientDivider.vue +26 -0
  101. package/app/components/Ui/IframeLazy.vue +97 -0
  102. package/app/components/Ui/Input.vue +97 -0
  103. package/app/components/Ui/InputGroup/Addon.vue +66 -0
  104. package/app/components/Ui/InputGroup/Button.vue +50 -0
  105. package/app/components/Ui/InputGroup/Input.vue +25 -0
  106. package/app/components/Ui/InputGroup/InputGroup.vue +44 -0
  107. package/app/components/Ui/InputGroup/Text.vue +33 -0
  108. package/app/components/Ui/InputGroup/Textarea.vue +25 -0
  109. package/app/components/Ui/Kbd/Group.vue +32 -0
  110. package/app/components/Ui/Kbd/Kbd.vue +62 -0
  111. package/app/components/Ui/Label.vue +40 -0
  112. package/app/components/Ui/Popover/Anchor.vue +13 -0
  113. package/app/components/Ui/Popover/Arrow.vue +42 -0
  114. package/app/components/Ui/Popover/Close.vue +13 -0
  115. package/app/components/Ui/Popover/Content.vue +55 -0
  116. package/app/components/Ui/Popover/Popover.vue +15 -0
  117. package/app/components/Ui/Popover/Portal.vue +13 -0
  118. package/app/components/Ui/Popover/Trigger.vue +12 -0
  119. package/app/components/Ui/Popover/X.vue +38 -0
  120. package/app/components/Ui/ScrollArea/Corner.vue +12 -0
  121. package/app/components/Ui/ScrollArea/ScrollArea.vue +38 -0
  122. package/app/components/Ui/ScrollArea/Scrollbar.vue +39 -0
  123. package/app/components/Ui/ScrollArea/Thumb.vue +39 -0
  124. package/app/components/Ui/ScrollArea/Viewport.vue +27 -0
  125. package/app/components/Ui/Scrollspy.vue +61 -0
  126. package/app/components/Ui/Separator.vue +40 -0
  127. package/app/components/Ui/Skeleton.vue +39 -0
  128. package/app/components/Ui/Sonner.vue +25 -0
  129. package/app/components/Ui/Tabs/Content.vue +27 -0
  130. package/app/components/Ui/Tabs/Indicator.vue +37 -0
  131. package/app/components/Ui/Tabs/List.vue +37 -0
  132. package/app/components/Ui/Tabs/Tabs.vue +25 -0
  133. package/app/components/Ui/Tabs/Trigger.vue +41 -0
  134. package/app/components/Ui/Textarea.vue +81 -0
  135. package/app/components/Ui/Tooltip/Arrow.vue +30 -0
  136. package/app/components/Ui/Tooltip/Content.vue +50 -0
  137. package/app/components/Ui/Tooltip/Portal.vue +12 -0
  138. package/app/components/Ui/Tooltip/Provider.vue +14 -0
  139. package/app/components/Ui/Tooltip/Tooltip.vue +25 -0
  140. package/app/components/Ui/Tooltip/Trigger.vue +12 -0
  141. package/app/components/Ui/Tree/Item.vue +15 -0
  142. package/app/components/Ui/Tree/Tree.vue +15 -0
  143. package/app/components/Ui/Tree/Virtualizer.vue +13 -0
  144. package/app/components/component-api/ComponentApiSection.vue +135 -0
  145. package/app/components/content/docs/Callout/DocsCallout.vue +99 -0
  146. package/app/components/content/prose/ProseA.global.vue +31 -0
  147. package/app/components/content/prose/ProseBlockquote.global.vue +28 -0
  148. package/app/components/content/prose/ProseCallout.global.vue +306 -0
  149. package/app/components/content/prose/ProseCard.global.vue +100 -0
  150. package/app/components/content/prose/ProseCodeCollapse.global.vue +125 -0
  151. package/app/components/content/prose/ProseCodeCopy.global.vue +67 -0
  152. package/app/components/content/prose/ProseCodeGroup.global.vue +104 -0
  153. package/app/components/content/prose/ProseCodeTree.global.vue +277 -0
  154. package/app/components/content/prose/ProseCollapsible.global.vue +64 -0
  155. package/app/components/content/prose/ProseColorModeImage.global.vue +58 -0
  156. package/app/components/content/prose/ProseComponentApi.global.vue +104 -0
  157. package/app/components/content/prose/ProseComponentEvents.global.vue +27 -0
  158. package/app/components/content/prose/ProseComponentExposed.global.vue +27 -0
  159. package/app/components/content/prose/ProseComponentProps.global.vue +27 -0
  160. package/app/components/content/prose/ProseComponentSlots.global.vue +27 -0
  161. package/app/components/content/prose/ProseEm.global.vue +5 -0
  162. package/app/components/content/prose/ProseField.global.vue +118 -0
  163. package/app/components/content/prose/ProseFieldGroup.global.vue +62 -0
  164. package/app/components/content/prose/ProseH1.global.vue +58 -0
  165. package/app/components/content/prose/ProseH2.global.vue +58 -0
  166. package/app/components/content/prose/ProseH3.global.vue +58 -0
  167. package/app/components/content/prose/ProseH4.global.vue +58 -0
  168. package/app/components/content/prose/ProseH5.global.vue +47 -0
  169. package/app/components/content/prose/ProseH6.global.vue +47 -0
  170. package/app/components/content/prose/ProseHr.global.vue +33 -0
  171. package/app/components/content/prose/ProseIconList.global.vue +113 -0
  172. package/app/components/content/prose/ProseImg.global.vue +119 -0
  173. package/app/components/content/prose/ProseLead.global.vue +28 -0
  174. package/app/components/content/prose/ProseLi.global.vue +25 -0
  175. package/app/components/content/prose/ProseMermaid.global.vue +127 -0
  176. package/app/components/content/prose/ProseOl.global.vue +25 -0
  177. package/app/components/content/prose/ProseP.global.vue +25 -0
  178. package/app/components/content/prose/ProsePmInstall.global.vue +60 -0
  179. package/app/components/content/prose/ProsePmRun.global.vue +51 -0
  180. package/app/components/content/prose/ProsePmX.global.vue +56 -0
  181. package/app/components/content/prose/ProsePre.global.vue +181 -0
  182. package/app/components/content/prose/ProseShowCase.global.vue +56 -0
  183. package/app/components/content/prose/ProseSmartIcon.global.vue +54 -0
  184. package/app/components/content/prose/ProseStep.global.vue +22 -0
  185. package/app/components/content/prose/ProseSteps.global.vue +22 -0
  186. package/app/components/content/prose/ProseStrong.global.vue +34 -0
  187. package/app/components/content/prose/ProseTable.global.vue +34 -0
  188. package/app/components/content/prose/ProseTabs.global.vue +104 -0
  189. package/app/components/content/prose/ProseTabsInner.global.vue +274 -0
  190. package/app/components/content/prose/ProseTbody.global.vue +5 -0
  191. package/app/components/content/prose/ProseTd.global.vue +25 -0
  192. package/app/components/content/prose/ProseTh.global.vue +25 -0
  193. package/app/components/content/prose/ProseThead.global.vue +9 -0
  194. package/app/components/content/prose/ProseTr.global.vue +35 -0
  195. package/app/components/content/prose/ProseUl.global.vue +25 -0
  196. package/app/components/docs/DocsExtraStuff.vue +39 -0
  197. package/app/components/docs/DocsGithubLink.vue +11 -0
  198. package/app/components/docs/DocsHeader.vue +3 -0
  199. package/app/components/docs/DocsLogo.vue +74 -0
  200. package/app/components/docs/DocsMobileBar.vue +26 -0
  201. package/app/components/docs/DocsMobileNav.vue +49 -0
  202. package/app/components/docs/DocsNav.vue +161 -0
  203. package/app/components/docs/DocsPageTransition.vue +32 -0
  204. package/app/components/docs/DocsSearch.vue +220 -0
  205. package/app/components/docs/DocsSearchButton.vue +20 -0
  206. package/app/components/docs/DocsThemeCustomizer.vue +229 -0
  207. package/app/components/docs/DocsThemeToggler.vue +98 -0
  208. package/app/components/docs/DocsTocRail.vue +162 -0
  209. package/app/components/docs/DocsToclink.vue +52 -0
  210. package/app/components/docs/DocsZigZagRail.vue +70 -0
  211. package/app/components/landing/Hero.vue +222 -0
  212. package/app/components/page/PageFooter.vue +49 -0
  213. package/app/components/page/PageHeader.vue +68 -0
  214. package/app/components/page/PageHeaderLinks.vue +138 -0
  215. package/app/components/page/PageMobileToc.vue +162 -0
  216. package/app/components/page/PageToc.vue +33 -0
  217. package/app/composables/useDefaultSlotItems.ts +90 -0
  218. package/app/composables/useDocPage.ts +66 -0
  219. package/app/composables/useDocSearch.ts +23 -0
  220. package/app/composables/useDocd.ts +107 -0
  221. package/app/composables/useLogoAssets.ts +319 -0
  222. package/app/composables/usePm.ts +73 -0
  223. package/app/composables/useProseComponentMeta.ts +30 -0
  224. package/app/composables/useScrollspy.ts +327 -0
  225. package/app/composables/useSeo.ts +240 -0
  226. package/app/composables/useUIConfig.ts +36 -0
  227. package/app/layouts/default.vue +5 -0
  228. package/app/layouts/docs.vue +64 -0
  229. package/app/middleware/colorMode.global.ts +8 -0
  230. package/app/middleware/doc-page-layout.ts +11 -0
  231. package/app/middleware/landing-page-layout.ts +11 -0
  232. package/app/pages/[...slug].vue +63 -0
  233. package/app/plugins/mermaid.client.ts +35 -0
  234. package/app/plugins/navigation-direction.client.ts +15 -0
  235. package/app/plugins/theme-restore.client.ts +7 -0
  236. package/app/templates/landing.vue +40 -0
  237. package/app/transitions/presets.ts +71 -0
  238. package/app/types/prose-component-meta.d.ts +4 -0
  239. package/app/utils/og.ts +26 -0
  240. package/app/utils/prerender.ts +9 -0
  241. package/app/utils/translucent.ts +56 -0
  242. package/app/utils/tw-helper.ts +4 -0
  243. package/content.config.ts +81 -0
  244. package/index.d.ts +25 -0
  245. package/modules/config.ts +89 -0
  246. package/modules/custom-icons.ts +17 -0
  247. package/modules/markdown-rewrite.ts +96 -0
  248. package/modules/prose-component-meta.ts +150 -0
  249. package/modules/routing.ts +22 -0
  250. package/modules/skills/index.ts +167 -0
  251. package/modules/skills/runtime/server/routes/skills-files.ts +49 -0
  252. package/modules/skills/runtime/server/routes/skills-index.ts +8 -0
  253. package/nuxt.config.ts +96 -0
  254. package/nuxt.schema.ts +288 -0
  255. package/package.json +95 -0
  256. package/server/mcp/tools/get-page.ts +66 -0
  257. package/server/mcp/tools/list-pages.ts +61 -0
  258. package/server/routes/sitemap.xml.ts +73 -0
  259. package/server/utils/content.ts +3 -0
  260. package/tailwind.config.cjs +55 -0
  261. package/utils/component-api-content.ts +467 -0
  262. package/utils/component-api-discovery.ts +165 -0
  263. package/utils/component-api-schema.ts +28 -0
  264. package/utils/component-api.ts +243 -0
  265. package/utils/generate-prose-component-meta.ts +303 -0
  266. package/utils/git.ts +123 -0
  267. package/utils/meta.ts +40 -0
  268. package/utils/pages.ts +21 -0
@@ -0,0 +1,181 @@
1
+ <template>
2
+ <div data-slot="prose-pre-wrapper" :class="styles().wrapper({ class: $attrs?.class as any })">
3
+ <template v-if="hasFileName">
4
+ <div data-slot="prose-pre-file-name-wrapper" :class="styles().fileNameWrapper()">
5
+ <prose-smart-icon v-if="iconFromMeta" :name="iconFromMeta" class="size-4 shrink-0" />
6
+ <img
7
+ v-else-if="language || filename"
8
+ :src="getMaterialFileIcon(language! || filename!)"
9
+ :alt="language || filename"
10
+ class="size-4 shrink-0"
11
+ />
12
+
13
+ <p data-slot="prose-pre-file-name" :class="styles().fileName()">{{ fileNameEdited }}</p>
14
+ </div>
15
+ </template>
16
+ <div
17
+ v-if="!hideCopyButton"
18
+ class="absolute right-3.5 flex items-center justify-center"
19
+ :class="[hasFileName ? 'top-2.75' : 'top-3']"
20
+ >
21
+ <prose-code-copy :code @code-copied="onCopy" />
22
+ </div>
23
+ <ProseMermaid v-if="isMermaid" :code="code" @mermaid-error="onMermaidError">
24
+ <slot />
25
+ </ProseMermaid>
26
+ <pre v-else :class="[$attrs?.class, 'shadow-xs ring-1 ring-border/60']"><slot /></pre>
27
+ </div>
28
+ </template>
29
+
30
+ <script lang="ts" setup>
31
+ import { getMaterialFileIcon } from "@baybreezy/file-extension-icon";
32
+ import { startCase } from "lodash-es";
33
+
34
+ const { page } = await useDocPage();
35
+ const route = useRoute();
36
+
37
+ const props = defineProps<{
38
+ /**
39
+ * The code content to display
40
+ */
41
+ code?: string;
42
+ /**
43
+ * The programming language of the code block
44
+ */
45
+ language?: string;
46
+ /**
47
+ * The filename to display in the header (if any)
48
+ */
49
+ filename?: string;
50
+ /**
51
+ * An array of line numbers to highlight
52
+ */
53
+ highlights?: Array<number>;
54
+ /**
55
+ * Additional meta information for the code block
56
+ */
57
+ meta?: string;
58
+ /**
59
+ * Optional icon name to display next to the filename
60
+ */
61
+ icon?: string;
62
+ }>();
63
+
64
+ /**
65
+ * Parse meta string and create a lowercase key map for easy checking
66
+ * Example: "noFormat hideHeader icon='lucide:code'" => Map { 'noformat' => true, 'hideheader' => true, 'icon' => 'lucide:code' }
67
+ */
68
+ const metaMap = computed(() => {
69
+ const map = new Map<string, string | boolean>();
70
+ if (!props.meta) return map;
71
+
72
+ // Split by spaces but preserve quoted values
73
+ const parts = props.meta.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) || [];
74
+
75
+ parts.forEach((part) => {
76
+ // Check if it's a key=value pair
77
+ const keyValueMatch = part.match(/^([^=]+)=(.+)$/);
78
+ if (keyValueMatch) {
79
+ const key = keyValueMatch[1]!.toLowerCase();
80
+ // Remove quotes from value if present
81
+ const value = keyValueMatch[2]!.replace(/^["']|["']$/g, "");
82
+ map.set(key, value);
83
+ } else {
84
+ // It's just a flag (boolean)
85
+ map.set(part.toLowerCase(), true);
86
+ }
87
+ });
88
+
89
+ return map;
90
+ });
91
+
92
+ const hideCopyButton = ref(false);
93
+ const noFormatMeta = computed(() => metaMap.value.has("noformat"));
94
+ const hideHeaderMeta = computed(
95
+ () => metaMap.value.has("hideheader") || metaMap.value.has("noheader")
96
+ );
97
+ const hasLinesInMeta = computed(() => metaMap.value.has("lines"));
98
+ const metaHasMermaid = computed(() => metaMap.value.has("mermaid"));
99
+
100
+ const iconFromMeta = computed(() => {
101
+ // First check if icon is passed as a direct prop
102
+ if (props.icon) return props.icon;
103
+ // Then check metaMap for icon key
104
+ const icon = metaMap.value.get("icon");
105
+ return typeof icon === "string" ? icon : undefined;
106
+ });
107
+
108
+ const fileNameEdited = computed(() => {
109
+ if (!props.filename) return;
110
+ if (noFormatMeta.value) return props.filename;
111
+
112
+ let processedName = props.filename;
113
+
114
+ // Check if it looks like a filename (ends with .[anything])
115
+ const hasFileExtension = /\.[^.]+$/.test(processedName);
116
+
117
+ if (hasFileExtension) {
118
+ // It's a filename - remove the extension
119
+ processedName = processedName.split(".").slice(0, -1).join(".");
120
+ // if we have something like .env or .gitignore, we might end up with an empty string
121
+ if (!processedName) {
122
+ processedName = props.filename;
123
+ }
124
+ }
125
+
126
+ // Clean up any extra spaces and apply startCase
127
+ return startCase(processedName.trim());
128
+ });
129
+
130
+ const hasFileName = computed(() => !!props.filename && !hideHeaderMeta.value);
131
+ const isMermaid = computed(() => props.language === "mermaid" || metaHasMermaid.value);
132
+
133
+ const onMermaidError = (errorMessage?: string) => {
134
+ if (errorMessage) {
135
+ hideCopyButton.value = true;
136
+ } else {
137
+ hideCopyButton.value = false;
138
+ }
139
+ };
140
+
141
+ const onCopy = () => {
142
+ // Track copied code event
143
+ useTrackEvent("copy_code", {
144
+ code_source: "inline",
145
+ code_language: props.language,
146
+ file_name: props.filename,
147
+ block_path: "N/A",
148
+ component: props.filename,
149
+ page_title: page.value?.title || "unknown",
150
+ page_path: route.path,
151
+ page_location: window.location.href,
152
+ });
153
+ };
154
+
155
+ const styles = tv({
156
+ slots: {
157
+ wrapper: [
158
+ "relative mt-3 rounded-lg border bg-muted/60 p-1.5 dark:bg-muted/10",
159
+ hasLinesInMeta.value && "show-line-number",
160
+ ],
161
+ fileNameWrapper: "not-prose flex items-center gap-2 p-2 pb-4",
162
+ fileName: "truncate text-sm font-medium text-ellipsis",
163
+ },
164
+ });
165
+ </script>
166
+
167
+ <style>
168
+ .show-line-number .line::before {
169
+ font-size: var(--text-sm);
170
+ line-height: var(--tw-leading, var(--text-xs--line-height));
171
+ width: calc(var(--spacing) * 5);
172
+ display: inline-block;
173
+ text-align: center;
174
+ margin-right: calc(var(--spacing) * 4);
175
+ color: var(--muted-foreground);
176
+ }
177
+
178
+ .show-line-number .line:not(.diff)::before {
179
+ content: attr(line);
180
+ }
181
+ </style>
@@ -0,0 +1,56 @@
1
+ <template>
2
+ <TabsRoot v-model="tab">
3
+ <TabsList class="relative inline-flex items-center">
4
+ <UiTabsTrigger aria-label="Preview" :pill="false" value="preview"> Preview </UiTabsTrigger>
5
+ <UiTabsTrigger aria-label="Code" :pill="false" value="code"> Code </UiTabsTrigger>
6
+ <UiTabsIndicator class="px-3" />
7
+ </TabsList>
8
+ <LayoutGroup>
9
+ <AnimatePresence mode="wait">
10
+ <Motion
11
+ v-if="tab == 'preview'"
12
+ layout="position"
13
+ :initial="false"
14
+ :animate="{ opacity: 1 }"
15
+ :exit="{ opacity: 0 }"
16
+ :transition="{ duration: 0.2 }"
17
+ >
18
+ <TabsContent force-mount value="preview">
19
+ <div
20
+ class="mt-4 flex min-h-75 items-center justify-center rounded-lg border p-3 lg:p-10"
21
+ :class="[isDashed ? 'border-dashed' : '']"
22
+ >
23
+ <div class="mx-auto w-full" :class="[!props.prose ? 'not-prose' : '']">
24
+ <slot />
25
+ </div>
26
+ </div>
27
+ </TabsContent>
28
+ </Motion>
29
+ <Motion
30
+ v-else
31
+ layout="position"
32
+ :initial="{ opacity: 0 }"
33
+ :animate="{ opacity: 1 }"
34
+ :exit="{ opacity: 0 }"
35
+ :transition="{ duration: 0.2 }"
36
+ >
37
+ <TabsContent force-mount value="code">
38
+ <slot name="code" mdc-unwrap="p" />
39
+ </TabsContent>
40
+ </Motion>
41
+ </AnimatePresence>
42
+ </LayoutGroup>
43
+ </TabsRoot>
44
+ </template>
45
+
46
+ <script lang="ts" setup>
47
+ import { TabsContent, TabsList, TabsRoot } from "reka-ui";
48
+
49
+ const tab = ref("preview");
50
+
51
+ const props = defineProps<{
52
+ prose?: boolean;
53
+ }>();
54
+
55
+ const { isDashed } = useDocd();
56
+ </script>
@@ -0,0 +1,54 @@
1
+ <template>
2
+ <!-- Iconify Icons -->
3
+ <Icon v-if="checkIcon(name)" :name :size />
4
+ <!-- Emojis -->
5
+ <span
6
+ v-else-if="
7
+ /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/g.test(
8
+ name
9
+ )
10
+ "
11
+ :style="`font-size: ${size}px;`"
12
+ aria-hidden="true"
13
+ >{{ name }}</span
14
+ >
15
+ <!-- Link -->
16
+ <NuxtImg
17
+ v-else
18
+ :src="name"
19
+ :style="`width: ${size}px; height: ${size}px;`"
20
+ :class="['not-prose inline', $attrs.class]"
21
+ />
22
+ </template>
23
+
24
+ <script lang="ts">
25
+ import { stringToIcon, validateIconName } from "@iconify/utils";
26
+
27
+ export type SmartIconProps = {
28
+ /**
29
+ * This can be on of the following:
30
+ *
31
+ * - An [Iconify](https://icon-sets.iconify.design/) icon name, e.g. `mdi:home`
32
+ * - An emoji, e.g. `😀`
33
+ * - A link to an image, e.g. `https://example.com/icon.png`
34
+ */
35
+ name: string;
36
+ /**
37
+ * Size of the icon in pixels (default: 16)
38
+ * @default 16
39
+ */
40
+ size?: number;
41
+ };
42
+ </script>
43
+
44
+ <script setup lang="ts">
45
+ const { size = 16 } = defineProps<SmartIconProps>();
46
+
47
+ /**
48
+ * Check if the provided name is a valid Iconify icon name
49
+ */
50
+ function checkIcon(name: string): boolean {
51
+ if (name.includes("http") || name.startsWith("data:image/")) return false;
52
+ return validateIconName(stringToIcon(name));
53
+ }
54
+ </script>
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <div :class="styles({ class: normalizeClass(props.class) || undefined })">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script lang="ts" setup>
8
+ import { normalizeClass } from "vue";
9
+ import type { HtmlHTMLAttributes } from "vue";
10
+
11
+ const props = withDefaults(
12
+ defineProps<{
13
+ /** Additional CSS classes to apply to the step item */
14
+ class?: HtmlHTMLAttributes["class"];
15
+ }>(),
16
+ {}
17
+ );
18
+
19
+ const styles = tv({
20
+ base: "before:absolute before:-left-4 before:z-10 before:flex before:h-8 before:w-8 before:items-center before:justify-center before:rounded-full before:bg-secondary before:text-sm before:text-secondary-foreground before:content-[counter(step)] before:[counter-increment:step]",
21
+ });
22
+ </script>
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <div :class="styles({ class: normalizeClass(props.class) || undefined })">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script lang="ts" setup>
8
+ import { normalizeClass } from "vue";
9
+ import type { HtmlHTMLAttributes } from "vue";
10
+
11
+ const props = withDefaults(
12
+ defineProps<{
13
+ /** Additional CSS classes to apply to the steps container */
14
+ class?: HtmlHTMLAttributes["class"];
15
+ }>(),
16
+ {}
17
+ );
18
+
19
+ const styles = tv({
20
+ base: "relative ml-4 border-l pl-7 [counter-reset:step]",
21
+ });
22
+ </script>
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <strong
3
+ data-slot="prose-strong"
4
+ :class="proseStrongStyles({ class: normalizeClass(_class) || undefined })"
5
+ >
6
+ <slot />
7
+ </strong>
8
+ </template>
9
+
10
+ <script lang="ts">
11
+ import { normalizeClass } from "vue";
12
+ import type { HTMLAttributes } from "vue";
13
+
14
+ export type ProseStrongProps = {
15
+ /**
16
+ * Additional classes for the parent element
17
+ */
18
+ class?: HTMLAttributes["class"];
19
+ };
20
+
21
+ export const proseStrongStyles = tv({
22
+ base: "font-semibold text-inherit",
23
+ });
24
+ </script>
25
+
26
+ <script setup lang="ts">
27
+ const { class: _class } = defineProps<ProseStrongProps>();
28
+ </script>
29
+
30
+ <style>
31
+ [data-slot="prose-strong"] + [data-slot="prose-strong"] {
32
+ margin-inline-start: 0.25em;
33
+ }
34
+ </style>
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <div :class="proseTableStyles({ class: normalizeClass(_class) || undefined, isDashed })">
3
+ <table class="relative mt-0 mb-0 w-full overflow-hidden border-none" data-slot="prose-table">
4
+ <slot />
5
+ </table>
6
+ </div>
7
+ </template>
8
+
9
+ <script lang="ts">
10
+ import { normalizeClass } from "vue";
11
+ import type { HTMLAttributes } from "vue";
12
+
13
+ export type ProseTableProps = {
14
+ /**
15
+ * Additional classes for the parent element
16
+ */
17
+ class?: HTMLAttributes["class"];
18
+ };
19
+
20
+ export const proseTableStyles = tv({
21
+ base: "w-full overflow-y-auto rounded-md border not-last:mb-6",
22
+ variants: {
23
+ isDashed: {
24
+ true: "border-dashed",
25
+ false: "",
26
+ },
27
+ },
28
+ });
29
+ </script>
30
+
31
+ <script setup lang="ts">
32
+ const { class: _class } = defineProps<ProseTableProps>();
33
+ const { isDashed } = useDocd();
34
+ </script>
@@ -0,0 +1,104 @@
1
+ <template>
2
+ <render />
3
+ </template>
4
+
5
+ <script lang="ts">
6
+ import type { HTMLAttributes } from "vue";
7
+
8
+ import { ProseTabsInner } from "#components";
9
+
10
+ export type ProseTabsProps = {
11
+ /**
12
+ * The variant of the tabs
13
+ * @default 'separate'
14
+ */
15
+ variant?: "separate" | "card" | "line" | "combobox";
16
+ /**
17
+ * Whether to add padding around the tabs
18
+ * @default true
19
+ */
20
+ padded?: boolean;
21
+ /**
22
+ * Whether the tabs are in a stack (e.g. accordion)
23
+ * @default false
24
+ */
25
+ inStack?: boolean;
26
+ /**
27
+ * Disable the search functionality
28
+ * @default false
29
+ */
30
+ disableSearch?: boolean;
31
+ /**
32
+ * Placeholder text for the search input
33
+ * @default 'Search Tab...'
34
+ */
35
+ searchPlaceholder?: string;
36
+ /**
37
+ * Text to display when no tab is found
38
+ * @default 'No tab found.'
39
+ */
40
+ searchEmpty?: string;
41
+ /**
42
+ * Whether the combobox should take the full width of the container
43
+ * @default false
44
+ */
45
+ comboBoxFullWidth?: boolean;
46
+ /**
47
+ * A scope to sync the active tab state with other tab groups
48
+ */
49
+ sync?: string;
50
+ /**
51
+ * Additional classes to add to the wrapper div
52
+ */
53
+ class?: HTMLAttributes["class"];
54
+ };
55
+ </script>
56
+
57
+ <script setup lang="ts">
58
+ const {
59
+ variant = "separate",
60
+ padded = true,
61
+ inStack = false,
62
+ disableSearch = false,
63
+ searchPlaceholder = "Search Tab...",
64
+ searchEmpty = "No tab found.",
65
+ ...rest
66
+ } = defineProps<ProseTabsProps>();
67
+
68
+ const _slots = useSlots();
69
+ const { items: slotItems } = useDefaultSlotItems({
70
+ slots: _slots,
71
+ mapMeta: ({ props, index }) => ({
72
+ label: props.label ?? props.filename ?? `Tab ${index + 1}`,
73
+ icon: props?.icon,
74
+ }),
75
+ });
76
+
77
+ const slotsData = computed(() =>
78
+ slotItems.value.map(({ index, meta, props }) => ({
79
+ index,
80
+ label: meta.label,
81
+ icon: props.icon || meta.icon,
82
+ }))
83
+ );
84
+
85
+ /**
86
+ * Render function to pass slots as props to ProseTabsInner
87
+ */
88
+ function render() {
89
+ return h(
90
+ ProseTabsInner,
91
+ {
92
+ variant,
93
+ padded,
94
+ inStack,
95
+ disableSearch,
96
+ searchEmpty,
97
+ searchPlaceholder,
98
+ slotsData: slotsData.value,
99
+ ...rest,
100
+ },
101
+ () => slotItems.value.map(({ vnode }) => vnode)
102
+ );
103
+ }
104
+ </script>