修改首页卡片
This commit is contained in:
@@ -37,6 +37,215 @@ export default defineAppConfig({
|
|||||||
root: 'border-t border-default',
|
root: 'border-t border-default',
|
||||||
left: 'text-sm text-muted'
|
left: 'text-sm text-muted'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
pageCard: {
|
||||||
|
slots: {
|
||||||
|
root: 'relative flex rounded-lg',
|
||||||
|
spotlight: 'absolute inset-0 rounded-[inherit] pointer-events-none bg-default/90',
|
||||||
|
container: 'relative flex flex-col flex-1 lg:grid gap-x-8 gap-y-4 p-4 sm:p-6',
|
||||||
|
wrapper: 'flex flex-col flex-1 items-start',
|
||||||
|
header: 'mb-4',
|
||||||
|
body: 'flex-1',
|
||||||
|
footer: 'pt-4 mt-auto',
|
||||||
|
leading: 'inline-flex items-center mb-2.5',
|
||||||
|
leadingIcon: 'size-5 shrink-0 text-primary',
|
||||||
|
title: 'text-base text-pretty font-semibold text-highlighted',
|
||||||
|
description: 'text-[15px] text-pretty'
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
orientation: {
|
||||||
|
horizontal: {
|
||||||
|
container: 'lg:grid-cols-2 lg:items-center'
|
||||||
|
},
|
||||||
|
vertical: {
|
||||||
|
container: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reverse: {
|
||||||
|
true: {
|
||||||
|
wrapper: 'lg:order-last'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
variant: {
|
||||||
|
solid: {
|
||||||
|
root: 'bg-inverted text-inverted',
|
||||||
|
title: 'text-inverted',
|
||||||
|
description: 'text-dimmed'
|
||||||
|
},
|
||||||
|
outline: {
|
||||||
|
root: 'bg-default ring ring-default',
|
||||||
|
description: 'text-muted'
|
||||||
|
},
|
||||||
|
soft: {
|
||||||
|
root: 'bg-elevated/50',
|
||||||
|
description: 'text-toned'
|
||||||
|
},
|
||||||
|
subtle: {
|
||||||
|
root: 'bg-elevated/50 ring ring-default',
|
||||||
|
description: 'text-toned'
|
||||||
|
},
|
||||||
|
ghost: {
|
||||||
|
description: 'text-muted'
|
||||||
|
},
|
||||||
|
naked: {
|
||||||
|
container: 'p-0 sm:p-0',
|
||||||
|
description: 'text-muted'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
to: {
|
||||||
|
true: {
|
||||||
|
root: [
|
||||||
|
'transition'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
true: {
|
||||||
|
description: 'mt-1'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
highlight: {
|
||||||
|
true: {
|
||||||
|
root: 'ring-2'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
highlightColor: {
|
||||||
|
primary: '',
|
||||||
|
secondary: '',
|
||||||
|
success: '',
|
||||||
|
info: '',
|
||||||
|
warning: '',
|
||||||
|
error: '',
|
||||||
|
neutral: ''
|
||||||
|
},
|
||||||
|
spotlight: {
|
||||||
|
true: {
|
||||||
|
root: '[--spotlight-size:400px] before:absolute before:-inset-px before:pointer-events-none before:rounded-[inherit] before:bg-[radial-gradient(var(--spotlight-size)_var(--spotlight-size)_at_calc(var(--spotlight-x,0px))_calc(var(--spotlight-y,0px)),var(--spotlight-color),transparent_70%)]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
spotlightColor: {
|
||||||
|
primary: '',
|
||||||
|
secondary: '',
|
||||||
|
success: '',
|
||||||
|
info: '',
|
||||||
|
warning: '',
|
||||||
|
error: '',
|
||||||
|
neutral: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
compoundVariants: [
|
||||||
|
{
|
||||||
|
variant: 'solid',
|
||||||
|
to: true,
|
||||||
|
class: {
|
||||||
|
root: 'hover:bg-inverted/90'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: 'outline',
|
||||||
|
to: true,
|
||||||
|
class: {
|
||||||
|
root: 'hover:bg-elevated/50'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: 'soft',
|
||||||
|
to: true,
|
||||||
|
class: {
|
||||||
|
root: 'hover:bg-elevated'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: 'subtle',
|
||||||
|
to: true,
|
||||||
|
class: {
|
||||||
|
root: 'hover:bg-elevated'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: 'subtle',
|
||||||
|
to: true,
|
||||||
|
highlight: false,
|
||||||
|
class: {
|
||||||
|
root: 'hover:ring-accented'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
variant: 'ghost',
|
||||||
|
to: true,
|
||||||
|
class: {
|
||||||
|
root: 'hover:bg-elevated/50'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
highlightColor: 'primary',
|
||||||
|
highlight: true,
|
||||||
|
class: {
|
||||||
|
root: 'ring-primary'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
highlightColor: 'neutral',
|
||||||
|
highlight: true,
|
||||||
|
class: {
|
||||||
|
root: 'ring-inverted'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spotlightColor: 'primary',
|
||||||
|
spotlight: true,
|
||||||
|
class: {
|
||||||
|
root: '[--spotlight-color:var(--ui-primary)]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spotlightColor: 'secondary',
|
||||||
|
spotlight: true,
|
||||||
|
class: {
|
||||||
|
root: '[--spotlight-color:var(--ui-secondary)]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spotlightColor: 'success',
|
||||||
|
spotlight: true,
|
||||||
|
class: {
|
||||||
|
root: '[--spotlight-color:var(--ui-success)]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spotlightColor: 'info',
|
||||||
|
spotlight: true,
|
||||||
|
class: {
|
||||||
|
root: '[--spotlight-color:var(--ui-info)]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spotlightColor: 'warning',
|
||||||
|
spotlight: true,
|
||||||
|
class: {
|
||||||
|
root: '[--spotlight-color:var(--ui-warning)]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spotlightColor: 'error',
|
||||||
|
spotlight: true,
|
||||||
|
class: {
|
||||||
|
root: '[--spotlight-color:var(--ui-error)]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
spotlightColor: 'neutral',
|
||||||
|
spotlight: true,
|
||||||
|
class: {
|
||||||
|
root: '[--spotlight-color:var(--ui-bg-inverted)]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
defaultVariants: {
|
||||||
|
variant: 'outline',
|
||||||
|
highlightColor: 'primary',
|
||||||
|
spotlightColor: 'primary'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
seo: {
|
seo: {
|
||||||
|
88
app/components/IndexCard.vue
Normal file
88
app/components/IndexCard.vue
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<template>
|
||||||
|
<div class="w-full bg-gray-50 dark:bg-gray-900 min-h-screen p-2 sm:p-4 lg:p-2">
|
||||||
|
<!-- 响应式卡片网格 -->
|
||||||
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 max-w-8xl mx-auto">
|
||||||
|
<div v-for="item in firstLevelItems" :key="item.path"
|
||||||
|
class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-5 sm:p-6 shadow-sm hover:shadow-md transition-all duration-200 cursor-pointer"
|
||||||
|
@click="navigateTo(item.path)">
|
||||||
|
|
||||||
|
<!-- 卡片头部 -->
|
||||||
|
<div class="flex items-center justify-between mb-1">
|
||||||
|
<h2 class="text-xl sm:text-xl lg:text-2xl font-bold text-gray-900 dark:text-white leading-tight">
|
||||||
|
{{ item.title }}
|
||||||
|
</h2>
|
||||||
|
<span class="text-sm sm:text-base lg:text-lg text-gray-600 dark:text-gray-400 font-normal">
|
||||||
|
<sum class="text-primary mr-0.3">{{ getChildrenCount(item) }}</sum>篇
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 子页面列表 -->
|
||||||
|
<div v-if="getChildrenTitles(item).length > 0" class="">
|
||||||
|
<div v-for="(child, index) in getChildrenWithIcons(item).slice(0, 5)" :key="index"
|
||||||
|
class="flex items-center justify-between
|
||||||
|
text-sm sm:text-base lg:text-lg text-gray-700 dark:text-gray-300
|
||||||
|
hover:text-blue-600 dark:hover:text-blue-400
|
||||||
|
transition-colors duration-200 py-1
|
||||||
|
border-b border-gray-200 dark:border-gray-700 pt-2">
|
||||||
|
|
||||||
|
<div class="flex items-center flex-1 min-w-0 pl-1 ">
|
||||||
|
<Icon :name="child.icon || 'i-lucide-file-text'" class="mr-2 text-gray-400" size="14" />
|
||||||
|
<span class="text-base font-sans">{{ child.title }}</span>
|
||||||
|
</div>
|
||||||
|
<Icon name="i-lucide-chevron-right" class="text-gray-400 flex-shrink-0 ml-2" size="16" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { ContentNavigationItem } from "@nuxt/content";
|
||||||
|
|
||||||
|
const navigation = inject<Ref<ContentNavigationItem[]>>("navigation");
|
||||||
|
|
||||||
|
// 计算属性:提取第一级数据
|
||||||
|
const firstLevelItems = computed(() => {
|
||||||
|
if (!navigation?.value) return [];
|
||||||
|
return navigation.value
|
||||||
|
.filter(item => item.title && item.path)
|
||||||
|
.map(item => ({
|
||||||
|
...item,
|
||||||
|
description: item.description,
|
||||||
|
icon: item.icon || 'i-lucide-book-open'
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取子页面数量
|
||||||
|
const getChildrenCount = (item: ContentNavigationItem) => {
|
||||||
|
return item.children?.length || 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取子页面标题列表
|
||||||
|
const getChildrenTitles = (item: ContentNavigationItem) => {
|
||||||
|
if (!item.children) return [];
|
||||||
|
return item.children.map(child => child.title).filter(Boolean);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取子页面数据(包含图标)
|
||||||
|
const getChildrenWithIcons = (item: ContentNavigationItem) => {
|
||||||
|
if (!item.children) return [];
|
||||||
|
return item.children.filter(child => child.title);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取描述信息
|
||||||
|
const getDescription = (item: ContentNavigationItem) => {
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
return `${item.children.length} 个子页面`;
|
||||||
|
}
|
||||||
|
return "文档页面";
|
||||||
|
};
|
||||||
|
|
||||||
|
// 导航方法
|
||||||
|
const navigateTo = (path: string) => {
|
||||||
|
if (path) {
|
||||||
|
window.location.href = path;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
25
app/components/IndexHero.vue
Normal file
25
app/components/IndexHero.vue
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const links = ref([
|
||||||
|
{
|
||||||
|
label: 'Get started',
|
||||||
|
to: '/getting-started',
|
||||||
|
icon: 'i-lucide-square-play'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Learn more',
|
||||||
|
to: '/getting-started/theme',
|
||||||
|
color: 'neutral',
|
||||||
|
variant: 'subtle',
|
||||||
|
trailingIcon: 'i-lucide-arrow-right'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<UPageHero
|
||||||
|
headline="New release"
|
||||||
|
title="Ultimate Vue UI library"
|
||||||
|
description="A Nuxt/Vue-integrated UI library providing a rich set of fully-styled, accessible and highly customizable components for building modern web applications."
|
||||||
|
:links="links"
|
||||||
|
/>
|
||||||
|
</template>
|
@@ -35,7 +35,6 @@ const items = ref<NavigationMenuItem[][]>([
|
|||||||
label: 'Components',
|
label: 'Components',
|
||||||
icon: 'i-lucide-box',
|
icon: 'i-lucide-box',
|
||||||
to: '/components',
|
to: '/components',
|
||||||
active: true,
|
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
label: 'Link',
|
label: 'Link',
|
||||||
|
@@ -3,13 +3,8 @@ definePageMeta({
|
|||||||
layout: 'default'
|
layout: 'default'
|
||||||
})
|
})
|
||||||
|
|
||||||
const { data: page } = await useAsyncData('index', () => queryCollection('landing').path('/').first())
|
const title = "Estel Docs"
|
||||||
if (!page.value) {
|
const description = "Estel Docs"
|
||||||
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
|
|
||||||
}
|
|
||||||
|
|
||||||
const title = page.value.seo?.title || page.value.title
|
|
||||||
const description = page.value.seo?.description || page.value.description
|
|
||||||
|
|
||||||
useSeoMeta({
|
useSeoMeta({
|
||||||
titleTemplate: '',
|
titleTemplate: '',
|
||||||
@@ -23,9 +18,6 @@ useSeoMeta({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ContentRenderer
|
<!-- <IndexHero /> -->
|
||||||
v-if="page"
|
<IndexCard />
|
||||||
:value="page"
|
|
||||||
:prose="false"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
@@ -1,2 +1,3 @@
|
|||||||
title: 简单文档
|
title: 简单文档
|
||||||
icon: i-lucide-book-open
|
description: 一个简约但功能强大的开源文档系统
|
||||||
|
icon: i-lucide-rocket
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
title: Introduction
|
title: 入门指南
|
||||||
description: Welcome to Nuxt UI Pro documentation template.
|
description: 欢迎使用简单文档
|
||||||
navigation:
|
navigation:
|
||||||
icon: i-lucide-house
|
icon: i-lucide-house
|
||||||
---
|
---
|
||||||
|
Reference in New Issue
Block a user