wire frontend password login

This commit is contained in:
Yisroel Baum 2026-07-31 11:44:19 +03:00
parent 1dff3f6976
commit 3da9c586c3
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
4 changed files with 239 additions and 3 deletions

View file

@ -1,16 +1,34 @@
<script setup lang="ts">
defineProps<{
submitLabel: string
submittingLabel?: string
submitting?: boolean
error?: string
}>()
defineEmits<{
submit: []
}>()
</script>
<template>
<form class="auth-form" @submit.prevent>
<form
class="auth-form"
:aria-busy="submitting === true ? 'true' : undefined"
novalidate
@submit.prevent="$emit('submit')"
>
<div class="auth-form__fields">
<slot></slot>
</div>
<button type="submit">{{ submitLabel }}</button>
<p v-if="error !== undefined" class="auth-form__error" role="alert">
{{ error }}
</p>
<button type="submit" :disabled="submitting">
{{ submitting && submittingLabel ? submittingLabel : submitLabel }}
</button>
</form>
</template>
@ -60,6 +78,22 @@ button:focus-visible {
outline-offset: 0.2rem;
}
button:disabled {
border-color: #708079;
background: #708079;
box-shadow: none;
cursor: wait;
transform: none;
}
.auth-form__error {
margin: -0.65rem 0;
color: #a33f37;
font-size: 0.8rem;
font-weight: 650;
line-height: 1.5;
}
@media (prefers-reduced-motion: reduce) {
button {
transition: none;

View file

@ -5,7 +5,20 @@ defineProps<{
type: 'email' | 'password' | 'text'
autocomplete: string
placeholder: string
modelValue?: string
error?: string
disabled?: boolean
}>()
const emit = defineEmits<{
'update:modelValue': [value: string]
}>()
function updateValue(event: Event): void {
if (event.target instanceof HTMLInputElement) {
emit('update:modelValue', event.target.value)
}
}
</script>
<template>
@ -17,7 +30,15 @@ defineProps<{
:name="id"
:autocomplete="autocomplete"
:placeholder="placeholder"
:value="modelValue"
:disabled="disabled"
:aria-invalid="error === undefined ? undefined : 'true'"
:aria-describedby="error === undefined ? undefined : `${id}-error`"
@input="updateValue"
/>
<p v-if="error !== undefined" :id="`${id}-error`" class="text-field__error">
{{ error }}
</p>
</div>
</template>
@ -62,6 +83,23 @@ input:focus {
box-shadow: 0 0 0 3px rgb(77 125 109 / 16%);
}
input[aria-invalid='true'] {
border-color: #a54e46;
}
input:disabled {
color: #67736e;
background: #f5f5f2;
cursor: not-allowed;
}
.text-field__error {
margin: 0;
color: #a33f37;
font-size: 0.76rem;
line-height: 1.4;
}
@media (prefers-reduced-motion: reduce) {
input {
transition: none;