Skip to content

Commit

Permalink
feat: add landing page
Browse files Browse the repository at this point in the history
Signed-off-by: ZTL-UwU <zhangtianli2006@163.com>
  • Loading branch information
ZTL-UwU committed May 25, 2024
1 parent ee9d213 commit abe5c49
Show file tree
Hide file tree
Showing 39 changed files with 722 additions and 324 deletions.
77 changes: 77 additions & 0 deletions app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ export default defineAppConfig({
},
darkModeToggle: true,
nav: [{
title: 'Docs',
links: [{
title: 'Getting Started',
to: '/getting-started',
description: 'For the beautiful component design & docs design',
target: undefined,
}, {
title: 'API',
to: '/api',
description: 'For the vue port of shadcn-ui & some docs component source',
target: undefined,
}],
}, {
title: 'Credits',
links: [{
title: 'shadcn-ui',
Expand Down Expand Up @@ -91,6 +104,7 @@ export default defineAppConfig({
'yarn': 'vscode-icons:file-type-yarn',
'bun': 'vscode-icons:file-type-bun',
'yml': 'vscode-icons:file-type-yaml',
'json': 'vscode-icons:file-type-json',
'terminal': 'lucide:terminal',
},
},
Expand Down Expand Up @@ -119,3 +133,66 @@ export default defineAppConfig({
},
},
});

declare module '@nuxt/schema' {
interface AppConfigInput {
shadcnDocs?: {
site: {
name: string;
};
header: {
title: string;
showTitle: true;
logo: {
light: string;
dark: string;
};
darkModeToggle: true;
nav: ({
title: string;
to?: string;
target?: string;
links?: ({
title: string;
to: string;
target?: string;
description?: string;
})[];
})[];
links: ({
icon: string;
to: string;
target: string;
})[];
};
aside: {
useLevel: boolean;
collapse: boolean;
};
main: {
breadCrumb: boolean;
showTitle: boolean;
codeIcon: {
[key: string]: string;
};
};
footer: {
credits: string;
links: ({
icon?: string;
title?: string;
to: string;
target?: string;
})[];
};
toc: {
enable: boolean;
title: string;
};
search: {
enable: boolean;
inAside: boolean;
};
};
}
}
4 changes: 2 additions & 2 deletions components/content/Alert.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
:class="[typeTwClass[type], to && 'cursor-pointer hover:bg-zinc-50 dark:hover:bg-zinc-900']"
@click="alertClick"
>
<Icon v-if="icon && title" :name="icon" />
<Icon v-if="icon && title" :name="icon" size="16" />
<UiAlertTitle v-if="title" class="font-semibold">
{{ title }}
</UiAlertTitle>
<UiAlertDescription>
<div class="flex flex-row space-x-2">
<Icon v-if="icon && !title" :name="icon" class="self-center mb-[2px] min-w-5" />
<Icon v-if="icon && !title" :name="icon" size="16" class="self-center mb-[2px] min-w-5" />
<span :class="[to && 'pr-3']">
<slot />
</span>
Expand Down
36 changes: 36 additions & 0 deletions components/content/CodeCopy.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<template>
<span>
<Transition name="fade" mode="out-in">
<Icon
v-if="copied === false"
name="lucide:copy"
class="self-center cursor-pointer text-muted-foreground hover:text-primary"
@click="copyCode"
/>
<Icon
v-else
ref="checkIconRef"
name="lucide:check"
class="self-center cursor-pointer text-muted-foreground hover:text-primary"
/>
</Transition>
</span>
</template>

<script setup lang="ts">
const props = defineProps<{
code: string;
}>();
const { copy } = useClipboard({ source: props.code });
const copied = ref(false);
function copyCode() {
copy(props.code).then(
() => { copied.value = true; },
);
}
const checkIconRef = ref<HTMLElement>();
onClickOutside(checkIconRef, () => {
copied.value = false;
});
</script>
71 changes: 71 additions & 0 deletions components/content/CodeGroup.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<template>
<render class="[&:not(:first-child)]:mt-5" />
</template>

<script setup lang="ts">
import CodeGroupHeader from './CodeGroupHeader.vue';
const _slots = useSlots()?.default?.() || [];
const activeTabIndex = ref(0);
function isTag(slot: any, tag: string) {
return slot.type && slot.type.tag && slot.type.tag === tag;
}
function checkTag(slot: any) {
return isTag(slot, 'code-block') || isTag(slot, 'code') || isTag(slot, 'pre') || isTag(slot, 'preview');
}
function onChangeActiveTab(index: number) {
activeTabIndex.value = index;
}
const tabs = _slots
.filter(slot => checkTag(slot))
.map((slot, index) => {
return {
label: slot?.props?.filename || slot?.props?.label || `${index}`,
language: slot?.props?.language || null,
code: slot?.props?.code || '',
};
});
function render() {
return h(
'div',
[
h(
CodeGroupHeader,
{
'activeTabIndex': activeTabIndex.value,
tabs,
'onUpdate:activeTabIndex': onChangeActiveTab,
},
),
h(
'div',
_slots.map((slot, index) => {
if (slot.props && checkTag(slot))
slot.props.inGroup = true;
return h(
'div',
{
style: {
display: index === activeTabIndex.value ? 'block' : 'none',
},
},
[
checkTag(slot)
? slot
: h(
'div',
[(slot.children as any)?.default?.() || h('div')],
),
],
);
}),
),
],
);
}
</script>
45 changes: 45 additions & 0 deletions components/content/CodeGroupHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<template>
<UiCard class="rounded-b-none border-b-0 p-0.5 flex text-sm">
<UiTabs v-if="tabs" :default-value="tabs[0].label">
<UiTabsList>
<UiTabsTrigger
v-for="({ label, language }, i) in tabs"
:key="`${i}${label}`"
:value="label"
class="flex"
@click="updateTabs(i)"
>
<Icon v-if="getIcon(label, language)" :name="getIcon(label, language)!" class="self-center mr-1.5" />
{{ label }}
</UiTabsTrigger>
</UiTabsList>
</UiTabs>
<CodeCopy v-show="selected.label !== 'Preview'" class="self-center ml-auto mr-3" :code="selected.code" />
</UiCard>
<slot name="footer" />
</template>

<script setup lang="ts">
const props = defineProps<{
tabs: ({
label: string;
language: string;
code: string;
})[];
activeTabIndex: number;
}>();
const emit = defineEmits(['update:activeTabIndex']);
const selected = computed(() => {
return props.tabs[props.activeTabIndex];
});
function updateTabs(index: number) {
emit('update:activeTabIndex', index);
}
const iconMap = new Map(Object.entries(useConfig().value.main.codeIcon));
function getIcon(label: string, language: string) {
return iconMap.get(label?.toLowerCase()) || iconMap.get(language);
}
</script>
61 changes: 61 additions & 0 deletions components/content/Hero.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<template>
<section class="mx-auto flex max-w-[980px] flex-col items-center gap-2 py-8 md:py-12 md:pb-8 lg:py-24 lg:pb-20">
<NuxtLink
v-if="announcement"
:to="announcement.to"
:target="announcement.target"
class="inline-flex items-center rounded-lg bg-muted px-3 py-1 text-sm font-medium"
>
<template v-if="announcement.icon">
<Icon :name="announcement.icon" size="16" />
<UiSeparator class="mx-2 h-4" orientation="vertical" />
</template>
<span class="sm:hidden">{{ announcement.title }}</span>
<span class="hidden sm:inline">
{{ announcement.title }}
</span>
<Icon name="lucide:arrow-right" class="ml-1 h-4 w-4" />
</NuxtLink>

<h1 class="text-center text-3xl font-bold leading-tight tracking-tighter md:text-6xl lg:leading-[1.1]">
<ContentSlot :use="$slots.title" unwrap="p" />
</h1>
<span class="max-w-[750px] text-center text-lg text-muted-foreground sm:text-xl">
<ContentSlot :use="$slots.description" unwrap="p" />
</span>

<section class="flex w-full items-center justify-center space-x-4 py-4 md:pb-10">
<NuxtLink
v-for="(action, i) in actions"
:key="i"
:to="action.to"
:target="action.target"
>
<UiButton :variant="action.variant">
<Icon v-if="action.leftIcon" :name="action.leftIcon" class="mr-1" />
{{ action.name }}
<Icon v-if="action.rightIcon" :name="action.rightIcon" class="ml-1" />
</UiButton>
</NuxtLink>
</section>
</section>
</template>

<script setup lang="ts">
defineProps<{
announcement?: {
to?: string;
target?: string;
icon?: string;
title: string;
};
actions: [{
name: string;
leftIcon?: string;
rightIcon?: string;
variant?: 'default' | 'link' | 'destructive' | 'outline' | 'secondary' | 'ghost';
to: string;
target?: string;
}];
}>();
</script>
14 changes: 14 additions & 0 deletions components/content/Preview.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<UiCard class="rounded-t-none p-3 bg-zinc-50 dark:bg-zinc-900">
<slot />
</UiCard>
</template>

<script setup lang="ts">
defineProps<{
language?: undefined;
code?: undefined;
filename?: string;
inGroup?: true;
}>();
</script>
Loading

0 comments on commit abe5c49

Please sign in to comment.