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组件

old
宇天 2019-07-23 23:16:30 +08:00
parent acc957341a
commit 1003ec1e0d
4 changed files with 211 additions and 20 deletions

View File

@ -87,12 +87,22 @@ function mkWCFile({ style, html, js }) {
/import ([\w]*) from '([a-z0-9\/\.\-_]*)'/g,
'import $1 from "$2.js"'
)
.replace(/constructor\([^)]?\)\s+\{/, 'constructor() {\n super()')
.replace(
'/* render */',
`
super()
this.root = this.attachShadow({ mode: 'open' })
this.props = ${props}
Object.defineProperty(this, 'root', {
value: this.attachShadow({ mode: 'open' }),
writable: true,
enumerable: false,
configurable: true
})
Object.defineProperty(this, 'props', {
value: ${props},
writable: true,
enumerable: false,
configurable: true
})
this.root.innerHTML = \`<style>${style}</style>${html}\`
`

View File

@ -100,8 +100,19 @@ function mkWCFile({ style, html, js }) {
'/* render */',
`
super()
this.root = this.attachShadow({ mode: 'open' })
this.props = ${props}
Object.defineProperty(this, 'root', {
value: this.attachShadow({ mode: 'open' }),
writable: true,
enumerable: false,
configurable: true
})
Object.defineProperty(this, 'props', {
value: ${props},
writable: true,
enumerable: false,
configurable: true
})
this.root.innerHTML = \`<style>${style}</style>${html}\`
`

View File

@ -1,8 +1,8 @@
<template>
<label>
<slot name="left"></slot>
<input />
<wc-icon></wc-icon>
<slot class="prepend" name="prepend"></slot>
${input}
<wc-icon class="icon"></wc-icon>
<slot class="append" name="append"></slot>
</label>
</template>
@ -12,23 +12,26 @@
display: inline-block;
user-select: none;
color: nth($cd, 2);
border-radius: 4px;
}
label {
position: relative;
display: flex;
justify-content: center;
align-items: center;
min-width: 32px;
min-width: 64px;
height: 32px;
font-size: 14px;
border: 1px solid nth($cp, 3);
border-radius: 4px;
border-radius: inherit;
background: #fff;
color: inherit;
cursor: inherit;
cursor: text;
input,
textarea {
width: 100%;
padding: 0 5px;
border: 0;
border-radius: inherit;
@ -37,15 +40,60 @@ label {
background: none;
outline: none;
box-shadow: none;
cursor: inherit;
}
textarea {
height: 100%;
padding: 5px;
resize: none;
}
.prepend,
.append {
display: inherit;
display: none;
justify-content: center;
align-items: center;
width: auto;
height: 30px;
padding: 0 18px;
padding: 0 10px;
background: nth($cp, 1);
}
.prepend {
border-right: 1px solid nth($cp, 3);
border-radius: 4px 0 0 4px;
}
.append {
border-left: 1px solid nth($cp, 3);
border-radius: 0 4px 4px 0;
}
&[prepend] .prepend {
display: flex;
}
&[append] .append {
display: flex;
}
/* ----- */
.icon {
padding: 0 5px;
--size: 20px;
}
}
/* --- */
:host([disabled]) label {
background: nth($cp, 1);
cursor: not-allowed;
opacity: 0.6;
}
:host(:focus-within) {
box-shadow: 0 0 3px nth($ct, 1);
}
:host([type='textarea']) {
display: flex;
height: 80px;
label {
overflow: auto;
width: 100%;
height: 100%;
}
}
</style>
@ -53,18 +101,142 @@ label {
<script>
import '../icon/index'
const TYPES = ['text', 'textarea', 'password']
const INPUTS = {
text: '<input spellcheck="false">',
textarea: '<textarea spellcheck="false"></textarea>'
}
export default class Input {
props = {
value: '',
defaultValue: '',
placeholder: ''
icon: '',
type: 'text',
label: '',
placeholder: '',
autofocus: false,
disabled: false
}
constructor() {
var type = this.getAttribute('type')
var input = ''
if (type !== 'textarea') {
type = 'text'
}
input = INPUTS[type]
/* render */
this.props.type = type
this.__OUTER__ = this.root.children[1]
this.__PREPEND__ = this.__OUTER__.children[0]
this.__INPUT__ = this.__OUTER__.children[1]
this.__ICO__ = this.__OUTER__.children[2]
this.__APPEND__ = this.__OUTER__.children[3]
}
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', '')
this.__INPUT__.setAttribute('disabled', '')
} else {
this.props.disabled = false
this.removeAttribute('disabled')
this.__INPUT__.removeAttribute('disabled')
}
}
get value() {
return this.__INPUT__.value
}
set value(val) {
this.props.value = val
this.__INPUT__.value = val
}
get type() {
return this.__INPUT__.type
}
set type(val) {
if (val !== 'textarea') {
this.__INPUT__.type = val
}
}
mounted() {
var prepend = this.__PREPEND__.assignedNodes()
var append = this.__APPEND__.assignedNodes()
// 相同插槽, 只允许1个
while (prepend.length > 1) {
this.removeChild(prepend.pop())
}
while (append.length > 1) {
this.removeChild(append.pop())
}
if (prepend.length && this.props.type !== 'textarea') {
this.__OUTER__.setAttribute('prepend', '')
}
if (append.length && this.props.type !== 'textarea') {
this.__OUTER__.setAttribute('append', '')
}
}
watch(name, old, val) {
if (old === val) {
return
}
switch (name) {
case 'icon':
this.props.icon = val
if (val) {
this.__ICO__.setAttribute('is', val)
} else {
this.removeAttribute('icon')
this.__ICO__.removeAttribute('is')
}
break
case 'autofocus':
setTimeout(_ => {
this.__INPUT__.focus()
}, 10)
break
// label和placeholder 功能相同
case 'label':
case 'placeholder':
this.__INPUT__.setAttribute('placeholder', val)
break
case 'type':
if (~TYPES.indexOf(val)) {
this.type = val
} else {
this.type = 'text'
}
break
case 'disabled':
if (val === '') {
this[name] = true
}
break
}
}
}
</script>

View File

@ -5,16 +5,14 @@
<style lang="scss">
:host {
display: inline-block;
width: 32px;
height: 32px;
color: nth($cd, 2);
}
:host(:not([is])) {
display: none;
}
.icon {
width: inherit;
height: inherit;
width: var(--size, 32px);
height: var(--size, 32px);
fill: currentColor;
vertical-align: -0.1em;