776 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Vue
		
	
	
	
			
		
		
	
	
			776 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Vue
		
	
	
	
| <template>
 | |
|   <md-field-item
 | |
|     class="md-input-item"
 | |
|     :class="[
 | |
|       isHighlight ? 'is-highlight' : '',
 | |
|       isTitleLatent ? 'is-title-latent' : '',
 | |
|       isInputActive ? 'is-active' : '',
 | |
|       isInputFocus ? 'is-focus' : '',
 | |
|       isInputError() ? 'is-error' : '',
 | |
|       isInputBrief() && !isInputError() ? 'with-brief' : '',
 | |
|       isDisabled ? 'is-disabled': '',
 | |
|       isAmount ? 'is-amount': '',
 | |
|       clearable ? 'is-clear' : '',
 | |
|       align,
 | |
|       size
 | |
|     ]"
 | |
|     :title="title"
 | |
|     :solid="solid && !isTitleLatent"
 | |
|   >
 | |
|     <template slot="left">
 | |
|       <slot name="left"></slot>
 | |
|     </template>
 | |
|     <!-- ------------ -->
 | |
|     <!--    INPUT     -->
 | |
|     <!-- ------------ -->
 | |
|     <!-- Native Input -->
 | |
|     <template v-if="!isVirtualKeyboard">
 | |
|       <input
 | |
|         class="md-input-item-input"
 | |
|         :type="inputType"
 | |
|         :name="name"
 | |
|         v-model="inputBindValue"
 | |
|         :placeholder="inputPlaceholder"
 | |
|         :disabled="isDisabled"
 | |
|         :readonly="readonly"
 | |
|         :maxlength="isInputFormative ? '' : maxlength"
 | |
|         autocomplete="off"
 | |
|         @focus="$_onFocus"
 | |
|         @blur="$_onBlur"
 | |
|         @keyup="$_onKeyup"
 | |
|         @keydown="$_onKeydown"
 | |
|         @input="$_onInput"
 | |
|       />
 | |
|     </template>
 | |
|     <!-- Fake Input -->
 | |
|     <template v-else>
 | |
|       <div
 | |
|         class="md-input-item-fake"
 | |
|         :class="{
 | |
|           'is-focus': isInputFocus,
 | |
|           'is-waiting': !isInputEditing,
 | |
|           'disabled': isDisabled,
 | |
|           'readonly': readonly
 | |
|         }"
 | |
|         @click="$_onFakeInputClick"
 | |
|       >
 | |
|         <input class="md-input-item-input" :placeholder="inputPlaceholder" v-model="inputValue"/>
 | |
|         <!-- <span
 | |
|           class="md-input-item-fake-placeholder"
 | |
|           v-if="inputValue === '' && inputPlaceholder !== ''"
 | |
|           v-text="inputPlaceholder"></span> -->
 | |
|       </div>
 | |
|     </template>
 | |
| 
 | |
|     <template slot="right">
 | |
|       <!-- ------------ -->
 | |
|       <!--  CLEART BTN  -->
 | |
|       <!-- ------------ -->
 | |
|       <div
 | |
|         class="md-input-item-clear"
 | |
|         v-if="clearable && !isDisabled && !readonly"
 | |
|         v-show="!isInputEmpty && isInputFocus"
 | |
|         @click="$_clearInput"
 | |
|       >
 | |
|         <md-icon name="clear"></md-icon>
 | |
|       </div>
 | |
| 
 | |
|       <!-- ------------ -->
 | |
|       <!--  RIGHT SLOT  -->
 | |
|       <!-- ------------ -->
 | |
|       <slot name="right"></slot>
 | |
|     </template>
 | |
| 
 | |
|     <template slot="children">
 | |
|       <!-- -------------------- -->
 | |
|       <!-- BRIEF/ERROR TIP -->
 | |
|       <!-- -------------------- -->
 | |
|       <div
 | |
|         v-if="isInputError()"
 | |
|         class="md-input-item-msg"
 | |
|       >
 | |
|         <p v-if="error !== ''" v-text="error"></p>
 | |
|         <slot name="error" v-else></slot>
 | |
|       </div>
 | |
|       <div
 | |
