docs: add layout-slots example (#560)

This commit is contained in:
pengzhanbo 2025-04-21 00:19:28 +08:00 committed by GitHub
parent 939e51c5c3
commit 614d7f5f0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 746 additions and 3 deletions

View File

@ -0,0 +1,39 @@
name: Deploy Docs
on:
workflow_dispatch:
jobs:
deploy-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Install deps
run: pnpm install --frozen-lockfile
- name: Build Packages
run: pnpm build:package
- name: Docs build
env:
NODE_OPTIONS: --max_old_space_size=8192
run: cd examples/layout-slots && pnpm docs:build
- name: Deploy docs
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages-layout-slots
folder: examples/layout-slots/docs/.vuepress/dist
single-commit: true

6
.gitignore vendored
View File

@ -1,8 +1,8 @@
**/node_modules/
docs/.vuepress/.cache
docs/.vuepress/.temp
docs/.vuepress/dist
**/.vuepress/.cache
**/.vuepress/.temp
**/.vuepress/dist
lib/
dist/

View File

@ -0,0 +1,89 @@
import { h } from 'vue'
import { Layout, NotFound } from 'vuepress-theme-plume/client'
import { defineClientConfig } from 'vuepress/client'
import SlotDemo from './theme/components/SlotDemo.vue'
import './theme/styles/custom.css'
export default defineClientConfig({
layouts: {
Layout: () => h(Layout, null, {
'layout-top': () => h(SlotDemo, { name: 'layout-top' }),
'layout-bottom': () => h(SlotDemo, { name: 'layout-bottom' }),
'nav-bar-title-before': () => h(SlotDemo, { name: 'nav-bar-title-before', w: 64, h: 44, small: true }),
'nav-bar-title-after': () => h(SlotDemo, { name: 'nav-bar-title-after', w: 64, h: 44, small: true }),
'nav-bar-content-before': () => h(SlotDemo, { name: 'nav-bar-content-before', h: 44, small: true }),
'nav-bar-content-after': () => h(SlotDemo, { name: 'nav-bar-content-after', h: 44, small: true }),
'nav-bar-menu-before': () => h(SlotDemo, { name: 'nav-bar-menu-before', h: 44, small: true }),
'nav-bar-menu-after': () => h(SlotDemo, { name: 'nav-bar-menu-after', h: 44, small: true }),
'nav-screen-content-before': () => h(SlotDemo, { name: 'nav-screen-content-before', h: 44, small: true }),
'nav-screen-content-after': () => h(SlotDemo, { name: 'nav-screen-content-after', h: 44, small: true }),
'nav-screen-menu-before': () => h(SlotDemo, { name: 'nav-screen-menu-before', h: 44, small: true }),
'nav-screen-menu-after': () => h(SlotDemo, { name: 'nav-screen-menu-after', h: 44, small: true }),
'footer-content': () => h(SlotDemo, { name: 'footer-content' }),
'bulletin-content': () => h(SlotDemo, { name: 'bulletin-content' }),
'doc-top': () => h(SlotDemo, { name: 'doc-top' }),
'doc-bottom': () => h(SlotDemo, { name: 'doc-bottom' }),
'doc-footer-before': () => h(SlotDemo, { name: 'doc-footer-before' }),
'doc-before': () => h(SlotDemo, { name: 'doc-before', mt: 16 }),
'doc-after': () => h(SlotDemo, { name: 'doc-after' }),
'doc-meta-before': () => h(SlotDemo, { name: 'doc-meta-before', h: 24 }),
'doc-meta-after': () => h(SlotDemo, { name: 'doc-meta-after', h: 24 }),
'doc-meta-top': () => h(SlotDemo, { name: 'doc-meta-top' }),
'doc-meta-bottom': () => h(SlotDemo, { name: 'doc-meta-bottom' }),
'sidebar-nav-before': () => h(SlotDemo, { name: 'sidebar-nav-before' }),
'sidebar-nav-after': () => h(SlotDemo, { name: 'sidebar-nav-after' }),
'aside-top': () => h(SlotDemo, { name: 'aside-top' }),
'aside-bottom': () => h(SlotDemo, { name: 'aside-bottom' }),
'aside-outline-before': () => h(SlotDemo, { name: 'aside-outline-before', mt: 16 }),
'aside-outline-after': () => h(SlotDemo, { name: 'aside-outline-after' }),
'page-top': () => h(SlotDemo, { name: 'page-top' }),
'page-bottom': () => h(SlotDemo, { name: 'page-bottom' }),
'blog-top': () => h(SlotDemo, { name: 'blog-top' }),
'blog-bottom': () => h(SlotDemo, { name: 'blog-bottom', mt: 16 }),
'blog-aside-top': () => h(SlotDemo, { name: 'blog-aside-top', h: 44, mt: 16 }),
'blog-aside-bottom': () => h(SlotDemo, { name: 'blog-aside-bottom', h: 44 }),
'blog-extract-before': () => h(SlotDemo, { name: 'blog-extract-before' }),
'blog-extract-after': () => h(SlotDemo, { name: 'blog-extract-after' }),
'blog-post-list-before': () => h(SlotDemo, { name: 'blog-post-list-before', mt: 16 }),
'blog-post-list-after': () => h(SlotDemo, { name: 'blog-post-list-after' }),
'blog-post-list-pagination-after': () => h(SlotDemo, {
name: 'blog-post-list-pagination-after',
}),
'blog-tags-before': () => h(SlotDemo, { name: 'blog-tags-before', mt: 16 }),
'blog-tags-after': () => h(SlotDemo, { name: 'blog-tags-after', mt: 16 }),
'blog-tags-content-before': () => h(SlotDemo, { name: 'blog-tags-content-before', mt: 16 }),
'blog-tags-title-after': () => h(SlotDemo, { name: 'blog-tags-title-after' }),
'blog-archives-before': () => h(SlotDemo, { name: 'blog-archives-before', mt: 16 }),
'blog-archives-after': () => h(SlotDemo, { name: 'blog-archives-after' }),
'blog-categories-before': () => h(SlotDemo, { name: 'blog-categories-before' }),
'blog-categories-content-before': () => h(SlotDemo, { name: 'blog-categories-content-before' }),
'blog-categories-after': () => h(SlotDemo, { name: 'blog-categories-after' }),
}),
NotFound: () => h(NotFound, null, {
'layout-top': () => h(SlotDemo, { name: 'layout-top' }),
'layout-bottom': () => h(SlotDemo, { name: 'layout-bottom' }),
'nav-bar-title-before': () => h(SlotDemo, { name: 'nav-bar-title-before', w: 64, h: 44, small: true }),
'nav-bar-title-after': () => h(SlotDemo, { name: 'nav-bar-title-after', w: 64, h: 44, small: true }),
'nav-bar-content-before': () => h(SlotDemo, { name: 'nav-bar-content-before', h: 44, small: true }),
'nav-bar-content-after': () => h(SlotDemo, { name: 'nav-bar-content-after', h: 44, small: true }),
'nav-bar-menu-before': () => h(SlotDemo, { name: 'nav-bar-menu-before', h: 44, small: true }),
'nav-bar-menu-after': () => h(SlotDemo, { name: 'nav-bar-menu-after', h: 44, small: true }),
'nav-screen-content-before': () => h(SlotDemo, { name: 'nav-screen-content-before', h: 44, small: true }),
'nav-screen-content-after': () => h(SlotDemo, { name: 'nav-screen-content-after', h: 44, small: true }),
'nav-screen-menu-before': () => h(SlotDemo, { name: 'nav-screen-menu-before', h: 44, small: true }),
'nav-screen-menu-after': () => h(SlotDemo, { name: 'nav-screen-menu-after', h: 44, small: true }),
'footer-content': () => h(SlotDemo, { name: 'footer-content' }),
'not-found': () => h(SlotDemo, { name: 'not-found' }),
}),
},
})

View File

@ -0,0 +1,34 @@
import { viteBundler } from '@vuepress/bundler-vite'
import { defineUserConfig } from 'vuepress'
import { plumeTheme } from 'vuepress-theme-plume'
export default defineUserConfig({
base: '/',
lang: 'zh-CN',
title: 'Plume',
description: 'vuepress-theme-plume',
head: [
// 配置站点图标
['link', { rel: 'icon', type: 'image/png', href: 'https://theme-plume.vuejs.press/favicon-32x32.png' }],
],
bundler: viteBundler(),
shouldPrefetch: false, // 站点较大,页面数量较多时,不建议启用
theme: plumeTheme({
/* 添加您的部署域名, 有助于 SEO, 生成 sitemap */
// hostname: 'https://your_site_url',
/* 文档仓库配置,用于 editLink */
docsRepo: 'pengzhanbo/vuepress-theme-plume',
docsDir: 'examples/layout-slots/docs',
/* 页内信息 */
contributors: { mode: 'block' },
changelog: true,
/* 本地搜索, 默认启用 */
search: { provider: 'local' },
}),
})

View File

@ -0,0 +1,8 @@
import { defineNavbarConfig } from 'vuepress-theme-plume'
export const navbar = defineNavbarConfig([
{ text: '首页', link: '/' },
{ text: '博客', link: '/blog/' },
{ text: '404', link: '/404/' },
{ text: '笔记', link: '/notes/demo/README.md' },
])

View File

@ -0,0 +1,13 @@
import { defineNoteConfig, defineNotesConfig } from 'vuepress-theme-plume'
const demoNote = defineNoteConfig({
dir: 'demo',
link: '/demo',
sidebar: ['', 'foo', 'bar'],
})
export const notes = defineNotesConfig({
dir: 'notes',
link: '/',
notes: [demoNote],
})

View File

@ -0,0 +1,31 @@
import { defineThemeConfig } from 'vuepress-theme-plume'
import { navbar } from './navbar'
import { notes } from './notes'
/**
* @see https://theme-plume.vuejs.press/config/basic/
*/
export default defineThemeConfig({
logo: 'https://theme-plume.vuejs.press/plume.png',
appearance: true, // 配置 深色模式
social: [
{ icon: 'github', link: '/' },
],
/**
* @see https://theme-plume.vuejs.press/config/basic/#profile
*/
profile: {
avatar: 'https://theme-plume.vuejs.press/plume.png',
name: 'VuePress Plume',
description: 'vuepress-theme-plume',
// circle: true,
// location: '',
// organization: '',
},
navbar,
notes,
})

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 72 72">
<path fill="#5086a1" d="M42.334 49.147a29.945 29.945 0 0 1-19.338-8.151c-8.014-7.365-8.378-18.076-8.533-22.649l-.022-.627a2.904 2.904 0 0 1 3.457-2.951c17.005 3.355 21.695 16.324 22.056 17.4a49.543 49.543 0 0 1 3.574 15.922a1 1 0 0 1-.967 1.052c-.029.001-.106.004-.227.004" />
<path fill="#8cccd5" d="M44.436 55.316c-11.646 0-17.376-6.974-17.653-7.354a1 1 0 0 1 .262-1.424a11.103 11.103 0 0 1 12.774-1.574c-1.465-9.078 1.877-13.568 2.031-13.77a.998.998 0 0 1 .75-.39a.97.97 0 0 1 .78.325c8.944 9.771 8.793 16.532 7.908 19.691c-.034.14-1.062 4.092-4.772 4.406c-.711.062-1.405.09-2.08.09" />
<g fill="none" stroke="#333" stroke-linecap="round" stroke-linejoin="round" stroke-width="1">
<path d="M55.184 57.69S34.96 45.877 23.097 24.206m22.131 30.096c-11.93.46-17.628-6.88-17.628-6.88" />
<path d="M40.528 42.483c-.56-7.195 2.116-10.679 2.116-10.679c8.834 9.654 8.406 16.162 7.681 18.747m-13.311-3.129a30.15 30.15 0 0 1-13.341-7.162c-8.072-7.419-8.067-18.241-8.232-22.577a1.903 1.903 0 0 1 2.264-1.932C34.694 19.103 39.02 32.528 39.02 32.528" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,11 @@
<script setup lang="ts">
import { ref } from 'vue'
const message = ref('Hello World!')
</script>
<template>
<div class="my-custom-content">
{{ message }}
</div>
</template>

View File

@ -0,0 +1,68 @@
<script setup lang="ts">
withDefaults(defineProps<{
name: string
w?: number
h?: number
mt?: number
small?: boolean
}>(), {
h: 60,
})
</script>
<template>
<div
class="slot-demo"
:class="{ [name]: true, small }"
:style="{ width: `${w}px`, height: `${h}px`, marginTop: `${mt}px` }"
:title="name"
>
<span>{{ name }}</span>
</div>
</template>
<style scoped>
.slot-demo {
--slot-demo-bg-1: #ddd;
--slot-demo-bg-2: #eee;
display: flex;
align-items: center;
justify-content: center;
max-width: 100%;
max-height: 100%;
padding: 0 8px;
background:
repeating-linear-gradient(
-45deg,
var(--slot-demo-bg-1) 0,
var(--slot-demo-bg-2) 1px,
var(--slot-demo-bg-2) 0.4em,
var(--slot-demo-bg-1) calc(0.25em + 1px),
var(--slot-demo-bg-1) 0.75em
);
border-radius: 6px;
}
[data-theme="dark"] .slot-demo {
--slot-demo-bg-1: #333;
--slot-demo-bg-2: #444;
}
.slot-demo.small {
font-size: 12px !important;
}
.slot-demo span {
overflow: hidden;
text-overflow: ellipsis;
}
.slot-demo.layout-top {
position: fixed;
top: 0;
left: 0;
z-index: 100;
width: 100%;
}
</style>

View File

@ -0,0 +1,6 @@
declare module '*.vue' {
import type { ComponentOptions } from 'vue'
const comp: ComponentOptions
export default comp
}

View File

@ -0,0 +1,3 @@
:root {
--vp-layout-top-height: 60px;
}

View File

@ -0,0 +1,33 @@
---
pageLayout: home
config:
-
type: doc-hero
hero:
name: Theme Plume
text: VuePress Next Theme
tagline: 示例用于展示所有的布局插槽
image:
src: /plume.svg
width: 240
actions:
-
theme: brand
text: 博客
link: /blog/
-
theme: alt
text: Github →
link: https://github.com/pengzhanbo/vuepress-theme-plume
---
<style>
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: linear-gradient(120deg, var(--vp-c-purple-1) 30%, var(--vp-c-brand-2));
--vp-home-hero-tagline: var(--vp-c-text-2);
--vp-home-hero-text: var(--vp-c-text-1);
--vp-home-hero-image-background-image: linear-gradient(-45deg, var(--vp-c-brand-soft) 50%, var(--vp-c-brand-2) 50%);
--vp-home-hero-image-filter: blur(44px);
}
</style>

