-
Notifications
You must be signed in to change notification settings - Fork 138
/
Input.tsx
128 lines (112 loc) · 4.32 KB
/
Input.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
* @license
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/
import type { CSSProperties, Slot } from 'vue'
import { computed, defineComponent, normalizeClass, ref } from 'vue'
import { useGlobalConfig } from '@idux/components/config'
import { IxIcon } from '@idux/components/icon'
import { useThemeToken } from '@idux/components/theme'
import { inputProps } from './types'
export default defineComponent({
name: 'ɵInput',
inheritAttrs: false,
props: inputProps,
setup(props, { attrs, slots, expose }) {
const common = useGlobalConfig('common')
const { globalHashId } = useThemeToken()
const mergedPrefixCls = computed(() => `${common.prefixCls}-input`)
const inputRef = ref<HTMLInputElement>()
const getInputElement = () => inputRef.value
expose({ getInputElement })
const classes = computed(() => {
const { borderless, clearable, disabled, focused, size, status, addonAfter, addonBefore, prefix, suffix } = props
const prefixCls = mergedPrefixCls.value
return normalizeClass({
[prefixCls]: true,
[`${prefixCls}-${size}`]: true,
[`${prefixCls}-${status}`]: !!status,
[`${prefixCls}-borderless`]: borderless,
[`${prefixCls}-clearable`]: clearable,
[`${prefixCls}-disabled`]: disabled,
[`${prefixCls}-focused`]: focused,
[`${prefixCls}-with-addon-after`]: addonAfter || slots.addonAfter,
[`${prefixCls}-with-addon-before`]: addonBefore || slots.addonBefore,
[`${prefixCls}-with-prefix`]: prefix || slots.prefix,
[`${prefixCls}-with-suffix`]: suffix || slots.suffix,
})
})
return () => {
const { clearable, clearIcon, clearVisible, disabled, addonAfter, addonBefore, prefix, suffix, onClear } = props
const prefixCls = mergedPrefixCls.value
const addonBeforeNode = renderAddon(slots.addonBefore, addonBefore, `${prefixCls}-addon`, '__before-addon')
const addonAfterNode = renderAddon(slots.addonAfter, addonAfter, `${prefixCls}-addon`, '__before-after')
const prefixNode = renderIcon(slots.prefix, prefix, `${prefixCls}-prefix`, '__prefix')
const suffixNode = renderIcon(slots.suffix, suffix, `${prefixCls}-suffix`, '__suffix')
const clearNode = clearable && (
<span key="__clear" class={`${prefixCls}-clear${clearVisible ? ' visible' : ''}`} onClick={onClear}>
{slots.clearIcon ? slots.clearIcon() : <IxIcon name={clearIcon} />}
</span>
)
if (!(addonBeforeNode || addonAfterNode || prefixNode || suffixNode || clearNode)) {
return <input ref={inputRef} class={classes.value} disabled={disabled} {...attrs} />
}
const { class: className, style, ...rest } = attrs
const classNames = normalizeClass([classes.value, className, globalHashId.value])
const inputNode = <input ref={inputRef} class={`${prefixCls}-inner`} disabled={disabled} {...rest} />
if (!(addonBeforeNode || addonAfterNode)) {
return (
<span class={classNames} style={style as CSSProperties}>
{prefixNode}
{inputNode}
{suffixNode}
{clearNode}
</span>
)
}
if (!(prefixNode || suffixNode || clearNode)) {
return (
<span class={classNames} style={style as CSSProperties}>
{addonBeforeNode}
{inputNode}
{addonAfterNode}
</span>
)
}
return (
<span class={classNames} style={style as CSSProperties}>
{addonBeforeNode}
<span key="__wrapper" class={`${prefixCls}-wrapper`}>
{prefixNode}
{inputNode}
{suffixNode}
{clearNode}
</span>
{addonAfterNode}
</span>
)
}
},
})
function renderAddon(slot: Slot | undefined, prop: string | undefined, cls: string, key: string) {
if (!(slot || prop)) {
return undefined
}
return (
<span key={key} class={cls}>
{slot ? slot() : prop}
</span>
)
}
function renderIcon(slot: Slot | undefined, prop: string | undefined, cls: string, key: string) {
if (!(slot || prop)) {
return undefined
}
return (
<span key={key} class={cls}>
{slot ? slot() : <IxIcon name={prop} />}
</span>
)
}