123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- <script setup lang="ts">
- import { type Ref, inject } from 'vue'
- import type { DefaultTheme } from 'vitepress/theme'
- import VPButton from 'vitepress/dist/client/theme-default/components/VPButton.vue'
- import Hero from './icons/hero.vue';
- export interface HeroAction {
- theme?: 'brand' | 'alt'
- text: string
- link: string
- target?: string
- rel?: string
- }
- defineProps<{
- name?: string
- text?: string
- tagline?: string
- image?: DefaultTheme.ThemeableImage
- actions?: HeroAction[]
- }>()
- const heroImageSlotExists = inject('hero-image-slot-exists') as Ref<boolean>
- </script>
- <template>
- <div class="VPHero" :class="{ 'has-image': image || heroImageSlotExists }">
- <div class="container">
- <div class="main">
- <slot name="home-hero-info-before" />
- <slot name="home-hero-info">
- <h1 v-if="name" class="name">
- <span v-html="name" class="clip"></span>
- </h1>
- <p v-if="text" v-html="text" class="text"></p>
- <p v-if="tagline" v-html="tagline" class="tagline"></p>
- </slot>
- <slot name="home-hero-info-after" />
- <div v-if="actions" class="actions">
- <div v-for="action in actions" :key="action.link" class="action">
- <VPButton
- tag="a"
- size="medium"
- :theme="action.theme"
- :text="action.text"
- :href="action.link"
- :target="action.target"
- :rel="action.rel"
- />
- </div>
- </div>
- <slot name="home-hero-actions-after" />
- </div>
- <div class="image">
- <div class="image-container">
- <div class="image-bg" />
- <slot name="home-hero-image">
- <Hero />
- </slot>
- </div>
- </div>
- </div>
- </div>
- </template>
- <style scoped>
- .VPHero {
- margin-top: calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);
- padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px;
- }
- @media (min-width: 640px) {
- .VPHero {
- padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px;
- }
- }
- @media (min-width: 960px) {
- .VPHero {
- padding: calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px;
- }
- }
- .container {
- display: flex;
- flex-direction: column;
- margin: 0 auto;
- max-width: 1152px;
- }
- @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;
- width: calc((100% / 3) * 2);
- }
- .VPHero.has-image .main {
- max-width: 592px;
- }
- }
- .name,
- .text {
- max-width: 392px;
- letter-spacing: -0.4px;
- line-height: 40px;
- font-size: 32px;
- font-weight: 700;
- white-space: pre-wrap;
- }
- .VPHero.has-image .name,
- .VPHero.has-image .text {
- margin: 0 auto;
- }
- .name {
- color: var(--vp-home-hero-name-color);
- }
- .clip {
- background: var(--vp-home-hero-name-background);
- -webkit-background-clip: text;
- background-clip: text;
- -webkit-text-fill-color: var(--vp-home-hero-name-color);
- }
- @media (min-width: 640px) {
- .name,
- .text {
- max-width: 576px;
- line-height: 56px;
- font-size: 48px;
- }
- }
- @media (min-width: 960px) {
- .name,
- .text {
- line-height: 64px;
- font-size: 56px;
- }
- .VPHero.has-image .name,
- .VPHero.has-image .text {
- margin: 0;
- }
- }
- .tagline {
- padding-top: 8px;
- max-width: 392px;
- line-height: 28px;
- font-size: 18px;
- font-weight: 500;
- white-space: pre-wrap;
- color: var(--vp-c-text-2);
- }
- .VPHero.has-image .tagline {
- margin: 0 auto;
- }
- @media (min-width: 640px) {
- .tagline {
- padding-top: 12px;
- max-width: 576px;
- line-height: 32px;
- font-size: 20px;
- }
- }
- @media (min-width: 960px) {
- .tagline {
- line-height: 36px;
- font-size: 24px;
- }
- .VPHero.has-image .tagline {
- margin: 0;
- }
- }
- .actions {
- display: flex;
- flex-wrap: wrap;
- margin: -6px;
- padding-top: 24px;
- }
- .VPHero.has-image .actions {
- justify-content: center;
- }
- @media (min-width: 640px) {
- .actions {
- padding-top: 32px;
- }
- }
- @media (min-width: 960px) {
- .VPHero.has-image .actions {
- justify-content: flex-start;
- }
- }
- .action {
- flex-shrink: 0;
- padding: 6px;
- }
- .image {
- order: 1;
- margin: -76px -24px -48px;
- }
- @media (min-width: 640px) {
- .image {
- margin: -108px -24px -48px;
- }
- }
- @media (min-width: 960px) {
- .image {
- flex-grow: 1;
- order: 2;
- margin: 0;
- min-height: 100%;
- }
- }
- .image-container {
- position: relative;
- margin: 0 auto;
- width: 320px;
- height: 320px;
- }
- @media (min-width: 640px) {
- .image-container {
- width: 392px;
- height: 392px;
- }
- }
- @media (min-width: 960px) {
- .image-container {
- display: flex;
- justify-content: center;
- align-items: center;
- width: 100%;
- height: 100%;
- /*rtl:ignore*/
- transform: translate(-32px, -32px);
- }
- }
- .image-bg {
- position: absolute;
- top: 50%;
- /*rtl:ignore*/
- left: 50%;
- border-radius: 50%;
- width: 192px;
- height: 192px;
- background-image: var(--vp-home-hero-image-background-image);
- filter: var(--vp-home-hero-image-filter);
- /*rtl:ignore*/
- transform: translate(-50%, -50%);
- }
- @media (min-width: 640px) {
- .image-bg {
- width: 256px;
- height: 256px;
- }
- }
- @media (min-width: 960px) {
- .image-bg {
- width: 320px;
- height: 320px;
- }
- }
- :deep(.image-src) {
- position: absolute;
- top: 50%;
- /*rtl:ignore*/
- left: 50%;
- max-width: 192px;
- max-height: 192px;
- /*rtl:ignore*/
- transform: translate(-50%, -50%);
- }
- @media (min-width: 640px) {
- :deep(.image-src) {
- max-width: 256px;
- max-height: 256px;
- }
- }
- @media (min-width: 960px) {
- :deep(.image-src) {
- max-width: 320px;
- max-height: 320px;
- }
- }
- </style>
|