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

优化input/button/date组件;完成select组件

old
宇天 2019-08-13 16:50:47 +08:00
parent f2cb1beecf
commit 4ac76f3e54
5 changed files with 178 additions and 34 deletions

View File

@ -41,6 +41,9 @@
&:active { &:active {
border-color: nth($cgr, 1); border-color: nth($cgr, 1);
} }
&::-moz-focus-inner {
border: none;
}
} }
.icon { .icon {

View File

@ -343,6 +343,7 @@ export default class Input {
} }
items.forEach((it, i) => { items.forEach((it, i) => {
if (i === this.props.mvidx) { if (i === this.props.mvidx) {
this.__LIST__.firstElementChild.scrollTop = it.offsetTop - 150
it.setAttribute('focus', '') it.setAttribute('focus', '')
} else { } else {
it.removeAttribute('focus') it.removeAttribute('focus')
@ -475,7 +476,6 @@ export default class Input {
unbind(this.__INPUT__, 'input', this._handleChange) unbind(this.__INPUT__, 'input', this._handleChange)
unbind(this, 'click', this._bubbleFn) unbind(this, 'click', this._bubbleFn)
unbind(document, 'click', this._inactiveFn) unbind(document, 'click', this._inactiveFn)
unbind(this.__INPUT__, 'blur', this._handleBlur)
unbind(this.__LIST__, 'click', this._handleSelect) unbind(this.__LIST__, 'click', this._handleSelect)
} }

View File

@ -102,6 +102,7 @@ li {
border-radius: 4px; border-radius: 4px;
background: #fff; background: #fff;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.2); box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);
cursor: default;
.list { .list {
width: 100%; width: 100%;
@ -136,7 +137,6 @@ li {
dt { dt {
font-size: 12px; font-size: 12px;
color: nth($cgr, 1); color: nth($cgr, 1);
cursor: default;
} }
dd { dd {
@ -149,6 +149,11 @@ li {
&[sub] { &[sub] {
text-indent: 1em; text-indent: 1em;
} }
&[disabled] {
color: nth($cgr, 1);
cursor: not-allowed;
background: none;
}
} }
} }
@ -217,16 +222,28 @@ import '../scroll/index'
import '../icon/index' import '../icon/index'
import { nextTick, ebind, bind, unbind } from '../utils' import { nextTick, ebind, bind, unbind } from '../utils'
function parseOptions(list) { function parseOptions(arr, props) {
let html = '' let html = ''
for (let it of list) { for (let it of arr) {
if (it.list) { if (it.list) {
html += `<dt>${it.name}</dt>` html += `<dt>${it.name}</dt>`
for (let _ of it.list) { for (let _ of it.list) {
html += `<dd sub data-value="${_.value}">${_.label}</dd>` props.DICT[_.value] = _
if (!_.disabled) {
props.LIST.push(_)
}
html += `<dd sub ${
_.disabled ? 'disabled' : `data-idx="${props.LIST.length - 1}"`
} ${_.value === props.value ? 'focus' : ''}>${_.label}</dd>`
} }
} else { } else {
html += `<dd data-value="${it.value}">${it.label}</dd>` if (!it.disabled) {
props.LIST.push(it)
}
props.DICT[it.value] = it
html += `<dd ${
it.disabled ? 'disabled' : `data-idx="${props.LIST.length - 1}"`
} ${it.value === props.value ? 'focus' : ''}>${it.label}</dd>`
} }
} }
return html return html
@ -237,7 +254,8 @@ export default class Select {
label: '', label: '',
placeholder: '', placeholder: '',
multi: '', multi: '',
options: [], value: '',
options: '',
mvidx: null, //下拉列表光标的索引ID mvidx: null, //下拉列表光标的索引ID
disabled: false disabled: false
} }
@ -275,11 +293,67 @@ export default class Select {
} }
get value() { get value() {
return this.__INPUT__.value return this.props.value
} }
set value(val) { set value(val) {
this.__INPUT__.value = val var { DICT } = this.props
this.props.value = val
this.__INPUT__.value = (DICT && DICT[val] && DICT[val].label) || val
}
_renderOptions(options) {
this.props.DICT = {}
this.props.LIST = []
var elem = this.__OPTG__.firstElementChild.firstElementChild
elem.innerHTML = parseOptions(options, this.props)
}
// 移动光标选择下拉选项
_moveSelect(ev) {
var { LIST, DICT } = this.props
if (LIST && LIST.length) {
ev.preventDefault()
var step = ev.keyCode === 38 ? -1 : 1
var items = Array.from(
this.__OPTG__.firstElementChild.firstElementChild.children
).filter(it => {
return it.tagName === 'DD' && !it.hasAttribute('disabled')
})
if (this.props.mvidx === null) {
this.props.mvidx = 0
} else {
this.props.mvidx += step
}
if (this.props.mvidx < 0) {
this.props.mvidx = 0
} else if (this.props.mvidx > items.length - 1) {
this.props.mvidx = items.length - 1
}
items.forEach((it, i) => {
if (i === this.props.mvidx) {
this.__OPTG__.firstElementChild.scrollTop = it.offsetTop - 150
it.setAttribute('focus', '')
} else {
it.removeAttribute('focus')
}
})
}
}
// 触发列表选择
_fetchSelect(idx, ev) {
var item = this.props.LIST[idx]
this.value = item.value
this.dispatchEvent(
new CustomEvent('select', {
detail: item
})
)
this.props.active = false
this.__OPTG__.classList.remove('show')
} }
mounted() { mounted() {
@ -301,24 +375,60 @@ export default class Select {
this.__OUTER__.setAttribute('append', '') this.__OUTER__.setAttribute('append', '')
} }
// 渲染建议列表 function initPos() {
this._parseOptGroup = bind(this.__INPUT__, 'click', ev => { var { x, y, width } = this.getBoundingClientRect()
var { options: list } = this.props this.props.active = true
let { x, y, width } = this.getBoundingClientRect()
log(list, this.props)
if (list && list.length) {
this.__OPTG__.firstElementChild.firstElementChild.innerHTML = parseOptions(
list
)
this.__OPTG__.classList.toggle('show', true)
this.__OPTG__.style.cssText = `left:${x}px;top:${y + this.__OPTG__.style.cssText = `left:${x}px;top:${y +
50}px;width:${width}px;` 50}px;width:${width}px;`
} else { }
this.__OPTG__.classList.toggle('show', false)
/* ---------------------------------------------------- */
/* ----------------- 各种事件 ------------------ */
/* ---------------------------------------------------- */
// 键盘事件
this._handleKeydown = ebind(this.__INPUT__, 'keydown', ev => {
if (this.disabled || this.readonly) {
return
}
// up: 38, down: 40
if (ev.keyCode === 38 || ev.keyCode === 40) {
if (!this.props.active) {
initPos.call(this)
this.__OPTG__.classList.toggle('show', true)
return
}
return this._moveSelect(ev)
}
// 回车触发select事件
if (ev.keyCode === 13) {
if (this.props.mvidx !== null) {
return this._fetchSelect(this.props.mvidx, ev)
}
}
})
// 渲染建议列表
this._activeFn = bind(this.__INPUT__, 'click', ev => {
var { options } = this.props
initPos.call(this)
this.__OPTG__.classList.toggle('show', true)
})
// 选择选项
this._handleSelect = bind(this.__OPTG__, 'click', ev => {
if (ev.target.tagName === 'DD' && !ev.target.hasAttribute('disabled')) {
this._fetchSelect(ev.target.dataset.idx, ev)
this.dispatchEvent(new CustomEvent('input'))
} }
}) })
this._bubbleFn = ebind(this, 'click') this._bubbleFn = ebind(this, 'click')
this._inactiveFn = bind(document, 'click', ev => {
this.__OPTG__.classList.toggle('show', false)
this.props.active = false
})
} }
watch(name, old, val) { watch(name, old, val) {
@ -335,8 +445,9 @@ export default class Select {
case 'options': case 'options':
if (val) { if (val) {
try { try {
this.props.options = JSON.parse(val) this._renderOptions(JSON.parse(val))
} catch (err) {} } catch (err) {}
this.removeAttribute('options')
} }
break break
@ -352,5 +463,13 @@ export default class Select {
break break
} }
} }
unmount() {
unbind(this.__INPUT__, 'keydown', this._handleKeydown)
unbind(this.__INPUT__, 'click', this._activeFn)
unbind(this, 'click', this._bubbleFn)
unbind(document, 'click', this._inactiveFn)
unbind(this.__OPTG__, 'click', this._handleSelect)
}
} }
</script> </script>

View File

@ -553,14 +553,18 @@ export default class DatePicker {
if (ev.target.tagName === 'SPAN') { if (ev.target.tagName === 'SPAN') {
let { calendar, last } = this.props let { calendar, last } = this.props
let item = calendar.list[ev.target.dataset.idx] let item = calendar.list[ev.target.dataset.idx]
if (item.disabled) {
return
}
// 日期未变化时, 直接隐藏, 不作处理
if ( if (
item.disabled || last &&
(last &&
calendar.year === last.year && calendar.year === last.year &&
calendar.month === last.month && calendar.month === last.month &&
item.day === last.day) item.day === last.day
) { ) {
return return this._inactiveFn()
} }
this._updateValue(item._, true) this._updateValue(item._, true)

View File

@ -94,7 +94,16 @@ export default class Scroll {
} }
set scrollTop(n) { set scrollTop(n) {
// this.__BOX__.scrollTop n = +n
if (n === n) {
var { sh, oh, yh } = this.props
this.__BOX__.scrollTop = n
var fixedY = (this.__BOX__.scrollTop / (sh - oh)) * (oh - yh)
this.props.thumbY = fixedY
this.__Y__.style.transform = `translateY(${fixedY}px)`
}
} }
get scrollLeft() { get scrollLeft() {
@ -102,7 +111,16 @@ export default class Scroll {
} }
set scrollLeft(val) { set scrollLeft(val) {
// this.__BOX__.scrollLeft n = +n
if (n === n) {
var { sw, ow, xw } = this.props
this.__BOX__.scrollLeft = n
var fixedX = (this.__BOX__.scrollLeft / (sw - ow)) * (ow - xw)
this.props.thumbX = fixedX
this.__X__.style.transform = `translateX(${fixedX}px)`
}
} }
get scrollHeight() { get scrollHeight() {
@ -110,7 +128,7 @@ export default class Scroll {
} }
_fetchScrollX(moveX) { _fetchScrollX(moveX) {
var { sw, ow, xw, sh, oh, yh } = this.props var { sw, ow, xw } = this.props
if (moveX < 0) { if (moveX < 0) {
moveX = 0 moveX = 0
@ -124,7 +142,7 @@ export default class Scroll {
} }
_fetchScrollY(moveY) { _fetchScrollY(moveY) {
var { sw, ow, xw, sh, oh, yh } = this.props var { sh, oh, yh } = this.props
if (moveY < 0) { if (moveY < 0) {
moveY = 0 moveY = 0