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

master
chenjiajian 2023-04-26 17:28:51 +08:00
commit 734dbc0785
5 changed files with 118 additions and 139 deletions

View File

@ -13,11 +13,11 @@
- @bd/core 针对`web components`的核心封装库, 以数据驱动, 可以更方便的开发 wc 组件
### 开发进度 && 计划 (33/54)
### 开发进度 && 计划 (34/54)
- [x] `wc-card` 卡片组件
- [x] `wc-space` 间隔组件
- [ ] `wc-avatar` 头像组件
- [x] `wc-avatar` 头像组件
- [x] `wc-badge` 徽标组件
- [x] `wc-drawer` 抽屉组件
- [x] `wc-collapse` 折叠组件

View File

@ -1,6 +1,6 @@
{
"name": "@bd/ui",
"version": "0.1.5",
"version": "0.1.6",
"description": "",
"files": [
"dist/*"

108
src/avatar/index.js Normal file
View File

@ -0,0 +1,108 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/04/25 09:27:25
*/
import { html, raw, css, Component, nextTick } from '@bd/core'
import '../icon/index.js'
class Avatar extends Component {
static props = {
src: {
type: String,
default: null
}
}
static styles = [
css`
:host {
display: inline-flex;
border-radius: 4px;
}
.avatar {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
padding: 2px;
border-radius: inherit;
text-align: center;
background: var(--color-grey-3);
color: #fff;
user-select: none;
img {
width: 100%;
height: 100%;
border-radius: inherit;
-webkit-user-drag: none;
}
}
:host([src]) {
.avatar {
padding: 0;
}
}
:host([round]) {
border-radius: 50%;
}
`,
// 尺寸
css`
@use 'sass:map';
$sizes: (
s: (
h: 20px,
f: 12px
),
m: (
h: 24px,
f: 12px
),
l: (
h: 32px,
f: 14px
),
xl: (
h: 36px,
f: 14px
),
xxl: (
h: 44px,
f: 14px
)
);
@loop $s, $v in $sizes {
:host([size='#{$s}']) {
width: map.get($v, 'h');
height: map.get($v, 'h');
font-size: map.get($v, 'f');
--size: #{map.get($v, 'h') - 8px};
}
}
`
]
mounted() {
if (this.textContent.trim().length > 4) {
this.textContent = this.textContent.trim().slice(0, 4)
}
}
render() {
return html`
<div class="avatar">
${this.src
? html`<img src=${this.src} />`
: html`<slot><wc-icon name="user"></wc-icon></slot>`}
</div>
`
}
}
Avatar.reg('avatar')

View File

@ -195,15 +195,19 @@ export function colorHtml(code) {
export function colorCss(code) {
code = code
.replace(STR, '<cc class="t-str">$1$2$1</cc>')
.replace(/(\$[a-zA-Z\d_]+)/g, '<c class="t-var">$1</c>')
.replace(/(\$[a-zA-Z\d_\-]+)/g, '<c class="t-var">$1</c>')
.replace(/(\-\-[a-z\d]+\-[a-z\d]+)/g, '<c class="t-const">$1</c>')
.replace(
/:(hover|after|active|last\-child|first\-child|nth\-child)/g,
'<c class="t-buildin">:$1</c>'
)
.replace(
/(?=\s)?([ ][\.#])([\w\-]+)/g,
'<c class="t-comment">$1</c><c class="t-buildin">$2</c>'
/^((?:[ ])*)([\.#])([\w\-]+)/gm,
'$1<c class="t-comment">$2</c><c class="t-keyword">$3</c>'
)
.replace(
/:(root|host)/g,
'<c class="t-comment">:</c><c class="t-keyword">$1</c>'
)
.replace(/([a-zA-Z\-]+):(\s?[^\n]+)/g, (m, k, v) => {
if (v.trim() !== '(' && !v.endsWith('</cc>;')) {

133
test.md
View File

@ -1,133 +0,0 @@
```html
<div class="code-box">
<header class="title">
<section><i></i><i></i><i></i></section>
<section>${this.lang}</section>
<wc-icon
title="复制"
class="act"
name="doc"
@click=${this.copyCode}
></wc-icon>
</header>
<div class="code-block">
${this.#code.map(s => html`<code>${raw(s)}</code>`)}
</div>
</div>
```
```js
import { html, raw, css, Component, nextTick } from '@bd/core'
import { colorHtml, colorJs, colorCss, colorMd } from './colorful.js'
import '../icon/index.js'
import '../layer/index.js'
function trim(str) {
return str
.trim()
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/&amp;/g, '&')
}
class Code extends Component {
static props = {
code: {
type: String,
default: '',
attribute: false,
observer(v) {
this.setCode(v.trim())
}
},
lang: ''
}
#code = []
setCode(txt, a) {
let lang = this.lang
switch (lang) {
case 'js':
case 'javascript':
case 'ts':
case 'typescript':
txt = colorJs(txt)
break
case 'html':
txt = colorHtml(txt)
break
case 'css':
case 'scss':
case 'less':
txt = colorCss(txt)
break
case 'md':
case 'markdown':
txt = colorMd(txt)
break
}
this.#code = txt.split('\n')
}
copyCode() {
navigator.clipboard.writeText(this.code)
layer.toast('复制到粘贴板成功', 'success')
}
mounted() {
var txt = this.innerHTML || this.textContent
txt = txt.trim().replace(/^[\r\n]|\s{2,}$/g, '')
if (txt.startsWith('<xmp>') && txt.endsWith('</xmp>')) {
txt = txt.slice(5, -6).trim()
} else if (this.firstElementChild?.tagName === 'TEXTAREA') {
txt = this.firstElementChild.value.trim()
} else if (txt.startsWith('<pre>') && txt.endsWith('</pre>')) {
txt = trim(txt.slice(5, -6))
} else {
txt = trim(txt)
}
this.textContent = ''
if (txt) {
nextTick(_ => {
this.code = txt
})
}
}
render() {
let foo = html`<section>${this.#code.map(s => html`<a>${s}</a>`)}</section>`
return html`
<div class="code-box">
<header class="title">
<section><i></i><i></i><i></i></section>
<section>${this.lang}</section>
<wc-icon
title="复制"
class="act"
name="doc"
@click=${this.copyCode}
></wc-icon>
</header>
<div class="code-block">
${this.#code.map(s => html`<code>${raw(s)}</code>`)}
</div>
</div>
`
}
}
Code.reg('code')
```