This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0

重构wc-option;优化radio和checkbox组件

old
宇天 2021-04-13 19:39:33 +08:00
parent afd6d5715c
commit 0ae310b871
4 changed files with 146 additions and 58 deletions

View File

@ -253,7 +253,7 @@ export default class Checkbox {
this._checkGroup()
this._handlClick = $.bind(this, 'click', ev => {
ev.preventDefault()
ev.stopPropagation()
this._toggleCheck()
})

View File

@ -4,19 +4,11 @@
<input readonly />
<wc-icon is="trigon-down"></wc-icon>
</section>
<ul class="options-box"></ul>
<slot name="option"></slot>
<div class="options-box"><slot /></div>
</div>
</template>
<style lang="scss" scoped>
ul,
li {
list-style: none;
}
slot {
display: none;
}
:host {
display: inline-flex;
min-width: 72px;
@ -74,8 +66,6 @@ slot {
.options-box {
overflow: hidden;
visibility: hidden;
display: flex;
flex-direction: column;
position: absolute;
left: 0;
top: 36px;
@ -87,19 +77,6 @@ slot {
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.15);
transition: height 0.15s linear;
li {
display: flex;
align-items: center;
height: 32px;
padding: 0 8px;
transition: background 0.15s linear;
&:hover,
&.active {
background: var(--color-plain-1);
}
}
&.active {
visibility: visible;
height: auto;
@ -126,6 +103,7 @@ slot {
<script>
import '../icon/index'
import './option'
import $ from '../utils'
export default class Dropdown {
@ -136,8 +114,7 @@ export default class Dropdown {
}
state = {
optionShow: false,
options: []
optionShow: false
}
__init__() {
@ -146,23 +123,30 @@ export default class Dropdown {
var outbox = this.root.children[1]
this.__PREVIEW__ = outbox.children[0]
this.__OPTIONS__ = outbox.children[1]
this.__SLOT__ = outbox.children[2]
this.__INPUT__ = this.__PREVIEW__.children[0]
this.__ICO__ = this.__PREVIEW__.children[1]
}
_updateChildrenStat() {
Array.from(this.children).forEach(it => {
if (it.tagName === 'WC-OPTION' && it.root) {
if (it.value === this.props.value) {
it.setAttribute('active', '')
this.__INPUT__.value = it.label || it.textContent
} else {
it.removeAttribute('active')
}
}
})
}
get value() {
return this.props.value
}
set value(val) {
this.props.value = val
for (let it of this.state.options) {
if (it.opt.value === val) {
this.__INPUT__.value = it.label
break
}
}
this._updateChildrenStat()
}
get disabled() {
@ -187,24 +171,6 @@ export default class Dropdown {
}
mounted() {
let opts = this.__SLOT__.assignedNodes()
this.state.options = []
this.__OPTIONS__.innerHTML = opts
.map(it => {
let attr = ''
let tmp = { label: it.textContent, opt: { ...it.dataset } }
for (let k in tmp.opt) {
attr += `data-${k}="${tmp.opt[k]}" `
}
tmp.label = tmp.label || tmp.opt.value
tmp.opt.value = tmp.opt.value || tmp.label
this.state.options.push(tmp)
return `<li ${attr}>${tmp.label}</li>`
})
.join('')
this._activeFn = $.bind(this.__PREVIEW__, 'click', ev => {
if (this.disabled) {
return
@ -214,16 +180,20 @@ export default class Dropdown {
})
this._pickedFn = $.bind(this.__OPTIONS__, 'click', ev => {
if (ev.target === ev.currentTarget) {
let elem = ev.target
if (elem === ev.currentTarget) {
return
}
let detail = { ...ev.target.dataset }
this.__INPUT__.value = ev.target.textContent
this.props.value = detail.value || ev.target.textContent
while (elem.tagName !== 'WC-OPTION') {
elem = elem.parentNode
}
this.props.value = elem.value
this._updateChildrenStat()
this.dispatchEvent(new CustomEvent('input'))
this.dispatchEvent(new CustomEvent('select', { detail }))
this.state.optionShow = false
this.__OPTIONS__.classList.toggle('active', false)

118
src/form/option.wc Normal file
View File

@ -0,0 +1,118 @@
<template>
<label><slot /></label>
</template>
<style lang="scss" scoped>
:host {
display: flex;
justify-content: space-between;
align-items: center;
height: 32px;
transition: background 0.15s linear;
color: var(--color-dark-1);
cursor: pointer;
label {
flex: 1;
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
padding: 0 8px;
cursor: inherit;
}
}
:host(:hover),
:host([active]) {
label {
background: var(--color-plain-1);
}
}
:host([disabled]) {
color: var(--color-grey-1);
opacity: 0.6;
cursor: not-allowed;
}
</style>
<script>
import $ from '../utils'
export default class Option {
props = {
value: '',
label: '',
disabled: false
}
__init__() {
/* render */
}
get value() {
return this.props.value
}
set value(val) {
if (val === this.props.value) {
return
}
this.props.value = val
}
get label() {
return this.props.label
}
set label(val) {
if (val === this.props.label) {
return
}
this.props.label = val
}
get disabled() {
return this.props.disabled
}
set disabled(val) {
var type = typeof val
if (val === this.props.disabled) {
return
}
if ((type === 'boolean' && val) || type !== 'boolean') {
this.props.disabled = true
this.setAttribute('disabled', '')
} else {
this.props.disabled = false
this.removeAttribute('disabled')
}
}
mounted() {
this._clickFn = $.bind(this, 'click', ev => {
if (this.disabled) {
ev.stopPropagation()
}
})
}
unmount() {
$.unbind(this, 'click', this._clickFn)
}
watch() {
switch (name) {
case 'value':
case 'label':
this[name] = val
break
case 'disabled':
this.disabled = val !== null
break
}
}
}
</script>

View File

@ -239,7 +239,7 @@ export default class Radio {
}
this._handleClick = $.catch(this, 'click', ev => {
ev.preventDefault()
ev.stopPropagation()
this._toggleCheck()
})