Skip to content

Commit bb44710

Browse files
committed
feat(theme-default): support multiple action buttons in homepage (close #23)
1 parent fccd59c commit bb44710

File tree

3 files changed

+147
-45
lines changed

3 files changed

+147
-45
lines changed
Lines changed: 93 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,29 @@
11
<template>
2-
<main
3-
class="home"
4-
:aria-labelledby="$frontmatter.heroText !== null ? 'main-title' : null"
5-
>
2+
<main class="home" :aria-labelledby="heroText ? 'main-title' : null">
63
<header class="hero">
7-
<img
8-
v-if="$frontmatter.heroImage"
9-
:src="$withBase($frontmatter.heroImage)"
10-
:alt="$frontmatter.heroAlt || 'hero'"
11-
/>
12-
13-
<h1 v-if="$frontmatter.heroText !== null" id="main-title">
14-
{{ $frontmatter.heroText || $siteLocale.title || 'Hello' }}
4+
<img v-if="heroImage" :src="heroImage" :alt="heroAlt" />
5+
6+
<h1 v-if="heroText" id="main-title">
7+
{{ heroText }}
158
</h1>
169

17-
<p v-if="$frontmatter.tagline !== null" class="description">
18-
{{
19-
$frontmatter.tagline ||
20-
$siteLocale.description ||
21-
'Welcome to your VuePress site'
22-
}}
10+
<p v-if="tagline" class="description">
11+
{{ tagline }}
2312
</p>
2413

25-
<p
26-
v-if="$frontmatter.actionText && $frontmatter.actionLink"
27-
class="action"
28-
>
14+
<p v-if="actions.length" class="actions">
2915
<NavLink
16+
v-for="action in actions"
17+
:key="action.text"
3018
class="action-button"
31-
:item="{
32-
text: $frontmatter.actionText,
33-
link: $frontmatter.actionLink,
34-
}"
19+
:class="[action.type]"
20+
:item="action"
3521
/>
3622
</p>
3723
</header>
3824

39-
<div
40-
v-if="$frontmatter.features && $frontmatter.features.length"
41-
class="features"
42-
>
43-
<div
44-
v-for="(feature, index) in $frontmatter.features"
45-
:key="index"
46-
class="feature"
47-
>
25+
<div v-if="features.length" class="features">
26+
<div v-for="feature in features" :key="feature.title" class="feature">
4827
<h2>{{ feature.title }}</h2>
4928
<p>{{ feature.details }}</p>
5029
</div>
@@ -54,20 +33,96 @@
5433
<Content />
5534
</div>
5635

57-
<div v-if="$frontmatter.footer" class="footer">
58-
{{ $frontmatter.footer }}
36+
<div v-if="footer" class="footer">
37+
{{ footer }}
5938
</div>
6039
</main>
6140
</template>
6241

