HomeHero.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <script setup lang="ts">
  2. import { computed } from 'vue'
  3. import { useData, withBase } from 'vitepress'
  4. import NavLink from './NavLink.vue'
  5. const { site, frontmatter } = useData()
  6. const showHero = computed(() => {
  7. const { heroImage, heroText, tagline, actionLink, actionText } =
  8. frontmatter.value
  9. return heroImage || heroText || tagline || (actionLink && actionText)
  10. })
  11. const heroText = computed(() => frontmatter.value.heroText || site.value.title)
  12. const tagline = computed(
  13. () => frontmatter.value.tagline || site.value.description
  14. )
  15. </script>
  16. <template>
  17. <header v-if="showHero" class="home-hero">
  18. <figure v-if="frontmatter.heroImage" class="figure">
  19. <img
  20. class="image"
  21. :src="withBase(frontmatter.heroImage)"
  22. :alt="frontmatter.heroAlt"
  23. />
  24. </figure>
  25. <h1 v-if="heroText" id="main-title" class="title">{{ heroText }}</h1>
  26. <p v-if="tagline" class="tagline">{{ tagline }}</p>
  27. <NavLink
  28. v-if="frontmatter.actionLink && frontmatter.actionText"
  29. :item="{ link: frontmatter.actionLink, text: frontmatter.actionText }"
  30. class="action"
  31. />
  32. <NavLink
  33. v-if="frontmatter.altActionLink && frontmatter.altActionText"
  34. :item="{
  35. link: frontmatter.altActionLink,
  36. text: frontmatter.altActionText
  37. }"
  38. class="action alt"
  39. />
  40. </header>
  41. </template>
  42. <style scoped>
  43. .home-hero {
  44. margin: 2.5rem 0 2.75rem;
  45. padding: 0 1.5rem;
  46. text-align: center;
  47. }
  48. @media (min-width: 420px) {
  49. .home-hero {
  50. margin: 3.5rem 0;
  51. }
  52. }
  53. @media (min-width: 720px) {
  54. .home-hero {
  55. margin: 4rem 0 4.25rem;
  56. }
  57. }
  58. .figure {
  59. padding: 0 1.5rem;
  60. }
  61. .image {
  62. display: block;
  63. margin: 0 auto;
  64. width: auto;
  65. max-width: 100%;
  66. max-height: 280px;
  67. }
  68. .title {
  69. margin-top: 1.5rem;
  70. font-size: 2rem;
  71. }
  72. @media (min-width: 420px) {
  73. .title {
  74. font-size: 3rem;
  75. }
  76. }
  77. @media (min-width: 720px) {
  78. .title {
  79. margin-top: 2rem;
  80. }
  81. }
  82. .tagline {
  83. margin: 0;
  84. margin-top: 0.25rem;
  85. line-height: 1.3;
  86. font-size: 1.2rem;
  87. color: var(--c-text-light);
  88. }
  89. @media (min-width: 420px) {
  90. .tagline {
  91. line-height: 1.2;
  92. font-size: 1.6rem;
  93. }
  94. }
  95. .action {
  96. margin-top: 1.5rem;
  97. display: inline-block;
  98. }
  99. .action.alt {
  100. margin-left: 1.5rem;
  101. }
  102. @media (min-width: 420px) {
  103. .action {
  104. margin-top: 2rem;
  105. display: inline-block;
  106. }
  107. }
  108. .action :deep(.item) {
  109. display: inline-block;
  110. border-radius: 6px;
  111. padding: 0 20px;
  112. line-height: 44px;
  113. font-size: 1rem;
  114. font-weight: 500;
  115. color: var(--c-bg);
  116. background-color: var(--c-brand);
  117. border: 2px solid var(--c-brand);
  118. transition: background-color 0.1s ease;
  119. }
  120. .action.alt :deep(.item) {
  121. background-color: var(--c-bg);
  122. color: var(--c-brand);
  123. }
  124. .action :deep(.item:hover) {
  125. text-decoration: none;
  126. color: var(--c-bg);
  127. background-color: var(--c-brand-light);
  128. }
  129. @media (min-width: 420px) {
  130. .action :deep(.item) {
  131. padding: 0 24px;
  132. line-height: 52px;
  133. font-size: 1.2rem;
  134. font-weight: 500;
  135. }
  136. }
  137. </style>