@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.
- package/app/app.config.ts +239 -0
- package/app/app.vue +19 -0
- package/app/assets/css/tailwind.css +335 -0
- package/app/assets/css/theme.css +1171 -0
- package/app/components/OgImage/Docs.takumi.vue +69 -0
- package/app/components/OgImage/Landing.takumi.vue +64 -0
- package/app/components/OgImage/Site.takumi.vue +32 -0
- package/app/components/Ui/Avatar/Avatar.vue +75 -0
- package/app/components/Ui/Avatar/Badge.vue +34 -0
- package/app/components/Ui/Avatar/Fallback.vue +30 -0
- package/app/components/Ui/Avatar/Group.vue +29 -0
- package/app/components/Ui/Avatar/GroupCount.vue +29 -0
- package/app/components/Ui/Avatar/Image.vue +29 -0
- package/app/components/Ui/Badge.vue +86 -0
- package/app/components/Ui/BadgeGroup.vue +314 -0
- package/app/components/Ui/BgPattern/Grid.vue +137 -0
- package/app/components/Ui/BorderBeam.vue +97 -0
- package/app/components/Ui/Breadcrumbs.vue +103 -0
- package/app/components/Ui/Button.vue +169 -0
- package/app/components/Ui/ButtonGroup/ButtonGroup.vue +54 -0
- package/app/components/Ui/ButtonGroup/Separator.vue +38 -0
- package/app/components/Ui/ButtonGroup/Text.vue +33 -0
- package/app/components/Ui/Card/Action.vue +31 -0
- package/app/components/Ui/Card/Card.vue +58 -0
- package/app/components/Ui/Card/Content.vue +34 -0
- package/app/components/Ui/Card/Description.vue +36 -0
- package/app/components/Ui/Card/Footer.vue +31 -0
- package/app/components/Ui/Card/Header.vue +31 -0
- package/app/components/Ui/Card/Title.vue +37 -0
- package/app/components/Ui/Collapsible/Collapsible.vue +16 -0
- package/app/components/Ui/Collapsible/Content.vue +27 -0
- package/app/components/Ui/Collapsible/Trigger.vue +13 -0
- package/app/components/Ui/Command/Command.vue +115 -0
- package/app/components/Ui/Command/Dialog.vue +65 -0
- package/app/components/Ui/Command/Empty.vue +32 -0
- package/app/components/Ui/Command/Footer.vue +40 -0
- package/app/components/Ui/Command/Group.vue +58 -0
- package/app/components/Ui/Command/Input.vue +57 -0
- package/app/components/Ui/Command/Item.vue +102 -0
- package/app/components/Ui/Command/List.vue +33 -0
- package/app/components/Ui/Command/Separator.vue +30 -0
- package/app/components/Ui/Command/Shortcut.vue +28 -0
- package/app/components/Ui/Container.vue +46 -0
- package/app/components/Ui/ContextMenu/Arrow.vue +43 -0
- package/app/components/Ui/ContextMenu/CheckboxItem.vue +42 -0
- package/app/components/Ui/ContextMenu/Content.vue +53 -0
- package/app/components/Ui/ContextMenu/ContextMenu.vue +14 -0
- package/app/components/Ui/ContextMenu/Group.vue +12 -0
- package/app/components/Ui/ContextMenu/Item.vue +65 -0
- package/app/components/Ui/ContextMenu/ItemIndicator.vue +30 -0
- package/app/components/Ui/ContextMenu/Label.vue +35 -0
- package/app/components/Ui/ContextMenu/Portal.vue +12 -0
- package/app/components/Ui/ContextMenu/RadioGroup.vue +16 -0
- package/app/components/Ui/ContextMenu/RadioItem.vue +40 -0
- package/app/components/Ui/ContextMenu/Separator.vue +25 -0
- package/app/components/Ui/ContextMenu/Shortcut.vue +30 -0
- package/app/components/Ui/ContextMenu/Sub.vue +15 -0
- package/app/components/Ui/ContextMenu/SubContent.vue +55 -0
- package/app/components/Ui/ContextMenu/SubTrigger.vue +42 -0
- package/app/components/Ui/ContextMenu/Trigger.vue +12 -0
- package/app/components/Ui/Dialog/Close.vue +12 -0
- package/app/components/Ui/Dialog/Content.vue +79 -0
- package/app/components/Ui/Dialog/Description.vue +29 -0
- package/app/components/Ui/Dialog/Dialog.vue +14 -0
- package/app/components/Ui/Dialog/Footer.vue +32 -0
- package/app/components/Ui/Dialog/Header.vue +32 -0
- package/app/components/Ui/Dialog/Overlay.vue +25 -0
- package/app/components/Ui/Dialog/Portal.vue +12 -0
- package/app/components/Ui/Dialog/Title.vue +29 -0
- package/app/components/Ui/Dialog/Trigger.vue +12 -0
- package/app/components/Ui/Divider.vue +102 -0
- package/app/components/Ui/Drawer/Close.vue +12 -0
- package/app/components/Ui/Drawer/Content.vue +67 -0
- package/app/components/Ui/Drawer/Description.vue +33 -0
- package/app/components/Ui/Drawer/Drawer.vue +17 -0
- package/app/components/Ui/Drawer/Footer.vue +35 -0
- package/app/components/Ui/Drawer/Header.vue +34 -0
- package/app/components/Ui/Drawer/Overlay.vue +20 -0
- package/app/components/Ui/Drawer/Portal.vue +12 -0
- package/app/components/Ui/Drawer/Title.vue +35 -0
- package/app/components/Ui/Drawer/Trigger.vue +12 -0
- package/app/components/Ui/DropdownMenu/Arrow.vue +43 -0
- package/app/components/Ui/DropdownMenu/CheckboxItem.vue +41 -0
- package/app/components/Ui/DropdownMenu/Content.vue +56 -0
- package/app/components/Ui/DropdownMenu/DropdownMenu.vue +15 -0
- package/app/components/Ui/DropdownMenu/Group.vue +12 -0
- package/app/components/Ui/DropdownMenu/Item.vue +64 -0
- package/app/components/Ui/DropdownMenu/ItemIndicator.vue +32 -0
- package/app/components/Ui/DropdownMenu/Label.vue +34 -0
- package/app/components/Ui/DropdownMenu/Portal.vue +12 -0
- package/app/components/Ui/DropdownMenu/RadioGroup.vue +16 -0
- package/app/components/Ui/DropdownMenu/RadioItem.vue +40 -0
- package/app/components/Ui/DropdownMenu/Separator.vue +25 -0
- package/app/components/Ui/DropdownMenu/Shortcut.vue +44 -0
- package/app/components/Ui/DropdownMenu/Sub.vue +14 -0
- package/app/components/Ui/DropdownMenu/SubContent.vue +56 -0
- package/app/components/Ui/DropdownMenu/SubTrigger.vue +47 -0
- package/app/components/Ui/DropdownMenu/Trigger.vue +12 -0
- package/app/components/Ui/FancyIcon.vue +243 -0
- package/app/components/Ui/GradientDivider.vue +26 -0
- package/app/components/Ui/IframeLazy.vue +97 -0
- package/app/components/Ui/Input.vue +97 -0
- package/app/components/Ui/InputGroup/Addon.vue +66 -0
- package/app/components/Ui/InputGroup/Button.vue +50 -0
- package/app/components/Ui/InputGroup/Input.vue +25 -0
- package/app/components/Ui/InputGroup/InputGroup.vue +44 -0
- package/app/components/Ui/InputGroup/Text.vue +33 -0
- package/app/components/Ui/InputGroup/Textarea.vue +25 -0
- package/app/components/Ui/Kbd/Group.vue +32 -0
- package/app/components/Ui/Kbd/Kbd.vue +62 -0
- package/app/components/Ui/Label.vue +40 -0
- package/app/components/Ui/Popover/Anchor.vue +13 -0
- package/app/components/Ui/Popover/Arrow.vue +42 -0
- package/app/components/Ui/Popover/Close.vue +13 -0
- package/app/components/Ui/Popover/Content.vue +55 -0
- package/app/components/Ui/Popover/Popover.vue +15 -0
- package/app/components/Ui/Popover/Portal.vue +13 -0
- package/app/components/Ui/Popover/Trigger.vue +12 -0
- package/app/components/Ui/Popover/X.vue +38 -0
- package/app/components/Ui/ScrollArea/Corner.vue +12 -0
- package/app/components/Ui/ScrollArea/ScrollArea.vue +38 -0
- package/app/components/Ui/ScrollArea/Scrollbar.vue +39 -0
- package/app/components/Ui/ScrollArea/Thumb.vue +39 -0
- package/app/components/Ui/ScrollArea/Viewport.vue +27 -0
- package/app/components/Ui/Scrollspy.vue +61 -0
- package/app/components/Ui/Separator.vue +40 -0
- package/app/components/Ui/Skeleton.vue +39 -0
- package/app/components/Ui/Sonner.vue +25 -0
- package/app/components/Ui/Tabs/Content.vue +27 -0
- package/app/components/Ui/Tabs/Indicator.vue +37 -0
- package/app/components/Ui/Tabs/List.vue +37 -0
- package/app/components/Ui/Tabs/Tabs.vue +25 -0
- package/app/components/Ui/Tabs/Trigger.vue +41 -0
- package/app/components/Ui/Textarea.vue +81 -0
- package/app/components/Ui/Tooltip/Arrow.vue +30 -0
- package/app/components/Ui/Tooltip/Content.vue +50 -0
- package/app/components/Ui/Tooltip/Portal.vue +12 -0
- package/app/components/Ui/Tooltip/Provider.vue +14 -0
- package/app/components/Ui/Tooltip/Tooltip.vue +25 -0
- package/app/components/Ui/Tooltip/Trigger.vue +12 -0
- package/app/components/Ui/Tree/Item.vue +15 -0
- package/app/components/Ui/Tree/Tree.vue +15 -0
- package/app/components/Ui/Tree/Virtualizer.vue +13 -0
- package/app/components/component-api/ComponentApiSection.vue +135 -0
- package/app/components/content/docs/Callout/DocsCallout.vue +99 -0
- package/app/components/content/prose/ProseA.global.vue +31 -0
- package/app/components/content/prose/ProseBlockquote.global.vue +28 -0
- package/app/components/content/prose/ProseCallout.global.vue +306 -0
- package/app/components/content/prose/ProseCard.global.vue +100 -0
- package/app/components/content/prose/ProseCodeCollapse.global.vue +125 -0
- package/app/components/content/prose/ProseCodeCopy.global.vue +67 -0
- package/app/components/content/prose/ProseCodeGroup.global.vue +104 -0
- package/app/components/content/prose/ProseCodeTree.global.vue +277 -0
- package/app/components/content/prose/ProseCollapsible.global.vue +64 -0
- package/app/components/content/prose/ProseColorModeImage.global.vue +58 -0
- package/app/components/content/prose/ProseComponentApi.global.vue +104 -0
- package/app/components/content/prose/ProseComponentEvents.global.vue +27 -0
- package/app/components/content/prose/ProseComponentExposed.global.vue +27 -0
- package/app/components/content/prose/ProseComponentProps.global.vue +27 -0
- package/app/components/content/prose/ProseComponentSlots.global.vue +27 -0
- package/app/components/content/prose/ProseEm.global.vue +5 -0
- package/app/components/content/prose/ProseField.global.vue +118 -0
- package/app/components/content/prose/ProseFieldGroup.global.vue +62 -0
- package/app/components/content/prose/ProseH1.global.vue +58 -0
- package/app/components/content/prose/ProseH2.global.vue +58 -0
- package/app/components/content/prose/ProseH3.global.vue +58 -0
- package/app/components/content/prose/ProseH4.global.vue +58 -0
- package/app/components/content/prose/ProseH5.global.vue +47 -0
- package/app/components/content/prose/ProseH6.global.vue +47 -0
- package/app/components/content/prose/ProseHr.global.vue +33 -0
- package/app/components/content/prose/ProseIconList.global.vue +113 -0
- package/app/components/content/prose/ProseImg.global.vue +119 -0
- package/app/components/content/prose/ProseLead.global.vue +28 -0
- package/app/components/content/prose/ProseLi.global.vue +25 -0
- package/app/components/content/prose/ProseMermaid.global.vue +127 -0
- package/app/components/content/prose/ProseOl.global.vue +25 -0
- package/app/components/content/prose/ProseP.global.vue +25 -0
- package/app/components/content/prose/ProsePmInstall.global.vue +60 -0
- package/app/components/content/prose/ProsePmRun.global.vue +51 -0
- package/app/components/content/prose/ProsePmX.global.vue +56 -0
- package/app/components/content/prose/ProsePre.global.vue +181 -0
- package/app/components/content/prose/ProseShowCase.global.vue +56 -0
- package/app/components/content/prose/ProseSmartIcon.global.vue +54 -0
- package/app/components/content/prose/ProseStep.global.vue +22 -0
- package/app/components/content/prose/ProseSteps.global.vue +22 -0
- package/app/components/content/prose/ProseStrong.global.vue +34 -0
- package/app/components/content/prose/ProseTable.global.vue +34 -0
- package/app/components/content/prose/ProseTabs.global.vue +104 -0
- package/app/components/content/prose/ProseTabsInner.global.vue +274 -0
- package/app/components/content/prose/ProseTbody.global.vue +5 -0
- package/app/components/content/prose/ProseTd.global.vue +25 -0
- package/app/components/content/prose/ProseTh.global.vue +25 -0
- package/app/components/content/prose/ProseThead.global.vue +9 -0
- package/app/components/content/prose/ProseTr.global.vue +35 -0
- package/app/components/content/prose/ProseUl.global.vue +25 -0
- package/app/components/docs/DocsExtraStuff.vue +39 -0
- package/app/components/docs/DocsGithubLink.vue +11 -0
- package/app/components/docs/DocsHeader.vue +3 -0
- package/app/components/docs/DocsLogo.vue +74 -0
- package/app/components/docs/DocsMobileBar.vue +26 -0
- package/app/components/docs/DocsMobileNav.vue +49 -0
- package/app/components/docs/DocsNav.vue +161 -0
- package/app/components/docs/DocsPageTransition.vue +32 -0
- package/app/components/docs/DocsSearch.vue +220 -0
- package/app/components/docs/DocsSearchButton.vue +20 -0
- package/app/components/docs/DocsThemeCustomizer.vue +229 -0
- package/app/components/docs/DocsThemeToggler.vue +98 -0
- package/app/components/docs/DocsTocRail.vue +162 -0
- package/app/components/docs/DocsToclink.vue +52 -0
- package/app/components/docs/DocsZigZagRail.vue +70 -0
- package/app/components/landing/Hero.vue +222 -0
- package/app/components/page/PageFooter.vue +49 -0
- package/app/components/page/PageHeader.vue +68 -0
- package/app/components/page/PageHeaderLinks.vue +138 -0
- package/app/components/page/PageMobileToc.vue +162 -0
- package/app/components/page/PageToc.vue +33 -0
- package/app/composables/useDefaultSlotItems.ts +90 -0
- package/app/composables/useDocPage.ts +66 -0
- package/app/composables/useDocSearch.ts +23 -0
- package/app/composables/useDocd.ts +107 -0
- package/app/composables/useLogoAssets.ts +319 -0
- package/app/composables/usePm.ts +73 -0
- package/app/composables/useProseComponentMeta.ts +30 -0
- package/app/composables/useScrollspy.ts +327 -0
- package/app/composables/useSeo.ts +240 -0
- package/app/composables/useUIConfig.ts +36 -0
- package/app/layouts/default.vue +5 -0
- package/app/layouts/docs.vue +64 -0
- package/app/middleware/colorMode.global.ts +8 -0
- package/app/middleware/doc-page-layout.ts +11 -0
- package/app/middleware/landing-page-layout.ts +11 -0
- package/app/pages/[...slug].vue +63 -0
- package/app/plugins/mermaid.client.ts +35 -0
- package/app/plugins/navigation-direction.client.ts +15 -0
- package/app/plugins/theme-restore.client.ts +7 -0
- package/app/templates/landing.vue +40 -0
- package/app/transitions/presets.ts +71 -0
- package/app/types/prose-component-meta.d.ts +4 -0
- package/app/utils/og.ts +26 -0
- package/app/utils/prerender.ts +9 -0
- package/app/utils/translucent.ts +56 -0
- package/app/utils/tw-helper.ts +4 -0
- package/content.config.ts +81 -0
- package/index.d.ts +25 -0
- package/modules/config.ts +89 -0
- package/modules/custom-icons.ts +17 -0
- package/modules/markdown-rewrite.ts +96 -0
- package/modules/prose-component-meta.ts +150 -0
- package/modules/routing.ts +22 -0
- package/modules/skills/index.ts +167 -0
- package/modules/skills/runtime/server/routes/skills-files.ts +49 -0
- package/modules/skills/runtime/server/routes/skills-index.ts +8 -0
- package/nuxt.config.ts +96 -0
- package/nuxt.schema.ts +288 -0
- package/package.json +95 -0
- package/server/mcp/tools/get-page.ts +66 -0
- package/server/mcp/tools/list-pages.ts +61 -0
- package/server/routes/sitemap.xml.ts +73 -0
- package/server/utils/content.ts +3 -0
- package/tailwind.config.cjs +55 -0
- package/utils/component-api-content.ts +467 -0
- package/utils/component-api-discovery.ts +165 -0
- package/utils/component-api-schema.ts +28 -0
- package/utils/component-api.ts +243 -0
- package/utils/generate-prose-component-meta.ts +303 -0
- package/utils/git.ts +123 -0
- package/utils/meta.ts +40 -0
- package/utils/pages.ts +21 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
role="list"
|
|
4
|
+
data-slot="prose-icon-list"
|
|
5
|
+
:class="proseIconListStyles().base({ class: normalizeClass(props.class) || undefined })"
|
|
6
|
+
>
|
|
7
|
+
<div
|
|
8
|
+
v-for="item in slottedItems"
|
|
9
|
+
:key="item.key ?? item.index"
|
|
10
|
+
role="listitem"
|
|
11
|
+
:class="proseIconListStyles().item()"
|
|
12
|
+
>
|
|
13
|
+
<Icon
|
|
14
|
+
v-if="item.meta.icon"
|
|
15
|
+
data-slot="icon"
|
|
16
|
+
:name="item.meta.icon"
|
|
17
|
+
:class="proseIconListStyles().icon({ variant: item.meta.variant })"
|
|
18
|
+
/>
|
|
19
|
+
<component :is="item.vnode" />
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script lang="ts">
|
|
25
|
+
import type { VariantProps } from "tailwind-variants";
|
|
26
|
+
import { normalizeClass } from "vue";
|
|
27
|
+
import type { HTMLAttributes } from "vue";
|
|
28
|
+
|
|
29
|
+
export type ProseIconListProps = {
|
|
30
|
+
/**
|
|
31
|
+
* Additional classes for the list element
|
|
32
|
+
*/
|
|
33
|
+
class?: HTMLAttributes["class"];
|
|
34
|
+
/**
|
|
35
|
+
* Default variant for all list items (can be overridden per item)
|
|
36
|
+
*/
|
|
37
|
+
variant?: VariantProps<typeof proseIconListStyles>["variant"];
|
|
38
|
+
/**
|
|
39
|
+
* Default icon for all list items (can be overridden per item)
|
|
40
|
+
*/
|
|
41
|
+
icon?: string;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
type ListItemMeta = {
|
|
45
|
+
icon: string;
|
|
46
|
+
variant?: VariantProps<typeof proseIconListStyles>["variant"];
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const proseIconListStyles = tv({
|
|
50
|
+
slots: {
|
|
51
|
+
base: "ml-4 flex list-none flex-col gap-3",
|
|
52
|
+
item: "flex items-start gap-2 *:my-0! *:leading-normal **:[[role=list]]:mt-2 **:[[role=list]]:mb-2 [&>svg]:mt-1! has-[>*_code]:[&>svg]:mt-1!",
|
|
53
|
+
icon: "mt-0.5 inline-block size-4 shrink-0",
|
|
54
|
+
},
|
|
55
|
+
variants: {
|
|
56
|
+
variant: {
|
|
57
|
+
success: {
|
|
58
|
+
icon: "text-emerald-500",
|
|
59
|
+
},
|
|
60
|
+
error: {
|
|
61
|
+
icon: "text-destructive",
|
|
62
|
+
},
|
|
63
|
+
warning: {
|
|
64
|
+
icon: "text-yellow-500",
|
|
65
|
+
},
|
|
66
|
+
info: {
|
|
67
|
+
icon: "text-blue-500",
|
|
68
|
+
},
|
|
69
|
+
default: {
|
|
70
|
+
icon: "text-muted-foreground",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
defaultVariants: {
|
|
75
|
+
variant: "default",
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<script setup lang="ts">
|
|
81
|
+
const props = defineProps<ProseIconListProps>();
|
|
82
|
+
|
|
83
|
+
function getDefaultIcon(variant?: ProseIconListProps["variant"]): string {
|
|
84
|
+
if (props.icon) return props.icon;
|
|
85
|
+
|
|
86
|
+
switch (variant ?? props.variant) {
|
|
87
|
+
case "success":
|
|
88
|
+
return "lucide:circle-check";
|
|
89
|
+
case "error":
|
|
90
|
+
return "lucide:circle-x";
|
|
91
|
+
case "warning":
|
|
92
|
+
return "lucide:triangle-alert";
|
|
93
|
+
case "info":
|
|
94
|
+
return "lucide:info";
|
|
95
|
+
default:
|
|
96
|
+
return "radix-icons:dot-filled";
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const { items: slottedItems } = useDefaultSlotItems<ListItemMeta>({
|
|
101
|
+
slots: useSlots(),
|
|
102
|
+
mapMeta({ props: itemProps }) {
|
|
103
|
+
// Each li can have its own icon and variant
|
|
104
|
+
const itemVariant = (itemProps.variant as ProseIconListProps["variant"]) ?? props.variant;
|
|
105
|
+
const itemIcon = (itemProps.icon as string) ?? getDefaultIcon(itemVariant);
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
icon: itemIcon,
|
|
109
|
+
variant: itemVariant,
|
|
110
|
+
};
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
</script>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<DefineImg>
|
|
3
|
+
<NuxtImg
|
|
4
|
+
:src="refinedSrc"
|
|
5
|
+
:alt
|
|
6
|
+
:width
|
|
7
|
+
:height
|
|
8
|
+
:class="proseImgStyles({ lifted, zoom, class: normalizeClass(props.class) || undefined })"
|
|
9
|
+
/>
|
|
10
|
+
</DefineImg>
|
|
11
|
+
|
|
12
|
+
<DialogRoot v-if="zoom">
|
|
13
|
+
<DialogTrigger class="block w-full">
|
|
14
|
+
<ReuseImg />
|
|
15
|
+
</DialogTrigger>
|
|
16
|
+
<DialogPortal>
|
|
17
|
+
<DialogOverlay
|
|
18
|
+
class="fixed inset-0 z-50 bg-background/80 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0"
|
|
19
|
+
/>
|
|
20
|
+
<DialogContent
|
|
21
|
+
class="fixed top-1/2 left-1/2 z-50 grid -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-0 shadow-lg duration-200 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 sm:rounded-lg"
|
|
22
|
+
>
|
|
23
|
+
<DialogTitle class="sr-only">{{ props.alt || "Image Preview" }}</DialogTitle>
|
|
24
|
+
<DialogDescription class="sr-only">{{ props.alt || "Image Preview" }}</DialogDescription>
|
|
25
|
+
<DialogClose>
|
|
26
|
+
<NuxtImg
|
|
27
|
+
:src="refinedSrc"
|
|
28
|
+
:alt
|
|
29
|
+
:width
|
|
30
|
+
:height
|
|
31
|
+
class="max-h-svh max-w-svw cursor-zoom-out md:rounded-lg"
|
|
32
|
+
/>
|
|
33
|
+
</DialogClose>
|
|
34
|
+
</DialogContent>
|
|
35
|
+
</DialogPortal>
|
|
36
|
+
</DialogRoot>
|
|
37
|
+
<ReuseImg v-else />
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<script lang="ts">
|
|
41
|
+
import {
|
|
42
|
+
DialogClose,
|
|
43
|
+
DialogContent,
|
|
44
|
+
DialogOverlay,
|
|
45
|
+
DialogPortal,
|
|
46
|
+
DialogRoot,
|
|
47
|
+
DialogTrigger,
|
|
48
|
+
} from "reka-ui";
|
|
49
|
+
import { joinURL, withLeadingSlash, withTrailingSlash } from "ufo";
|
|
50
|
+
import { normalizeClass } from "vue";
|
|
51
|
+
import type { HTMLAttributes } from "vue";
|
|
52
|
+
|
|
53
|
+
export type ProseImgProps = {
|
|
54
|
+
/**
|
|
55
|
+
* Image source URL
|
|
56
|
+
*/
|
|
57
|
+
src?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Alt text for the image
|
|
60
|
+
*/
|
|
61
|
+
alt?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Width of the image
|
|
64
|
+
* @default "100%"
|
|
65
|
+
*/
|
|
66
|
+
width?: string | number;
|
|
67
|
+
/**
|
|
68
|
+
* Height of the image
|
|
69
|
+
*/
|
|
70
|
+
height?: string | number;
|
|
71
|
+
/**
|
|
72
|
+
* Whether the image should have a lifted style
|
|
73
|
+
*/
|
|
74
|
+
lifted?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Whether the image should have zoom effect on hover
|
|
77
|
+
* @default true
|
|
78
|
+
*/
|
|
79
|
+
zoom?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Additional CSS classes for the image element
|
|
82
|
+
*/
|
|
83
|
+
class?: HTMLAttributes["class"];
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const proseImgStyles = tv({
|
|
87
|
+
base: "w-full rounded-md object-cover",
|
|
88
|
+
variants: {
|
|
89
|
+
lifted: {
|
|
90
|
+
true: "rounded-lg border bg-card text-card-foreground shadow-xs",
|
|
91
|
+
},
|
|
92
|
+
zoom: {
|
|
93
|
+
true: "cursor-zoom-in",
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
defaultVariants: {
|
|
97
|
+
lifted: false,
|
|
98
|
+
zoom: true,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
</script>
|
|
102
|
+
|
|
103
|
+
<script lang="ts" setup>
|
|
104
|
+
const props = withDefaults(defineProps<ProseImgProps>(), {
|
|
105
|
+
lifted: false,
|
|
106
|
+
zoom: true,
|
|
107
|
+
width: "100%",
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const [DefineImg, ReuseImg] = createReusableTemplate();
|
|
111
|
+
|
|
112
|
+
const refinedSrc = computed(() => {
|
|
113
|
+
if (props.src?.startsWith("/") && !props.src.startsWith("//")) {
|
|
114
|
+
const _base = withLeadingSlash(withTrailingSlash(useRuntimeConfig().app.baseURL));
|
|
115
|
+
if (_base !== "/" && !props.src.startsWith(_base)) return joinURL(_base, props.src);
|
|
116
|
+
}
|
|
117
|
+
return props.src;
|
|
118
|
+
});
|
|
119
|
+
</script>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<p
|
|
3
|
+
data-slot="prose-lead"
|
|
4
|
+
:class="proseLeadStyles({ class: normalizeClass(_class) || undefined })"
|
|
5
|
+
>
|
|
6
|
+
<slot />
|
|
7
|
+
</p>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script lang="ts">
|
|
11
|
+
import { normalizeClass } from "vue";
|
|
12
|
+
import type { HTMLAttributes } from "vue";
|
|
13
|
+
|
|
14
|
+
export type ProseLeadProps = {
|
|
15
|
+
/**
|
|
16
|
+
* Additional classes for the parent element
|
|
17
|
+
*/
|
|
18
|
+
class?: HTMLAttributes["class"];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const proseLeadStyles = tv({
|
|
22
|
+
base: "text-xl leading-7 text-pretty text-muted-foreground not-first:mt-6",
|
|
23
|
+
});
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<script setup lang="ts">
|
|
27
|
+
const { class: _class } = defineProps<ProseLeadProps>();
|
|
28
|
+
</script>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<li data-slot="prose-li" :class="proseLiStyles({ class: normalizeClass(_class) || undefined })">
|
|
3
|
+
<slot mdc-unwrap="p" />
|
|
4
|
+
</li>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import { normalizeClass } from "vue";
|
|
9
|
+
import type { HTMLAttributes } from "vue";
|
|
10
|
+
|
|
11
|
+
export type ProseListItemProps = {
|
|
12
|
+
/**
|
|
13
|
+
* Additional classes for the parent element
|
|
14
|
+
*/
|
|
15
|
+
class?: HTMLAttributes["class"];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const proseLiStyles = tv({
|
|
19
|
+
base: "text-pretty [&>ol]:mt-2! [&>ul]:mt-2!",
|
|
20
|
+
});
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script setup lang="ts">
|
|
24
|
+
const { class: _class } = defineProps<ProseListItemProps>();
|
|
25
|
+
</script>
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ProseCallout v-if="error" variant="error" title="Mermaid Chart Error" :description="error" />
|
|
3
|
+
<div v-else class="rounded-lg p-4 text-card-foreground not-first:mt-5 not-last:mb-5">
|
|
4
|
+
<div v-if="loading" class="flex items-center justify-center">
|
|
5
|
+
<div class="flex flex-col items-center gap-2 p-4">
|
|
6
|
+
<Icon name="lucide:loader-circle" class="size-6! animate-spin" />
|
|
7
|
+
<span class="text-sm text-muted-foreground">Rendering Chart</span>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
<div
|
|
11
|
+
ref="mermaidContainer"
|
|
12
|
+
class="flex justify-center overflow-x-auto transition-all"
|
|
13
|
+
v-html="svgContent"
|
|
14
|
+
/>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script setup lang="ts">
|
|
19
|
+
const props = defineProps<{
|
|
20
|
+
/** The Mermaid diagram definition code */
|
|
21
|
+
code?: string;
|
|
22
|
+
}>();
|
|
23
|
+
|
|
24
|
+
const mermaidContainer = useTemplateRef("mermaidContainer");
|
|
25
|
+
const svgContent = ref<string>("");
|
|
26
|
+
const error = ref<string | null>(null);
|
|
27
|
+
const loading = ref(true);
|
|
28
|
+
const hasRenderedOnce = ref(false);
|
|
29
|
+
const mermaidDefinition = ref("");
|
|
30
|
+
|
|
31
|
+
const colorMode = useColorMode();
|
|
32
|
+
const { $mermaidInstance, $mermaidInitConfig } = useNuxtApp();
|
|
33
|
+
const slots = useSlots();
|
|
34
|
+
|
|
35
|
+
const mermaidTheme = computed(() => (colorMode.value === "dark" ? "dark" : "default"));
|
|
36
|
+
// Generate unique IDs
|
|
37
|
+
const uniqueId = `mermaid-${Math.random().toString(36).substring(2, 9)}`;
|
|
38
|
+
/**
|
|
39
|
+
* Renders the Mermaid diagram with the current theme and configuration
|
|
40
|
+
*/
|
|
41
|
+
async function renderMermaid() {
|
|
42
|
+
if (!$mermaidInstance) {
|
|
43
|
+
error.value = "Mermaid instance not initialized";
|
|
44
|
+
loading.value = false;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
loading.value = true;
|
|
50
|
+
error.value = null;
|
|
51
|
+
|
|
52
|
+
// Get diagram definition from props or slot content
|
|
53
|
+
mermaidDefinition.value =
|
|
54
|
+
props.code?.trim() ||
|
|
55
|
+
slots
|
|
56
|
+
.default?.()
|
|
57
|
+
.map((vnode) => vnode.children)
|
|
58
|
+
.join("")
|
|
59
|
+
.trim() ||
|
|
60
|
+
"";
|
|
61
|
+
|
|
62
|
+
if (!mermaidDefinition.value) {
|
|
63
|
+
error.value = "No Mermaid definition provided";
|
|
64
|
+
loading.value = false;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Initialize Mermaid with current theme
|
|
69
|
+
$mermaidInstance.initialize({
|
|
70
|
+
...$mermaidInitConfig,
|
|
71
|
+
theme: mermaidTheme.value,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
await nextTick();
|
|
75
|
+
|
|
76
|
+
// Render the diagram with a unique ID
|
|
77
|
+
const { svg } = await $mermaidInstance.render(`mermaid-${uniqueId}`, mermaidDefinition.value);
|
|
78
|
+
|
|
79
|
+
svgContent.value = svg;
|
|
80
|
+
hasRenderedOnce.value = true;
|
|
81
|
+
} catch (e) {
|
|
82
|
+
console.error("Error rendering Mermaid chart:", e);
|
|
83
|
+
error.value = (e as any)?.message || String(e);
|
|
84
|
+
} finally {
|
|
85
|
+
loading.value = false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
useIntersectionObserver(
|
|
90
|
+
mermaidContainer,
|
|
91
|
+
([entry]) => {
|
|
92
|
+
if (entry?.isIntersecting && !hasRenderedOnce.value) {
|
|
93
|
+
renderMermaid();
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{ threshold: 0.1 }
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// Re-render when theme changes (only if already rendered once)
|
|
100
|
+
watch(mermaidTheme, () => {
|
|
101
|
+
if (hasRenderedOnce.value) {
|
|
102
|
+
renderMermaid();
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Re-render when code prop changes (only if already rendered once)
|
|
107
|
+
watch(
|
|
108
|
+
() => props.code,
|
|
109
|
+
() => {
|
|
110
|
+
if (hasRenderedOnce.value) {
|
|
111
|
+
renderMermaid();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const emit = defineEmits<{
|
|
117
|
+
mermaidError: [payload?: string];
|
|
118
|
+
}>();
|
|
119
|
+
|
|
120
|
+
// Watch error and emit event
|
|
121
|
+
watch(error, (newError) => {
|
|
122
|
+
if (newError) {
|
|
123
|
+
// Emit an event or handle the error as needed
|
|
124
|
+
emit("mermaidError", newError);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
</script>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<ol data-slot="prose-ol" :class="proseOlStyles({ class: normalizeClass(_class) || undefined })">
|
|
3
|
+
<slot mdc-unwrap="p" />
|
|
4
|
+
</ol>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import { normalizeClass } from "vue";
|
|
9
|
+
import type { HTMLAttributes } from "vue";
|
|
10
|
+
|
|
11
|
+
export type ProseOlProps = {
|
|
12
|
+
/**
|
|
13
|
+
* Additional classes for the parent element
|
|
14
|
+
*/
|
|
15
|
+
class?: HTMLAttributes["class"];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const proseOlStyles = tv({
|
|
19
|
+
base: "ml-4 list-decimal not-first:mt-6 not-last:mb-6 [&>li:not(:first-child)]:mt-2",
|
|
20
|
+
});
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script setup lang="ts">
|
|
24
|
+
const { class: _class } = defineProps<ProseOlProps>();
|
|
25
|
+
</script>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<p data-slot="prose-p" :class="prosePStyles({ class: normalizeClass(_class) || undefined })">
|
|
3
|
+
<slot />
|
|
4
|
+
</p>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import { normalizeClass } from "vue";
|
|
9
|
+
import type { HTMLAttributes } from "vue";
|
|
10
|
+
|
|
11
|
+
export type ProsePProps = {
|
|
12
|
+
/**
|
|
13
|
+
* Additional classes for the parent element
|
|
14
|
+
*/
|
|
15
|
+
class?: HTMLAttributes["class"];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const prosePStyles = tv({
|
|
19
|
+
base: "leading-7 text-pretty not-first:mt-6",
|
|
20
|
+
});
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script setup lang="ts">
|
|
24
|
+
const { class: _class } = defineProps<ProsePProps>();
|
|
25
|
+
</script>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<MDC v-if="md" unwrap="p" :value="md" class="not-first:mt-5" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
const props = withDefaults(
|
|
7
|
+
defineProps<{
|
|
8
|
+
/**
|
|
9
|
+
* Whether to render in a stack layout
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
inStack?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Package name to install
|
|
15
|
+
*/
|
|
16
|
+
name?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Sync identifier for syncing with other code groups
|
|
19
|
+
* @default "_pm"
|
|
20
|
+
*/
|
|
21
|
+
sync?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Add --save-dev flag for dev dependencies
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
saveDev?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Disable syncing between code groups
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
noSync?: boolean;
|
|
32
|
+
}>(),
|
|
33
|
+
{
|
|
34
|
+
inStack: false,
|
|
35
|
+
sync: "_pm",
|
|
36
|
+
saveDev: false,
|
|
37
|
+
noSync: false,
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const { packageManagers } = usePm();
|
|
42
|
+
|
|
43
|
+
const md = computed(() => {
|
|
44
|
+
const codeBlocks = packageManagers
|
|
45
|
+
.map((pm) => {
|
|
46
|
+
const command = props.name
|
|
47
|
+
? `${pm.command}${pm.install}${props.saveDev ? pm.saveDev : ""}${props.name}`
|
|
48
|
+
: `${pm.command}${pm.installEmpty}`;
|
|
49
|
+
|
|
50
|
+
return `\`\`\`bash icon="${pm.icon}" noFormat hideHeader [${pm.name}]\n${command}\n\`\`\``;
|
|
51
|
+
})
|
|
52
|
+
.join("\n\n");
|
|
53
|
+
|
|
54
|
+
const attributes = [props.inStack && "in-stack", !props.noSync && `sync="${props.sync}"`]
|
|
55
|
+
.filter(Boolean)
|
|
56
|
+
.join(" ");
|
|
57
|
+
|
|
58
|
+
return `::prose-code-group${attributes ? `{${attributes}}` : ""}\n${codeBlocks}\n::`;
|
|
59
|
+
});
|
|
60
|
+
</script>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<MDC v-if="md" unwrap="p" :value="md" class="not-first:mt-5" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
const props = withDefaults(
|
|
7
|
+
defineProps<{
|
|
8
|
+
/**
|
|
9
|
+
* Whether to render in a stack layout
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
inStack?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Script name to run (e.g., "dev", "build", "test")
|
|
15
|
+
*/
|
|
16
|
+
script: string;
|
|
17
|
+
/**
|
|
18
|
+
* Sync identifier for syncing with other code groups
|
|
19
|
+
* @default "_pm"
|
|
20
|
+
*/
|
|
21
|
+
sync?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Disable syncing between code groups
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
noSync?: boolean;
|
|
27
|
+
}>(),
|
|
28
|
+
{
|
|
29
|
+
inStack: false,
|
|
30
|
+
sync: "_pm",
|
|
31
|
+
noSync: false,
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const { packageManagers } = usePm();
|
|
36
|
+
|
|
37
|
+
const md = computed(() => {
|
|
38
|
+
const codeBlocks = packageManagers
|
|
39
|
+
.map((pm) => {
|
|
40
|
+
const command = `${pm.command}${pm.run}${props.script}`;
|
|
41
|
+
return `\`\`\`bash icon="${pm.icon}" noFormat hideHeader [${pm.name}]\n${command}\n\`\`\``;
|
|
42
|
+
})
|
|
43
|
+
.join("\n\n");
|
|
44
|
+
|
|
45
|
+
const attributes = [props.inStack && "in-stack", !props.noSync && `sync="${props.sync}"`]
|
|
46
|
+
.filter(Boolean)
|
|
47
|
+
.join(" ");
|
|
48
|
+
|
|
49
|
+
return `::prose-code-group${attributes ? `{${attributes}}` : ""}\n${codeBlocks}\n::`;
|
|
50
|
+
});
|
|
51
|
+
</script>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<MDC unwrap="p" :value="md" class="not-first:mt-5" v-if="md" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
const props = withDefaults(
|
|
7
|
+
defineProps<{
|
|
8
|
+
/**
|
|
9
|
+
* Whether to render in a stack layout
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
inStack?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Command to execute (e.g., "create-vue@latest", "nuxi init")
|
|
15
|
+
*/
|
|
16
|
+
command: string;
|
|
17
|
+
/**
|
|
18
|
+
* Sync identifier for syncing with other code groups
|
|
19
|
+
* @default "_pm"
|
|
20
|
+
*/
|
|
21
|
+
sync?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Disable syncing between code groups
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
noSync?: boolean;
|
|
27
|
+
}>(),
|
|
28
|
+
{
|
|
29
|
+
inStack: false,
|
|
30
|
+
sync: "_pm",
|
|
31
|
+
noSync: false,
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const { packageManagers } = usePm();
|
|
36
|
+
|
|
37
|
+
const md = computed(() => {
|
|
38
|
+
const codeBlocks = packageManagers
|
|
39
|
+
.map((pm) => {
|
|
40
|
+
const command = `${pm.x}${props.command}`;
|
|
41
|
+
return `\`\`\`bash icon="${pm.icon}" noFormat hideHeader [${pm.name}]\n${command}\n\`\`\``;
|
|
42
|
+
})
|
|
43
|
+
.join("\n\n");
|
|
44
|
+
|
|
45
|
+
const attributes = [
|
|
46
|
+
props.inStack && "in-stack",
|
|
47
|
+
!props.noSync && `sync="${props.sync}"`,
|
|
48
|
+
`noFormat`,
|
|
49
|
+
"hideHeaderMeta",
|
|
50
|
+
]
|
|
51
|
+
.filter(Boolean)
|
|
52
|
+
.join(" ");
|
|
53
|
+
|
|
54
|
+
return `::prose-code-group${attributes ? `{${attributes}}` : ""}\n${codeBlocks}\n::`;
|
|
55
|
+
});
|
|
56
|
+
</script>
|