View File

@ -0,0 +1,10 @@
---
title: Demo
createTime: 2025/04/17 02:28:30
permalink: /demo/
---
## Links
- [bar](./bar.md)
- [foo](./foo.md)

View File

@ -0,0 +1,9 @@
---
title: bar
createTime: 2025/04/17 02:28:30
permalink: /demo/yo5telb7/
---
## Links
[foo](./foo.md)

View File

@ -0,0 +1,9 @@
---
title: foo
createTime: 2025/04/17 02:28:30
permalink: /demo/nsgytm0i/
---
## Links
[bar](./bar.md)

View File

@ -0,0 +1,11 @@
---
pageLayout: page
title: "Layout: Page"
tags:
- 预览
- 组件
createTime: 2025/04/17 02:28:30
permalink: /article/u2pon1pb/
---
Layout: Page Content

View File

@ -0,0 +1,315 @@
---
title: Markdown
tags:
- markdown
createTime: 2025/04/17 02:28:30
permalink: /article/fs03b2zf/
---
## 标题H2
### 标题H3
#### 标题H4
##### 标题H5
###### 标题H6
## 标题2 Badge <Badge type="tip" text="Badge" />
### 标题3 Badge <Badge type="warning" text="Badge" />
#### 标题4 Badge <Badge type="danger" text="Badge" />
正文内容。
`@property` CSS at-rule是 [CSS Houdini API](https://developer.mozilla.org/zh-CN/docs/Web/Guide/Houdini)
的一部分,它允许开发者显式地定义他们的 [CSS 自定义属性](https://developer.mozilla.org/zh-CN/docs/Web/CSS/--*),
允许进行属性类型检查、设定默认值以及定义该自定义属性是否可以被继承。
`@property` 的出现,极大的增强了 CSS 的能力。
加粗:**加粗文字**
斜体: _斜体文字_
~~删除文字~~
内容 ==标记==
数学表达式: $-(2^{n-1})$ ~ $2^{n-1} -1$
$\frac {\partial^r} {\partial \omega^r} \left(\frac {y^{\omega}} {\omega}\right)
= \left(\frac {y^{\omega}} {\omega}\right) \left\{(\log y)^r + \sum_{i=1}^r \frac {(-1)^ Ir \cdots (r-i+1) (\log y)^{ri}} {\omega^i} \right\}$
19^th^
H~2~O
::: center
内容居中
:::
::: right
内容右对齐
:::
- 无序列表1
- 无序列表2
- 无序列表3
1. 有序列表1
2. 有序列表2
3. 有序列表3
- [ ] 任务列表1
- [ ] 任务列表2
- [x] 任务列表3
- [x] 任务列表4
| Tables | Are | Cool |
| ------------- |:-------------:| -----:|
| col 3 is | right-aligned | $1600 |
| col 2 is | centered | $12 |
| zebra stripes | are neat | $1 |
> 引用内容
>
> 引用内容
[链接](/)
[外部链接](https://github.com/pengzhanbo)
![plume](/plume.svg)
**Badge**
- <Badge type="info" text="info badge" />
- <Badge type="tip" text="tip badge" />
- <Badge type="warning" text="warning badge" />
- <Badge type="danger" text="danger badge" />
**图标:**
- home - <Icon name="material-symbols:home" color="currentColor" size="1em" />
- vscode - <Icon name="skill-icons:vscode-dark" size="2em" />
- twitter - <Icon name="skill-icons:twitter" size="2em" />
**demo wrapper**
::: demo-wrapper title="示例" no-padding height="200px"
<style scoped>
.open-door {
display: flex;
gap: 20px;
padding: 20px;
}
.open-door .main {
background: #ccc;
}
</style>
<div class="open-door">
<div class="main">main</div>
<div class="aside">aside</div>
</div>
:::
**代码:**
```js whitespace
const a = 1
const b = 2
const c = a + b
// [!code word:obj]
const obj = {
toLong: {
deep: {
deep: {
deep: {
value: 'this is to long text. this is to long text. this is to long text. this is to long text.', // [!code highlight]
}
}
}
}
}
```
**代码分组:**
::: code-tabs
@tab tab1
```js
const a = 1
const b = 2
const c = a + b
```
@tab tab2
```ts
const a: number = 1
const b: number = 2
const c: number = a + b
```
:::
**代码块高亮:**
```ts
function foo() {
const a = 1 // [!code highlight]
console.log(a)
const b = 2 // [!code ++]
const c = 3 // [!code --]
console.log(a + b + c) // [!code error]
console.log(a + b) // [!code warning]
}
```
**代码块聚焦:**
```ts
function foo() {
const a = 1 // [!code focus]
}
```
::: tip 仅标题
:::
::: note 注释
注释内容 [link](https://github.com/pengzhanbo) `inline code`
```js
const a = 1
const b = 2
const c = a + b
```
:::
::: info 信息
信息内容 [link](https://github.com/pengzhanbo) `inline code`
```js
const a = 1
const b = 2
const c = a + b
```
:::
::: tip 提示
提示内容 [link](https://github.com/pengzhanbo) `inline code`
```js
const a = 1
const b = 2
const c = a + b
```
:::
::: warning 警告
警告内容 [link](https://github.com/pengzhanbo) `inline code`
```js
const a = 1
const b = 2
const c = a + b
```
:::
::: caution 错误
错误内容 [link](https://github.com/pengzhanbo) `inline code`
```js
const a = 1
const b = 2
const c = a + b
```
:::
::: important 重要
重要内容 [link](https://github.com/pengzhanbo) `inline code`
```js
const a = 1
const b = 2
const c = a + b
```
:::
::: details 详细标题
这里是内容。
:::
**GFM alert**
> [!note]
> note
> [!info]
> info
> [!tip]
> tip
> [!warning]
> warning
> [!caution]
> caution
> [!important]
> important
**选项卡:**
::: tabs
@tab 标题1
内容区块
@tab 标题2
内容区块
:::
:::: warning
::: tabs
@tab 标题1
内容区块
@tab 标题2
内容区块
:::
::::
**脚注:**
脚注 1 链接[^first]。
脚注 2 链接[^second]。
行内的脚注^[行内脚注文本] 定义。
重复的页脚定义[^second]。
[^first]: 脚注 **可以包含特殊标记**
也可以由多个段落组成
[^second]: 脚注文字。

View File

@ -0,0 +1,21 @@
{
"name": "layout-slots",
"type": "module",
"private": true,
"scripts": {
"docs:build": "vuepress build docs --clean-cache --clean-temp",
"docs:clean": "rimraf .vuepress/.temp .vuepress/.cache .vuepress/dist",
"docs:dev": "vuepress dev docs"
},
"peerDependencies": {
"vuepress": "catalog:vuepress"
},
"dependencies": {
"@iconify/json": "catalog:peer",
"@vuepress/bundler-vite": "catalog:vuepress",
"http-server": "catalog:dev",
"sass-embedded": "catalog:peer",
"vue": "catalog:prod",
"vuepress-theme-plume": "workspace:*"
}
}

24
pnpm-lock.yaml generated
View File

@ -544,6 +544,30 @@ importers:
specifier: catalog:dev
version: 5.0.1
examples/layout-slots:
dependencies:
'@iconify/json':
specifier: catalog:peer
version: 2.2.329
'@vuepress/bundler-vite':
specifier: catalog:vuepress
version: 2.0.0-rc.21(@types/node@22.14.1)(jiti@2.4.2)(less@4.3.0)(sass-embedded@1.86.3)(sass@1.86.3)(stylus@0.64.0)(typescript@5.8.3)(yaml@2.7.0)
http-server:
specifier: catalog:dev
version: 14.1.1
sass-embedded:
specifier: ^1.86.3
version: 1.86.3
vue:
specifier: catalog:prod
version: 3.5.13(typescript@5.8.3)
vuepress:
specifier: catalog:vuepress
version: 2.0.0-rc.21(@vuepress/bundler-vite@2.0.0-rc.21(@types/node@22.14.1)(jiti@2.4.2)(less@4.3.0)(sass-embedded@1.86.3)(sass@1.86.3)(stylus@0.64.0)(typescript@5.8.3)(yaml@2.7.0))(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3))
vuepress-theme-plume:
specifier: workspace:*
version: link:../../theme
plugins/plugin-fonts:
dependencies:
vuepress:

View File

@ -3,6 +3,7 @@ packages:
- theme
- cli
- plugins/*
- examples/*
overrides:
'@typescript-eslint/utils': ^8.30.1