refactor(input): compositin & new theme

This commit is contained in:
07akioni 2021-01-04 21:39:15 +08:00
parent a4ef5d78d1
commit 29e576d463
8 changed files with 219 additions and 264 deletions

View File

@ -53,74 +53,94 @@
@change="handleChange"
@keyup="handleKeyUp"
/>
<div v-else class="n-input-first-input">
<input
ref="input"
:type="type"
class="n-input__input n-input__input--first"
:tabindex="passivelyActivated && !inputFocused ? -1 : false"
:placeholder="mergedPlaceholder[0]"
:disabled="disabled"
:maxlength="maxlength"
:minlength="minlength"
:value="pair ? mergedValue && mergedValue[0] : mergedValue"
:readonly="readonly"
:autofocus="autofocus"
:size="attrSize"
@blur="handleInputBlur"
@focus="handleInputFocus"
@input="handleInput($event, 0)"
@change="handleChange($event, 0)"
@keyup="handleKeyUp"
<div v-else class="n-input-wrapper">
<n-icon-config-provider
v-if="$slots.affix || $slots.prefix"
class="n-input__prefix"
:depth="disabled ? 5 : 4"
>
<div v-if="showPlaceholder1" class="n-input__placeholder">
{{ mergedPlaceholder[0] }}
<slot name="affix">
<slot name="prefix" />
</slot>
</n-icon-config-provider>
<div class="n-input__input">
<input
ref="inputRef"
:type="type"
class="n-input__input-el"
:tabindex="passivelyActivated && !inputFocused ? -1 : false"
:placeholder="mergedPlaceholder[0]"
:disabled="disabled"
:maxlength="maxlength"
:minlength="minlength"
:value="pair ? mergedValue && mergedValue[0] : mergedValue"
:readonly="readonly"
:autofocus="autofocus"
:size="attrSize"
@blur="handleInputBlur"
@focus="handleInputFocus"
@input="handleInput($event, 0)"
@change="handleChange($event, 0)"
@keyup="handleKeyUp"
>
<div v-if="showPlaceholder1" class="n-input__placeholder">
{{ mergedPlaceholder[0] }}
</div>
</div>
<n-icon-config-provider
v-if="!pair"
class="n-input__suffix"
:depth="disabled ? 5 : 4"
>
<slot name="suffix" />
<n-base-clear-button
v-if="clearable || $slots.clear"
:theme="'light'"
:show="showClearButton"
@clear="handleClear"
>
<slot name="clear" />
</n-base-clear-button>
</n-icon-config-provider>
</div>
<span v-if="pair" class="n-input__splitor">
{{ separator }}
</span>
<div v-if="pair" class="n-input-second-input">
<input
ref="input2"
:type="type"
class="n-input__input n-input__input--second"
:tabindex="passivelyActivated && !inputFocused ? -1 : false"
:placeholder="mergedPlaceholder[1]"
:disabled="disabled"
:maxlength="maxlength"
:minlength="minlength"
:value="mergedValue && mergedValue[1]"
:readonly="readonly"
@blur="handleInputBlur"
@focus="handleInputFocus"
@input="handleInput($event, 1)"
@change="handleChange($event, 1)"
@keyup="handleKeyUp"
>
<div v-if="showPlaceholder2" class="n-input__placeholder">
{{ mergedPlaceholder[1] }}
<div v-if="pair" class="n-input-wrapper">
<div class="n-input__input">
<input
ref="input2Ref"
:type="type"
class="n-input__input-el"
:tabindex="passivelyActivated && !inputFocused ? -1 : false"
:placeholder="mergedPlaceholder[1]"
:disabled="disabled"
:maxlength="maxlength"
:minlength="minlength"
:value="mergedValue && mergedValue[1]"
:readonly="readonly"
@blur="handleInputBlur"
@focus="handleInputFocus"
@input="handleInput($event, 1)"
@change="handleChange($event, 1)"
@keyup="handleKeyUp"
>
<div v-if="showPlaceholder2" class="n-input__placeholder">
{{ mergedPlaceholder[1] }}
</div>
</div>
<n-icon-config-provider class="n-input__suffix" :depth="disabled ? 5 : 4">
<slot name="suffix" />
<n-base-clear-button
v-if="clearable || $slots.clear"
:theme="'light'"
:show="showClearButton"
@clear="handleClear"
>
<slot name="clear" />
</n-base-clear-button>
</n-icon-config-provider>
</div>
<n-icon-config-provider
v-if="$slots.affix || $slots.prefix"
class="n-input__prefix"
:depth="disabled ? 5 : 4"
>
<slot name="affix">
<slot name="prefix" />
</slot>
</n-icon-config-provider>
<n-icon-config-provider class="n-input__suffix" :depth="disabled ? 5 : 4">
<slot name="suffix" />
<n-base-clear-button
:theme="'light'"
:show="showClearButton"
@clear="handleClear"
>
<slot name="clear" />
</n-base-clear-button>
</n-icon-config-provider>
<div v-if="showTextareaPlaceholder" class="n-input__placeholder">
{{ placeholder }}
</div>
@ -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
}
}

View File

@ -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,

View File

@ -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);
`)
])

View File

@ -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;

View File

@ -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'
})
])
])
])

View File

@ -1,5 +1,5 @@
export default {
paddingLeft: '14px',
paddingRight: '14px',
paddingRight: '8px',
paddingIcon: '38px'
}

View File

@ -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'

View File

@ -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
}