Merge branch 'master' of github.com:bd-js/bd-js.github.io

master
chenjiajian 2023-04-27 11:26:32 +08:00
commit b6e395a759
10 changed files with 406 additions and 311 deletions

View File

@ -15,24 +15,62 @@ import {
export default { export default {
props: { props: {
lang: { type: String, default: 'vue' }, lang: { type: String, default: 'vue' },
code: String code: ''
},
watch: {
code(v) {
let doc = this.$view.state.doc
this.$view.dispatch({
changes: {
from: 0,
to: doc.length,
insert: v
}
})
}
}, },
mounted() { mounted() {
let lang = this.lang
this.$last = this.code
this.$view = new EditorView({ this.$view = new EditorView({
doc: this.code, doc: this.code,
extensions: minimalSetup(vue(), EditorView.lineWrapping), extensions: minimalSetup(
lang === 'html'
? html()
: lang === 'js'
? javascript()
: lang === 'css'
? css()
: vue(),
EditorView.lineWrapping,
//
EditorView.updateListener.of(v => {
let value = v.state.doc.toString().trim()
if (!this.$last || value === this.$last) {
this.$last = value
return
}
this.$last = value
this.$emit('change', value, lang)
})
),
parent: this.$refs.container parent: this.$refs.container
}) })
} },
methods: {}
} }
</script> </script>
<style> <style>
.container { .container {
width: 50%; width: 100%;
height: 100%;
flex-shrink: 0; flex-shrink: 0;
border-right: 1px solid var(--color-plain-2);
} }
.cm-editor { .cm-editor {
width: 100%; width: 100%;

View File

@ -1,10 +1,11 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './app.vue' import App from './app.vue'
// import '//jscdn.ink/@bd/ui/latest/form/index.js'
import '//jscdn.ink/@bd/ui/latest/form/index.js' import '//jscdn.ink/@bd/ui/latest/form/index.js'
import '//jscdn.ink/@bd/ui/latest/markd/index.js' import '//jscdn.ink/@bd/ui/latest/markd/index.js'
import '//jscdn.ink/@bd/ui/latest/sandbox/index.js' import '//jscdn.ink/@bd/ui/latest/sandbox/index.js'
// import '//127.0.0.1:8090/dist/markd/index.js'
// import '//127.0.0.1:8090/dist/sandbox/index.js'
const app = createApp(App) const app = createApp(App)

View File

@ -1,98 +1,77 @@
<template> <template>
<Topbar /> <Topbar />
<banner class="banner flex-ac"> <banner class="banner">
<div class="wrapper flex-ac"> <div class="wrapper">
<h1>轻量级模块化组件库</h1> <section class="slogen">
<cite>一款基于Web Components, 面向未来的桌面UI组件库</cite> <h1>轻量级模块化组件库</h1>
<cite>不挑框架, 可无缝适配React, Angular, Avalon, Vue, jQuery...</cite> <cite>一款基于Web Components, 面向未来的桌面UI组件库</cite>
<cite>网站快速成型工具</cite> <cite>不挑框架, 可无缝适配React, Angular, Avalon, Vue, jQuery...</cite>
<cite>网站快速成型工具</cite>
<wc-space gap="xxxl">
<wc-button size="xl" round solid @click="navto('/@wcui/docs.html')"
>开始使用</wc-button
>
<wc-button
size="xl"
type="secondary"
round
@click="navto('https://github.com/bd-js/wcui')"
>GitHub</wc-button
>
</wc-space>
<wc-space>
<img src="https://img.shields.io/npm/dt/@bd/ui.svg" />
<img src="https://img.shields.io/npm/v/@bd/ui.svg" />
<img src="https://img.shields.io/github/stars/bd-js/wcui.svg" />
</wc-space>
</section>
<div class="blur-bg"></div>
<svg class="line" width="1200" height="300">
<g>
<path
d="M20,283 C288,288 604,64 1080,16"
fill="none"
stroke="var(--color-blue-a)"
stroke-width="0.5"
/>
<path
d="M424,300 C512,288 588,108 1080,23"
fill="none"
stroke="var(--color-dark-a)"
stroke-width="0.5"
/>
<path
d="M234,300 C512,288 588,108 1080,63"
fill="none"
stroke="var(--color-teal-a)"
stroke-width="0.5"
/>
</g>
</svg>
</div> </div>
</banner> </banner>
<div class="colorful flex-ac"> <div class="feature">
<div class="wrapper flex-ac"> <div class="wrapper">
<header class="title">- 主题配色 -</header> <section class="item">
<section> <wc-icon name="client"></wc-icon>
<ul class="blue"> <h3>基于原生影子节点</h3>
<li></li> <cite>优秀的兼容性, 不挑框架</cite>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="teal">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="green">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="red">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="orange">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="plain">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="grey">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="dark">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</section>
</div>
</div>
<div class="basic-demo flex-ac">
<div class="wrapper flex-ac">
<header class="title">Buttons</header>
<section>
<wc-button type="primary">Primary Button</wc-button>
<wc-button type="secondary">Secondary Button</wc-button>
<wc-button type="info">Info Button</wc-button>
<wc-button type="help">Help Button</wc-button>
</section>
<section>
<wc-button solid>Solid Button</wc-button>
<wc-button solid type="success">Success Button</wc-button>
<wc-button solid type="warning">Warning Button</wc-button>
<wc-button solid type="danger">Danger Button</wc-button>
</section> </section>
<header class="title">Inputs</header> <section class="item">
<section> <wc-icon name="finger-print"></wc-icon>
<wc-input placeholder="Normal Input"></wc-input> <h3>原生的隔离能力</h3>
<wc-input placeholder="Success Input" type="success"></wc-input> <cite>无样式污染, 灵活的拓展接口</cite>
<wc-input placeholder="Danger Input" type="danger"></wc-input>
<wc-input placeholder="Disabled Input" disabled></wc-input>
</section> </section>
<div class="more"> <section class="item">
<wc-link type="danger" to="./docs.html">更多组件...</wc-link> <wc-icon name="fly"></wc-icon>
</div> <h3>基于强大的@bd/core</h3>
<cite>Vue一样的开发体验</cite>
</section>
</div> </div>
</div> </div>
@ -106,6 +85,11 @@ export default {
components: { components: {
Topbar, Topbar,
Footer Footer
},
methods: {
navto(target) {
location.href = target
}
} }
} }
</script> </script>
@ -122,7 +106,7 @@ a {
} }
.wrapper { .wrapper {
width: 960px; width: 1024px;
} }
.banner { .banner {
@ -130,239 +114,112 @@ a {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
height: 400px; height: 400px;
background: linear-gradient(to right bottom, #155799, #157879, #159857);
.wrapper { .wrapper {
display: flex; display: flex;
flex-direction: column; justify-content: space-between;
align-items: center;
padding: 48px 0; padding: 48px 0;
.slogen {
display: flex;
flex-direction: column;
}
.blur-bg {
width: 212px;
height: 320px;
border-radius: 50%;
background-image: linear-gradient(
to bottom,
var(--color-blue-a),
var(--color-dark-a) 60%
);
transform: scale(1.25);
filter: blur(50px);
}
.line {
position: absolute;
z-index: -1;
}
h1 { h1 {
line-height: 2; line-height: 2;
font-size: 38px; font-size: 38px;
font-weight: normal; font-weight: normal;
color: var(--color-plain-1);
} }
cite { cite {
line-height: 2; line-height: 1.75;
font-size: 16px; font-size: 16px;
font-style: normal; font-style: normal;
color: var(--color-plain-3);
}
section {
margin-top: 64px;
text-align: center;
wc-button {
margin: 0 16px;
}
} }
} }
} }
.colorful {
.feature {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background: var(--color-plain-1);
.wrapper { .wrapper {
flex-direction: column; display: flex;
padding: 32px 0; justify-content: space-between;
padding: 64px 0;
.title { .item {
position: relative;
line-height: 3;
font-size: 26px;
text-align: center;
color: var(--color-grey-2);
}
section {
display: flex; display: flex;
justify-content: space-between; flex-direction: column;
margin-bottom: 32px; width: 300px;
height: 160px;
padding: 16px;
border-radius: 8px;
background: #f7f8fb;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
transition: background 0.2s ease-in-out, transform 0.2s ease-in-out;
ul { &:hover {
flex: 1; background: #fff;
display: flex; transform: translateY(-5px);
flex-direction: column;
justify-content: flex-end;
}
li {
height: 56px;
box-shadow: 0 -4px 8px rgba(0, 0, 0, 0.03);
} }
ul:nth-child(2), wc-icon {
ul:nth-child(5) { width: 64px;
li { height: 64px;
height: 48px; padding: 8px;
} border-radius: 6px;
}
ul:nth-child(3),
ul:nth-child(7) {
li {
height: 52px;
}
}
}
.blue {
li:nth-child(1) {
background: var(--color-blue-a);
}
li:nth-child(2) {
background: var(--color-blue-1);
}
li:nth-child(3) {
background: var(--color-blue-2);
}
li:nth-child(4) {
background: var(--color-blue-3);
}
}
.teal {
li:nth-child(1) {
background: var(--color-teal-a);
}
li:nth-child(2) {
background: var(--color-teal-1);
}
li:nth-child(3) {
background: var(--color-teal-2);
}
li:nth-child(4) {
background: var(--color-teal-3);
}
}
.green {
li:nth-child(1) {
background: var(--color-green-a);
}
li:nth-child(2) {
background: var(--color-green-1);
}
li:nth-child(3) {
background: var(--color-green-2);
}
li:nth-child(4) {
background: var(--color-green-3);
}
}
.red {
li:nth-child(1) {
background: var(--color-red-a);
}
li:nth-child(2) {
background: var(--color-red-1);
}
li:nth-child(3) {
background: var(--color-red-2);
}
li:nth-child(4) {
background: var(--color-red-3);
}
}
.orange {
li:nth-child(1) {
background: var(--color-orange-a);
}
li:nth-child(2) {
background: var(--color-orange-1);
}
li:nth-child(3) {
background: var(--color-orange-2);
}
li:nth-child(4) {
background: var(--color-orange-3);
}
}
.plain {
li:nth-child(1) {
background: #f7f8fb;
}
li:nth-child(2) {
background: var(--color-plain-1);
}
li:nth-child(3) {
background: var(--color-plain-2); background: var(--color-plain-2);
} }
li:nth-child(4) { h3 {
background: var(--color-plain-3); margin-top: 16px;
line-height: 2;
font-size: 16px;
font-weight: normal;
} }
}
.grey { cite {
li:nth-child(1) { font-size: 13px;
background: var(--color-grey-a); color: var(--color-grey-3);
}
li:nth-child(2) {
background: var(--color-grey-1);
}
li:nth-child(3) {
background: var(--color-grey-2);
}
li:nth-child(4) {
background: var(--color-grey-3);
}
}
.dark {
li:nth-child(1) {
background: var(--color-dark-a);
}
li:nth-child(2) {
background: var(--color-dark-1);
}
li:nth-child(3) {
background: var(--color-dark-2);
}
li:nth-child(4) {
background: var(--color-dark-3);
} }
} }
} }
} }
.basic-demo { @media screen and (min-width: 1440px) {
display: flex;
justify-content: center;
align-items: center;
.wrapper { .wrapper {
flex-direction: column; width: 1200px;
padding: 32px 0; }
.title { .banner .wrapper {
line-height: 2; h1 {
font-size: 22px; font-size: 46px;
color: var(--color-grey-2);
} }
section { cite {
display: flex; font-size: 18px;
justify-content: space-between;
margin-bottom: 32px;
wc-button,
wc-input {
flex: 1;
margin: 0 16px;
}
} }
.more { wc-button {
text-align: center; width: 160px;
a { height: 48px;
display: inline-flex;
padding: 4px 16px;
border-radius: 6px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.06);
&:hover {
color: var(--color-red-1);
}
}
} }
} }
} }

View File

@ -2,7 +2,7 @@
<footer class="footer"> <footer class="footer">
<div class="wrapper"> <div class="wrapper">
<section class="nav"> <section class="nav">
<a href="/">@bdjs 首页</a> | <a href="/">bd.js 首页</a> |
<a <a
href="https://github.com/bd-js/wcui/blob/master/LICENSE" href="https://github.com/bd-js/wcui/blob/master/LICENSE"
target="_blank" target="_blank"
@ -30,7 +30,7 @@ export default {}
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
height: 260px; height: 240px;
border-top: 1px solid var(--color-plain-3); border-top: 1px solid var(--color-plain-3);
.wrapper { .wrapper {

View File

@ -8,6 +8,7 @@
<nav class="menu"> <nav class="menu">
<a :class="{ active: nav === 'index' }" href="./index.html">主页</a> <a :class="{ active: nav === 'index' }" href="./index.html">主页</a>
<a :class="{ active: nav === 'docs' }" href="./docs.html">文档</a> <a :class="{ active: nav === 'docs' }" href="./docs.html">文档</a>
<a href="/playground.html">试一试</a>
<a target="_blank" href="https://github.com/bd-js/wcui" <a target="_blank" href="https://github.com/bd-js/wcui"
><img class="github" src="/assets/github.svg" alt="Web Components" ><img class="github" src="/assets/github.svg" alt="Web Components"
/></a> /></a>

View File

@ -1,7 +1,8 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './app.vue' import App from './app.vue'
import '//jscdn.ink/@bd/ui/0.1.3/form/index.js' import '//jscdn.ink/@bd/ui/latest/space/index.js'
import '//jscdn.ink/@bd/ui/latest/form/index.js'
const app = createApp(App) const app = createApp(App)

View File

@ -1,8 +1,18 @@
<template> <template>
<Topbar /> <Topbar />
<div class="playground"> <div class="playground">
<CodeEditor :code="code" /> <wc-tabs class="editor">
<Preview /> <wc-tab label="html" name="html">
<CodeEditor lang="html" :code="html" @change="updateCode" />
</wc-tab>
<wc-tab label="javascript" name="js">
<CodeEditor lang="js" :code="js" @change="updateCode" />
</wc-tab>
<wc-tab label="css" name="css">
<CodeEditor lang="css" :code="css" @change="updateCode" />
</wc-tab>
</wc-tabs>
<Preview :code="preview" />
</div> </div>
</template> </template>
@ -11,36 +21,105 @@ import CodeEditor from '@/components/code-editor.vue'
import Topbar from './views/topbar.vue' import Topbar from './views/topbar.vue'
import Preview from './views/preview.vue' import Preview from './views/preview.vue'
export default { import { gzip, ungzip } from '@bytedo/gzip'
components: { Topbar, CodeEditor, Preview },
data() { const template = `<!doctype html>
return {
code: `<!doctype html>
<html lang="zh-CN"> <html lang="zh-CN">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>{{title}}</title> <link rel="stylesheet" href="//jscdn.ink/@bd/ui/latest/css/reset-basic.css">
<meta name="keywords" content="{{keywords}}"> {{css}}
<meta name="description" content="{{description}}">
<link rel="stylesheet" href="//jscdn.ink/@bytedo/wcui/1.0.12/css/reset-basic.css">
<script async src="//jscdn.ink/es-module-shims/1.6.3/es-module-shims.wasm.js"><\/script> <script async src="//jscdn.ink/es-module-shims/1.6.3/es-module-shims.wasm.js"><\/script>
<script type="importmap">{{importmap}}<\/script> <script type="importmap">${JSON.stringify({
<\/head> imports: {
vue: '//jscdn.ink/vue/3.2.47/vue.runtime.esm-browser.prod.js',
'vue-router': '//jscdn.ink/@bytedo/vue-router/4.1.6/vue-router.js',
fetch: '//jscdn.ink/@bytedo/fetch/latest/next.js',
'@bytedo/editor': '//jscdn.ink/@bytedo/editor/latest/index.js',
'@bytedo/gzip': '//jscdn.ink/@bytedo/gzip/latest/index.js',
'@bd/core': '//jscdn.ink/@bd/core/latest/index.js'
}
})}<\/script>
<script type="module">
{{js}}
<\/script>
</head>
<body> <body>
<div class="app noselect"></div> {{html}}
<script src="main.js"><\/script>
<\/body> <\/body>
<\/html> <\/html>
` `
export default {
components: { Topbar, CodeEditor, Preview },
data() {
return {
html: '',
js: '',
css: '',
preview: ''
}
},
mounted() {
//
this.$needUpdate = true
window.addEventListener('hashchange', ev => {
this.handleHashChange()
})
this.handleHashChange()
},
methods: {
handleHashChange() {
if (this.$needUpdate) {
let code = location.hash.slice(1)
if (code) {
try {
code = ungzip(code)
code = JSON.parse(code)
} catch (e) {}
}
this.html = code.html
this.js = code.js
this.css = code.css
this.updatePreview()
}
this.$needUpdate = true
},
updateCode(code, lang) {
this[lang] = code
this.updatePreview(true)
},
updatePreview(sync) {
let { html, js, css } = this
if (sync) {
let code = gzip(JSON.stringify({ html, js, css }))
this.$needUpdate = false
location.hash = code
}
this.preview = template
.replace('{{css}}', css)
.replace('{{html}}', html)
.replace('{{js}}', js)
} }
} }
} }
</script> </script>
<style lang="scss"> <style lang="scss">
.app { body {
line-height: 1.5;
font-size: 14px;
}
#app {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100vh; height: 100vh;
@ -48,7 +127,12 @@ export default {
} }
.playground { .playground {
overflow: hidden;
flex: 1;
display: flex; display: flex;
height: calc(100vh - 48px); }
.editor {
width: 50%;
} }
</style> </style>

View File

@ -1,4 +1,12 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/04/26 18:28:13
*/
import { createApp } from 'vue' import { createApp } from 'vue'
import '//jscdn.ink/@bd/ui/latest/tabs/index.js'
import App from './app.vue' import App from './app.vue'
import store from './store' import store from './store'

View File

@ -1,12 +1,66 @@
<template> <template>
<main class="preview"></main> <main class="preview">
<div class="loading">
<span class="thumb" :style="{ width: progress + '%' }"></span>
</div>
<iframe class="web" ref="preview"></iframe>
</main>
</template> </template>
<script> <script>
import { nextTick } from 'vue'
let startTime = 0
export default { export default {
props: {
code: ''
},
data() { data() {
return { return {
content: '欢迎访问~~ 这是首页' progress: 0
}
},
watch: {
code(v) {
// console.log(v)
this.updatePreview(v)
}
},
methods: {
loading(stamp) {
if (startTime === 0) {
startTime = stamp
}
let _time = stamp - startTime
// _time / 2000 * 100 %
this.progress = ~~(_time / 20)
if (_time > 2000) {
this.progress = 0
let doc = this.$refs.preview.contentDocument
try {
doc.open()
doc.write(this.code)
doc.close()
} catch (e) {}
return
}
requestAnimationFrame(this.loading)
},
updatePreview(html) {
startTime = 0
this.progress = 0
requestAnimationFrame(this.loading)
} }
} }
} }
@ -14,7 +68,42 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.preview { .preview {
width: 50%; position: relative;
flex-shrink: 0; flex-shrink: 0;
width: 50%;
border-left: 1px solid var(--color-plain-2);
}
.web {
width: 100%;
height: 100%;
border: 0;
}
.loading {
position: absolute;
top: 0;
left: 0;
display: flex;
width: 100%;
height: 1px;
.thumb {
width: 0;
height: 1px;
background: var(--color-blue-1);
box-shadow: 0 0 5px var(--color-blue-1);
&.loading {
animation: loading 3s linear;
}
}
}
@keyframes loading {
from {
width: 0%;
}
to {
width: 100%;
}
} }
</style> </style>

View File

@ -1,8 +1,13 @@
<template> <template>
<header class="topbar noselect"> <header class="topbar noselect">
<a class="logo">@bd/ui playground</a> <a class="logo">@bd.js playground</a>
<a class="github" href="//github.com/bd-js/wcui" target="_blank">github</a> <span class="group">
<a class="link" href="/@wcui/index.html">返回首页</a>
<a class="link" href="//github.com/bd-js" target="_blank">
<img class="github" src="/assets/github.svg" alt="Web Components" />
</a>
</span>
</header> </header>
</template> </template>
@ -32,7 +37,18 @@ export default {
color: var(--color-red-2); color: var(--color-red-2);
} }
.github { .group {
display: inline-flex;
align-items: center;
}
.link {
display: inline-flex;
margin-left: 16px;
color: var(--color-dark-1); color: var(--color-dark-1);
img {
width: 18px;
height: 18px;
}
} }
</style> </style>