|         v-if="isInputBrief() && !isInputError()"
 | |
|         class="md-input-item-brief"
 | |
|       >
 | |
|         <p v-if="brief !== ''" v-text="brief"></p>
 | |
|         <slot name="brief" v-else></slot>
 | |
|       </div>
 | |
|       <!-- ------------ -->
 | |
|       <!--   KEYBORARD  -->
 | |
|       <!-- ------------ -->
 | |
|       <md-number-keyboard
 | |
|         v-if="isVirtualKeyboard && !virtualKeyboardVm"
 | |
|         ref="number-keyboard"
 | |
|         :id="`${name}-number-keyboard`"
 | |
|         class="md-input-item-number-keyboard"
 | |
|         :ok-text="virtualKeyboardOkText"
 | |
|         :disorder="virtualKeyboardDisorder"
 | |
|       ></md-number-keyboard>
 | |
|     </template>
 | |
|   </md-field-item>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import Icon from '../icon'
 | |
| import FieldItem from '../field-item'
 | |
| import NumberKeyboard from '../number-keyboard'
 | |
| import {getCursorsPosition, setCursorsPosition} from './cursor'
 | |
| import {noop, randomId, debounce} from '../_util'
 | |
| import {formatValueByGapRule, formatValueByGapStep, trimValue} from '../_util/formate-value'
 | |
| 
 | |