6342
<script lang="ts">
64-
import { defineComponent } from 'vue'
43+
import { computed, defineComponent } from 'vue'
44+
import {
45+
usePageFrontmatter,
46+
useSiteLocaleData,
47+
withBase,
48+
} from '@vuepress/client'
49+
import { isArray } from '@vuepress/shared'
50+
import type { DefaultThemeHomePageFrontmatter } from '../types'
6551
import NavLink from './NavLink.vue'
6652
6753
export default defineComponent({
6854
name: 'Home',
55+
6956
components: {
7057
NavLink,
7158
},
59+
60+
setup() {
61+
const frontmatter = usePageFrontmatter<DefaultThemeHomePageFrontmatter>()
62+
const siteLocale = useSiteLocaleData()
63+
64+
const heroImage = computed(() => {
65+
if (!frontmatter.value.heroImage) {
66+
return null
67+
}
68+
69+
return withBase(frontmatter.value.heroImage)
70+
})
71+
72+
const heroText = computed(() => {
73+
if (frontmatter.value.heroText === null) {
74+
return null
75+
}
76+
return frontmatter.value.heroText || siteLocale.value.title || 'Hello'
77+
})
78+
79+
const heroAlt = computed(
80+
() => frontmatter.value.heroAlt || heroText.value || 'hero'
81+
)
82+
83+
const tagline = computed(() => {
84+
if (frontmatter.value.tagline === null) {
85+
return null
86+
}
87+
return (
88+
frontmatter.value.tagline ||
89+
siteLocale.value.description ||
90+
'Welcome to your VuePress site'
91+
)
92+
})
93+
94+
const actions = computed(() => {
95+
if (!isArray(frontmatter.value.actions)) {
96+
return []
97+
}
98+
99+
return frontmatter.value.actions.map(
100+
({ text, link, type = 'primary' }) => ({
101+
text,
102+
link,
103+
type,
104+
})
105+
)
106+
})
107+
108+
const features = computed(() => {
109+
if (isArray(frontmatter.value.features)) {
110+
return frontmatter.value.features
111+
}
112+
return []
113+
})
114+
115+
const footer = computed(() => frontmatter.value.footer)
116+
117+
return {
118+
heroImage,
119+
heroAlt,
120+
heroText,
121+
tagline,
122+
actions,
123+
features,
124+
footer,
125+
}
126+
},
72127
})
73128
</script>

packages/@vuepress/theme-default/src/styles/home.styl

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
font-size: 3rem;
2121
}
2222

23-
h1, .description, .action {
23+
h1, .description, .actions {
2424
margin: 1.8rem auto;
2525
}
2626

@@ -34,16 +34,34 @@
3434
.action-button {
3535
display: inline-block;
3636
font-size: 1.2rem;
37-
color: #fff;
38-
background-color: $accentColor;
3937
padding: 0.8rem 1.6rem;
38+
border-width: 2px;
39+
border-style: solid;
4040
border-radius: 4px;
4141
transition: background-color 0.1s ease;
4242
box-sizing: border-box;
43-
border-bottom: 1px solid darken($accentColor, 10%);
4443

45-
&:hover {
46-
background-color: lighten($accentColor, 10%);
44+
&:not(:first-child) {
45+
margin-left: 1.5rem;
46+
}
47+
48+
&.primary {
49+
color: #fff;
50+
background-color: $tipColor;
51+
border-color: $tipColor;
52+
&:hover {
53+
background-color: lighten($tipColor, 10%);
54+
}
55+
}
56+
57+
&.secondary {
58+
color: $tipColor;
59+
background-color: #fff;
60+
border-color: $tipColor;
61+
&:hover {
62+
color: #fff;
63+
background-color: lighten($tipColor, 10%);
64+
}
4765
}
4866
}
4967
}
@@ -113,7 +131,7 @@
113131
font-size: 2rem;
114132
}
115133

116-
h1, .description, .action {
134+
h1, .description, .actions {
117135
margin: 1.2rem auto;
118136
}
119137

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,34 @@
11
import type { GitPluginPageData } from '@vuepress/plugin-git'
2+
import type { NavLink, SidebarConfig } from './nav'
23

34
export interface DefaultThemePageData extends GitPluginPageData {
45
filePathRelative: string
56
}
7+
8+
export interface DefaultThemeHomePageFrontmatter {
9+
home: true
10+
heroImage?: string
11+
heroAlt?: string
12+
heroText?: string
13+
tagline?: string
14+
actions?: {
15+
text: string
16+
link: string
17+
type?: 'primary' | 'secondary'
18+
}[]
19+
features?: {
20+
title: string
21+
details: string
22+
}[]
23+
footer?: string
24+
}
25+
26+
export interface DefaultThemePageFrontmatter {
27+
home?: boolean
28+
editLink?: boolean
29+
lastUpdated?: boolean
30+
contributors?: boolean
31+
prev?: string | NavLink
32+
next?: string | NavLink
33+
sidebar?: 'auto' | false | SidebarConfig
34+
}

0 commit comments

Comments
 (0)