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._checkGroup()
this._handlClick = $.bind(this, 'click', ev => { this._handlClick = $.bind(this, 'click', ev => {
ev.preventDefault() ev.stopPropagation()
this._toggleCheck() this._toggleCheck()
}) })

View File

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