Moderner Vue-Input mit Floating Label, Glow-Fokus, Clear-Button und Validierungsstatus
1<template>2 <div3 class="aurora-input-wrap"4 :class="{5 'is-focused': focused,6 'has-value': internalValue.length > 0,7 'is-error': error,8 'is-success': success && !error9 }"10 >11 <label class="aurora-input-shell">12 <span class="aurora-glow"></span>13
14 <span class="aurora-icon" aria-hidden="true">15 <svg viewBox="0 0 24 24">16 <path d="M4.75 7.75A3 3 0 0 1 7.75 4.75h8.5a3 3 0 0 1 3 3v8.5a3 3 0 0 1-3 3h-8.5a3 3 0 0 1-3-3v-8.5Z" />17 <path d="M8 9.5h8M8 12h5.5M8 14.5h7" />18 </svg>19 </span>20
21 <input22 class="aurora-input"23 :type="type"24 :value="internalValue"25 :placeholder="focused ? placeholder : ' '"26 :disabled="disabled"27 @input="onInput"28 @focus="focused = true"29 @blur="focused = false"30 />31
32 <span class="aurora-label">{{ label }}</span>33
34 <button35 v-if="clearable && internalValue.length > 0 && !disabled"36 class="aurora-clear"37 type="button"38 aria-label="Eingabe löschen"39 @click="clearInput"40 >41 <svg viewBox="0 0 24 24">42 <path d="M7 7l10 10M17 7 7 17" />43 </svg>44 </button>45 </label>46
47 <p v-if="hint || error || success" class="aurora-message">48 <span class="aurora-dot"></span>49 {{ error || success || hint }}50 </p>51 </div>52</template>53
54<script>55export default {56 name: 'AuroraFocusInput',57
58 props: {59 modelValue: {60 type: String,61 default: ''62 },63 label: {64 type: String,65 default: 'Projektname'66 },67 placeholder: {68 type: String,69 default: 'z. B. Elementa UI'70 },71 type: {72 type: String,73 default: 'text'74 },75 hint: {76 type: String,77 default: 'Gib einen klaren Namen ein.'78 },79 error: {80 type: String,81 default: ''82 },83 success: {84 type: String,85 default: ''86 },87 disabled: {88 type: Boolean,89 default: false90 },91 clearable: {92 type: Boolean,93 default: true94 }95 },96
97 emits: ['update:modelValue', 'clear'],98
99 data: function () {100 return {101 focused: false102 }103 },104
105 computed: {106 internalValue: function () {107 return this.modelValue || ''108 }109 },110
111 methods: {112 onInput: function (event) {113 this.$emit('update:modelValue', event.target.value)114 },115
116 clearInput: function () {117 this.$emit('update:modelValue', '')118 this.$emit('clear')119 }120 }121}122</script>123
124<style scoped>125.aurora-input-wrap {126 --bg: rgba(12, 16, 28, 0.92);127 --surface: rgba(18, 24, 39, 0.96);128 --line: rgba(255, 255, 255, 0.14);129 --text: #f8fafc;130 --muted: #94a3b8;131 --pink: #fb7185;132 --amber: #f59e0b;133 --green: #34d399;134 --blue: #60a5fa;135
136 width: min(100%, 420px);137 font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;138 color: var(--text);139}140
141.aurora-input-shell {142 position: relative;143 display: flex;144 align-items: center;145 min-height: 64px;146 padding: 0 52px 0 52px;147 border: 1px solid var(--line);148 border-radius: 22px;149 background:150 linear-gradient(180deg, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.025)),151 var(--bg);152 box-shadow:153 0 24px 70px rgba(0, 0, 0, 0.32),154 inset 0 1px 0 rgba(255, 255, 255, 0.1);155 overflow: hidden;156 isolation: isolate;157 transition: 220ms ease;158}159
160.aurora-input-shell::before {161 content: "";162 position: absolute;163 inset: -1px;164 z-index: -2;165 border-radius: inherit;166 background: linear-gradient(120deg, var(--pink), var(--amber), var(--green), var(--blue));167 opacity: 0;168 transition: opacity 260ms ease;169}170
171.aurora-input-shell::after {172 content: "";173 position: absolute;174 inset: 1px;175 z-index: -1;176 border-radius: 21px;177 background:178 radial-gradient(circle at 15% 0%, rgba(251, 113, 133, 0.15), transparent 36%),179 radial-gradient(circle at 85% 100%, rgba(52, 211, 153, 0.13), transparent 36%),180 var(--surface);181}182
183.aurora-glow {184 position: absolute;185 left: 28px;186 top: 50%;187 width: 180px;188 height: 180px;189 border-radius: 999px;190 background:191 radial-gradient(circle, rgba(251, 113, 133, 0.28), transparent 62%),192 radial-gradient(circle, rgba(245, 158, 11, 0.2), transparent 68%);193 filter: blur(20px);194 opacity: 0;195 transform: translate(-50%, -50%) scale(0.72);196 transition: 260ms ease;197 pointer-events: none;198}199
200.aurora-icon {201 position: absolute;202 left: 18px;203 width: 22px;204 height: 22px;205 color: var(--muted);206 transition: 220ms ease;207}208
209.aurora-icon svg,210.aurora-clear svg {211 width: 100%;212 height: 100%;213 fill: none;214 stroke: currentColor;215 stroke-width: 1.8;216 stroke-linecap: round;217 stroke-linejoin: round;218}219
220.aurora-input {221 width: 100%;222 height: 64px;223 border: 0;224 outline: 0;225 background: transparent;226 color: var(--text);227 font-size: 15.5px;228 font-weight: 650;229 letter-spacing: -0.01em;230 caret-color: var(--amber);231}232
233.aurora-input::placeholder {234 color: rgba(148, 163, 184, 0.72);235 font-weight: 500;236}237
238.aurora-label {239 position: absolute;240 left: 52px;241 top: 50%;242 color: var(--muted);243 font-size: 15px;244 font-weight: 650;245 letter-spacing: -0.01em;246 transform: translateY(-50%);247 transform-origin: left center;248 pointer-events: none;249 transition: 200ms ease;250}251
252.aurora-clear {253 position: absolute;254 right: 16px;255 display: grid;256 place-items: center;257 width: 32px;258 height: 32px;259 border: 1px solid rgba(255, 255, 255, 0.11);260 border-radius: 999px;261 background: rgba(255, 255, 255, 0.065);262 color: var(--muted);263 cursor: pointer;264 transition: 180ms ease;265}266
267.aurora-clear:hover {268 color: var(--text);269 background: rgba(255, 255, 255, 0.12);270 transform: scale(1.04);271}272
273.aurora-clear:focus-visible {274 outline: 3px solid rgba(245, 158, 11, 0.28);275 outline-offset: 3px;276}277
278.aurora-message {279 display: flex;280 align-items: center;281 gap: 8px;282 min-height: 22px;283 margin: 9px 4px 0;284 color: var(--muted);285 font-size: 13px;286 line-height: 1.4;287}288
289.aurora-dot {290 width: 7px;291 height: 7px;292 border-radius: 999px;293 background: currentColor;294 opacity: 0.75;295}296
297.aurora-input-wrap.is-focused .aurora-input-shell {298 border-color: transparent;299 box-shadow:300 0 30px 90px rgba(0, 0, 0, 0.42),301 0 0 0 5px rgba(245, 158, 11, 0.08),302 inset 0 1px 0 rgba(255, 255, 255, 0.14);303 transform: translateY(-1px);304}305
306.aurora-input-wrap.is-focused .aurora-input-shell::before {307 opacity: 1;308}309
310.aurora-input-wrap.is-focused .aurora-glow {311 opacity: 1;312 transform: translate(-50%, -50%) scale(1);313}314
315.aurora-input-wrap.is-focused .aurora-icon {316 color: var(--amber);317 transform: scale(1.05);318}319
320.aurora-input-wrap.is-focused .aurora-label,321.aurora-input-wrap.has-value .aurora-label {322 color: rgba(248, 250, 252, 0.72);323 transform: translateY(-25px) scale(0.78);324}325
326.aurora-input-wrap.is-error .aurora-input-shell {327 border-color: rgba(251, 113, 133, 0.58);328 box-shadow:329 0 24px 70px rgba(0, 0, 0, 0.32),330 0 0 0 5px rgba(251, 113, 133, 0.09);331}332
333.aurora-input-wrap.is-error .aurora-icon,334.aurora-input-wrap.is-error .aurora-label,335.aurora-input-wrap.is-error .aurora-message {336 color: var(--pink);337}338
339.aurora-input-wrap.is-success .aurora-input-shell {340 border-color: rgba(52, 211, 153, 0.5);341 box-shadow:342 0 24px 70px rgba(0, 0, 0, 0.32),343 0 0 0 5px rgba(52, 211, 153, 0.08);344}345
346.aurora-input-wrap.is-success .aurora-icon,347.aurora-input-wrap.is-success .aurora-label,348.aurora-input-wrap.is-success .aurora-message {349 color: var(--green);350}351
352.aurora-input:disabled {353 cursor: not-allowed;354}355
356.aurora-input-wrap:has(.aurora-input:disabled) {357 opacity: 0.58;358}359
360@media (prefers-reduced-motion: reduce) {361 .aurora-input-shell,362 .aurora-input-shell::before,363 .aurora-glow,364 .aurora-icon,365 .aurora-label,366 .aurora-clear {367 transition: none;368 }369}370</style>Keine Installation, kein Build-Step — reine Standards, sofort einsatzbereit.
Klicke oben auf „Code kopieren“ — HTML und CSS landen in deiner Zwischenablage.
Füge das Markup an der gewünschten Stelle deiner Seite oder Komponente ein.
Übernimm den <style>-Block bzw. die Klassen in deine Stylesheet-Datei.
Aus derselben Kategorie oder mit passenden Tags.
Melde dich an, um zu kommentieren.
Premium Vue Command/Search Input mit animiertem Gradient-Ring, Floating Label, Live-Suggestions, Keyboard-Navigation, Clear-Button, Ladezustand, Statuszeile und sauberem v-model-Support. Funktioniert auch direkt in der Komponenten-Vorschau ohne externe Abhängigkeiten.
Minimalistisches Feld ohne Rahmen, dessen Unterstrich beim Fokussieren als Verlauf aus Violett, Fuchsia und Cyan von links nach rechts einfährt. Klar und modern im Dark-Theme.