| export default {
 | |
|   name: 'md-input-item',
 | |
| 
 | |
|   components: {
 | |
|     [Icon.name]: Icon,
 | |
|     [FieldItem.name]: FieldItem,
 | |
|     [NumberKeyboard.name]: NumberKeyboard,
 | |
|   },
 | |
| 
 | |
|   inject: {
 | |
|     rootField: {
 | |
|       from: 'rootField',
 | |
|       default: () => ({}),
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   props: {
 | |
|     type: {
 | |
|       // text, bankCard, password, phone, money, digit
 | |
|       type: String,
 | |
|       default: 'text',
 | |
|     },
 | |
|     previewType: {
 | |
|       type: String,
 | |
|       default: '',
 | |
|     },
 | |
|     name: {
 | |
|       type: [String, Number],
 | |
|       default() {
 | |
|         return randomId('input-item')
 | |
|       },
 | |
|     },
 | |
|     title: {
 | |
|       type: String,
 | |
|       default: '',
 | |
|     },
 | |
|     brief: {
 | |
|       type: String,
 | |
|       default: '',
 | |
|     },
 | |
|     value: {
 | |
|       type: [String, Number],
 | |
|       default: '',
 | |
|     },
 | |
|     placeholder: {
 | |
|       type: String,
 | |
|       default: '',
 | |
|     },
 | |
|     maxlength: {
 | |
|       type: [String, Number],
 | |
|       default: '',
 | |
|     },
 | |
|     size: {
 | |
|       // large, normal
 | |
|       type: String,
 | |
|       default: 'normal',
 | |
|     },
 | |
|     align: {
 | |
|       // left, center, right
 | |
|       type: String,
 | |
|       default: 'left',
 | |
|     },
 | |
|     error: {
 | |
|       type: String,
 | |
|       default: '',
 | |
|     },
 | |
|     readonly: {
 | |
|       type: Boolean,
 | |
|       default: false,
 | |
|     },
 | |
|     disabled: {
 | |
|       type: Boolean,
 | |
|       default: false,
 | |
|     },
 | |
|     solid: {
 | |
|       type: Boolean,
 | |
|       default: true,
 | |
|     },
 | |
|     clearable: {
 | |
|       type: Boolean,
 | |
|       default: false,
 | |
|     },
 | |
|     isVirtualKeyboard: {
 | |
|       type: Boolean,
 | |
|       default: false,
 | |
|     },
 | |
|     virtualKeyboardDisorder: {
 | |
|       type: Boolean,
 | |
|     },
 | |
|     virtualKeyboardOkText: {
 | |
|       type: String,
 | |
|     },
 | |
|     virtualKeyboardVm: {
 | |
|       type: [Object, String],
 | |
|       default: null,
 | |
|     },
 | |
|     isTitleLatent: {
 | |
|       type: Boolean,
 | |
|       default: false,
 | |
|     },
 | |
|     isFormative: {
 | |
|       type: Boolean,
 | |
|       default: false,
 | |
|     },
 | |
|     isHighlight: {
 | |
|       type: Boolean,
 | |
|       default: false,
 | |
|     },
 | |
|     isAmount: {
 | |
|       type: Boolean,
 | |
|       default: false,
 | |
|     },
 | |
|     formation: {
 | |
|       type: Function,
 | |
|       default: noop,
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   data() {
 | |
|     return {
 | |
|       inputValue: '',
 | |
|       inputBindValue: '',
 | |
|       inputNumberKeyboard: '',
 | |
|       isInputFocus: false,
 | |
|       isInputEditing: false,
 | |
|       isPreview: false,
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   computed: {
 | |
|     inputItemType() {
 | |
|       return (this.isPreview ? this.previewType : this.type) || 'text'
 | |
|     },
 | |
|     inputType() {
 | |
|       let inputType = this.inputItemType || 'text'
 | |
|       if (inputType === 'bankCard' || inputType === 'phone' || inputType === 'digit') {
 | |
|         inputType = 'tel'
 | |
|       } else if (inputType === 'money') {
 | |
|         inputType = 'text'
 | |
|       }
 | |
|       return inputType
 | |
|     },
 | |
|     inputMaxLength() {
 | |
|       if (this.inputItemType === 'phone') {
 | |
|         return 11
 | |
|       } else {
 | |
|         return this.maxlength
 | |
|       }
 | |
|     },
 | |
|     inputPlaceholder() {
 | |
|       return this.isTitleLatent && this.isInputActive ? '' : this.placeholder
 | |
|     },
 | |
|     isInputActive() {
 | |
|       return !this.isInputEmpty || this.isInputFocus
 | |
|     },
 | |
|     isInputEmpty() {
 | |
|       return !this.inputValue.length
 | |
|     },
 | |
|     isInputFormative() {
 | |
|       const type = this.inputItemType
 | |
|       return this.isFormative || (type === 'bankCard' || type === 'phone' || type === 'money' || type === 'digit')
 | |
|     },
 | |
|     isDisabled() {
 | |
|       return this.rootField.disabled || this.disabled
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   watch: {
 | |
|     value(val) {
 | |
|       // Filter out two-way binding
 | |
|       if (val !== this.$_trimValue(this.inputValue)) {
 | |
|         this.inputValue = this.$_formateValue(this.$_subValue(val + '')).value
 | |
|       }
 | |
|     },
 | |
|     previewType: {
 | |
|       handler(val) {
 | |
|         this.isPreview = !!val
 | |
|       },
 | |
|       immediate: true,
 | |
|     },
 | |
|     inputValue(val) {
 | |
|       this.inputBindValue = val
 | |
|       val = this.isInputFormative ? this.$_trimValue(val) : val
 | |
|       if (val !== this.value) {
 | |
|         this.$emit('input', val)
 | |
|         this.$emit('change', this.name, val)
 | |
|       }
 | |
|     },
 | |
|     isInputFocus(val) {
 | |
|       if (!this.isVirtualKeyboard || !this.inputNumberKeyboard) {
 | |
|         return
 | |
|       }
 | |
|       if (val) {
 | |
|         this.inputNumberKeyboard.show()
 | |
|         this.$emit('focus', this.name)
 | |
|       } else {
 | |
|         this.inputNumberKeyboard.hide()
 | |
|         this.$emit('blur', this.name)
 | |
|       }
 | |
|     },
 | |
|   },
 | |
|   created() {
 | |
|     this.inputValue = this.$_formateValue(this.$_subValue(this.value + '')).value
 | |
|     this.$_stopEditInput = debounce(function() {
 | |
|       this.isInputEditing = false
 | |
|     }, 500)
 | |
|   },
 | |
|   mounted() {
 | |
|     this.isVirtualKeyboard &&
 | |
|       this.$nextTick(() => {
 | |
|         this.$_initNumberKeyBoard()
 | |
|       })
 | |
|   },
 | |
|   beforeDestroy() {
 | |
|     const keyboard = this.inputNumberKeyboard
 | |
|     if (keyboard && keyboard.$el) {
 | |
|       document.body.removeChild(keyboard.$el)
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   methods: {
 | |
|     // MARK: private methods
 | |
|     $_formateValue(curValue, curPos = 0) {
 | |
|       const type = this.inputItemType
 | |
|       const name = this.name
 | |
|       const oldValue = this.inputValue
 | |
|       const isAdd = oldValue.length > curValue.length ? -1 : 1
 | |
| 
 | |
|       let formateValue = {value: curValue, range: curPos}
 | |
| 
 | |
|       // no format
 | |
|       if (!this.isInputFormative || curValue === '') {
 | |
|         return formateValue
 | |
|       }
 | |
| 
 | |
|       // custom format by user
 | |
|       const customValue = this.formation(name, curValue, curPos)
 | |
| 
 | |
|       if (customValue) {
 | |
|         return customValue
 | |
|       }
 | |
| 
 | |
|       // default format by component
 | |
|       let gap = ' '
 | |
|       switch (type) {
 | |
|         case 'bankCard':
 | |
|           curValue = this.$_subValue(trimValue(curValue.replace(/\D/g, '')))
 | |
|           formateValue = formatValueByGapStep(4, curValue, gap, 'left', curPos, isAdd, oldValue)
 | |
|           break
 | |
|         case 'phone':
 | |
|           curValue = this.$_subValue(trimValue(curValue.replace(/\D/g, '')))
 | |
|           formateValue = formatValueByGapRule('3|4|4', curValue, gap, curPos, isAdd)
 | |
|           break
 | |
|         case 'money':
 | |
|           gap = ','
 | |
|           curValue = this.$_subValue(trimValue(curValue.replace(/[^\d.]/g, '')))
 | |
|           // curValue = curValue.replace(/\D/g, '')
 | |
|           const dotPos = curValue.indexOf('.')
 | |
|           // format if no dot or new add dot or insert befor dot
 | |
|           const moneyCurValue = curValue.split('.')[0]
 | |
|           const moneyCurDecimal = ~dotPos ? `.${curValue.split('.')[1]}` : ''
 | |
| 
 | |
|           formateValue = formatValueByGapStep(
 | |
|             3,
 | |
|             trimValue(moneyCurValue, gap),
 | |
|             gap,
 | |
|             'right',
 | |
|             curPos,
 | |
|             isAdd,
 | |
|             oldValue.split('.')[0],
 | |
|           )
 | |
|           formateValue.value += moneyCurDecimal
 | |
|           break
 | |
|         case 'digit':
 | |
|           curValue = this.$_subValue(trimValue(curValue.replace(/\D/g, '')))
 | |
|           formateValue.value = curValue
 | |
|           break
 | |
|         /* istanbul ignore next */
 | |
|         default:
 | |
|           break
 | |
|       }
 | |
| 
 | |
|       return formateValue
 | |
|     },
 | |
|     isInputError() {
 | |
|       return this.$slots.error || this.error !== ''
 | |
|     },
 | |
|     isInputBrief() {
 | |
|       return this.$slots.brief || this.brief !== ''
 | |
|     },
 | |
|     $_trimValue(val) {
 | |
|       return trimValue(val, '\\s|,')
 | |
|     },
 | |
|     $_subValue(val) {
 | |
|       const len = this.inputMaxLength
 | |
|       if (len !== '') {
 | |
|         return val.substring(0, len)
 | |
|       } else {
 | |
|         return val
 | |
|       }
 | |
|     },
 | |
|     $_startEditInput() {
 | |
|       this.isInputEditing = true
 | |
|       this.$_stopEditInput()
 | |
|     },
 | |
|     $_stopEditInput: noop,
 | |
|     $_clearInput() {
 | |
|       this.inputValue = ''
 | |
|       !this.isTitleLatent && this.focus()
 | |
|       this.isPreview = false
 | |
|     },
 | |
|     $_stopPreview() {
 | |
|       this.$_clearInput()
 | |
|       this.$emit('update:previewType', '')
 | |
|     },
 | |
|     $_focusFakeInput() {
 | |
|       this.isInputFocus = true
 | |
| 
 | |
|       setTimeout(() => {
 | |
|         this.$_addBlurListener()
 | |
|       }, 0)
 | |
|     },
 | |
|     $_blurFakeInput() {
 | |
|       this.isInputFocus = false
 | |
|       this.$_removeBlurListener()
 | |
|     },
 | |
|     $_addBlurListener() {
 | |
|       document.addEventListener('click', this.$_blurFakeInput, false)
 | |
|     },
 | |
|     $_removeBlurListener() {
 | |
|       document.removeEventListener('click', this.$_blurFakeInput, false)
 | |
|     },
 | |
|     $_initNumberKeyBoard() {
 | |
|       let keyboard =
 | |
|         (typeof this.virtualKeyboardVm === 'object'
 | |
|           ? this.virtualKeyboardVm
 | |
|           : this.$vnode.context.$refs[this.virtualKeyboardVm]) || this.$refs['number-keyboard']
 | |
| 
 | |
|       if (Array.isArray(keyboard)) {
 | |
|         keyboard = keyboard[0]
 | |
|       }
 | |
| 
 | |
|       keyboard.$on('enter', this.$_onNumberKeyBoardEnter)
 | |
|       keyboard.$on('delete', this.$_onNumberKeyBoardDelete)
 | |
|       keyboard.$on('confirm', this.$_onNumberKeyBoardConfirm)
 | |
|       this.inputNumberKeyboard = keyboard
 | |
|       document.body.appendChild(keyboard.$el)
 | |
|     },
 | |
| 
 | |
|     // MARK: events handler
 | |
|     $_onInput(event) {
 | |
|       const formateValue = this.$_formateValue(
 | |
|         event.target.value,
 | |
|         this.isInputFormative ? getCursorsPosition(event.target) : 0,
 | |
|       )
 | |
| 
 | |
|       this.inputValue = formateValue.value
 | |
|       this.inputBindValue = formateValue.value
 | |
| 
 | |
|       if (this.isInputFormative) {
 | |
|         this.$nextTick(() => {
 | |
|           setCursorsPosition(event.target, formateValue.range)
 | |
|         })
 | |
|       }
 | |
|     },
 | |
|     $_onKeyup(event) {
 | |
|       this.$emit('keyup', this.name, event)
 | |
|       if (+event.keyCode === 13 || +event.keyCode === 108) {
 | |
|         this.$emit('confirm', this.name, this.inputValue)
 | |
|       }
 | |
|     },
 | |
|     $_onKeydown(event) {
 | |
|       this.$emit('keydown', this.name, event)
 | |
|       if (!(+event.keyCode === 13 || +event.keyCode === 108)) {
 | |
|         this.$_startEditInput()
 | |
|         this.isPreview && this.$_stopPreview()
 | |
|       }
 | |
|     },
 | |
|     $_onFocus() {
 | |
|       this.isInputFocus = true
 | |
|       this.$emit('focus', this.name)
 | |
|     },
 | |
|     $_onBlur() {
 | |
|       setTimeout(() => {
 | |
|         this.isInputFocus = false
 | |
|         this.$emit('blur', this.name)
 | |
|       }, 100)
 | |
|     },
 | |
|     $_onFakeInputClick(event) {
 | |
|       if (this.isDisabled || this.readonly) {
 | |
|         return
 | |
|       }
 | |
| 
 | |
|       this.$_blurFakeInput()
 | |
| 
 | |
|       if (!this.isInputFocus) {
 | |
|         this.$_focusFakeInput(event)
 | |
|       }
 | |
|     },
 | |
|     $_onNumberKeyBoardEnter(val) {
 | |
|       if (this.isPreview) {
 | |
|         this.$_stopPreview()
 | |
|       }
 | |
|       if (this.inputMaxLength > 0 && this.$_trimValue(this.inputValue).length >= this.inputMaxLength) {
 | |
|         return
 | |
|       }
 | |
|       this.inputValue = this.$_formateValue(this.inputValue + val).value
 | |
|       this.$_startEditInput()
 | |
|     },
 | |
|     $_onNumberKeyBoardDelete() {
 | |
|       const inputValue = this.inputValue
 | |
|       if (inputValue === '') {
 | |
|         return
 | |
|       }
 | |
|       this.inputValue = this.$_formateValue(inputValue.substring(0, inputValue.length - 1)).value
 | |
|       this.$_startEditInput()
 | |
|       if (this.isPreview) {
 | |
|         this.$_stopPreview()
 | |
|       }
 | |
|     },
 | |
|     $_onNumberKeyBoardConfirm() {
 | |
|       this.$emit('confirm', this.name, this.inputValue)
 | |
|     },
 | |
| 
 | |
|     // MARK: public methods
 | |
|     focus() {
 | |
|       if (this.isVirtualKeyboard) {
 | |
|         this.$_onFakeInputClick()
 | |
|       } else {
 | |
|         this.$el.querySelector('.md-input-item-input').focus()
 | |
|         setTimeout(() => {
 | |
|           this.isInputFocus = true
 | |
|         }, 200)
 | |
|       }
 | |
|     },
 | |
|     blur() {
 | |
|       if (this.isVirtualKeyboard) {
 | |
|         this.$_blurFakeInput()
 | |
|       } else {
 | |
|         this.$el.querySelector('.md-input-item-input').blur()
 | |
|         this.isInputFocus = false
 | |
|       }
 | |
|     },
 | |
|     getValue() {
 | |
|       return this.inputValue
 | |
|     },
 | |
|   },
 | |
| }
 | |
| 
 | |
| </script>
 | |
| 
 | |
| <style lang="stylus">
 | |
| .md-input-item
 | |
|   .md-field-item-content
 | |
|     padding-top 0
 | |
|     padding-bottom 0
 | |
|   .md-field-item-control
 | |
|     display flex
 | |
|     align-items center
 | |
| 
 | |
| .md-input-item-clear
 | |
|   padding 10px 0
 | |
|   color input-item-icon
 | |
|   .md-icon
 | |
|     display flex
 | |
|     background color-bg-base
 | |
|     border-radius radius-circle
 | |
| 
 | |
| .md-input-item-input,
 | |
| .md-input-item-fake
 | |
|   // display flex
 | |
|   width 100%
 | |
|   height input-item-height
 | |
|   color input-item-color
 | |
|   font-size input-item-font-size
 | |
|   font-weight input-item-font-weight
 | |
|   font-family font-family-normal
 | |
|   line-height 1
 | |
|   -webkit-appearance none
 | |
|   border none
 | |
|   background transparent
 | |
|   outline none
 | |
|   box-sizing border-box
 | |
|   -webkit-tap-highlight-color transparent
 | |
|   appearance none
 | |
| 
 | |
| .md-input-item-input
 | |
|   &:disabled, &[disabled]
 | |
|     opacity 1
 | |
|   &::-webkit-input-placeholder
 | |
|     color input-item-placeholder
 | |
|     font-weight font-weight-normal
 | |
|   &::-webkit-outer-spin-button, &::-webkit-inner-spin-button
 | |
|     -webkit-appearance none
 | |
| 
 | |
| .md-input-item-fake
 | |
|   line-height input-item-height
 | |
|   word-ellipsis()
 | |
|   cursor text
 | |
|   &::after
 | |
|     position relative
 | |
|     z-index 2
 | |
|     display none
 | |
|     content " "
 | |
|     height input-item-font-size-large
 | |
|     border-right solid 1.5px color-text-base
 | |
|   &.is-focus:after
 | |
|     display inline
 | |
|   &.is-waiting:after
 | |
|     animation keyboard-cursor infinite 1s step-start
 | |
| 
 | |
| .md-input-item-fake-placeholder
 | |
|   position absolute
 | |
|   top 0
 | |
|   left 0
 | |
|   width 100%
 | |
|   color input-item-placeholder
 | |
|   font-weight font-weight-normal
 | |
| 
 | |
| .md-input-item-msg,
 | |
| .md-input-item-brief
 | |
|   word-break()
 | |
|   &:not(:last-child)
 | |
|     margin-bottom 10px
 | |
| 
 | |
| .md-input-item-brief
 | |
|   font-size input-item-font-size-brief
 | |
|   color input-item-color-brief
 | |
| 
 | |
| .md-input-item-msg
 | |
|   font-size input-item-font-size-error
 | |
|   color input-item-color-error
 | |
|   animation-name errtips
 | |
|   animation-duration 0.5s
 | |
| 
 | |
| @keyframes errtips {
 | |
|   10% {
 | |
|     transform translateX(4px)
 | |
|   }
 | |
|   60% {
 | |
|     transform translateX(-4px)
 | |
|   }
 | |
|   100% {
 | |
|     transform translateX(4)
 | |
|   }
 | |
| }
 | |
| 
 | |
| .md-input-item
 | |
|   &.left
 | |
|     .md-input-item-input,
 | |
|     .md-input-item-fake
 | |
|       text-align left
 | |
| 
 | |
|   &.center
 | |
|     .md-input-item-input,
 | |
|     .md-input-item-fake
 | |
|       text-align center
 | |
| 
 | |
|   &.right
 | |
|     .md-input-item-input,
 | |
|     .md-input-item-fake
 | |
|       text-align right
 | |
| 
 | |
|   &.is-title-latent
 | |
|     .md-field-item-title
 | |
|       position absolute
 | |
|       top 50%
 | |
|       left 0
 | |
|       height auto
 | |
|       font-size input-item-title-latent-font-size
 | |
|       color input-item-title-latent-color
 | |
|       transform translate3d(0, -50%, 0)
 | |
|       transition all .3s ease
 | |
|       opacity 0
 | |
|       will-change auto
 | |
|     .md-field-item-content
 | |
|       min-height 115px
 | |
|     .md-field-item-content,
 | |
|     .md-field-item-left,
 | |
|     .md-field-item-right,
 | |
|     .md-input-item-input,
 | |
|     .md-input-item-fake
 | |
|       padding-top 20px
 | |
|     &.is-active
 | |
|       .md-field-item-title
 | |
|         opacity 1
 | |
|         top 20px
 | |
|         transform translate3d(0, 0, 0)
 | |
| 
 | |
|   &.is-highlight
 | |
|     &.is-focus
 | |
|       .md-field-item-content
 | |
|         hairline(bottom, input-item-color-highlight, 0, 4px)
 | |
| 
 | |
|   &.is-disabled
 | |
|     .md-input-item-input,
 | |
|     .md-input-item-fake,
 | |
|     .md-input-item-fake-placeholder
 | |
|       -webkit-text-fill-color input-item-color-disabled
 | |
|       color input-item-color-disabled
 | |
| 
 | |
|   &.is-amount
 | |
|     .md-input-item-input,
 | |
|     .md-input-item-fake
 | |
|       font-family font-family-number
 | |
|     &.large
 | |
|       .md-input-item-input,
 | |
|       .md-input-item-fake
 | |
|         padding-top v-gap-xs
 | |
| 
 | |
|   &.large
 | |
|     .md-input-item-input,
 | |
|     .md-input-item-fake
 | |
|       padding-bottom 15px
 | |
|       font-size input-item-font-size-large
 | |
|     .md-input-item-input::-webkit-input-placeholder
 | |
|         font-size 60px
 | |
|         line-height 100px
 | |
| 
 | |
|   &.is-error
 | |
|     .md-field-item-content
 | |
|       hairline(bottom, input-item-color-error, 0, 4px)
 | |
| 
 | |
|   &.is-ios
 | |
|     .md-input-item-input::-webkit-input-placeholder
 | |
|       position relative
 | |
|       top 3px
 | |
|       overflow visible
 | |
|     .md-input-item-fake::after
 | |
|       border-right solid 6px #2C6CF5
 | |
|       border-radius 2px
 | |
|   &.is-android
 | |
|     .md-input-item-fake::after
 | |
|       border-right solid 4px color-text-base
 | |
|     .md-input-item-input,
 | |
|     .md-input-item-fake
 | |
|       font-weight input-item-font-weight-android
 | |
| 
 | |
| @-webkit-keyframes keyboard-cursor
 | |
|   0%
 | |
|     opacity 1
 | |
|   50%
 | |
|     opacity 0
 | |
|   to
 | |
|     opacity 1
 | |
| @keyframes keyboard-cursor
 | |
|   0%
 | |
|     opacity 1
 | |
|   50%
 | |
|     opacity 0
 | |
|   to
 | |
|     opacity 1
 | |
| </style>
 |