From 29e576d46370d01bcbf19818ba57239063ca9525 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Mon, 4 Jan 2021 21:39:15 +0800 Subject: [PATCH] refactor(input): compositin & new theme --- src/input/src/Input.vue | 159 ++++++---- src/input/src/InputGroupLabel.vue | 2 + .../src/styles/input-group-label.cssr.js | 2 +- src/input/src/styles/input-group.cssr.js | 28 +- src/input/src/styles/input.cssr.js | 284 +++++++----------- src/input/styles/_common.js | 2 +- src/styles.js | 2 +- src/styles.new.js | 4 +- 8 files changed, 219 insertions(+), 264 deletions(-) diff --git a/src/input/src/Input.vue b/src/input/src/Input.vue index 1c3a0cc9e..a05f21fb7 100644 --- a/src/input/src/Input.vue +++ b/src/input/src/Input.vue @@ -53,74 +53,94 @@ @change="handleChange" @keyup="handleKeyUp" /> -
- + -
- {{ mergedPlaceholder[0] }} + + + + +
+ +
+ {{ mergedPlaceholder[0] }} +
+ + + + + +
{{ separator }} -
- -
- {{ mergedPlaceholder[1] }} +
+
+ +
+ {{ mergedPlaceholder[1] }} +
+ + + + + +
- - - - - - - - - - -
{{ placeholder }}
@@ -137,7 +157,8 @@ import { ref, toRef, watch, - onMounted + onMounted, + getCurrentInstance } from 'vue' import { useMergedState } from 'vooks' import { NBaseClearButton } from '../../_base' @@ -164,6 +185,7 @@ function createMethods ( textareaMirrorRef } ) { + const vm = getCurrentInstance().proxy const doInput = (value) => { const { 'onUpdate:value': onUpdateValue, onInput } = props const { nTriggerFormInput } = formItem @@ -254,8 +276,9 @@ function createMethods ( value[index] = changedValue event === 'input' ? doInput(value) : doChange(value) } - /** force update to sync input's view with value */ - // ? this.$forceUpdate() + // force update to sync input's view with value + // if not set, after input, input value won't sync with dom input value + vm.$forceUpdate() } const handleInputBlur = (e) => { doInputBlur(e) @@ -336,8 +359,11 @@ function createMethods ( } const handleWrapperKeyDownEnter = (e) => { if (props.passivelyActivated) { - if (inputFocusedRef.value && props.deactivateOnEnter) { - handleWrapperKeyDownEsc() + const { value: focused } = inputFocusedRef + if (focused) { + if (props.deactivateOnEnter) { + handleWrapperKeyDownEsc() + } return } e.preventDefault() @@ -383,7 +409,8 @@ function createMethods ( handleChange, handleClick, handleClear, - handleWrapperKeyDownEnter + handleWrapperKeyDownEnter, + handleWrapperKeyDownEsc } } diff --git a/src/input/src/InputGroupLabel.vue b/src/input/src/InputGroupLabel.vue index d9b428bff..f592efbbe 100644 --- a/src/input/src/InputGroupLabel.vue +++ b/src/input/src/InputGroupLabel.vue @@ -43,12 +43,14 @@ export default defineComponent({ textColor, lineHeight, fontSize, + border, [createKey('height', size)]: height } } = themeRef.value return { '--bezier': cubicBezierEaseInOut, '--group-label-color': groupLabelColor, + '--border': border, '--border-radius': borderRadius, '--text-color': textColor, '--font-size': fontSize, diff --git a/src/input/src/styles/input-group-label.cssr.js b/src/input/src/styles/input-group-label.cssr.js index 82cf65f08..64194055c 100644 --- a/src/input/src/styles/input-group-label.cssr.js +++ b/src/input/src/styles/input-group-label.cssr.js @@ -32,6 +32,6 @@ export default cB('input-group-label', ` bottom: 0; border-radius: inherit; border: var(--border); - transition: 'border-color .3s var(--bezier); + transition: border-color .3s var(--bezier); `) ]) diff --git a/src/input/src/styles/input-group.cssr.js b/src/input/src/styles/input-group.cssr.js index a9466124a..f8ecada45 100644 --- a/src/input/src/styles/input-group.cssr.js +++ b/src/input/src/styles/input-group.cssr.js @@ -11,22 +11,12 @@ export default cB('input-group', ` c('&:not(:last-child)', ` border-top-right-radius: 0!important; border-bottom-right-radius: 0!important; - `, [ - cE('box-shadow, state-border, border', ` - border-top-right-radius: 0!important; - border-bottom-right-radius: 0!important; - `) - ]), + `), c('&:not(:first-child)', ` border-top-left-radius: 0!important; border-bottom-left-radius: 0!important; margin-left: -1px!important; - `, [ - cE('box-shadow, state-border, border', ` - border-top-left-radius: 0!important; - border-bottom-left-radius: 0!important; - `) - ]) + `) ]), cB('input-number', [ c('&:not(:last-child)', ` @@ -97,12 +87,7 @@ export default cB('input-group', ` cB('input', ` border-top-right-radius: 0!important; border-bottom-right-radius: 0!important; - `, [ - cE('box-shadow, state-border, border', ` - border-top-right-radius: 0!important; - border-bottom-right-radius: 0!important; - `) - ]), + `), cB('base-selection', [ cB('base-selection-label', ` border-top-right-radius: 0!important; @@ -128,12 +113,7 @@ export default cB('input-group', ` cB('input', ` border-top-left-radius: 0!important; border-bottom-left-radius: 0!important; - `, [ - cE('box-shadow, border, state-border', ` - border-top-left-radius: 0!important; - border-bottom-left-radius: 0!important; - `) - ]), + `), cB('base-selection', [ cB('base-selection-label', ` border-top-left-radius: 0!important; diff --git a/src/input/src/styles/input.cssr.js b/src/input/src/styles/input.cssr.js index a9fa361da..8674a87bf 100644 --- a/src/input/src/styles/input.cssr.js +++ b/src/input/src/styles/input.cssr.js @@ -1,5 +1,4 @@ import { cB, c, cE, cM, cNotM } from '../../../_utils/cssr' -import fadeInScaleUpTransition from '../../../_styles/transitions/fade-in-scale-up' // vars: // --bezier @@ -32,93 +31,125 @@ export default c([ box-sizing: border-box; position: relative; width: 100%; - display: inline-block; + display: inline-flex; border-radius: var(--border-radius); background-color: var(--color); transition: background-color .3s var(--bezier); --padding-vertical: calc((var(--height) - 1.5 * var(--font-size)) / 2); `, [ - cE('input', { - height: 'var(--height)' - }), - cE('input, textarea, textarea-mirror, splitor, placeholder', ` - padding-left: var(--padding-left); - padding-right: var(--padding-right); - padding-top: var(--padding-vertical); - padding-bottom: var(--padding-vertical); - font-size: var(--font-size); - line-height: 1.5; + // common + cE('input', ` + flex-grow: 1; + position: relative; `), - // cM('suffix, clearable', [ - // cM('split', [ - // cE('input', [ - // cM('second', { - // // paddingRight: `${paddingIcon} !important` - // }, [ - // c('& +', [ - // cE('placeholder', { - // // right: `${paddingIcon} !important` - // }) - // ]) - // ]) - // ]) - // ]), - // cNotM('split', [ - // cE('input', [ - // cM('first', { - // // paddingRight: `${paddingIcon} !important` - // }) - // ]), - // cE('placeholder', { - // //right: `${paddingIcon} !important` - // }) - // ]) - // ]), - // cM('prefix', [ - // cNotM('split', [ - // cE('placeholder', { - // left: `${paddingIcon} !important` - // }) - // ]), - // cM('split', [ - // cE('input', [ - // cM('first', [ - // c('& +', [ - // cE('placeholder', { - // left: `${paddingIcon} !important` - // }) - // ]) - // ]) - // ]) - // ]), - // cE('input', [ - // cM('first', { - // paddingLeft: `${paddingIcon} !important` - // }) - // ]) - // ]), + cE('input-el, textarea, textarea-mirror, splitor, placeholder', ` + box-sizing: border-box; + font-size: inherit; + line-height: 1.5; + font-family: inherit; + border: none; + outline: none; + background-color: transparent; + transition: + caret-color .3s var(--bezier), + color .3s var(--bezier), + text-decoration-color .3s var(--bezier); + `), + cE('input-el, textarea', ` + -webkit-appearance: none; + width: 100%; + min-width: 0; + text-decoration-color: var(--text-decoration-color); + color: var(--text-color); + caret-color: var(--caret-color); + `, [ + c('&::placeholder', { + color: 'transparent' + }) + ]), cM('round', [ cNotM('textarea', { borderRadius: 'calc(var(--height) / 2)' }) ]), - cM('split', { - display: 'inline-flex' + cE('placeholder', ` + pointer-events: none; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + overflow: hidden; + color: var(--placeholder-color); + `), + // input + cB('input-wrapper', ` + display: inline-flex; + flex-grow: 1; + position: relative; + padding-left: var(--padding-left); + padding-right: var(--padding-right); + `), + cE('input-el', { + padding: 0, + height: 'var(--height)' }, [ - cE('input, placeholder', { - textAlign: 'center' - }) + c('+', [ + cE('placeholder', ` + display: flex; + align-items: center; + `) + ]) ]), cNotM('textarea', [ cE('placeholder', { whiteSpace: 'nowrap' }) ]), + // textarea cM('textarea', [ - cE('placeholder', { - whiteSpace: 'unset' - }) + cE('textarea, textarea-mirror, placeholder', ` + padding-left: var(--padding-left); + padding-right: var(--padding-right); + padding-top: var(--padding-vertical); + padding-bottom: var(--padding-vertical); + display: inline-block; + vertical-align: bottom; + box-sizing: border-box; + line-height: var(--line-height-textarea); + margin: 0; + resize: vertical; + `), + cE('textarea', [ + cM('autosize', ` + position: absolute; + top: 0; + left: 0; + height: 100%; + resize: none; + `) + ]), + cE('textarea-mirror', ` + overflow: hidden; + visibility: hidden; + position: static; + white-space: pre-wrap; + overflow-wrap: break-word; + `) ]), + // pair + cM('split', [ + cE('input-el, placeholder', { + textAlign: 'center' + }), + cE('splitor', ` + display: flex; + align-items: center; + transition: color .3s var(--bezier); + color: var(--text-color); + `) + ]), + cM('disabled', { cursor: 'not-allowed', backgroundColor: 'var(--color-disabled)' @@ -126,7 +157,7 @@ export default c([ cE('border', { border: 'var(--border-disabled)' }), - cE('input, textarea', { + cE('input-el, textarea', { cursor: 'not-allowed', color: 'var(--text-color-disabled)' }), @@ -166,118 +197,31 @@ export default c([ box-shadow .3s var(--bezier), border-color .3s var(--bezier); `), - cE('state-border', { - borderColor: 'transparent', - zIndex: 1 - }), - cE('placeholder', ` - box-sizing: border-box; - pointer-events: none; - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - overflow: hidden; - transition: color .3s var(--bezier); - color: var(--placeholder-color); + cE('state-border', ` + border-color: transparent; + z-index: 1; `), + cE('prefix', { + marginRight: '4px' + }), + cE('suffix', { + marginLeft: '4px' + }), cE('suffix, prefix', ` - position: absolute; - line-height: 1; - height: 0; + line-height: 1.5; white-space: nowrap; - display: flex; + display: inline-flex; align-items: center; - top: 50%; - width: var(--icon-size); + justify-content: center; + min-width: var(--icon-size); `, [ cB('base-clear-button', { fontSize: 'var(--icon-size)' }), cB('icon', { - justifySelf: 'center', fontSize: 'var(--icon-size)', transition: 'color .3s var(--bezier)' }) - ]), - cE('suffix', { - justifyContent: 'flex-end', - right: '12px' - }, [ - fadeInScaleUpTransition() // button suffix - ]), - cE('prefix', { - justifyContent: 'flex-start', - left: '12px' - }), - cE('textarea, textarea-mirror', ` - display: inline-block; - vertical-align: bottom; - box-sizing: border-box; - font-family: inherit; - font-size: inherit; - line-height: var(--line-height-textarea); - margin: 0; - resize: vertical; - padding-left: 14px; - padding-right: 14px; - `), - cE('textarea', [ - cM('autosize', ` - position: absolute; - top: 0; - left: 0; - height: 100%; - resize: none; - `) - ]), - cE('textarea-mirror', ` - overflow: hidden; - visibility: hidden; - position: static; - white-space: pre-wrap; - overflow-wrap: break-word; - `), - cE('input, textarea', ` - -webkit-appearance: none; - box-sizing: border-box; - border: none; - font-size: inherit; - outline: none; - font-family: inherit; - width: 100%; - background-color: transparent; - min-width: 0; - text-decoration-color: var(--text-decoration-color); - color: var(--text-color); - caret-color: var(--caret-color); - transition: - caret-color .3s var(--bezier), - color .3s var(--bezier), - text-decoration-color .3s var(--bezier); - `, [ - c('&::placeholder', { - color: 'transparent' - }) - ]), - cE('splitor', { - transition: 'color .3s var(--bezier)', - color: 'var(--text-color)', - paddingLeft: '0 !important', - paddingRight: '0 !important' - }), - cB('input-clear', { - display: 'flex', - marginRight: '4px' - }), - cB('input-first-input', { - flexGrow: 1, - position: 'relative' - }), - cB('input-second-input', { - flexGrow: 1, - position: 'relative' - }) + ]) ]) ]) diff --git a/src/input/styles/_common.js b/src/input/styles/_common.js index 1d65cfe8f..fcadd4ec5 100644 --- a/src/input/styles/_common.js +++ b/src/input/styles/_common.js @@ -1,5 +1,5 @@ export default { paddingLeft: '14px', - paddingRight: '14px', + paddingRight: '8px', paddingIcon: '38px' } diff --git a/src/styles.js b/src/styles.js index e84197857..9f22826d3 100644 --- a/src/styles.js +++ b/src/styles.js @@ -46,7 +46,7 @@ export { baseDark, baseLight } from './_styles/base' // export { gradientTextDark, gradientTextLight } from './gradient-text/styles' // export { gridDark, gridLight } from './grid/styles' // export { iconDark, iconLight } from './icon/styles' -export { inputDark, inputLight } from './input/styles' +// export { inputDark, inputLight } from './input/styles' export { inputNumberDark, inputNumberLight } from './input-number/styles' export { layoutDark, layoutLight } from './layout/styles' export { listDark, listLight } from './list/styles' diff --git a/src/styles.new.js b/src/styles.new.js index 8c6aeaff1..3a9aafb5e 100644 --- a/src/styles.new.js +++ b/src/styles.new.js @@ -28,6 +28,7 @@ import { formDark } from './form/styles' import { gradientTextDark } from './gradient-text/styles' import { gridDark } from './grid/styles' import { iconDark } from './icon/styles' +import { inputDark } from './input/styles' export const darkTheme = { common: commonDark, @@ -59,5 +60,6 @@ export const darkTheme = { Form: formDark, GradientText: gradientTextDark, Grid: gridDark, - Icon: iconDark + Icon: iconDark, + Input: inputDark }