commit
ff06eabffe
@ -2,11 +2,17 @@ import { type ClientConfig, defineClientConfig } from 'vuepress/client'
|
||||
import HeroTintPlateConfig from './themes/components/HeroTintPlateConfig.vue'
|
||||
import CanIUseConfig from './themes/components/CanIUseConfig.vue'
|
||||
import Demos from './themes/components/Demos.vue'
|
||||
import ThemeColors from './themes/components/ThemeColors.vue'
|
||||
import { setupThemeColors } from './themes/composables/theme-colors.js'
|
||||
|
||||
export default defineClientConfig({
|
||||
enhance({ app }) {
|
||||
app.component('HeroTintPlateConfig', HeroTintPlateConfig)
|
||||
app.component('CanIUseConfig', CanIUseConfig)
|
||||
app.component('Demos', Demos)
|
||||
app.component('ThemeColors', ThemeColors)
|
||||
},
|
||||
setup() {
|
||||
setupThemeColors()
|
||||
},
|
||||
}) as ClientConfig
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import * as path from 'node:path'
|
||||
import { type UserConfig, defineUserConfig } from 'vuepress'
|
||||
import { viteBundler } from '@vuepress/bundler-vite'
|
||||
import { addViteOptimizeDepsInclude, addViteSsrExternal } from '@vuepress/helper'
|
||||
import { theme } from './theme.js'
|
||||
|
||||
export default defineUserConfig({
|
||||
@ -21,6 +22,11 @@ export default defineUserConfig({
|
||||
|
||||
pagePatterns: ['**/*.md', '!**/*.snippet.md', '!.vuepress', '!node_modules'],
|
||||
|
||||
extendsBundlerOptions(bundlerOptions, app) {
|
||||
addViteOptimizeDepsInclude(bundlerOptions, app, '@simonwep/pickr')
|
||||
addViteSsrExternal(bundlerOptions, app, '@simonwep/pickr')
|
||||
},
|
||||
|
||||
bundler: viteBundler(),
|
||||
|
||||
theme,
|
||||
|
||||
@ -147,7 +147,7 @@ export const zhNotes = definePlumeNotesConfig({
|
||||
{
|
||||
text: '工具',
|
||||
icon: 'tabler:tools',
|
||||
items: ['home-hero-tint-plate', 'caniuse'],
|
||||
items: ['custom-theme', 'home-hero-tint-plate', 'caniuse'],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@ -6,19 +6,19 @@ defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="`code-viewer language-${lang}`" :data-ext="lang">
|
||||
<button class="copy-code-button" :data-lang="lang" />
|
||||
<div :class="`code-viewer language-${lang}`" :data-title="lang">
|
||||
<button class="copy" :data-lang="lang" title="Copy code" data-copied="已复制" />
|
||||
<pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code>{{ content }}</code></pre>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.code-viewer .copy-code-button {
|
||||
.code-viewer .copy {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.code-viewer .copy-code-button {
|
||||
.code-viewer .copy {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
66
docs/.vuepress/themes/components/ColorPick.vue
Normal file
66
docs/.vuepress/themes/components/ColorPick.vue
Normal file
@ -0,0 +1,66 @@
|
||||
<script setup lang="ts">
|
||||
import '@simonwep/pickr/dist/themes/nano.min.css'
|
||||
import { onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
|
||||
const emit = defineEmits<{ (e: 'update:modelValue', value: string): void }>()
|
||||
|
||||
const color = defineModel<string>('modelValue', { default: 'rgba(0,0,0,1)' })
|
||||
const pickerEl = ref<HTMLDivElement>()
|
||||
let picker: any
|
||||
|
||||
onMounted(async () => {
|
||||
if (!pickerEl.value || picker)
|
||||
return
|
||||
|
||||
const { default: Pickr } = await import('@simonwep/pickr')
|
||||
|
||||
picker = Pickr.create({
|
||||
el: pickerEl.value,
|
||||
theme: 'nano',
|
||||
default: color.value,
|
||||
defaultRepresentation: 'RGBA',
|
||||
showAlways: false,
|
||||
components: {
|
||||
preview: true,
|
||||
opacity: true,
|
||||
hue: true,
|
||||
interaction: { input: true },
|
||||
},
|
||||
})
|
||||
picker.on('change', (hsva) => {
|
||||
emit('update:modelValue', hsva.toRGBA().toString(0))
|
||||
})
|
||||
watch(color, () => {
|
||||
picker?.setColor(color.value)
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
picker?.destroyAndRemove()
|
||||
picker = null
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="color-picker">
|
||||
<div ref="pickerEl" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.color-picker {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4px;
|
||||
background-color: var(--vp-c-bg-soft);
|
||||
border: solid 1px var(--vp-c-divider);
|
||||
border-radius: 32px;
|
||||
transition: border-color var(--t-color), background-color var(--t-color);
|
||||
}
|
||||
|
||||
.pickr .pcr-button {
|
||||
overflow: hidden;
|
||||
border-radius: 50% !important;
|
||||
}
|
||||
</style>
|
||||
74
docs/.vuepress/themes/components/ThemeColors.vue
Normal file
74
docs/.vuepress/themes/components/ThemeColors.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<script setup lang="ts">
|
||||
import VPButton from '@theme/VPButton.vue'
|
||||
import { useThemeColors } from '../composables/theme-colors.js'
|
||||
import ColorPick from './ColorPick.vue'
|
||||
import CodeViewer from './CodeViewer.vue'
|
||||
|
||||
const { lightColors, darkColors, css, reset } = useThemeColors()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VPButton theme="alt" text="重置" @click="reset" />
|
||||
|
||||
<h2>浅色主题</h2>
|
||||
<div class="theme-colors-wrapper">
|
||||
<div v-for="({ name, group }, index) in lightColors" :key="index" class="group">
|
||||
<h4>{{ name }}</h4>
|
||||
<section v-for="color in group" :key="color.key" class="theme-color">
|
||||
<ColorPick v-model="color.value" />
|
||||
<h5>{{ color.name }}</h5>
|
||||
<span class="desc">{{ color.desc }}</span>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<h2>深色主题</h2>
|
||||
<div class="theme-colors-wrapper">
|
||||
<div v-for="({ name, group }, index) in darkColors" :key="index" class="group">
|
||||
<h4>{{ name }}</h4>
|
||||
<section v-for="color in group" :key="color.key" class="theme-color">
|
||||
<ColorPick v-model="color.value" />
|
||||
<h5>{{ color.name }}</h5>
|
||||
<span class="desc">{{ color.desc }}</span>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<p>复制下方的代码到您的项目中,请参考 <a href="/custom-style/">主题定制</a> </p>
|
||||
<CodeViewer :content="css" lang="css" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.theme-colors-wrapper {
|
||||
display: grid;
|
||||
gap: 8px 16px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.theme-colors-wrapper {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1440px) {
|
||||
.theme-colors-wrapper {
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.theme-color {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.theme-color h5 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.theme-color .desc {
|
||||
font-size: 14px;
|
||||
color: var(--vp-c-text-2);
|
||||
transition: color var(--t-color);
|
||||
}
|
||||
</style>
|
||||
148
docs/.vuepress/themes/composables/theme-colors.ts
Normal file
148
docs/.vuepress/themes/composables/theme-colors.ts
Normal file
@ -0,0 +1,148 @@
|
||||
import { type InjectionKey, type Ref, inject, provide, watch } from 'vue'
|
||||
import { useSessionStorage, useStyleTag } from '@vueuse/core'
|
||||
|
||||
export interface ThemeColor {
|
||||
name: string
|
||||
key: string
|
||||
value: string
|
||||
desc: string
|
||||
}
|
||||
export type ThemeColors = ThemeColor[]
|
||||
export interface ThemeColorsGroup {
|
||||
name: string
|
||||
group: ThemeColors
|
||||
}
|
||||
|
||||
const DEFAULT_PRESET = {
|
||||
light: {
|
||||
'--vp-c-brand-1': '#5086a1',
|
||||
'--vp-c-brand-2': '#6aa1b7',
|
||||
'--vp-c-brand-3': '#8cccd5',
|
||||
'--vp-c-brand-soft': 'rgba(131, 208, 218, 0.314)',
|
||||
|
||||
'--vp-c-text-1': 'rgba(60, 60, 67)',
|
||||
'--vp-c-text-2': 'rgba(60, 60, 67, 0.78)',
|
||||
'--vp-c-text-3': 'rgba(60, 60, 67, 0.56)',
|
||||
|
||||
'--vp-c-bg': '#fff',
|
||||
'--vp-nav-bg-color': '#fff',
|
||||
'--vp-nav-screen-bg-color': '#fff',
|
||||
'--vp-local-nav-bg-color': '#fff',
|
||||
'--vp-sidebar-bg-color': '#f6f6f7',
|
||||
'--vp-code-block-bg': '#f6f8fa',
|
||||
},
|
||||
dark: {
|
||||
'--vp-c-brand-1': '#8cccd5',
|
||||
'--vp-c-brand-2': '#6aa1b7',
|
||||
'--vp-c-brand-3': '#5086a1',
|
||||
'--vp-c-brand-soft': 'rgba(131, 208, 218, 0.314)',
|
||||
|
||||
'--vp-c-text-1': 'rgba(255, 255, 245, 0.86)',
|
||||
'--vp-c-text-2': 'rgba(235, 235, 245, 0.6)',
|
||||
'--vp-c-text-3': 'rgba(235, 235, 245, 0.38)',
|
||||
|
||||
'--vp-c-bg': '#1b1b1f',
|
||||
'--vp-nav-bg-color': '#1b1b1f',
|
||||
'--vp-nav-screen-bg-color': '#1b1b1f',
|
||||
'--vp-local-nav-bg-color': '#1b1b1f',
|
||||
'--vp-sidebar-bg-color': '#161618',
|
||||
'--vp-code-block-bg': '#202127',
|
||||
},
|
||||
}
|
||||
|
||||
const preset: ThemeColorsGroup[] = [
|
||||
{
|
||||
name: '主题色',
|
||||
group: [
|
||||
{ name: 'brand-1', key: '--vp-c-brand-1', value: '', desc: '链接颜色、强调色' },
|
||||
{ name: 'brand-2', key: '--vp-c-brand-2', value: '', desc: '链接、按钮 hover 颜色' },
|
||||
{ name: 'brand-3', key: '--vp-c-brand-3', value: '', desc: '背景色、边框色' },
|
||||
{ name: 'brand-soft', key: '--vp-c-brand-soft', value: '', desc: '辅助色' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '文本颜色',
|
||||
group: [
|
||||
{ name: 'text-1', key: '--vp-c-text-1', value: '', desc: '主要文本' },
|
||||
{ name: 'text-2', key: '--vp-c-text-2', value: '', desc: '次要文本' },
|
||||
{ name: 'text-3', key: '--vp-c-text-3', value: '', desc: '辅助文本' },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '背景色',
|
||||
group: [
|
||||
{ name: 'bg', key: '--vp-c-bg', value: '', desc: '主体背景' },
|
||||
{ name: 'nav-bg', key: '--vp-nav-bg-color', value: '', desc: '导航栏背景' },
|
||||
{ name: 'nav-screen-bg', key: '--vp-nav-screen-bg-color', value: '', desc: '移动端导航栏' },
|
||||
{ name: 'local-nav-bg', key: '--vp-local-nav-bg-color', value: '', desc: '页面内导航栏' },
|
||||
{ name: 'sidebar-bg', key: '--vp-sidebar-bg-color', value: '', desc: '侧边栏背景' },
|
||||
{ name: 'code-block-bg', key: '--vp-code-block-bg', value: '', desc: '代码块背景' },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const themeColorSymbol: InjectionKey<{
|
||||
lightColors: Ref<ThemeColorsGroup[]>
|
||||
darkColors: Ref<ThemeColorsGroup[]>
|
||||
css: Ref<string>
|
||||
reset: () => void
|
||||
}> = Symbol(__VUEPRESS_DEV__ ? 'theme-color' : '')
|
||||
|
||||
export function setupThemeColors() {
|
||||
const lightColors = useSessionStorage<ThemeColorsGroup[]>('custom-theme-colors-light', resolveDefaultColors('light'))
|
||||
const darkColors = useSessionStorage<ThemeColorsGroup[]>('custom-theme-colors-dark', resolveDefaultColors('dark'))
|
||||
|
||||
const { css, load } = useStyleTag('')
|
||||
|
||||
watch([lightColors, darkColors], () => {
|
||||
const content = `${resolveContent(lightColors.value, 'light')}\n${resolveContent(darkColors.value, 'dark')}`
|
||||
css.value = content
|
||||
load()
|
||||
}, { deep: true, immediate: true })
|
||||
|
||||
function resolveContent(colors: ThemeColorsGroup[], type: 'light' | 'dark') {
|
||||
const name = type === 'light' ? ':root' : '.dark'
|
||||
let content = `${name} {\n`
|
||||
colors.forEach(({ name, group }) => {
|
||||
content += `\n /**\n * ${name}\n * -------------------------------------------------------------------------- */\n\n`
|
||||
group.forEach((item) => {
|
||||
const str = ` ${item.key}: ${item.value};`
|
||||
content += `${str}${' '.repeat(54 - str.length)}/* ${item.desc} */\n`
|
||||
})
|
||||
})
|
||||
content += '}\n'
|
||||
return content
|
||||
}
|
||||
|
||||
function resolveDefaultColors(type: 'light' | 'dark') {
|
||||
return preset.map(group => ({
|
||||
name: group.name,
|
||||
group: group.group.map(item => ({
|
||||
...item,
|
||||
value: DEFAULT_PRESET[type][item.key],
|
||||
})),
|
||||
}))
|
||||
}
|
||||
|
||||
function reset() {
|
||||
lightColors.value = resolveDefaultColors('light')
|
||||
darkColors.value = resolveDefaultColors('dark')
|
||||
}
|
||||
|
||||
provide(themeColorSymbol, {
|
||||
lightColors,
|
||||
darkColors,
|
||||
css,
|
||||
reset,
|
||||
})
|
||||
}
|
||||
|
||||
export function useThemeColors() {
|
||||
const result = inject(themeColorSymbol)
|
||||
|
||||
if (!result) {
|
||||
throw new Error('useThemeColors() can only be used inside `setupThemeColors()`.')
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@ -127,19 +127,19 @@ config:
|
||||
:::code-tabs
|
||||
@tab pnpm
|
||||
|
||||
```sh
|
||||
```sh :no-line-numbers
|
||||
pnpm add vuepress@next vuepress-theme-plume vue
|
||||
```
|
||||
|
||||
@tab npm
|
||||
|
||||
```sh
|
||||
```sh :no-line-numbers
|
||||
npm install vuepress@next vuepress-theme-plume
|
||||
```
|
||||
|
||||
@tab yarn
|
||||
|
||||
```sh
|
||||
```sh :no-line-numbers
|
||||
yarn add vuepress@next vuepress-theme-plume
|
||||
```
|
||||
|
||||
@ -150,7 +150,7 @@ yarn add vuepress@next vuepress-theme-plume
|
||||
::: code-tabs
|
||||
@tab .vuepress/config.ts
|
||||
|
||||
```ts
|
||||
```ts :no-line-numbers
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
|
||||
@ -166,7 +166,7 @@ export default defineUserConfig({
|
||||
|
||||
### 更新记录
|
||||
|
||||
[Changelog](/changelog/)
|
||||
[Changelog](./changelog.md)
|
||||
|
||||
### 贡献者
|
||||
|
||||
|
||||
@ -632,12 +632,24 @@ interface LastUpdatedOptions {
|
||||
- 默认值: `'Contributors'`
|
||||
- 详情: 贡献者的文本
|
||||
|
||||
### prevPage
|
||||
|
||||
- 类型: `boolean`
|
||||
- 默认值: `true`
|
||||
- 详情: 是否显示上一页
|
||||
|
||||
### prevPageLabel
|
||||
|
||||
- 类型: `string`
|
||||
- 默认值: `'Previous Page'`
|
||||
- 详情: 上一页的文本
|
||||
|
||||
### nextPage
|
||||
|
||||
- 类型: `boolean`
|
||||
- 默认值: `true`
|
||||
- 详情: 是否显示下一页
|
||||
|
||||
### nextPageLabel
|
||||
|
||||
- 类型: `string`
|
||||
|
||||
@ -28,7 +28,7 @@ tags:
|
||||
|
||||
- ### 新建文件夹并进入目录
|
||||
|
||||
``` sh
|
||||
``` sh :no-line-numbers
|
||||
mkdir my-blog
|
||||
cd my-blog
|
||||
```
|
||||
@ -38,21 +38,21 @@ tags:
|
||||
::: code-tabs
|
||||
@tab pnpm
|
||||
|
||||
``` sh
|
||||
``` sh :no-line-numbers
|
||||
git init
|
||||
pnpm init
|
||||
```
|
||||
|
||||
@tab yarn
|
||||
|
||||
``` sh
|
||||
``` sh :no-line-numbers
|
||||
git init
|
||||
yarn init
|
||||
```
|
||||
|
||||
@tab npm
|
||||
|
||||
``` sh
|
||||
``` sh :no-line-numbers
|
||||
git init
|
||||
npm init
|
||||
```
|
||||
@ -66,7 +66,7 @@ tags:
|
||||
::: code-tabs
|
||||
@tab pnpm
|
||||
|
||||
```sh
|
||||
```sh :no-line-numbers
|
||||
# 安装 vuepress
|
||||
pnpm add -D vuepress@next vue
|
||||
# 安装 主题和打包工具
|
||||
@ -75,7 +75,7 @@ tags:
|
||||
|
||||
@tab yarn
|
||||
|
||||
``` sh
|
||||
``` sh :no-line-numbers
|
||||
# 安装 vuepress
|
||||
yarn add -D vuepress@next
|
||||
# 安装 主题和打包工具
|
||||
@ -84,7 +84,7 @@ tags:
|
||||
|
||||
@tab npm
|
||||
|
||||
``` sh
|
||||
``` sh :no-line-numbers
|
||||
# 安装 vuepress
|
||||
npm i -D vuepress@next
|
||||
# 安装 主题和打包工具
|
||||
@ -103,7 +103,7 @@ tags:
|
||||
::: code-tabs
|
||||
@tab package.json
|
||||
|
||||
``` json
|
||||
``` json :no-line-numbers
|
||||
{
|
||||
"scripts": {
|
||||
"dev": "vuepress dev docs",
|
||||
@ -121,7 +121,7 @@ tags:
|
||||
::: code-tabs
|
||||
@tab .gitignore
|
||||
|
||||
``` txt
|
||||
``` txt :no-line-numbers
|
||||
node_modules
|
||||
.temp
|
||||
.cache
|
||||
@ -129,7 +129,7 @@ tags:
|
||||
|
||||
@tab sh
|
||||
|
||||
``` sh
|
||||
``` sh :no-line-numbers
|
||||
echo 'node_modules' >> .gitignore
|
||||
echo '.temp' >> .gitignore
|
||||
echo '.cache' >> .gitignore
|
||||
@ -142,7 +142,7 @@ tags:
|
||||
::: code-tabs
|
||||
@tab docs/.vuepress/config.js
|
||||
|
||||
``` ts
|
||||
``` ts :no-line-numbers
|
||||
import { defineUserConfig } from 'vuepress'
|
||||
import { viteBundler } from '@vuepress/bundler-vite'
|
||||
import { plumeTheme } from 'vuepress-theme-plume'
|
||||
@ -170,7 +170,7 @@ tags:
|
||||
::: code-tabs
|
||||
@tab README.md
|
||||
|
||||
``` md
|
||||
``` md :no-line-numbers
|
||||
---
|
||||
home: true
|
||||
---
|
||||
@ -183,19 +183,19 @@ tags:
|
||||
::: code-tabs
|
||||
@tab pnpm
|
||||
|
||||
```sh
|
||||
```sh :no-line-numbers
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
@tab yarn
|
||||
|
||||
``` sh
|
||||
``` sh :no-line-numbers
|
||||
yarn dev
|
||||
```
|
||||
|
||||
@tab npm
|
||||
|
||||
``` sh
|
||||
``` sh :no-line-numbers
|
||||
npm run dev
|
||||
```
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ tags:
|
||||
|
||||
由于文件夹名称将作为分类名称,且不在主题配置中进行排序配置,对于有排序需要的场景,使用以下规则进行命名
|
||||
|
||||
``` ts
|
||||
``` ts :no-line-numbers
|
||||
const dir = /\d+\.[\s\S]+/
|
||||
// 即 数字 + . + 分类名称
|
||||
// 如: 1.前端
|
||||
@ -40,7 +40,7 @@ const dir = /\d+\.[\s\S]+/
|
||||
|
||||
__example:__
|
||||
|
||||
``` txt
|
||||
``` txt :no-line-numbers
|
||||
.{sourceDir}
|
||||
- 1.前端
|
||||
- 1.html
|
||||
|
||||
@ -92,3 +92,7 @@ export default defineClientConfig({
|
||||
--vp-c-text-3: rgba(235, 235, 245, 0.38);
|
||||
}
|
||||
```
|
||||
|
||||
::: tip
|
||||
主题提供了 [主题颜色工具](../../tools/custom-theme.md) , 你可以使用它来创建自定义颜色。
|
||||
:::
|
||||
|
||||
@ -17,7 +17,7 @@ lastUpdated: false
|
||||
搜索 `@property`,点击 `#` 会跳转到 `https://caniuse.com/mdn-css_at-rules_property`,
|
||||
可以直接复制 `mdn-css_at-rules_property` ,粘贴到 markdown 文件中:
|
||||
|
||||
```md
|
||||
```md :no-line-numbers
|
||||
@[caniuse](mdn-css_at-rules_property)
|
||||
```
|
||||
|
||||
|
||||
21
docs/notes/tools/custom-theme.md
Normal file
21
docs/notes/tools/custom-theme.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
title: 主题颜色工具
|
||||
icon: unjs:theme-colors
|
||||
author: pengzhanbo
|
||||
createTime: 2024/07/29 13:58:29
|
||||
permalink: /tools/theme-colors/
|
||||
readingTime: false
|
||||
editLink: false
|
||||
contributors: false
|
||||
lastUpdated: false
|
||||
---
|
||||
|
||||
::: tip
|
||||
这个工具可以帮助您快速创建自定义主题颜色。点击下方的按钮,选择您想要的主题颜色进行配置。
|
||||
|
||||
工具会自动应用您的修改到当前站点,您可以随意切换到任意页面查看效果。
|
||||
|
||||
本工具只能帮助您简单的创建主题颜色。如果您期望更加复杂的主题颜色配置,请查看 [styles/vars.css](https://github.com/pengzhanbo/vuepress-theme-plume/blob/main/theme/src/client/styles/vars.css)
|
||||
:::
|
||||
|
||||
<ThemeColors />
|
||||
@ -12,14 +12,15 @@
|
||||
"vuepress": "2.0.0-rc.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/json": "^2.2.229",
|
||||
"@iconify/json": "^2.2.234",
|
||||
"@simonwep/pickr": "^1.9.1",
|
||||
"@vuepress/bundler-vite": "2.0.0-rc.14",
|
||||
"chart.js": "^4.4.3",
|
||||
"echarts": "^5.5.1",
|
||||
"flowchart.ts": "^3.0.0",
|
||||
"http-server": "^14.1.1",
|
||||
"mermaid": "^10.9.1",
|
||||
"vue": "^3.4.33",
|
||||
"vue": "^3.4.35",
|
||||
"vuepress-theme-plume": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
16
package.json
16
package.json
@ -3,7 +3,7 @@
|
||||
"type": "module",
|
||||
"version": "1.0.0-rc.83",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@9.5.0",
|
||||
"packageManager": "pnpm@9.6.0",
|
||||
"author": "pengzhanbo <q942450674@outlook.com> (https://github.com/pengzhanbo/)",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@ -44,19 +44,19 @@
|
||||
"@types/lodash.merge": "^4.6.9",
|
||||
"@types/node": "20.12.10",
|
||||
"@types/webpack-env": "^1.18.5",
|
||||
"bumpp": "^9.4.1",
|
||||
"bumpp": "^9.4.2",
|
||||
"commitizen": "^4.3.0",
|
||||
"conventional-changelog-cli": "^5.0.0",
|
||||
"cpx2": "^7.0.1",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"eslint": "^9.7.0",
|
||||
"husky": "^9.1.1",
|
||||
"lint-staged": "^15.2.7",
|
||||
"eslint": "^9.8.0",
|
||||
"husky": "^9.1.4",
|
||||
"lint-staged": "^15.2.8",
|
||||
"rimraf": "^6.0.1",
|
||||
"stylelint": "^16.7.0",
|
||||
"stylelint": "^16.8.1",
|
||||
"tsconfig-vuepress": "^4.5.0",
|
||||
"tsup": "^8.2.0",
|
||||
"typescript": "^5.5.3",
|
||||
"tsup": "^8.2.4",
|
||||
"typescript": "^5.5.4",
|
||||
"wait-on": "^7.2.0"
|
||||
},
|
||||
"lint-staged": {
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
"vuepress": "2.0.0-rc.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.4.33"
|
||||
"vue": "^3.4.35"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -46,20 +46,20 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/utils": "^2.1.25",
|
||||
"@vuepress/helper": "2.0.0-rc.39",
|
||||
"@iconify/utils": "^2.1.30",
|
||||
"@vuepress/helper": "2.0.0-rc.40",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"local-pkg": "^0.5.0",
|
||||
"markdown-it-container": "^4.0.0",
|
||||
"nanoid": "^5.0.7",
|
||||
"shiki": "^1.10.3",
|
||||
"tm-grammars": "^1.13.13",
|
||||
"tm-themes": "^1.5.5",
|
||||
"vue": "^3.4.33"
|
||||
"shiki": "^1.12.1",
|
||||
"tm-grammars": "^1.16.2",
|
||||
"tm-themes": "^1.6.1",
|
||||
"vue": "^3.4.35"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "^2.2.229",
|
||||
"@types/markdown-it": "^14.1.1"
|
||||
"@iconify/json": "^2.2.234",
|
||||
"@types/markdown-it": "^14.1.2"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -40,15 +40,15 @@
|
||||
"vuepress": "2.0.0-rc.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vuepress/helper": "2.0.0-rc.39",
|
||||
"@vuepress/helper": "2.0.0-rc.40",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"@vueuse/integrations": "^10.11.0",
|
||||
"chokidar": "^3.6.0",
|
||||
"focus-trap": "^7.5.4",
|
||||
"mark.js": "^8.11.1",
|
||||
"minisearch": "^7.0.2",
|
||||
"minisearch": "^7.1.0",
|
||||
"p-map": "^7.0.2",
|
||||
"vue": "^3.4.33"
|
||||
"vue": "^3.4.35"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -36,17 +36,17 @@
|
||||
"vuepress": "2.0.0-rc.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@shikijs/transformers": "^1.10.3",
|
||||
"@shikijs/twoslash": "^1.10.3",
|
||||
"@shikijs/transformers": "^1.12.1",
|
||||
"@shikijs/twoslash": "^1.12.1",
|
||||
"@types/hast": "^3.0.4",
|
||||
"@vuepress/helper": "2.0.0-rc.39",
|
||||
"@vuepress/helper": "2.0.0-rc.40",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"floating-vue": "^5.2.2",
|
||||
"mdast-util-from-markdown": "^2.0.1",
|
||||
"mdast-util-gfm": "^3.0.0",
|
||||
"mdast-util-to-hast": "^13.2.0",
|
||||
"nanoid": "^5.0.7",
|
||||
"shiki": "^1.10.3",
|
||||
"shiki": "^1.12.1",
|
||||
"twoslash": "^0.2.9",
|
||||
"twoslash-vue": "^0.2.9"
|
||||
},
|
||||
|
||||
1721
pnpm-lock.yaml
generated
1721
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -71,26 +71,26 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/utils": "^2.1.25",
|
||||
"@iconify/utils": "^2.1.30",
|
||||
"@iconify/vue": "^4.1.2",
|
||||
"@pengzhanbo/utils": "^1.1.2",
|
||||
"@vuepress-plume/plugin-content-update": "workspace:*",
|
||||
"@vuepress-plume/plugin-fonts": "workspace:*",
|
||||
"@vuepress-plume/plugin-search": "workspace:*",
|
||||
"@vuepress-plume/plugin-shikiji": "workspace:*",
|
||||
"@vuepress/helper": "2.0.0-rc.39",
|
||||
"@vuepress/plugin-active-header-links": "2.0.0-rc.39",
|
||||
"@vuepress/helper": "2.0.0-rc.40",
|
||||
"@vuepress/plugin-active-header-links": "2.0.0-rc.40",
|
||||
"@vuepress/plugin-cache": "2.0.0-rc.39",
|
||||
"@vuepress/plugin-comment": "2.0.0-rc.39",
|
||||
"@vuepress/plugin-docsearch": "2.0.0-rc.39",
|
||||
"@vuepress/plugin-comment": "2.0.0-rc.40",
|
||||
"@vuepress/plugin-docsearch": "2.0.0-rc.40",
|
||||
"@vuepress/plugin-git": "2.0.0-rc.38",
|
||||
"@vuepress/plugin-markdown-container": "2.0.0-rc.37",
|
||||
"@vuepress/plugin-nprogress": "2.0.0-rc.39",
|
||||
"@vuepress/plugin-photo-swipe": "2.0.0-rc.39",
|
||||
"@vuepress/plugin-reading-time": "2.0.0-rc.39",
|
||||
"@vuepress/plugin-seo": "2.0.0-rc.39",
|
||||
"@vuepress/plugin-sitemap": "2.0.0-rc.39",
|
||||
"@vuepress/plugin-watermark": "2.0.0-rc.39",
|
||||
"@vuepress/plugin-nprogress": "2.0.0-rc.40",
|
||||
"@vuepress/plugin-photo-swipe": "2.0.0-rc.40",
|
||||
"@vuepress/plugin-reading-time": "2.0.0-rc.40",
|
||||
"@vuepress/plugin-seo": "2.0.0-rc.40",
|
||||
"@vuepress/plugin-sitemap": "2.0.0-rc.40",
|
||||
"@vuepress/plugin-watermark": "2.0.0-rc.40",
|
||||
"@vueuse/core": "^10.11.0",
|
||||
"bcrypt-ts": "^5.0.2",
|
||||
"chokidar": "^3.6.0",
|
||||
@ -103,12 +103,12 @@
|
||||
"katex": "^0.16.11",
|
||||
"local-pkg": "^0.5.0",
|
||||
"nanoid": "^5.0.7",
|
||||
"vue": "^3.4.33",
|
||||
"vue-router": "^4.4.0",
|
||||
"vue": "^3.4.35",
|
||||
"vue-router": "^4.4.2",
|
||||
"vuepress-plugin-md-enhance": "2.0.0-rc.52",
|
||||
"vuepress-plugin-md-power": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "^2.2.229"
|
||||
"@iconify/json": "^2.2.234"
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,13 +11,16 @@ import { useBlogPageData } from './page.js'
|
||||
|
||||
export function usePrevNext() {
|
||||
const route = useRoute()
|
||||
const { frontmatter } = useData()
|
||||
const { frontmatter, theme } = useData()
|
||||
const { sidebar } = useSidebar()
|
||||
const postList = usePostList() as unknown as Ref<PlumeThemeBlogPostItem[]>
|
||||
const locale = usePageLang()
|
||||
const { isBlogPost } = useBlogPageData()
|
||||
|
||||
const prevNavList = computed(() => {
|
||||
if (theme.value.prevPage === false)
|
||||
return null
|
||||
|
||||
const prevConfig = resolveFromFrontmatterConfig(frontmatter.value.prev)
|
||||
if (prevConfig !== false)
|
||||
return prevConfig
|
||||
@ -35,6 +38,9 @@ export function usePrevNext() {
|
||||
})
|
||||
|
||||
const nextNavList = computed(() => {
|
||||
if (theme.value.nextPage === false)
|
||||
return null
|
||||
|
||||
const nextConfig = resolveFromFrontmatterConfig(frontmatter.value.next)
|
||||
if (nextConfig !== false)
|
||||
return nextConfig
|
||||
|
||||
@ -26,6 +26,8 @@ const FALLBACK_OPTIONS: PlumeThemeLocaleData = {
|
||||
// page meta
|
||||
editLink: true,
|
||||
contributors: true,
|
||||
prevPage: true,
|
||||
nextPage: true,
|
||||
|
||||
footer: {
|
||||
message:
|
||||
|
||||
@ -86,7 +86,7 @@ function getIconsWithPage(page: Page): string[] {
|
||||
list.push(page.frontmatter.icon)
|
||||
}
|
||||
|
||||
return list
|
||||
return list.filter(icon => !isLinkHttp(icon) && !isLinkAbsolute(icon) && icon[0] !== '{')
|
||||
}
|
||||
|
||||
function getIconWithThemeConfig(localeOptions: PlumeThemeLocaleOptions): string[] {
|
||||
|
||||
@ -211,6 +211,13 @@ export interface PlumeThemeLocaleData extends LocaleData {
|
||||
*/
|
||||
outlineLabel?: string
|
||||
|
||||
/**
|
||||
* 是否显示上一页
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
prevPage?: boolean
|
||||
|
||||
/**
|
||||
* 上一页的文本
|
||||
*
|
||||
@ -218,6 +225,13 @@ export interface PlumeThemeLocaleData extends LocaleData {
|
||||
*/
|
||||
prevPageLabel?: string
|
||||
|
||||
/**
|
||||
* 是否显示下一页
|
||||
*
|
||||
* @default true
|
||||
*/
|
||||
nextPage?: boolean
|
||||
|
||||
/**
|
||||
* 下一页的文本
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user