File size: 2,845 Bytes
89ce340 |
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 129 130 131 132 133 134 135 136 |
<template>
<div
class="input"
:class="{
'disabled': disabled,
'focused': focused,
'simple': simple,
}"
>
<span class="prefix">
<slot name="prefix"></slot>
</span>
<input
type="text"
ref="inputRef"
:disabled="disabled"
:value="value"
:placeholder="placeholder"
:maxlength="maxlength"
@input="$event => handleInput($event)"
@focus="$event => handleFocus($event)"
@blur="$event => handleBlur($event)"
@change="$event => emit('change', $event)"
@keydown.enter="$event => emit('enter', $event)"
@keydown.backspace="$event => emit('backspace', $event)"
/>
<span class="suffix">
<slot name="suffix"></slot>
</span>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
withDefaults(defineProps<{
value: string
disabled?: boolean
placeholder?: string
simple?: boolean
maxlength?: number
}>(), {
disabled: false,
placeholder: '',
simple: false,
})
const emit = defineEmits<{
(event: 'update:value', payload: string): void
(event: 'input', payload: Event): void
(event: 'change', payload: Event): void
(event: 'blur', payload: Event): void
(event: 'focus', payload: Event): void
(event: 'enter', payload: Event): void
(event: 'backspace', payload: Event): void
}>()
const focused = ref(false)
const handleInput = (e: Event) => {
emit('update:value', (e.target as HTMLInputElement).value)
}
const handleBlur = (e: Event) => {
focused.value = false
emit('blur', e)
}
const handleFocus = (e: Event) => {
focused.value = true
emit('focus', e)
}
const inputRef = ref<HTMLInputElement>()
const focus = () => {
if (inputRef.value) inputRef.value.focus()
}
defineExpose({
focus,
})
</script>
<style lang="scss" scoped>
.input {
background-color: #fff;
border: 1px solid #d9d9d9;
padding: 0 5px;
border-radius: $borderRadius;
transition: border-color .25s;
font-size: 13px;
display: flex;
input {
min-width: 0;
height: 30px;
outline: 0;
border: 0;
line-height: 30px;
vertical-align: top;
color: $textColor;
padding: 0 5px;
flex: 1;
font-size: 13px;
font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji';
&::placeholder {
color: #bfbfbf;
}
}
&:not(.disabled):hover, &.focused {
border-color: $themeColor;
}
&.disabled {
background-color: #f5f5f5;
border-color: #dcdcdc;
color: #b7b7b7;
input {
color: #b7b7b7;
}
}
&.simple {
border: 0;
}
.prefix, .suffix {
display: flex;
justify-content: center;
align-items: center;
line-height: 30px;
user-select: none;
}
}
</style> |