Skip to content

Commit 6b76c77

Browse files
authored
feat(themes): new themes page (vuejs#1273)
1 parent 2be7404 commit 6b76c77

File tree

10 files changed

+682
-3
lines changed

10 files changed

+682
-3
lines changed

src/ecosystem/partners/PartnerHero.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
.PartnerHero :deep(.link) {
6060
color: var(--vt-c-brand);
6161
}
62+
6263
.PartnerHero :deep(.link:hover) {
6364
color: var(--vt-c-brand-dark);
6465
}

src/ecosystem/partners/PartnerListItem.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
<script setup lang="ts">
2-
import { defineProps } from 'vue'
32
import {
43
VTIconFacebook,
54
VTIconGitHub,

src/ecosystem/themes.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1-
# Themes
1+
---
2+
page: true
3+
---
24

3-
<!-- <community-themes-index/> -->
5+
<script setup>
6+
import ThemePage from './themes/ThemePage.vue'
7+
</script>
8+
9+
<ThemePage />

src/ecosystem/themes/ThemeContact.vue

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<template>
2+
<aside class="ThemeContact">
3+
<p class="text">
4+
<slot />
5+
</p>
6+
</aside>
7+
</template>
8+
9+
<style scoped>
10+
.ThemeContact {
11+
padding: 32px 24px;
12+
border-bottom: 1px solid var(--vt-c-divider-light);
13+
background-color: var(--vt-c-bg-soft);
14+
transition: border-color 0.25s, background-color 0.25s;
15+
}
16+
17+
.dark .ThemeContact {
18+
border-bottom-color: var(--vt-c-bg-soft);
19+
}
20+
21+
@media (min-width: 768px) {
22+
.ThemeContact {
23+
padding: 48px 32px;
24+
}
25+
}
26+
27+
.container {
28+
margin: 0 auto;
29+
max-width: 960px;
30+
}
31+
32+
.text {
33+
text-align: center;
34+
line-height: 24px;
35+
font-size: 16px;
36+
font-weight: 500;
37+
transition: color 0.25s;
38+
}
39+
40+
.text :deep(.link) {
41+
color: var(--vt-c-brand);
42+
white-space: nowrap;
43+
transition: color 0.25s;
44+
}
45+
46+
.text :deep(.link:hover) {
47+
color: var(--vt-c-brand-dark);
48+
}
49+
</style>

src/ecosystem/themes/ThemeHero.vue

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<template>
2+
<div class="ThemeHero">
3+
<div class="container">
4+
<h1 class="title">
5+
<slot name="title" />
6+
</h1>
7+
<p class="lead">
8+
<slot name="lead" />
9+
</p>
10+
</div>
11+
</div>
12+
</template>
13+
14+
<style scoped>
15+
.ThemeHero {
16+
padding: 48px 24px;
17+
}
18+
19+
@media (min-width: 768px) {
20+
.ThemeHero {
21+
padding: 64px 32px 48px;
22+
}
23+
}
24+
25+
.container {
26+
margin: 0 auto;
27+
max-width: 960px;
28+
}
29+
30+
.title,
31+
.lead {
32+
transition: color 0.25s;
33+
}
34+
35+
.title {
36+
line-height: 32px;
37+
font-size: 32px;
38+
font-weight: 500;
39+
}
40+
41+
@media (min-width: 768px) {
42+
.title {
43+
line-height: 40px;
44+
font-size: 40px;
45+
}
46+
}
47+
48+
.lead {
49+
padding-top: 8px;
50+
font-size: 16px;
51+
font-weight: 500;
52+
max-width: 512px;
53+
color: var(--vt-c-text-2);
54+
}
55+
</style>

src/ecosystem/themes/ThemeList.vue

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<script setup lang="ts">
2+
import themes from './themes.json'
3+
import ThemeListItem from './ThemeListItem.vue'
4+
</script>
5+
6+
<template>
7+
<div class="ThemeList">
8+
<div class="container">
9+
<div v-for="provider in themes" :key="provider.name" class="item">
10+
<ThemeListItem :provider="provider" />
11+
</div>
12+
</div>
13+
</div>
14+
</template>
15+
16+
<style scoped>
17+
.ThemeList {
18+
padding: 0 24px 96px;
19+
}
20+
21+
@media (min-width: 768px) {
22+
.ThemeList {
23+
padding: 0 32px 96px;
24+
}
25+
}
26+
27+
.container {
28+
margin: 0 auto;
29+
max-width: 960px;
30+
}
31+
32+
.item + .item {
33+
padding-top: 48px;
34+
}
35+
36+
@media (min-width: 768px) {
37+
.item + .item {
38+
padding-top: 64px;
39+
}
40+
}
41+
</style>
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<script setup lang="ts">
2+
import { computed } from 'vue'
3+
import { VTLink } from '@vue/theme'
4+
import ThemeProduct from './ThemeProduct.vue'
5+
6+
const props = defineProps({
7+
provider: { type: Object, required: true }
8+
})
9+
10+
const regex = /\[([^\[]+)\](\(.*\))/gm
11+
12+
const description = computed(() => {
13+
// replace markdown link to html tag.
14+
// [name](https://...) -> <a href="https://...">name</a>
15+
return props.provider.description.replace(
16+
/\[([^\]]+)\]\(([^\)]+)\)/,
17+
'<a href="$2" class="link" target="_blank" rel="noopener">$1</a>'
18+
)
19+
})
20+
</script>
21+
22+
<template>
23+
<section class="ThemeListItem">
24+
<h2 class="title">{{ provider.name }}</h2>
25+
<p class="description" v-html="description" />
26+
27+
<div class="container">
28+
<div class="products">
29+
<div v-for="product in provider.products" :key="product.name" class="product">
30+
<ThemeProduct :product="product" />
31+
</div>
32+
</div>
33+
</div>
34+
35+
<div class="action">
36+
<VTLink class="action-link" :href="provider.seeMoreUrl" no-icon>
37+
See More Themes from {{ provider.name }}
38+
</VTLink>
39+
</div>
40+
</section>
41+
</template>
42+
43+
<style scoped>
44+
.ThemeListItem {
45+
border-top: 1px solid var(--vt-c-divider-light);
46+
padding-top: 16px;
47+
}
48+
49+
@media (min-width: 768px) {
50+
.ThemeListItem {
51+
padding-top: 24px;
52+
}
53+
}
54+
55+
.title {
56+
font-size: 20px;
57+
font-weight: 500;
58+
transition: color 0.25s;
59+
}
60+
61+
.description {
62+
padding-top: 8px;
63+
font-size: 14px;
64+
font-weight: 500;
65+
max-width: 512px;
66+
color: var(--vt-c-text-2);
67+
transition: color 0.25s;
68+
}
69+
70+
.description :deep(.link) {
71+
color: var(--vt-c-brand);
72+
transition: color 0.25s;
73+
}
74+
75+
.description :deep(.link:hover) {
76+
color: var(--vt-c-brand-dark);
77+
}
78+
79+
.container {
80+
margin: 0 auto;
81+
padding-top: 32px;
82+
max-width: 304px;
83+
}
84+
85+
@media (min-width: 640px) {
86+
.container {
87+
max-width: 632px;
88+
}
89+
}
90+
91+
@media (min-width: 960px) {
92+
.container {
93+
max-width: 960px;
94+
}
95+
}
96+
97+
.products {
98+
display: flex;
99+
flex-wrap: wrap;
100+
margin: -16px -12px;
101+
}
102+
103+
.product {
104+
flex-shrink: 0;
105+
padding: 16px 12px;
106+
width: 100%;
107+
}
108+
109+
@media (min-width: 640px) {
110+
.product {
111+
width: 50%;
112+
}
113+
}
114+
115+
@media (min-width: 960px) {
116+
.product {
117+
width: calc(100% / 3);
118+
}
119+
}
120+
121+
.action {
122+
padding-top: 40px;
123+
text-align: center;
124+
}
125+
126+
.action-link {
127+
display: inline-block;
128+
border: 1px solid var(--vt-c-brand);
129+
border-radius: 24px;
130+
padding: 0 24px;
131+
line-height: 48px;
132+
font-size: 14px;
133+
font-weight: 500;
134+
color: var(--vt-c-brand);
135+
transition: border-color 0.25s, color 0.25s;
136+
}
137+
138+
.action-link:hover {
139+
border-color: var(--vt-c-brand-dark);
140+
color: var(--vt-c-brand-dark);
141+
}
142+
</style>

src/ecosystem/themes/ThemePage.vue

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script setup lang="ts">
2+
import ThemeHero from './ThemeHero.vue'
3+
import ThemeList from './ThemeList.vue'
4+
import ThemeContact from './ThemeContact.vue'
5+
</script>
6+
7+
<template>
8+
<div class="ThemePage">
9+
<ThemeHero>
10+
<template #title>Themes</template>
11+
<template #lead>Check out the themes, UI Kits, and plugins. you can see how a real world application is built with Vue by our partners.</template>
12+
</ThemeHero>
13+
14+
<ThemeList />
15+
16+
<ThemeContact>
17+
Want to feature your themes here? <a class="link" href="mailto:[email protected]?subject=Theme+affiliation">Contact us!</a>
18+
</ThemeContact>
19+
</div>
20+
</template>

0 commit comments

Comments
 (0)