revert home page feature

pull/183/head
Evan You 4 years ago
parent 8809d2dbfc
commit 2bde6bf88d

@ -72,6 +72,7 @@ function getConfigSidebar() {
{ {
text: 'Theme Config', text: 'Theme Config',
children: [ children: [
{ text: 'Homepage', link: '/config/homepage' },
{ text: 'Algolia Search', link: '/config/algolia-search' }, { text: 'Algolia Search', link: '/config/algolia-search' },
{ text: 'Carbon Ads', link: '/config/carbon-ads' } { text: 'Carbon Ads', link: '/config/carbon-ads' }
] ]

@ -0,0 +1,23 @@
# Theme Config: Homepage
VitePress provides a homepage layout. To use it, specify `home: true` plus some other metadata in your root `index.md`'s [YAML frontmatter](../guide/frontmatter). This is an example of how it works:
```yaml
---
home: true
heroImage: /logo.png
heroAlt: Logo image
heroText: Hero Title
tagline: Hero subtitle
actionText: Get Started
actionLink: /guide/
features:
- title: Simplicity First
details: Minimal setup with markdown-centered project structure helps you focus on writing.
- title: Vue-Powered
details: Enjoy the dev experience of Vue + webpack, use Vue components in markdown, and develop custom themes with Vue.
- title: Performant
details: VitePress generates pre-rendered static HTML for each page, and runs as an SPA once a page is loaded.
footer: MIT Licensed | Copyright © 2019-present Evan You
---
```

@ -19,7 +19,20 @@
<!-- TODO: make this button accessible --> <!-- TODO: make this button accessible -->
<div class="sidebar-mask" @click="toggleSidebar(false)" /> <div class="sidebar-mask" @click="toggleSidebar(false)" />
<Content v-if="isCustomLayout"/> <Content v-if="isCustomLayout" />
<Home v-else-if="enableHome">
<template #hero>
<slot name="home-hero" />
</template>
<template #features>
<slot name="home-features" />
</template>
<template #footer>
<slot name="home-footer" />
</template>
</Home>
<Page v-else> <Page v-else>
<template #top> <template #top>
<slot name="page-top-ads"> <slot name="page-top-ads">
@ -63,6 +76,7 @@ import type { DefaultTheme } from './config'
import NavBar from './components/NavBar.vue' import NavBar from './components/NavBar.vue'
import SideBar from './components/SideBar.vue' import SideBar from './components/SideBar.vue'
import Page from './components/Page.vue' import Page from './components/Page.vue'
const Home = defineAsyncComponent(() => import('./components/Home.vue'))
const CarbonAds = defineAsyncComponent( const CarbonAds = defineAsyncComponent(
() => import('./components/CarbonAds.vue') () => import('./components/CarbonAds.vue')
) )
@ -82,6 +96,8 @@ const page = usePageData()
// custom layout // custom layout
const isCustomLayout = computed(() => !!route.data.frontmatter.customLayout) const isCustomLayout = computed(() => !!route.data.frontmatter.customLayout)
// home
const enableHome = computed(() => !!route.data.frontmatter.home)
// navbar // navbar
const showNavbar = computed(() => { const showNavbar = computed(() => {
@ -105,7 +121,7 @@ const showSidebar = computed(() => {
const { frontmatter } = route.data const { frontmatter } = route.data
const { themeConfig } = siteRouteData.value const { themeConfig } = siteRouteData.value
return ( return (
!frontmatter.customLayout && !frontmatter.home &&
frontmatter.sidebar !== false && frontmatter.sidebar !== false &&
((typeof themeConfig.sidebar === 'object' && ((typeof themeConfig.sidebar === 'object' &&
Object.keys(themeConfig.sidebar).length != 0) || Object.keys(themeConfig.sidebar).length != 0) ||

@ -0,0 +1,22 @@
<template>
<main class="home" aria-labelledby="main-title">
<HomeHero />
<slot name="hero" />
<HomeFeatures />
<slot name="features" />
<HomeFooter />
<slot name="footer" />
</main>
</template>
<script setup lang="ts">
import HomeHero from './HomeHero.vue'
import HomeFeatures from './HomeFeatures.vue'
import HomeFooter from './HomeFooter.vue'
</script>
<style scoped>
.home {
padding-top: var(--header-height);
}
</style>

@ -0,0 +1,134 @@
<template>
<div v-if="hasFeatures" class="home-features">
<div class="wrapper">
<div class="container">
<div class="features">
<section v-for="(feature, index) in features" :key="index" class="feature">
<h2 class="title" v-if="feature.title">{{ feature.title }}</h2>
<p class="details" v-if="feature.details">{{ feature.details }}</p>
</section>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useSiteDataByRoute, useFrontmatter } from 'vitepress'
const data = useFrontmatter()
const hasFeatures = computed(() => {
return data.value.features && data.value.features.length > 0
})
const features = computed(() => {
return data.value.features ? data.value.features : []
})
</script>
<style scoped>
.home-features {
margin: 0 auto;
padding: 2.5rem 0 2.75rem;
max-width: 960px;
}
.home-hero + .home-features {
padding-top: 0;
}
@media (min-width: 420px) {
.home-features {
padding: 3.25rem 0 3.5rem;
}
.home-hero + .home-features {
padding-top: 0;
}
}
@media (min-width: 720px) {
.home-features {
padding-right: 1.5rem;
padding-left: 1.5rem;
}
}
.wrapper {
padding: 0 1.5rem;
}
.home-hero + .home-features .wrapper {
border-top: 1px solid var(--c-divider);
padding-top: 2.5rem;
}
@media (min-width: 420px) {
.home-hero + .home-features .wrapper {
padding-top: 3.25rem;
}
}
@media (min-width: 720px) {
.wrapper {
padding-right: 0;
padding-left: 0;
}
}
.container {
margin: 0 auto;
max-width: 392px;
}
@media (min-width: 720px) {
.container {
max-width: 960px;
}
}
.features {
display: flex;
flex-wrap: wrap;
margin: -20px -24px;
}
.feature {
flex-shrink: 0;
padding: 20px 24px;
width: 100%;
}
@media (min-width: 720px) {
.feature {
width: calc(100% / 3);
}
}
.title {
margin: 0;
border-bottom: 0;
line-height: 1.4;
font-size: 1.25rem;
font-weight: 500;
}
@media (min-width: 420px) {
.title {
font-size: 1.4rem;
}
}
.details {
margin: 0;
line-height: 1.6;
font-size: 1rem;
color: var(--c-text-light);
}
.title + .details {
padding-top: 0.25rem;
}
</style>

@ -0,0 +1,44 @@
<template>
<footer v-if="$frontmatter.footer" class="footer">
<div class="container">
<p class="text">{{ $frontmatter.footer }}</p>
</div>
</footer>
</template>
<style scoped>
.footer {
margin: 0 auto;
max-width: 960px;
}
@media (min-width: 720px) {
.footer {
padding: 0 1.5rem;
}
}
.container {
padding: 2rem 1.5rem 2.25rem;
}
.home-hero + .footer .container,
.home-features + .footer .container,
.home-content + .footer .container {
border-top: 1px solid var(--c-divider);
}
@media (min-width: 420px) {
.container {
padding: 3rem 1.5rem 3.25rem;
}
}
.text {
margin: 0;
text-align: center;
line-height: 1.4;
font-size: .9rem;
color: var(--c-text-light);
}
</style>

@ -0,0 +1,143 @@
<template>
<header v-if="showHero" class="home-hero">
<figure v-if="$frontmatter.heroImage" class="figure">
<img
class="image"
:src="$withBase($frontmatter.heroImage)"
:alt="$frontmatter.heroAlt"
>
</figure>
<h1 v-if="hasHeroText" class="title">{{ heroText }}</h1>
<p v-if="hasTagline" class="description">{{ tagline }}</p>
<div v-if="hasAction" class="action">
<a class="action-link" :href="$frontmatter.actionLink">
{{ $frontmatter.actionText }}
</a>
</div>
</header>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useSiteDataByRoute, useFrontmatter } from 'vitepress'
const site = useSiteDataByRoute()
const data = useFrontmatter()
const showHero = computed(() => {
return data.value.heroImage
|| hasHeroText.value
|| hasTagline.value
|| hasAction.value
})
const hasHeroText = computed(() => data.value.heroText !== null)
const heroText = computed(() => data.value.heroText || site.value.title)
const hasTagline = computed(() => data.value.tagline !== null)
const tagline = computed(() => data.value.tagline || site.value.description)
const hasAction = computed(() => data.value.actionLink && data.value.actionText)
</script>
<style scoped>
.home-hero {
margin: 2.5rem 0 2.75rem;
padding: 0 1.5rem;
text-align: center;
}
@media (min-width: 420px) {
.home-hero {
margin: 3.5rem 0;
}
}
@media (min-width: 720px) {
.home-hero {
margin: 4rem 0 4.25rem;
}
}
.figure {
padding: 0 1.5rem;
}
.image {
display: block;
margin: 0 auto;
width: auto;
max-width: 100%;
max-height: 280px;
}
.title {
margin-top: 1.5rem;
font-size: 2rem;
}
@media (min-width: 420px) {
.title {
font-size: 3rem;
}
}
@media (min-width: 720px) {
.title {
margin-top: 2rem;
}
}
.description {
margin: 0;
margin-top: .25rem;
line-height: 1.3;
font-size: 1.2rem;
color: var(--c-text-light);
}
@media (min-width: 420px) {
.description {
line-height: 1.2;
font-size: 1.6rem;
}
}
.action {
margin-top: 1.5rem;
}
@media (min-width: 420px) {
.action {
margin-top: 2rem;
}
}
.action-link {
display: inline-block;
border-radius: 4px;
padding: 0 20px;
line-height: 48px;
font-size: 1rem;
font-weight: 500;
color: #ffffff;
background-color: var(--c-brand);
transition: background-color .1s ease;
}
.action-link:hover {
text-decoration: none;
background-color: var(--c-brand-light);
}
@media (min-width: 420px) {
.action-link {
padding: 0 24px;
line-height: 56px;
font-size: 1.2rem;
font-weight: 500;
}
}
</style>
Loading…
Cancel
Save