feat: update demo-wrapper container

This commit is contained in:
pengzhanbo 2024-01-22 00:33:47 +08:00
parent ea6617554e
commit 0f8acc37dc
3 changed files with 128 additions and 7 deletions

View File

@ -106,17 +106,22 @@ H~2~O
**demo wrapper**
::: 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>main</div>
<div>aside</div>
<div class="main">main</div>
<div class="aside">aside</div>
</div>
:::

View File

@ -419,22 +419,53 @@
/* --------------------- demo-wrapper ------------------------ */
.plume-content .demo-wrapper {
display: flex;
flex-direction: column;
min-height: 40px;
margin: 40px -16px;
border: solid 1px var(--vp-c-divider);
border-radius: 8px;
box-shadow: var(--vp-shadow-2);
&.has-title .demo-head {
border-bottom-color: transparent;
}
&.only-img {
overflow: hidden;
}
&.only-img img {
display: block;
}
&.only-img .demo-container,
&.no-padding .demo-container {
padding: 0;
}
&.has-height .demo-container {
height: var(--demo-container-height);
overflow-y: auto;
}
.demo-head {
display: flex;
align-items: center;
justify-content: flex-start;
min-height: 0;
border-bottom: solid 1px var(--vp-c-divider);
}
.demo-ctrl {
display: flex;
gap: 5px;
align-items: center;
justify-content: flex-start;
padding: 5px 0 5px 8px;
border-bottom: solid 1px var(--vp-c-divider);
}
.demo-head i {
.demo-ctrl i {
display: inline-block;
width: 10px;
height: 10px;
@ -454,8 +485,52 @@
}
}
.demo-title {
position: relative;
min-width: 0;
padding: 0 16px;
margin: 0 20px -1px;
font-size: 14px;
font-weight: 500;
color: var(--vp-c-text-2);
background-color: var(--vp-c-bg-alt);
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
.demo-title p {
max-width: 100%;
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
text-wrap: nowrap;
}
.demo-title::after,
.demo-title::before {
position: absolute;
bottom: 0;
z-index: 1;
width: 8px;
height: 8px;
content: " ";
}
.demo-title::before {
left: 100%;
background: radial-gradient(16px at right top, transparent 50%, var(--vp-c-bg-alt) 50%);
}
.demo-title::after {
right: 100%;
background: radial-gradient(16px at left top, transparent 50%, var(--vp-c-bg-alt) 50%);
}
.demo-container {
min-height: 0;
padding: 20px;
font-size: 14px;
line-height: 22px;
background-color: var(--vp-c-bg-alt);
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;

View File

@ -2,13 +2,54 @@ import containerPlugin from '@vuepress/plugin-container'
import type { Plugin } from '@vuepress/core'
export const customContainers: Plugin[] = [
/**
* :::demo-wrapper img no-padding title="xxx" height="100px"
* :::
*/
containerPlugin({
type: 'demo-wrapper',
before() {
return `<div class="demo-wrapper"><div class="demo-head"><i></i><i></i><i></i></div><div class="demo-container">\n`
before(info) {
const title = resolveAttr(info, 'title')
const wrapperClasses: string[] = ['demo-wrapper']
let containerStyle = ''
if (title)
wrapperClasses.push('has-title')
if (info.includes('img'))
wrapperClasses.push('only-img')
if (info.includes('no-padding'))
wrapperClasses.push('no-padding')
const height = resolveAttr(info, 'height')
if (height) {
const h = Number.parseFloat(height) === Number(height) ? `${height}px` : height
containerStyle += `--demo-container-height: ${h};`
wrapperClasses.push('has-height')
}
return `<div class="${wrapperClasses.join(' ')}">
<div class="demo-head">
<div class="demo-ctrl"><i></i><i></i><i></i></div>
${title ? `<h4 class="demo-title"><p>${title}</p></h4>` : ''}
</div>
<div class="demo-container" ${containerStyle ? `style="${containerStyle}"` : ''}>\n`
},
after() {
return '</div></div>\n'
},
}),
]
/**
* Resolve the specified attribute from token info
*/
function resolveAttr(info: string, attr: string): string | null {
// try to match specified attr mark
const pattern = `\\b${attr}\\s*=\\s*(?<quote>['"])(?<content>.+?)\\k<quote>(\\s|$)`
const regex = new RegExp(pattern, 'i')
const match = info.match(regex)
// return content if matched, null if not specified
return match?.groups?.content ?? null
}