undocs 0.4.14 → 0.4.16
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 +46 -46
- package/app/app.vue +22 -20
- package/app/assets/main.css +1 -1
- package/app/components/AppFooter.vue +1 -1
- package/app/components/AppFooterNotes.vue +2 -2
- package/app/components/AppFooterNotesBase.vue +1 -1
- package/app/components/AppHeader.vue +22 -24
- package/app/components/AppHeaderVersionsMenu.vue +12 -10
- package/app/components/DocsCollapsable.vue +11 -11
- package/app/components/IconMenuToggle.vue +9 -9
- package/app/components/LandingBackground.vue +13 -9
- package/app/components/PageHeaderLinks.vue +27 -22
- package/app/components/SocialButtons.vue +9 -9
- package/app/components/color-picker/ColorPicker.vue +30 -23
- package/app/components/color-picker/ColorPickerPill.vue +2 -2
- package/app/components/global/Mermaid.vue +2 -2
- package/app/components/global/Pm-Install.vue +6 -4
- package/app/components/global/Pm-Run.vue +6 -4
- package/app/components/global/Pm-x.vue +6 -4
- package/app/components/global/ReadMore.vue +13 -13
- package/app/components/page/PageContributors.vue +2 -2
- package/app/components/page/PageSponsors.vue +21 -5
- package/app/composables/useContributors.ts +10 -10
- package/app/composables/useDocsNav.ts +15 -13
- package/app/composables/useMermaid.ts +17 -17
- package/app/composables/usePageSEO.ts +24 -24
- package/app/composables/useSponsors.ts +9 -9
- package/app/content.config.ts +5 -5
- package/app/error.vue +14 -12
- package/app/layouts/docs.vue +1 -1
- package/app/modules/content/hooks.ts +149 -131
- package/app/modules/content/icons.ts +15 -15
- package/app/modules/content/index.ts +12 -12
- package/app/modules/css.ts +20 -17
- package/app/modules/md-rewrite.ts +110 -29
- package/app/modules/og-image/index.ts +18 -18
- package/app/modules/og-image/runtime/handler.ts +71 -67
- package/app/modules/theme.ts +11 -11
- package/app/nuxt.config.ts +22 -22
- package/app/pages/[...slug].vue +29 -29
- package/app/pages/blog/[...slug].vue +14 -11
- package/app/pages/blog/index.vue +15 -11
- package/app/pages/index.vue +40 -36
- package/app/server/routes/raw/[...slug].md.get.ts +15 -15
- package/app/utils/numbers.ts +5 -5
- package/app/utils/pm.ts +6 -6
- package/app/utils/title.ts +5 -5
- package/cli/cli.mjs +41 -41
- package/cli/main.mjs +7 -7
- package/cli/setup.mjs +64 -64
- package/package.json +19 -24
- package/schema/config.d.ts +33 -33
- package/schema/config.json +9 -1
- package/schema/config.schema.ts +2 -2
package/app/app.config.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default defineAppConfig({
|
|
2
2
|
docs: {
|
|
3
|
-
socialBackground:
|
|
4
|
-
logo:
|
|
3
|
+
socialBackground: "https://github.com/unjs/undocs/blob/main/assets/ellipse.png?raw=true",
|
|
4
|
+
logo: "/icon.svg",
|
|
5
5
|
github: undefined,
|
|
6
6
|
socials: {},
|
|
7
7
|
banner: {},
|
|
@@ -10,54 +10,54 @@ export default defineAppConfig({
|
|
|
10
10
|
ui: {
|
|
11
11
|
colors: {
|
|
12
12
|
// primary: 'amber', // set in setup.mjs
|
|
13
|
-
important:
|
|
14
|
-
neutral:
|
|
13
|
+
important: "violet",
|
|
14
|
+
neutral: "neutral",
|
|
15
15
|
},
|
|
16
16
|
prose: {
|
|
17
17
|
codeIcon: {
|
|
18
|
-
|
|
18
|
+
".config": "vscode-icons:file-type-config",
|
|
19
19
|
// '.plugin': 'vscode-icons:file-type-plugin',
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
ts:
|
|
43
|
-
tsx:
|
|
44
|
-
mjs:
|
|
45
|
-
cjs:
|
|
46
|
-
js:
|
|
47
|
-
jsx:
|
|
48
|
-
md:
|
|
49
|
-
py:
|
|
50
|
-
ico:
|
|
51
|
-
npm:
|
|
52
|
-
pnpm:
|
|
53
|
-
npx:
|
|
54
|
-
yarn:
|
|
55
|
-
bun:
|
|
56
|
-
node:
|
|
57
|
-
deno:
|
|
58
|
-
yml:
|
|
59
|
-
terminal:
|
|
20
|
+
"package.json": "vscode-icons:file-type-node",
|
|
21
|
+
"tsconfig.json": "vscode-icons:file-type-tsconfig",
|
|
22
|
+
".npmrc": "vscode-icons:file-type-npm",
|
|
23
|
+
".editorconfig": "vscode-icons:file-type-editorconfig",
|
|
24
|
+
".eslintrc": "vscode-icons:file-type-eslint",
|
|
25
|
+
".eslintrc.cjs": "vscode-icons:file-type-eslint",
|
|
26
|
+
".eslintignore": "vscode-icons:file-type-eslint",
|
|
27
|
+
".gitignore": "vscode-icons:file-type-git",
|
|
28
|
+
"yarn.lock": "vscode-icons:file-type-yarn",
|
|
29
|
+
".env": "vscode-icons:file-type-dotenv",
|
|
30
|
+
".env.example": "vscode-icons:file-type-dotenv",
|
|
31
|
+
".vscode/settings.json": "vscode-icons:file-type-vscode",
|
|
32
|
+
".nuxtrc": "vscode-icons:file-type-nuxt",
|
|
33
|
+
".nuxtignore": "vscode-icons:file-type-nuxt",
|
|
34
|
+
"nuxt.config.ts": "vscode-icons:file-type-nuxt",
|
|
35
|
+
"nuxt.schema.ts": "vscode-icons:file-type-nuxt",
|
|
36
|
+
"nitro.config.ts": "i-undocs-nitro",
|
|
37
|
+
"vite.config.js": "i-logos-vitejs",
|
|
38
|
+
"vite.config.mjs": "i-logos-vitejs",
|
|
39
|
+
"vite.config.ts": "i-logos-vitejs",
|
|
40
|
+
"tailwind.config.js": "vscode-icons:file-type-tailwind",
|
|
41
|
+
"tailwind.config.ts": "vscode-icons:file-type-tailwind",
|
|
42
|
+
ts: "vscode-icons:file-type-typescript",
|
|
43
|
+
tsx: "vscode-icons:file-type-typescript",
|
|
44
|
+
mjs: "vscode-icons:file-type-js",
|
|
45
|
+
cjs: "vscode-icons:file-type-js",
|
|
46
|
+
js: "vscode-icons:file-type-js",
|
|
47
|
+
jsx: "vscode-icons:file-type-js",
|
|
48
|
+
md: "vscode-icons:file-type-markdown",
|
|
49
|
+
py: "vscode-icons:file-type-python",
|
|
50
|
+
ico: "vscode-icons:file-type-favicon",
|
|
51
|
+
npm: "vscode-icons:file-type-npm",
|
|
52
|
+
pnpm: "vscode-icons:file-type-pnpm",
|
|
53
|
+
npx: "vscode-icons:file-type-npm",
|
|
54
|
+
yarn: "vscode-icons:file-type-yarn",
|
|
55
|
+
bun: "vscode-icons:file-type-bun",
|
|
56
|
+
node: "vscode-icons:file-type-node",
|
|
57
|
+
deno: "vscode-icons:file-type-deno",
|
|
58
|
+
yml: "vscode-icons:file-type-yaml",
|
|
59
|
+
terminal: "i-heroicons-command-line",
|
|
60
60
|
},
|
|
61
61
|
},
|
|
62
62
|
},
|
|
63
|
-
})
|
|
63
|
+
});
|
package/app/app.vue
CHANGED
|
@@ -1,54 +1,56 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type { BannerProps } from
|
|
2
|
+
import type { BannerProps } from "@nuxt/ui";
|
|
3
3
|
|
|
4
|
-
const appConfig = useAppConfig()
|
|
4
|
+
const appConfig = useAppConfig();
|
|
5
5
|
|
|
6
|
-
const { data: navigation } = await useAsyncData(
|
|
7
|
-
|
|
6
|
+
const { data: navigation } = await useAsyncData("navigation", () =>
|
|
7
|
+
queryCollectionNavigation("content"),
|
|
8
|
+
);
|
|
9
|
+
const { data: files } = useLazyAsyncData("search", () => queryCollectionSearchSections("content"), {
|
|
8
10
|
server: false,
|
|
9
|
-
})
|
|
11
|
+
});
|
|
10
12
|
|
|
11
|
-
const twitterSite = appConfig.docs.socials?.twitter || appConfig.docs.socials?.x || undefined
|
|
12
|
-
const browserTabIcon = appConfig.docs?.logo || undefined
|
|
13
|
+
const twitterSite = appConfig.docs.socials?.twitter || appConfig.docs.socials?.x || undefined;
|
|
14
|
+
const browserTabIcon = appConfig.docs?.logo || undefined;
|
|
13
15
|
|
|
14
16
|
useSeoMeta({
|
|
15
17
|
twitterSite: twitterSite ? `@${twitterSite}` : undefined,
|
|
16
|
-
})
|
|
18
|
+
});
|
|
17
19
|
|
|
18
20
|
useHead({
|
|
19
21
|
htmlAttrs: {
|
|
20
|
-
lang: appConfig.docs.lang ||
|
|
22
|
+
lang: appConfig.docs.lang || "en",
|
|
21
23
|
},
|
|
22
24
|
link: [
|
|
23
25
|
{
|
|
24
|
-
rel:
|
|
26
|
+
rel: "icon",
|
|
25
27
|
href: browserTabIcon,
|
|
26
28
|
},
|
|
27
29
|
],
|
|
28
|
-
})
|
|
30
|
+
});
|
|
29
31
|
|
|
30
|
-
const route = useRoute()
|
|
32
|
+
const route = useRoute();
|
|
31
33
|
|
|
32
34
|
onMounted(() => {
|
|
33
35
|
watch(
|
|
34
36
|
route,
|
|
35
37
|
() => {
|
|
36
|
-
const hash = window.location.hash
|
|
38
|
+
const hash = window.location.hash;
|
|
37
39
|
if (hash) {
|
|
38
|
-
let attempts = 0
|
|
40
|
+
let attempts = 0;
|
|
39
41
|
const interval = setInterval(() => {
|
|
40
|
-
document.querySelector(hash)?.scrollIntoView()
|
|
42
|
+
document.querySelector(hash)?.scrollIntoView();
|
|
41
43
|
if (attempts++ > 5) {
|
|
42
|
-
clearInterval(interval)
|
|
44
|
+
clearInterval(interval);
|
|
43
45
|
}
|
|
44
|
-
}, 100)
|
|
46
|
+
}, 100);
|
|
45
47
|
}
|
|
46
48
|
},
|
|
47
49
|
{ immediate: true },
|
|
48
|
-
)
|
|
49
|
-
})
|
|
50
|
+
);
|
|
51
|
+
});
|
|
50
52
|
|
|
51
|
-
provide(
|
|
53
|
+
provide("navigation", navigation);
|
|
52
54
|
</script>
|
|
53
55
|
|
|
54
56
|
<template>
|
package/app/assets/main.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
const appConfig = useAppConfig()
|
|
2
|
+
const appConfig = useAppConfig();
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
<template>
|
|
@@ -12,7 +12,7 @@ const appConfig = useAppConfig()
|
|
|
12
12
|
>{{ appConfig.site.name }}
|
|
13
13
|
</NuxtLink>
|
|
14
14
|
</span>
|
|
15
|
-
<span class="text-muted">{{ appConfig.docs.shortDescription.replace(/\.$/,
|
|
15
|
+
<span class="text-muted">{{ appConfig.docs.shortDescription.replace(/\.$/, "") }}</span
|
|
16
16
|
>.
|
|
17
17
|
</p>
|
|
18
18
|
</template>
|
|
@@ -1,42 +1,40 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
const appConfig = useAppConfig()
|
|
3
|
-
const docsNav = useDocsNav()
|
|
2
|
+
const appConfig = useAppConfig();
|
|
3
|
+
const docsNav = useDocsNav();
|
|
4
4
|
|
|
5
|
-
const navigation = inject(
|
|
5
|
+
const navigation = inject("navigation");
|
|
6
6
|
|
|
7
7
|
const headerLinks = computed(() => {
|
|
8
|
-
return
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
]
|
|
20
|
-
})
|
|
8
|
+
return docsNav.links
|
|
9
|
+
.filter((link) => link.hasIndex)
|
|
10
|
+
.map((link) => {
|
|
11
|
+
return {
|
|
12
|
+
...link,
|
|
13
|
+
children: undefined,
|
|
14
|
+
icon: "",
|
|
15
|
+
// children: link.children?.filter((child) => !child.children || child.children.some((c) => c.to === child.to)),
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
});
|
|
21
19
|
|
|
22
20
|
const mobileLinks = computed(() => {
|
|
23
21
|
return navigation.value.map((item) => {
|
|
24
|
-
if (item.path ===
|
|
22
|
+
if (item.path === "/blog") {
|
|
25
23
|
return {
|
|
26
24
|
...item,
|
|
27
25
|
children: undefined,
|
|
28
|
-
}
|
|
26
|
+
};
|
|
29
27
|
}
|
|
30
28
|
if (item.children?.length === 1) {
|
|
31
|
-
return item.children[0]
|
|
29
|
+
return item.children[0];
|
|
32
30
|
}
|
|
33
|
-
const originalPath = item.path
|
|
31
|
+
const originalPath = item.path;
|
|
34
32
|
if (item.children?.length && item.children.some((c) => c.path === originalPath)) {
|
|
35
|
-
item.title = titleCase(originalPath)
|
|
33
|
+
item.title = titleCase(originalPath);
|
|
36
34
|
}
|
|
37
|
-
return item
|
|
38
|
-
})
|
|
39
|
-
})
|
|
35
|
+
return item;
|
|
36
|
+
});
|
|
37
|
+
});
|
|
40
38
|
</script>
|
|
41
39
|
|
|
42
40
|
<template>
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
const appConfig = useAppConfig()
|
|
2
|
+
const appConfig = useAppConfig();
|
|
3
3
|
|
|
4
4
|
const activeVersion = computed(() => {
|
|
5
|
-
return appConfig.docs.versions.find((version) => version.active) || appConfig.docs.versions[0]
|
|
6
|
-
})
|
|
5
|
+
return appConfig.docs.versions.find((version) => version.active) || appConfig.docs.versions[0];
|
|
6
|
+
});
|
|
7
7
|
const items = computed(() => {
|
|
8
8
|
return appConfig.docs.versions.map((version) => {
|
|
9
9
|
if (activeVersion.value === version) {
|
|
10
10
|
return {
|
|
11
11
|
label: version.label,
|
|
12
|
-
type:
|
|
13
|
-
color:
|
|
12
|
+
type: "checkbox" as const,
|
|
13
|
+
color: "primary" as const,
|
|
14
14
|
checked: true,
|
|
15
|
-
}
|
|
15
|
+
};
|
|
16
16
|
}
|
|
17
17
|
return {
|
|
18
18
|
label: version.label,
|
|
19
19
|
to: version.to,
|
|
20
|
-
}
|
|
21
|
-
})
|
|
22
|
-
})
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
23
|
</script>
|
|
24
24
|
|
|
25
25
|
<template>
|
|
@@ -40,7 +40,9 @@ const items = computed(() => {
|
|
|
40
40
|
class="-mb-[6px] font-semibold rounded-full truncate"
|
|
41
41
|
:class="[open && 'bg-primary/15']"
|
|
42
42
|
:ui="{
|
|
43
|
-
trailingIcon: ['transition-transform duration-200', open ? 'rotate-180' : undefined]
|
|
43
|
+
trailingIcon: ['transition-transform duration-200', open ? 'rotate-180' : undefined]
|
|
44
|
+
.filter(Boolean)
|
|
45
|
+
.join(' '),
|
|
44
46
|
}"
|
|
45
47
|
/>
|
|
46
48
|
</UDropdownMenu>
|
|
@@ -15,29 +15,29 @@
|
|
|
15
15
|
</template>
|
|
16
16
|
|
|
17
17
|
<script setup lang="ts">
|
|
18
|
-
import { Disclosure, DisclosureButton, DisclosurePanel } from
|
|
18
|
+
import { Disclosure, DisclosureButton, DisclosurePanel } from "@headlessui/vue";
|
|
19
19
|
|
|
20
|
-
const appConfig = useAppConfig()
|
|
20
|
+
const appConfig = useAppConfig();
|
|
21
21
|
|
|
22
22
|
const config = computed(() => ({
|
|
23
23
|
button: {
|
|
24
|
-
base:
|
|
24
|
+
base: "flex items-center gap-1 text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200",
|
|
25
25
|
icon: {
|
|
26
26
|
name: appConfig.ui.icons.chevron,
|
|
27
|
-
base:
|
|
28
|
-
active:
|
|
29
|
-
inactive:
|
|
27
|
+
base: "w-4 h-4 transform transition-transform duration-200",
|
|
28
|
+
active: "",
|
|
29
|
+
inactive: "-rotate-90",
|
|
30
30
|
},
|
|
31
31
|
},
|
|
32
|
-
panel:
|
|
33
|
-
}))
|
|
32
|
+
panel: "mt-4 ml-2 py-2.5 pl-4 border-l border-gray-200 dark:border-gray-800 [&>div]:!mt-0",
|
|
33
|
+
}));
|
|
34
34
|
|
|
35
35
|
defineProps({
|
|
36
36
|
name: {
|
|
37
37
|
type: String,
|
|
38
|
-
default:
|
|
38
|
+
default: "properties",
|
|
39
39
|
},
|
|
40
|
-
})
|
|
40
|
+
});
|
|
41
41
|
|
|
42
|
-
const { ui } = useUI(
|
|
42
|
+
const { ui } = useUI("prose.collapsible", undefined, config, undefined, true);
|
|
43
43
|
</script>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
// Source: https://github.com/nuxt-content/docus/blob/main/layer/app/components/IconMenuToggle.vue
|
|
3
|
-
import { motion } from
|
|
4
|
-
import type { VariantType } from
|
|
3
|
+
import { motion } from "motion-v";
|
|
4
|
+
import type { VariantType } from "motion-v";
|
|
5
5
|
|
|
6
6
|
const props = defineProps<{
|
|
7
|
-
open: boolean
|
|
8
|
-
}>()
|
|
7
|
+
open: boolean;
|
|
8
|
+
}>();
|
|
9
9
|
|
|
10
10
|
const variants: { [k: string]: VariantType | ((custom: unknown) => VariantType) } = {
|
|
11
11
|
normal: {
|
|
@@ -14,21 +14,21 @@ const variants: { [k: string]: VariantType | ((custom: unknown) => VariantType)
|
|
|
14
14
|
opacity: 1,
|
|
15
15
|
},
|
|
16
16
|
close: (custom: unknown) => {
|
|
17
|
-
const c = custom as number
|
|
17
|
+
const c = custom as number;
|
|
18
18
|
return {
|
|
19
19
|
rotate: c === 1 ? 45 : c === 3 ? -45 : 0,
|
|
20
20
|
y: c === 1 ? 6 : c === 3 ? -6 : 0,
|
|
21
21
|
opacity: c === 2 ? 0 : 1,
|
|
22
22
|
transition: {
|
|
23
|
-
type:
|
|
23
|
+
type: "spring",
|
|
24
24
|
stiffness: 260,
|
|
25
25
|
damping: 20,
|
|
26
26
|
},
|
|
27
|
-
}
|
|
27
|
+
};
|
|
28
28
|
},
|
|
29
|
-
}
|
|
29
|
+
};
|
|
30
30
|
|
|
31
|
-
const state = computed(() => (props.open ?
|
|
31
|
+
const state = computed(() => (props.open ? "close" : "normal"));
|
|
32
32
|
</script>
|
|
33
33
|
|
|
34
34
|
<template>
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
const points = useState(() =>
|
|
2
|
+
const points = useState(() =>
|
|
3
|
+
Array.from({ length: 16 })
|
|
4
|
+
.fill(0)
|
|
5
|
+
.map(() => [Math.random(), Math.random()]),
|
|
6
|
+
);
|
|
3
7
|
|
|
4
|
-
const poly = computed(() => points.value.map(([x, y]) => `${x * 100}% ${y * 100}%`).join(
|
|
8
|
+
const poly = computed(() => points.value.map(([x, y]) => `${x * 100}% ${y * 100}%`).join(", "));
|
|
5
9
|
|
|
6
10
|
function jumpVal(val: number) {
|
|
7
|
-
return Math.random() > 0.5 ? val + (Math.random() - 0.5) / 2 : Math.random()
|
|
11
|
+
return Math.random() > 0.5 ? val + (Math.random() - 0.5) / 2 : Math.random();
|
|
8
12
|
}
|
|
9
13
|
|
|
10
|
-
let timeout
|
|
14
|
+
let timeout;
|
|
11
15
|
function jumpPoints() {
|
|
12
16
|
for (let i = 0; i < points.value.length; i++) {
|
|
13
|
-
points.value[i] = [jumpVal(points.value[i][0]), jumpVal(points.value[i][1])]
|
|
17
|
+
points.value[i] = [jumpVal(points.value[i][0]), jumpVal(points.value[i][1])];
|
|
14
18
|
}
|
|
15
|
-
timeout = setTimeout(jumpPoints, 2000 + Math.random() * 1000)
|
|
19
|
+
timeout = setTimeout(jumpPoints, 2000 + Math.random() * 1000);
|
|
16
20
|
}
|
|
17
21
|
|
|
18
22
|
onMounted(() => {
|
|
19
|
-
jumpPoints()
|
|
20
|
-
onUnmounted(() => clearTimeout(timeout))
|
|
21
|
-
})
|
|
23
|
+
jumpPoints();
|
|
24
|
+
onUnmounted(() => clearTimeout(timeout));
|
|
25
|
+
});
|
|
22
26
|
</script>
|
|
23
27
|
|
|
24
28
|
<template>
|
|
@@ -1,44 +1,44 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { useClipboard } from
|
|
3
|
-
import { useRuntimeConfig } from
|
|
2
|
+
import { useClipboard } from "@vueuse/core";
|
|
3
|
+
import { useRuntimeConfig } from "#imports";
|
|
4
4
|
|
|
5
|
-
const route = useRoute()
|
|
6
|
-
const appBaseURL = useRuntimeConfig().app?.baseURL ||
|
|
5
|
+
const route = useRoute();
|
|
6
|
+
const appBaseURL = useRuntimeConfig().app?.baseURL || "/";
|
|
7
7
|
|
|
8
|
-
const { copy, copied } = useClipboard()
|
|
8
|
+
const { copy, copied } = useClipboard();
|
|
9
9
|
|
|
10
|
-
const markdownLink = computed(() => `${window?.location?.origin}${appBaseURL}raw${route.path}.md`)
|
|
10
|
+
const markdownLink = computed(() => `${window?.location?.origin}${appBaseURL}raw${route.path}.md`);
|
|
11
11
|
const items = [
|
|
12
12
|
{
|
|
13
|
-
label:
|
|
14
|
-
icon:
|
|
13
|
+
label: "Copy Markdown Link",
|
|
14
|
+
icon: "i-lucide-link",
|
|
15
15
|
onSelect() {
|
|
16
|
-
copy(markdownLink.value)
|
|
16
|
+
copy(markdownLink.value);
|
|
17
17
|
},
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
|
-
label:
|
|
21
|
-
icon:
|
|
22
|
-
target:
|
|
20
|
+
label: "View as Markdown",
|
|
21
|
+
icon: "i-simple-icons:markdown",
|
|
22
|
+
target: "_blank",
|
|
23
23
|
to: markdownLink.value,
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
|
-
label:
|
|
27
|
-
icon:
|
|
28
|
-
target:
|
|
26
|
+
label: "Open in ChatGPT",
|
|
27
|
+
icon: "i-simple-icons:openai",
|
|
28
|
+
target: "_blank",
|
|
29
29
|
to: `https://chatgpt.com/?hints=search&q=${encodeURIComponent(`Read ${markdownLink.value} so I can ask questions about it.`)}`,
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
|
-
label:
|
|
33
|
-
icon:
|
|
34
|
-
target:
|
|
32
|
+
label: "Open in Claude",
|
|
33
|
+
icon: "i-simple-icons:anthropic",
|
|
34
|
+
target: "_blank",
|
|
35
35
|
to: `https://claude.ai/new?q=${encodeURIComponent(`Read ${markdownLink.value} so I can ask questions about it.`)}`,
|
|
36
36
|
},
|
|
37
|
-
]
|
|
37
|
+
];
|
|
38
38
|
|
|
39
39
|
async function copyPage() {
|
|
40
|
-
const page = await $fetch<string>(`/raw${route.path}.md`)
|
|
41
|
-
copy(page)
|
|
40
|
+
const page = await $fetch<string>(`/raw${route.path}.md`);
|
|
41
|
+
copy(page);
|
|
42
42
|
}
|
|
43
43
|
</script>
|
|
44
44
|
|
|
@@ -64,7 +64,12 @@ async function copyPage() {
|
|
|
64
64
|
sideOffset: 8,
|
|
65
65
|
}"
|
|
66
66
|
>
|
|
67
|
-
<UButton
|
|
67
|
+
<UButton
|
|
68
|
+
icon="i-lucide-chevron-down"
|
|
69
|
+
color="neutral"
|
|
70
|
+
variant="soft"
|
|
71
|
+
class="border-l border-muted"
|
|
72
|
+
/>
|
|
68
73
|
</UDropdownMenu>
|
|
69
74
|
</UFieldGroup>
|
|
70
75
|
</template>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
const appConfig = useAppConfig()
|
|
2
|
+
const appConfig = useAppConfig();
|
|
3
3
|
|
|
4
4
|
const props = defineProps({
|
|
5
5
|
githubOnly: {
|
|
6
6
|
type: Boolean,
|
|
7
7
|
default: false,
|
|
8
8
|
},
|
|
9
|
-
})
|
|
9
|
+
});
|
|
10
10
|
|
|
11
11
|
const socialLinks = computed(() => {
|
|
12
12
|
return (
|
|
@@ -18,22 +18,22 @@ const socialLinks = computed(() => {
|
|
|
18
18
|
.reverse() // x<>github
|
|
19
19
|
// .filter(([key]) => props.socials?.includes(key) || !props.socials)
|
|
20
20
|
.map(([key, value]) => {
|
|
21
|
-
if (typeof value ===
|
|
22
|
-
return value
|
|
21
|
+
if (typeof value === "object") {
|
|
22
|
+
return value;
|
|
23
23
|
}
|
|
24
|
-
if (typeof value ===
|
|
24
|
+
if (typeof value === "string" && value) {
|
|
25
25
|
return {
|
|
26
26
|
// Workaround: i-simple-icons-x i-simple-icons-github
|
|
27
27
|
icon: `i-simple-icons-${key}`,
|
|
28
28
|
label: titleCase(key),
|
|
29
29
|
to: /^https?:\/\//.test(value) ? value : `https://${key}.com/${value}`,
|
|
30
|
-
}
|
|
30
|
+
};
|
|
31
31
|
}
|
|
32
|
-
return undefined
|
|
32
|
+
return undefined;
|
|
33
33
|
})
|
|
34
34
|
.filter(Boolean)
|
|
35
|
-
)
|
|
36
|
-
})
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
37
|
</script>
|
|
38
38
|
<template>
|
|
39
39
|
<UTooltip v-for="link of socialLinks" :key="link.label" :text="link.label">
|