valaxy-theme-press 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/client/index.ts +1 -0
- package/components/DocsBoard.vue +24 -0
- package/components/PressArticle.vue +15 -10
- package/components/PressArticleCard.vue +6 -2
- package/components/PressAside.vue +87 -0
- package/components/PressBackdrop.vue +39 -0
- package/components/PressButton.vue +31 -0
- package/components/PressCategories.vue +71 -0
- package/components/PressCategory.vue +58 -0
- package/components/PressDocFooter.vue +15 -0
- package/components/PressDocFooterLastUpdated.vue +44 -0
- package/components/PressFeature.vue +61 -0
- package/components/PressFeatures.vue +26 -0
- package/components/PressFooter.vue +53 -0
- package/components/PressHome.vue +15 -0
- package/components/PressHomeFeatures.vue +12 -0
- package/components/PressHomeHero.vue +34 -0
- package/components/PressLocalNav.vue +109 -0
- package/components/PressNav.vue +17 -35
- package/components/PressOutline.vue +111 -0
- package/components/PressOutlineItem.vue +48 -0
- package/components/PressSidebar.vue +88 -0
- package/components/PressToggleLocale.vue +1 -1
- package/components/ValaxyMain.vue +56 -12
- package/components/nav/PressNavBar.vue +111 -0
- package/components/nav/PressNavItemGroup.vue +101 -0
- package/components/nav/PressNavItemLink.vue +39 -0
- package/components/nav/PressSwitchAppearance.vue +71 -0
- package/composables/edit-link.ts +14 -0
- package/composables/index.ts +1 -0
- package/config/index.ts +7 -12
- package/layouts/404.vue +13 -12
- package/layouts/home.vue +1 -7
- package/layouts/layout.vue +52 -39
- package/node/index.ts +1 -42
- package/package.json +16 -15
- package/pages/[..all].vue +15 -0
- package/setup/main.ts +89 -0
- package/styles/css-vars.scss +46 -0
- package/styles/helper.scss +34 -0
- package/styles/index.scss +7 -0
- package/styles/markdown.scss +49 -0
- package/types/home.d.ts +5 -0
- package/types/index.d.ts +71 -0
- package/valaxy.config.ts +38 -0
- package/LICENSE +0 -21
- package/components/PressHeader.vue +0 -26
- package/pages/index.vue +0 -8
- package/tsup.config.ts +0 -16
- package/types/index.ts +0 -30
package/README.md
ADDED
package/client/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../composables'
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { useI18n } from 'vue-i18n'
|
|
3
|
+
|
|
4
|
+
const { t } = useI18n()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<YunBoard m="t-4">
|
|
9
|
+
这里是 Valaxy 的文档兼测试站点
|
|
10
|
+
|
|
11
|
+
<ul>
|
|
12
|
+
<li>
|
|
13
|
+
<router-link to="/docs" :title="t('docs.view_docs')">
|
|
14
|
+
{{ t('docs.view_docs') }}
|
|
15
|
+
</router-link>
|
|
16
|
+
</li>
|
|
17
|
+
<li>
|
|
18
|
+
<router-link class="flex justify-center" to="/examples">
|
|
19
|
+
Examples
|
|
20
|
+
</router-link>
|
|
21
|
+
</li>
|
|
22
|
+
</ul>
|
|
23
|
+
</YunBoard>
|
|
24
|
+
</template>
|
|
@@ -17,15 +17,14 @@ const prevPost = computed(() => posts.value[findCurrentIndex() + 1])
|
|
|
17
17
|
</script>
|
|
18
18
|
|
|
19
19
|
<template>
|
|
20
|
-
<article class="xl:divide-y xl:divide-gray-200">
|
|
21
|
-
<header class="pt-
|
|
20
|
+
<article class="xl:divide-y xl:divide-gray-200 max-w-7xl m-auto" p="x-6" w="full">
|
|
21
|
+
<header class="pt-20 xl:pb-10 space-y-1 text-center">
|
|
22
22
|
<PressDate :date="frontmatter.date" />
|
|
23
23
|
<h1
|
|
24
24
|
class="
|
|
25
25
|
text-3xl
|
|
26
26
|
leading-9
|
|
27
27
|
font-extrabold
|
|
28
|
-
text-gray-900
|
|
29
28
|
tracking-tight
|
|
30
29
|
sm:text-4xl sm:leading-10
|
|
31
30
|
md:text-5xl md:leading-14
|
|
@@ -40,14 +39,14 @@ const prevPost = computed(() => posts.value[findCurrentIndex() + 1])
|
|
|
40
39
|
divide-y
|
|
41
40
|
xl:divide-y-0
|
|
42
41
|
divide-gray-200
|
|
43
|
-
xl:grid xl:grid-cols-
|
|
42
|
+
xl:grid xl:grid-cols-12 xl:gap-x-6
|
|
44
43
|
pb-16
|
|
45
44
|
xl:pb-20
|
|
46
45
|
"
|
|
47
46
|
style="grid-template-rows: auto 1fr"
|
|
48
47
|
>
|
|
49
48
|
<PressAuthor v-if="frontmatter.author" :frontmatter="frontmatter" />
|
|
50
|
-
<div class="divide-y divide-gray-200 xl:pb-0 xl:col-span-
|
|
49
|
+
<div class="divide-y divide-gray-200 xl:pb-0 xl:col-span-8 xl:row-span-2">
|
|
51
50
|
<router-view />
|
|
52
51
|
</div>
|
|
53
52
|
|
|
@@ -57,7 +56,7 @@ const prevPost = computed(() => posts.value[findCurrentIndex() + 1])
|
|
|
57
56
|
font-medium
|
|
58
57
|
leading-5
|
|
59
58
|
divide-y divide-gray-200
|
|
60
|
-
xl:col-start-1 xl:row-start-2
|
|
59
|
+
xl:col-start-1 xl:row-start-2 xl:col-span-2
|
|
61
60
|
"
|
|
62
61
|
>
|
|
63
62
|
<div v-if="nextPost" class="py-8">
|
|
@@ -65,19 +64,25 @@ const prevPost = computed(() => posts.value[findCurrentIndex() + 1])
|
|
|
65
64
|
Next Article
|
|
66
65
|
</h2>
|
|
67
66
|
<div class="link">
|
|
68
|
-
<
|
|
67
|
+
<router-link :to="nextPost.href">
|
|
68
|
+
{{ nextPost.title }}
|
|
69
|
+
</router-link>
|
|
69
70
|
</div>
|
|
70
71
|
</div>
|
|
71
|
-
<div v-if="prevPost" class="py-8">
|
|
72
|
+
<div v-if="prevPost && prevPost.href" class="py-8">
|
|
72
73
|
<h2 class="text-xs tracking-wide uppercase text-gray-500">
|
|
73
74
|
Previous Article
|
|
74
75
|
</h2>
|
|
75
76
|
<div class="link">
|
|
76
|
-
<
|
|
77
|
+
<router-link :to="prevPost.href">
|
|
78
|
+
{{ prevPost.title }}
|
|
79
|
+
</router-link>
|
|
77
80
|
</div>
|
|
78
81
|
</div>
|
|
79
82
|
<div class="pt-8">
|
|
80
|
-
<
|
|
83
|
+
<router-link class="link" to="/">
|
|
84
|
+
← Back to Home
|
|
85
|
+
</router-link>
|
|
81
86
|
</div>
|
|
82
87
|
</footer>
|
|
83
88
|
</div>
|
|
@@ -12,7 +12,9 @@ defineProps<{
|
|
|
12
12
|
<div class="space-y-5 xl:col-span-3">
|
|
13
13
|
<div class="space-y-6">
|
|
14
14
|
<h2 class="text-2xl leading-8 font-bold tracking-tight">
|
|
15
|
-
<
|
|
15
|
+
<router-link class="text-gray-900" :to="post.path || ''">
|
|
16
|
+
{{ post.title }}
|
|
17
|
+
</router-link>
|
|
16
18
|
</h2>
|
|
17
19
|
<div
|
|
18
20
|
v-if="post.excerpt"
|
|
@@ -21,7 +23,9 @@ defineProps<{
|
|
|
21
23
|
/>
|
|
22
24
|
</div>
|
|
23
25
|
<div class="text-base leading-6 font-medium">
|
|
24
|
-
<
|
|
26
|
+
<router-link class="link" aria-label="read more" :to="post.path || ''">
|
|
27
|
+
Read more →
|
|
28
|
+
</router-link>
|
|
25
29
|
</div>
|
|
26
30
|
</div>
|
|
27
31
|
</article>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { useFrontmatter } from 'valaxy'
|
|
3
|
+
import { useAppStore } from 'valaxy/client/stores/app'
|
|
4
|
+
import PressOutline from './PressOutline.vue'
|
|
5
|
+
|
|
6
|
+
const frontmatter = useFrontmatter()
|
|
7
|
+
const app = useAppStore()
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<button
|
|
12
|
+
class="toc-btn shadow-lg fixed press-icon-btn z-99 xl:hidden!"
|
|
13
|
+
right="5" bottom="8"
|
|
14
|
+
@click="app.toggleRightSidebar()"
|
|
15
|
+
>
|
|
16
|
+
<div i-ri-file-list-line />
|
|
17
|
+
</button>
|
|
18
|
+
|
|
19
|
+
<ValaxyOverlay :show="app.isRightSidebarOpen" @click="app.toggleRightSidebar()" />
|
|
20
|
+
|
|
21
|
+
<aside
|
|
22
|
+
class="press-aside lt-xl:fixed shadow
|
|
23
|
+
press-card xl:(shadow-none hover:shadow-none) hover:shadow-lg"
|
|
24
|
+
p="l-0 xl:l-8" text="center"
|
|
25
|
+
z="5"
|
|
26
|
+
:class="app.isRightSidebarOpen && 'open'"
|
|
27
|
+
>
|
|
28
|
+
<div class="aside-container lt-xl:fixed" flex="~ col">
|
|
29
|
+
<PressOutline v-if="frontmatter.toc !== false" />
|
|
30
|
+
<div class="flex-grow" />
|
|
31
|
+
<div v-if="$slots.default" class="custom-container">
|
|
32
|
+
<slot />
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</aside>
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<style lang="scss">
|
|
39
|
+
@use 'valaxy/client/styles/mixins' as *;
|
|
40
|
+
|
|
41
|
+
.press-card{
|
|
42
|
+
background-color: var(--va-c-bg);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.press-aside {
|
|
46
|
+
top: 0;
|
|
47
|
+
bottom: 0;
|
|
48
|
+
right: 0;
|
|
49
|
+
z-index: var(--pr-z-index-aside);
|
|
50
|
+
width: var(--va-aside-width);
|
|
51
|
+
|
|
52
|
+
transform: translateX(100%);
|
|
53
|
+
|
|
54
|
+
transition: box-shadow var(--va-transition-duration), opacity 0.25s,
|
|
55
|
+
transform var(--va-transition-duration) cubic-bezier(0.19, 1, 0.22, 1);
|
|
56
|
+
|
|
57
|
+
&.open {
|
|
58
|
+
position: fixed;
|
|
59
|
+
right: 0;
|
|
60
|
+
display: block;
|
|
61
|
+
transform: translateX(0);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.aside-container {
|
|
66
|
+
position: sticky;
|
|
67
|
+
top: 0;
|
|
68
|
+
margin-top: calc(var(--pr-nav-height) * -1 - 20px);
|
|
69
|
+
padding-top: calc(var(--pr-nav-height) + 20px);
|
|
70
|
+
height: calc(100vh - var(--pr-nav-height) - 32px);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@include media('xl') {
|
|
74
|
+
.aside-container {
|
|
75
|
+
top: 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.press-aside {
|
|
79
|
+
transform: translateX(0);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.toc-btn {
|
|
84
|
+
color: var(--va-c-bg);
|
|
85
|
+
background-color: var(--va-c-primary);
|
|
86
|
+
}
|
|
87
|
+
</style>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
defineProps<{
|
|
3
|
+
show: boolean
|
|
4
|
+
}>()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<transition name="fade">
|
|
9
|
+
<div v-if="show" class="press-backdrop" />
|
|
10
|
+
</transition>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<style scoped lang="scss">
|
|
14
|
+
.press-backdrop {
|
|
15
|
+
position: fixed;
|
|
16
|
+
top: 0;
|
|
17
|
+
right: 0;
|
|
18
|
+
bottom: 0;
|
|
19
|
+
left: 0;
|
|
20
|
+
z-index: var(--pr-z-index-backdrop);
|
|
21
|
+
background: rgba(0, 0, 0, .6);
|
|
22
|
+
transition: opacity 0.5s;
|
|
23
|
+
|
|
24
|
+
.fade-enter-from,
|
|
25
|
+
.fade-leave-to {
|
|
26
|
+
opacity: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.fade-leave-active {
|
|
30
|
+
transition-duration: .25s;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@media (min-width: 1280px) {
|
|
35
|
+
.press-backdrop {
|
|
36
|
+
display: none;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
|
|
4
|
+
const props = defineProps<{
|
|
5
|
+
theme: 'brand' | 'alt'
|
|
6
|
+
link: string
|
|
7
|
+
text: string
|
|
8
|
+
}>()
|
|
9
|
+
|
|
10
|
+
const classes = computed(() => {
|
|
11
|
+
const arr = []
|
|
12
|
+
if (props.theme === 'brand')
|
|
13
|
+
arr.push('from-blue-500', 'to-blue-700')
|
|
14
|
+
else
|
|
15
|
+
arr.push('from-gray-600', 'to-stone-700')
|
|
16
|
+
|
|
17
|
+
return arr
|
|
18
|
+
})
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<AppLink
|
|
23
|
+
:to="link"
|
|
24
|
+
m="2"
|
|
25
|
+
:class="classes"
|
|
26
|
+
class="sese-btn btn rounded-full hover:shadow-lg" bg="gradient-to-r"
|
|
27
|
+
p="x-6"
|
|
28
|
+
>
|
|
29
|
+
{{ text }}
|
|
30
|
+
</AppLink>
|
|
31
|
+
</template>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { useThemeConfig } from 'valaxy'
|
|
3
|
+
import type { Categories } from 'valaxy'
|
|
4
|
+
import { computed, ref } from 'vue'
|
|
5
|
+
|
|
6
|
+
const props = withDefaults(defineProps<{
|
|
7
|
+
categories: Categories
|
|
8
|
+
/**
|
|
9
|
+
* 当前层级
|
|
10
|
+
*/
|
|
11
|
+
level?: number
|
|
12
|
+
displayCategory?: (category: string) => void
|
|
13
|
+
collapsable?: boolean
|
|
14
|
+
}>(), {
|
|
15
|
+
level: 0,
|
|
16
|
+
collapsable: true,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const collapsable = ref(props.collapsable)
|
|
20
|
+
|
|
21
|
+
const themeConfig = useThemeConfig()
|
|
22
|
+
const sidebar = computed(() => themeConfig.value.sidebar)
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template>
|
|
26
|
+
<ul v-for="item in sidebar" :key="item" class="category-list">
|
|
27
|
+
<PressCategory
|
|
28
|
+
v-if="categories.get(item)"
|
|
29
|
+
:name="item" :category="categories.get(item)"
|
|
30
|
+
:level="level + 1"
|
|
31
|
+
:display-category="displayCategory"
|
|
32
|
+
:collapsable="collapsable"
|
|
33
|
+
/>
|
|
34
|
+
</ul>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<style lang="scss">
|
|
38
|
+
.category-list {
|
|
39
|
+
&:first-child {
|
|
40
|
+
.category-list-item {
|
|
41
|
+
border-top: 0px;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
.post-list-item {
|
|
46
|
+
a {
|
|
47
|
+
color: var(--va-c-text-light);
|
|
48
|
+
transition: all 0.2s;
|
|
49
|
+
|
|
50
|
+
&:hover {
|
|
51
|
+
color: var(--va-c-primary);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&.active {
|
|
55
|
+
color: var(--va-c-primary);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.category-list-item {
|
|
61
|
+
.folder-action {
|
|
62
|
+
&:hover {
|
|
63
|
+
color: var(--va-c-primary);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.category-list+.category-list {
|
|
69
|
+
margin-top: 1rem;
|
|
70
|
+
}
|
|
71
|
+
</style>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import type { Category, Post } from 'valaxy'
|
|
4
|
+
import { isParentCategory } from 'valaxy'
|
|
5
|
+
import { useI18n } from 'vue-i18n'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
name: string
|
|
9
|
+
// to eliminate the warning
|
|
10
|
+
category: Category
|
|
11
|
+
level?: number
|
|
12
|
+
displayCategory?: (category: string) => void
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* collapse children
|
|
16
|
+
*/
|
|
17
|
+
collapsable?: boolean
|
|
18
|
+
}>(), {
|
|
19
|
+
collapsable: true,
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const collapsable = ref(props.collapsable)
|
|
23
|
+
const { t, locale } = useI18n()
|
|
24
|
+
|
|
25
|
+
const getTitle = (post: Post | any) => {
|
|
26
|
+
const lang = locale.value
|
|
27
|
+
return post[`title_${lang}`] ? post[`title_${lang}`] : post.title
|
|
28
|
+
}
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template>
|
|
32
|
+
<li
|
|
33
|
+
v-if="category.total"
|
|
34
|
+
p="t-2"
|
|
35
|
+
w="full" border="t t-$pr-c-divider-light"
|
|
36
|
+
class="category-list-item inline-flex items-center justify-between"
|
|
37
|
+
>
|
|
38
|
+
<span class="category-name" font="bold" m="l-1" @click="displayCategory ? displayCategory(name) : null">
|
|
39
|
+
{{ name === 'Uncategorized' ? t('category.uncategorized') : name }}
|
|
40
|
+
<!-- <sup font="normal">[{{ category.total }}]</sup> -->
|
|
41
|
+
</span>
|
|
42
|
+
<span class="folder-action inline-flex cursor-pointer" opacity="50" @click="collapsable = !collapsable">
|
|
43
|
+
<div v-if="collapsable" i-ri-folder-add-line />
|
|
44
|
+
<div v-else i-ri-folder-reduce-line />
|
|
45
|
+
</span>
|
|
46
|
+
</li>
|
|
47
|
+
|
|
48
|
+
<template v-if="!collapsable">
|
|
49
|
+
<ul v-if="!isParentCategory(category)">
|
|
50
|
+
<li v-for="post, i in category.posts" :key="i" class="post-list-item">
|
|
51
|
+
<router-link v-if="post.title" :to="post.path || ''" class="inline-flex items-center" active-class="active">
|
|
52
|
+
<span m="l-1" text="sm">{{ getTitle(post) }}</span>
|
|
53
|
+
</router-link>
|
|
54
|
+
</li>
|
|
55
|
+
</ul>
|
|
56
|
+
<PressCategories v-else :categories="category.children" :display-category="displayCategory" :collapsable="collapsable" />
|
|
57
|
+
</template>
|
|
58
|
+
</template>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { useEditLink } from '../composables'
|
|
3
|
+
|
|
4
|
+
const editLink = useEditLink()
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<div flex justify="between" text="sm">
|
|
9
|
+
<a flex items="center" :href="editLink.url" target="_blank">
|
|
10
|
+
<div i-ri-external-link-line />
|
|
11
|
+
<span ml-1>{{ editLink.text }}</span>
|
|
12
|
+
</a>
|
|
13
|
+
<PressDocFooterLastUpdated />
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, onMounted, ref, watchEffect } from 'vue'
|
|
3
|
+
import { useData, useThemeConfig } from 'valaxy'
|
|
4
|
+
|
|
5
|
+
const data = useData()
|
|
6
|
+
const themeConfig = useThemeConfig()
|
|
7
|
+
|
|
8
|
+
const date = computed(() => new Date(data.lastUpdated!))
|
|
9
|
+
const isoDatetime = computed(() => date.value.toISOString())
|
|
10
|
+
const datetime = ref('')
|
|
11
|
+
|
|
12
|
+
// set time on mounted hook because the locale string might be different
|
|
13
|
+
// based on end user and will lead to potential hydration mismatch if
|
|
14
|
+
// calculated at build time
|
|
15
|
+
onMounted(() => {
|
|
16
|
+
watchEffect(() => {
|
|
17
|
+
datetime.value = date.value.toLocaleString(window.navigator.language)
|
|
18
|
+
})
|
|
19
|
+
})
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<p class="press-lastUpdated">
|
|
24
|
+
{{ themeConfig.lastUpdatedText ?? 'Last updated' }}:
|
|
25
|
+
<time :datetime="isoDatetime">{{ datetime }}</time>
|
|
26
|
+
</p>
|
|
27
|
+
</template>
|
|
28
|
+
|
|
29
|
+
<style scoped>
|
|
30
|
+
.press-lastUpdated {
|
|
31
|
+
line-height: 24px;
|
|
32
|
+
font-size: 14px;
|
|
33
|
+
font-weight: 500;
|
|
34
|
+
color: var(--va-c-text-light);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@media (min-width: 640px) {
|
|
38
|
+
.press-lastUpdated {
|
|
39
|
+
line-height: 32px;
|
|
40
|
+
font-size: 14px;
|
|
41
|
+
font-weight: 500;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
</style>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { Feature } from '../types'
|
|
3
|
+
|
|
4
|
+
defineProps<{
|
|
5
|
+
feature: Feature
|
|
6
|
+
}>()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<article class="press-feature">
|
|
11
|
+
<div v-if="feature.icon" class="icon">
|
|
12
|
+
{{ feature.icon }}
|
|
13
|
+
</div>
|
|
14
|
+
<h2 class="title">
|
|
15
|
+
{{ feature.title }}
|
|
16
|
+
</h2>
|
|
17
|
+
<p class="details">
|
|
18
|
+
{{ feature.details }}
|
|
19
|
+
</p>
|
|
20
|
+
</article>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<style scoped>
|
|
24
|
+
.press-feature {
|
|
25
|
+
border: 1px solid var(--va-c-bg-soft);
|
|
26
|
+
border-radius: 12px;
|
|
27
|
+
padding: 24px;
|
|
28
|
+
height: 100%;
|
|
29
|
+
background-color: var(--va-c-bg-soft);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.icon {
|
|
33
|
+
display: flex;
|
|
34
|
+
justify-content: center;
|
|
35
|
+
align-items: center;
|
|
36
|
+
margin-bottom: 20px;
|
|
37
|
+
border-radius: 6px;
|
|
38
|
+
background-color: var(--va-c-gray-light-4);
|
|
39
|
+
width: 48px;
|
|
40
|
+
height: 48px;
|
|
41
|
+
font-size: 24px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.dark .icon {
|
|
45
|
+
background-color: var(--va-c-bg);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.title {
|
|
49
|
+
line-height: 24px;
|
|
50
|
+
font-size: 16px;
|
|
51
|
+
font-weight: 600;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.details {
|
|
55
|
+
padding-top: 8px;
|
|
56
|
+
line-height: 24px;
|
|
57
|
+
font-size: 14px;
|
|
58
|
+
font-weight: 500;
|
|
59
|
+
color: var(--va-c-text-lighter);
|
|
60
|
+
}
|
|
61
|
+
</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import type { Feature } from '../types'
|
|
4
|
+
|
|
5
|
+
const props = defineProps<{
|
|
6
|
+
features: Feature[]
|
|
7
|
+
}>()
|
|
8
|
+
|
|
9
|
+
const grid = computed(() => {
|
|
10
|
+
const length = props.features.length
|
|
11
|
+
if (length <= 3)
|
|
12
|
+
return `grid-cols-1 sm:grid-cols-2 md:grid-cols-${length}`
|
|
13
|
+
else
|
|
14
|
+
return 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4'
|
|
15
|
+
})
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template>
|
|
19
|
+
<div class="press-features">
|
|
20
|
+
<div class="m-auto container grid gap-4" :class="[grid]">
|
|
21
|
+
<div v-for="feature in features" :key="feature.title" class="inline-grid">
|
|
22
|
+
<PressFeature :feature="feature" />
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</template>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useSidebar } from 'valaxy'
|
|
3
|
+
import { useThemeConfig } from '../composables'
|
|
4
|
+
|
|
5
|
+
const themeConfig = useThemeConfig()
|
|
6
|
+
const { hasSidebar } = useSidebar()
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<footer v-if="themeConfig.footer" class="press-footer" :class="{ 'has-sidebar': hasSidebar }">
|
|
11
|
+
<div flex="~ col" class="container">
|
|
12
|
+
<p v-if="themeConfig.footer.message" class="message" v-html="themeConfig.footer.message" />
|
|
13
|
+
<p v-if="themeConfig.footer.copyright" class="copyright" v-html="themeConfig.footer.copyright" />
|
|
14
|
+
</div>
|
|
15
|
+
</footer>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<style lang="scss" scoped>
|
|
19
|
+
.press-footer {
|
|
20
|
+
position: relative;
|
|
21
|
+
z-index: var(--pr-z-index-footer);
|
|
22
|
+
border-top: 1px solid var(--pr-c-divider-light);
|
|
23
|
+
padding: 32px 24px;
|
|
24
|
+
background-color: var(--va-c-bg);
|
|
25
|
+
|
|
26
|
+
&.has-sidebar {
|
|
27
|
+
display: none;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@media (min-width: 768px) {
|
|
32
|
+
.VPFooter {
|
|
33
|
+
padding: 32px;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.container {
|
|
38
|
+
margin: 0 auto;
|
|
39
|
+
max-width: var(--pr-layout-max-width);
|
|
40
|
+
text-align: center;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.message,
|
|
44
|
+
.copyright {
|
|
45
|
+
line-height: 24px;
|
|
46
|
+
font-size: 14px;
|
|
47
|
+
font-weight: 500;
|
|
48
|
+
color: var(--va-c-text-lighter);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.message { order: 2; }
|
|
52
|
+
.copyright { order: 1; }
|
|
53
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="press-home" p="x-6">
|
|
3
|
+
<slot name="home-hero-before" />
|
|
4
|
+
<PressHomeHero />
|
|
5
|
+
<slot name="home-hero-after" />
|
|
6
|
+
|
|
7
|
+
<slot name="home-features-before" />
|
|
8
|
+
<PressHomeFeatures />
|
|
9
|
+
<slot name="home-features-after" />
|
|
10
|
+
|
|
11
|
+
<slot>
|
|
12
|
+
<router-view />
|
|
13
|
+
</slot>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { useFrontmatter } from 'valaxy'
|
|
3
|
+
import PressButton from './PressButton.vue'
|
|
4
|
+
|
|
5
|
+
const fm = useFrontmatter()
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<h1 m="md:t-24 t-10 md:t-20" text="center">
|
|
10
|
+
<span text="5rem" font="black" class="gradient-text from-purple-800 to-blue-500" bg="gradient-to-r">
|
|
11
|
+
{{ fm.hero.name }}
|
|
12
|
+
</span>
|
|
13
|
+
<br>
|
|
14
|
+
<small opacity="75">LOGO NOT READY</small>
|
|
15
|
+
</h1>
|
|
16
|
+
|
|
17
|
+
<h1 m="y-10" text="center 6xl" font="black" leading="tight">
|
|
18
|
+
Next Generation
|
|
19
|
+
<br>
|
|
20
|
+
Static <span class="gradient-text from-blue-500 to-purple-700" bg="gradient-to-r">Blog</span> Framework
|
|
21
|
+
</h1>
|
|
22
|
+
|
|
23
|
+
<div p="2" text="center">
|
|
24
|
+
<PressButton
|
|
25
|
+
v-for="action in fm.hero.actions"
|
|
26
|
+
:key="action.link"
|
|
27
|
+
:theme="action.theme"
|
|
28
|
+
:link="action.link"
|
|
29
|
+
:text="action.text"
|
|
30
|
+
/>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<br>
|
|
34
|
+
</template>
|