feat: add image feature to home hero

pull/685/head
Kia King Ishii 3 years ago
parent c219c0f1dd
commit 1aeebecbcf

@ -2,11 +2,11 @@
layout: home layout: home
title: VitePress title: VitePress
titleTemplate: Vite & Vue powered static site generator. titleTemplate: Vite & Vue Powered Static Site Generator
hero: hero:
name: VitePress name: VitePress
text: Vite & Vue powered static site generator. text: Vite & Vue Powered Static Site Generator
tagline: Simple, minimal, yet strikingly powerful. Meet the modern SSG framework you've always wanted. tagline: Simple, minimal, yet strikingly powerful. Meet the modern SSG framework you've always wanted.
actions: actions:
- theme: brand - theme: brand

@ -17,7 +17,7 @@ defineProps<{
<style scoped> <style scoped>
.VPBox { .VPBox {
border: 1px solid var(--vp-c-divider-light); border: 1px solid var(--vp-c-divider-light);
border-radius: 8px; border-radius: 12px;
padding: 24px; padding: 24px;
height: 100%; height: 100%;
background-color: var(--vp-c-bg-soft); background-color: var(--vp-c-bg-soft);

@ -42,7 +42,6 @@ const component = computed(() => {
.VPButton { .VPButton {
display: inline-block; display: inline-block;
border: 1px solid transparent; border: 1px solid transparent;
text-align: center; text-align: center;
font-weight: 500; font-weight: 500;
white-space: nowrap; white-space: nowrap;

@ -7,17 +7,24 @@ export interface HeroAction {
link: string link: string
} }
export interface Image {
light: string
dark: string
}
defineProps<{ defineProps<{
name?: string name?: string
text: string text: string
tagline?: string tagline?: string
image?: Image
actions?: HeroAction[] actions?: HeroAction[]
}>() }>()
</script> </script>
<template> <template>
<div class="VPHero"> <div class="VPHero" :class="{ 'has-image': image }">
<div class="container"> <div class="container">
<div class="main">
<p v-if="name" class="name"><span class="clip">{{ name }}</span></p> <p v-if="name" class="name"><span class="clip">{{ name }}</span></p>
<h1 v-if="text" class="text">{{ text }}</h1> <h1 v-if="text" class="text">{{ text }}</h1>
<p v-if="tagline" class="tagline">{{ tagline }}</p> <p v-if="tagline" class="tagline">{{ tagline }}</p>
@ -26,7 +33,7 @@ defineProps<{
<div v-for="action in actions" :key="action.link" class="action"> <div v-for="action in actions" :key="action.link" class="action">
<VPButton <VPButton
tag="a" tag="a"
size="big" size="medium"
:theme="action.theme" :theme="action.theme"
:text="action.text" :text="action.text"
:href="action.link" :href="action.link"
@ -34,6 +41,14 @@ defineProps<{
</div> </div>
</div> </div>
</div> </div>
<div v-if="image" class="image">
<div class="image-container">
<img class="image-src light" :src="image.light">
<img class="image-src dark" :src="image.dark">
</div>
</div>
</div>
</div> </div>
</template> </template>
@ -41,6 +56,7 @@ defineProps<{
.VPHero { .VPHero {
margin-top: calc(var(--vp-nav-height) * -1); margin-top: calc(var(--vp-nav-height) * -1);
padding: calc(var(--vp-nav-height) + 48px) 24px 48px; padding: calc(var(--vp-nav-height) + 48px) 24px 48px;
overflow: hidden;
} }
@media (min-width: 640px) { @media (min-width: 640px) {
@ -50,66 +66,113 @@ defineProps<{
} }
.container { .container {
display: flex;
flex-direction: column;
margin: 0 auto; margin: 0 auto;
max-width: 960px; max-width: 960px;
} }
@media (min-width: 960px) {
.container {
flex-direction: row;
}
}
.main {
position: relative;
z-index: 10;
order: 2;
flex-grow: 1;
flex-shrink: 0;
}
.VPHero.has-image .container {
text-align: center;
}
@media (min-width: 960px) {
.VPHero.has-image .container {
text-align: left;
}
}
@media (min-width: 960px) {
.main {
order: 1;
}
}
@media (min-width: 960px) {
.main {
width: 100%;
max-width: calc((100% / 3) * 2);
}
}
.name, .name,
.text { .text {
line-height: 48px; max-width: 392px;
font-size: 40px; letter-spacing: -0.4px;
line-height: 40px;
font-size: 32px;
font-weight: 700; font-weight: 700;
} }
.VPHero.has-image .name,
.VPHero.has-image .text {
margin: 0 auto;
}
.name { .name {
padding-bottom: 4px;
color: var(--vp-home-hero-name-color); color: var(--vp-home-hero-name-color);
} }
.clip { .clip {
background: var(--vp-home-hero-name-background); background: var(--vp-home-hero-name-background);
-webkit-text-fill-color: var(--vp-home-hero-name-color);
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: var(--vp-home-hero-name-color);
} }
@media (min-width: 640px) { @media (min-width: 640px) {
.name, .name,
.text { .text {
max-width: 640px; max-width: 576px;
line-height: 56px; line-height: 56px;
font-size: 48px; font-size: 48px;
} }
.name {
padding-bottom: 6px;
}
} }
@media (min-width: 960px) { @media (min-width: 960px) {
.name, .name,
.text { .text {
max-width: 720px;
line-height: 64px; line-height: 64px;
font-size: 56px; font-size: 56px;
} }
.name { .VPHero.has-image .name,
padding-bottom: 6px; .VPHero.has-image .text {
margin: 0;
} }
} }
.tagline { .tagline {
padding-top: 16px; padding-top: 16px;
max-width: 392px;
line-height: 28px; line-height: 28px;
font-size: 18px; font-size: 18px;
font-weight: 500; font-weight: 500;
color: var(--vp-c-text-2); color: var(--vp-c-text-2);
} }
.VPHero.has-image .tagline {
margin: 0 auto;
}
@media (min-width: 640px) { @media (min-width: 640px) {
.tagline { .tagline {
padding-top: 24px; padding-top: 24px;
max-width: 540px; max-width: 576px;
line-height: 32px; line-height: 32px;
font-size: 20px; font-size: 20px;
} }
@ -118,27 +181,105 @@ defineProps<{
@media (min-width: 960px) { @media (min-width: 960px) {
.tagline { .tagline {
padding-top: 24px; padding-top: 24px;
max-width: 640px;
line-height: 36px; line-height: 36px;
font-size: 24px; font-size: 24px;
} }
.VPHero.has-image .tagline {
margin: 0;
}
} }
.actions { .actions {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
margin: -8px; margin: -6px;
padding-top: 24px; padding-top: 24px;
} }
.VPHero.has-image .actions {
justify-content: center;
}
@media (min-width: 640px) { @media (min-width: 640px) {
.actions { .actions {
padding-top: 32px; padding-top: 32px;
} }
} }
@media (min-width: 960px) {
.VPHero.has-image .actions {
justify-content: flex-start;
}
}
.action { .action {
flex-shrink: 0; flex-shrink: 0;
padding: 8px; padding: 6px;
}
.image {
order: 1;
margin: -76px -24px -48px;
}
@media (min-width: 640px) {
.image {
margin: -108px -24px -48px;
}
}
.image-container {
position: relative;
margin: 0 auto;
width: 320px;
height: 320px;
}
@media (min-width: 640px) {
.image-container {
width: 392px;
height: 392px;
}
}
.image-src {
position: absolute;
top: 50%;
left: 50%;
max-width: 392px;
transform: translate(-50%, -50%);
}
.image-src.light { opacity: 1; }
.image-src.dark { opacity: 0; }
.dark .image-src.light { opacity: 0; }
.dark .image-src.dark { opacity: 1; }
@media (min-width: 640px) {
.image-src {
max-width: 512px;
transform: translate(-50%, -50%);
}
}
@media (min-width: 960px) {
.image {
order: 2;
margin: -8px 0;
width: calc(100% / 3);
min-height: 100%;
}
.image-container {
width: 100%;
height: 100%;
}
.image-src {
max-width: 640px;
transform: translate(calc(-50% - 32px), calc(-50% - 32px));
}
} }
</style> </style>

@ -42,6 +42,7 @@ const grid = computed(() => {
<style scoped> <style scoped>
.VPHomeFeatures { .VPHomeFeatures {
position: relative;
padding: 0 24px; padding: 0 24px;
} }

@ -11,6 +11,7 @@ const { frontmatter: fm } = useData()
:name="fm.hero.name" :name="fm.hero.name"
:text="fm.hero.text" :text="fm.hero.text"
:tagline="fm.hero.tagline" :tagline="fm.hero.tagline"
:image="fm.hero.image"
:actions="fm.hero.actions" :actions="fm.hero.actions"
/> />
</div> </div>

@ -42,7 +42,7 @@ defineProps<{
.VPMenu :deep(.group + .group) { .VPMenu :deep(.group + .group) {
border-top: 1px solid var(--vp-c-divider-light); border-top: 1px solid var(--vp-c-divider-light);
padding: 11px 0 12px; padding: 11px 12px 12px;
} }
.VPMenu :deep(.group:last-child) { .VPMenu :deep(.group:last-child) {

@ -53,10 +53,6 @@ const { site, theme } = useData()
} }
} }
.trans {
padding: 2px 16px 0;
}
.trans-title { .trans-title {
padding: 0 24px 0 12px; padding: 0 24px 0 12px;
line-height: 32px; line-height: 32px;
@ -69,7 +65,7 @@ const { site, theme } = useData()
.item.social-links { .item.social-links {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0 24px; padding: 0 12px;
} }
.item.appearance { .item.appearance {

@ -119,6 +119,10 @@ object {
vertical-align: middle; vertical-align: middle;
} }
figure {
margin: 0;
}
img, img,
video { video {
max-width: 100%; max-width: 100%;

Loading…
Cancel
Save