Реализация компонента инпута с плавающим лейблом
Попытался реализовать компонент инпута с плавающим лейблом (Floating Label). Код компонента FloatingInput.vue:
<script setup>
import { computed, ref } from 'vue'
const props = defineProps({
modelValue: String,
label: String,
type: {
type: String,
default: 'text',
},
})
const emit = defineEmits(['update:modelValue'])
const isFocused = ref(false)
const isFocusedOrText = computed(() => isFocused.value || !!props.modelValue.trim())
const handleInput = (e) => {
emit('update:modelValue', e.target.value)
}
</script>
<template>
<div :class="$style.form_group">
<input
:type="type"
:class="[$style.form_group_input, { [$style.form_group_input_active]: isFocused }]"
@focus="isFocused = true"
@blur="isFocused = false"
@input="handleInput"
/>
<label
:class="[$style.form_group_label, { [$style.form_group_label_active]: isFocusedOrText }]"
>{{ props.label }}</label
>
</div>
</template>
<style module>
.form_group {
position: relative;
flex: 1 0 260px;
block-size: max-content;
}
.form_group_input {
block-size: 100%;
inline-size: 100%;
padding: 26px 16px 8px;
border: none;
outline: none;
border-radius: var(--nd-border-radius-small);
color: var(--nd-color-light);
background-color: transparent;
box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.5);
transition-duration: var(--nd-transition-duration);
}
.form_group_input_active {
box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 1);
}
.form_group_label {
position: absolute;
top: 50%;
left: 16px;
transform: translateY(-53%);
transition-duration: var(--nd-transition-duration);
pointer-events: none;
}
.form_group_label_active {
transform: translate(0, -20px);
font-size: 14px;
}
</style>
Пример использования в <template> внутри HomePage.vue (в <script> всё необходимое создано и импортировано, email и nickname — реактивные поля):
<div :class="$style.fluid_form_body">
<FloatingInput v-model="email" label="Электронная почта" type="email" />
<FloatingInput v-model="nickname" label="Никнейм" />
</div>
В принципе сам код работает, но выглядит каким-то громоздким. Есть ли какие-то советы по улучшению качества кода, оптимизации? В этом проекте впервые работал с модульными стилями и с defineEmits.
