feat: add mini sponsor component (#648)

close #648
pull/672/head
Kia King Ishii 2 years ago
parent 12e1a12d1e
commit aa2289e488

@ -172,7 +172,14 @@ export default {
Full list of slots available in the default theme layout: Full list of slots available in the default theme layout:
- Only when `layout: 'home'` is enabled via frontmatter: - When `layout: 'doc'` (default) is enabled via frontmatter:
- `aside-top`
- `aside-bottom`
- `aside-outline-before`
- `aside-outline-after`
- `aside-ads-before`
- `aside-ads-after`
- When `layout: 'home'` is enabled via frontmatter:
- `home-hero-before` - `home-hero-before`
- `home-hero-after` - `home-hero-after`
- `home-features-before` - `home-features-before`

@ -33,6 +33,13 @@ provide('close-sidebar', closeSidebar)
<template #home-hero-after><slot name="home-hero-after" /></template> <template #home-hero-after><slot name="home-hero-after" /></template>
<template #home-features-before><slot name="home-features-before" /></template> <template #home-features-before><slot name="home-features-before" /></template>
<template #home-features-after><slot name="home-features-after" /></template> <template #home-features-after><slot name="home-features-after" /></template>
<template #aside-top><slot name="aside-top" /></template>
<template #aside-bottom><slot name="aside-bottom" /></template>
<template #aside-outline-before><slot name="aside-outline-before" /></template>
<template #aside-outline-after><slot name="aside-outline-after" /></template>
<template #aside-ads-before><slot name="aside-ads-before" /></template>
<template #aside-ads-after><slot name="aside-ads-after" /></template>
</VPContent> </VPContent>
<VPFooter /> <VPFooter />

@ -36,7 +36,7 @@ defineProps<{
} }
.dark .icon { .dark .icon {
background-color: var(--vp-c-bg-soft); background-color: var(--vp-c-bg);
} }
.title { .title {

@ -47,13 +47,13 @@ if (carbonOptions) {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 24px; padding: 24px;
border-radius: 8px; border-radius: 12px;
min-height: 240px; min-height: 240px;
text-align: center; text-align: center;
line-height: 18px; line-height: 18px;
font-size: 12px; font-size: 12px;
font-weight: 500; font-weight: 500;
background-color: var(--vp-c-bg-alt); background-color: var(--vp-c-bg-soft);
transition: color 0.5s, background-color 0.5s; transition: color 0.5s, background-color 0.5s;
} }

@ -34,7 +34,14 @@ useCopyCode()
<template #home-features-after><slot name="home-features-after" /></template> <template #home-features-after><slot name="home-features-after" /></template>
</VPHome> </VPHome>
<VPDoc v-else /> <VPDoc v-else>
<template #aside-top><slot name="aside-top" /></template>
<template #aside-outline-before><slot name="aside-outline-before" /></template>
<template #aside-outline-after><slot name="aside-outline-after" /></template>
<template #aside-ads-before><slot name="aside-ads-before" /></template>
<template #aside-ads-after><slot name="aside-ads-after" /></template>
<template #aside-bottom><slot name="aside-bottom" /></template>
</VPDoc>
</div> </div>
</template> </template>

@ -20,7 +20,14 @@ const pageName = computed(() => {
<div class="aside-curtain" /> <div class="aside-curtain" />
<div class="aside-container"> <div class="aside-container">
<div class="aside-content"> <div class="aside-content">
<VPDocAside /> <VPDocAside>
<template #aside-top><slot name="aside-top" /></template>
<template #aside-bottom><slot name="aside-bottom" /></template>
<template #aside-outline-before><slot name="aside-outline-before" /></template>
<template #aside-outline-after><slot name="aside-outline-after" /></template>
<template #aside-ads-before><slot name="aside-ads-before" /></template>
<template #aside-ads-after><slot name="aside-ads-after" /></template>
</VPDocAside>
</div> </div>
</div> </div>
</div> </div>
@ -126,8 +133,8 @@ const pageName = computed(() => {
bottom: 0; bottom: 0;
z-index: 10; z-index: 10;
width: 224px; width: 224px;
height: 64px; height: 88px;
background: linear-gradient(transparent, var(--vp-c-bg) 80%); background: linear-gradient(transparent, var(--vp-c-bg) 70%);
} }
.aside-content { .aside-content {

@ -8,13 +8,27 @@ const { page, theme } = useData()
<template> <template>
<div class="VPDocAside"> <div class="VPDocAside">
<slot name="aside-top" />
<slot name="aside-outline-before" />
<VPDocAsideOutline v-if="page.headers.length" /> <VPDocAsideOutline v-if="page.headers.length" />
<slot name="aside-outline-after" />
<slot name="aside-ads-before" />
<VPDocAsideCarbonAds v-if="theme.carbonAds" /> <VPDocAsideCarbonAds v-if="theme.carbonAds" />
<slot name="aside-ads-after" />
<slot name="aside-bottom" />
</div> </div>
</template> </template>
<style scoped> <style scoped>
.VPDocAside :deep(.VPDocAsideOutline + .VPDocAsideSponsors),
.VPDocAside :deep(.VPDocAsideOutline + .VPDocAsideCarbonAds) { .VPDocAside :deep(.VPDocAsideOutline + .VPDocAsideCarbonAds) {
margin-top: 24px; margin-top: 24px;
} }
.VPDocAside :deep(.VPDocAsideSponsors + .VPDocAsideCarbonAds) {
margin-top: 16px;
}
</style> </style>

@ -0,0 +1,32 @@
<script setup lang="ts">
import VPSponsors from './VPSponsors.vue'
export interface Sponsors {
tier?: string
size?: 'xmini' | 'mini' | 'small'
items: Sponsor[]
}
export interface Sponsor {
name: string
img: string
url: string
}
defineProps<{
tier?: string
size?: 'xmini' | 'mini' | 'small'
data: Sponsors[] | Sponsor[]
}>()
</script>
<template>
<div class="VPDocAsideSponsors">
<VPSponsors
mode="aside"
:tier="tier"
:size="size"
:data="data"
/>
</div>
</template>

@ -27,6 +27,10 @@ defineProps<{
.VPMenuLink:hover { .VPMenuLink:hover {
color: var(--vp-c-brand); color: var(--vp-c-brand);
background-color: var(--vp-c-bg-mute);
}
.dark .VPMenuLink:hover {
background-color: var(--vp-c-bg-soft); background-color: var(--vp-c-bg-soft);
} }
</style> </style>

@ -15,13 +15,16 @@ export interface Sponsor {
} }
const props = defineProps<{ const props = defineProps<{
mode?: 'normal' | 'aside'
tier?: string tier?: string
size?: 'small' | 'medium' | 'big' size?: 'xmini' | 'small' | 'medium' | 'big'
data: Sponsors[] | Sponsor[] data: Sponsors[] | Sponsor[]
}>() }>()
const sponsors = computed(() => { const sponsors = computed(() => {
const isSponsors = props.data.some((s: any) => s.items) const isSponsors = props.data.some((s) => {
return !!(s as Sponsors).items
})
if (isSponsors) { if (isSponsors) {
return props.data return props.data
@ -36,42 +39,14 @@ const sponsors = computed(() => {
</script> </script>
<template> <template>
<div class="VPSponsors"> <div class="VPSponsors vp-sponsor" :class="[mode ?? 'normal']">
<section v-for="(sponsor, index) in sponsors" :key="index" class="section"> <section
<h3 v-if="sponsor.tier" class="tier">{{ sponsor.tier }}</h3> v-for="(sponsor, index) in sponsors"
:key="index"
class="vp-sponsor-section"
>
<h3 v-if="sponsor.tier" class="vp-sponsor-tier">{{ sponsor.tier }}</h3>
<VPSponsorsGrid :size="sponsor.size" :data="sponsor.items" /> <VPSponsorsGrid :size="sponsor.size" :data="sponsor.items" />
</section> </section>
</div> </div>
</template> </template>
<style scoped>
.VPSponsors {
border-radius: 16px;
overflow: hidden;
}
.section + .section {
margin-top: 4px;
}
.tier {
margin-bottom: 4px;
padding: 13px 0 11px;
text-align: center;
letter-spacing: 1px;
line-height: 24px;
width: 100%;
font-size: 14px;
font-weight: 600;
color: var(--vp-c-text-2);
background-color: var(--vp-c-white-soft);
}
.dark .tier {
background-color: var(--vp-c-black-mute);
}
.VPSponsorsGrid + .tier {
margin-top: 4px;
}
</style>

@ -9,7 +9,7 @@ export interface Sponsor {
} }
const props = defineProps<{ const props = defineProps<{
size?: 'small' | 'medium' | 'big' size?: 'xmini' | 'mini' | 'small' | 'medium' | 'big'
data: Sponsor[] data: Sponsor[]
}>() }>()

@ -5,7 +5,7 @@ export interface GridSetting {
[size: string]: [number, number][] [size: string]: [number, number][]
} }
export type GridSize = 'small' | 'medium' | 'big' export type GridSize = 'xmini' | 'mini' | 'small' | 'medium' | 'big'
export interface UseSponsorsGridOprions { export interface UseSponsorsGridOprions {
el: Ref<HTMLElement | null> el: Ref<HTMLElement | null>
@ -17,14 +17,16 @@ export interface UseSponsorsGridOprions {
* *
* [Screen widh, Column size] * [Screen widh, Column size]
* *
* It sets grid size on matching screen size. For example, `[768, 5]` will set * It sets grid size on matching screen size. For example, `[768, 5]` will
* 5 columns when screen size is bigger or equal to 768px. * set 5 columns when screen size is bigger or equal to 768px.
* *
* Column will set only when item size is bigger than the column size. For * Column will set only when item size is bigger than the column size. For
* example, even we want 5 columns, if we only have 1 sponsor yet, we would * example, even we define 5 columns, if we only have 1 sponsor yet, we would
* like to show it in 1 column. * like to show it in 1 column to make it stand out.
*/ */
const GridSettings: GridSetting = { const GridSettings: GridSetting = {
xmini: [[0, 2]],
mini: [],
small: [ small: [
[920, 6], [920, 6],
[768, 5], [768, 5],

@ -15,6 +15,7 @@ export { DefaultTheme } from './config'
export { default as VPHomeHero } from './components/VPHomeHero.vue' export { default as VPHomeHero } from './components/VPHomeHero.vue'
export { default as VPHomeFeatures } from './components/VPHomeFeatures.vue' export { default as VPHomeFeatures } from './components/VPHomeFeatures.vue'
export { default as VPHomeSponsors } from './components/VPHomeSponsors.vue' export { default as VPHomeSponsors } from './components/VPHomeSponsors.vue'
export { default as VPDocAsideSponsors } from './components/VPDocAsideSponsors.vue'
const theme: Theme = { const theme: Theme = {
Layout, Layout,

@ -1,9 +1,57 @@
/**
* VPSponsors styles are defined as global because a new class gets
* allied in onMounted` hook and we can't use socped style.
*/
.vp-sponsor {
border-radius: 16px;
overflow: hidden;
}
.vp-sponsor.aside {
border-radius: 12px;
}
.vp-sponsor-section + .vp-sponsor-section {
margin-top: 4px;
}
.vp-sponsor-tier {
margin-bottom: 4px;
text-align: center;
letter-spacing: 1px;
line-height: 24px;
width: 100%;
font-weight: 600;
color: var(--vp-c-text-2);
background-color: var(--vp-c-bg-soft);
}
.vp-sponsor.normal .vp-sponsor-tier {
padding: 13px 0 11px;
font-size: 14px;
}
.vp-sponsor.aside .vp-sponsor-tier {
padding: 9px 0 7px;
font-size: 12px;
}
.vp-sponsor-grid + .vp-sponsor-tier {
margin-top: 4px;
}
.vp-sponsor-grid { .vp-sponsor-grid {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 4px; gap: 4px;
} }
.vp-sponsor-grid.xmini .vp-sponsor-grid-link { height: 64px; }
.vp-sponsor-grid.xmini .vp-sponsor-grid-image { max-width: 64px; max-height: 22px }
.vp-sponsor-grid.mini .vp-sponsor-grid-link { height: 72px; }
.vp-sponsor-grid.mini .vp-sponsor-grid-image { max-width: 96px; max-height: 24px }
.vp-sponsor-grid.small .vp-sponsor-grid-link { height: 96px; } .vp-sponsor-grid.small .vp-sponsor-grid-link { height: 96px; }
.vp-sponsor-grid.small .vp-sponsor-grid-image { max-width: 96px; max-height: 24px } .vp-sponsor-grid.small .vp-sponsor-grid-image { max-width: 96px; max-height: 24px }
@ -36,12 +84,12 @@
.vp-sponsor-grid-item { .vp-sponsor-grid-item {
flex-shrink: 0; flex-shrink: 0;
width: 100%; width: 100%;
background-color: var(--vp-c-white-soft); background-color: var(--vp-c-bg-soft);
transition: background-color 0.25s; transition: background-color 0.25s;
} }
.vp-sponsor-grid-item:hover { .vp-sponsor-grid-item:hover {
background-color: var(--vp-c-white-mute); background-color: var(--vp-c-bg-mute);
} }
.vp-sponsor-grid-item:hover .vp-sponsor-grid-image { .vp-sponsor-grid-item:hover .vp-sponsor-grid-image {
@ -49,11 +97,7 @@
} }
.vp-sponsor-grid-item.empty:hover { .vp-sponsor-grid-item.empty:hover {
background-color: var(--vp-c-white-soft); background-color: var(--vp-c-bg-soft);
}
.dark .vp-sponsor-grid-item {
background-color: var(--vp-c-black-mute);
} }
.dark .vp-sponsor-grid-item:hover { .dark .vp-sponsor-grid-item:hover {

1
theme.d.ts vendored

@ -4,6 +4,7 @@ import { ComponentOptions } from 'vue'
export const VPHomeHero = ComponentOptions export const VPHomeHero = ComponentOptions
export const VPHomeFeatures = ComponentOptions export const VPHomeFeatures = ComponentOptions
export const VPHomeSponsors = ComponentOptions export const VPHomeSponsors = ComponentOptions
export const VPDocAsideSponsors = ComponentOptions
declare const theme: { declare const theme: {
Layout: ComponentOptions Layout: ComponentOptions

Loading…
Cancel
Save