From c385779221da0e89db5737329bc23acfe3221900 Mon Sep 17 00:00:00 2001
From: Bastian Masanek
Date: Fri, 31 Oct 2025 17:40:10 +0100
Subject: [PATCH] Enhance FormMessage and styleguide for improved accessibility
and user feedback
- Add orange AlertCircle icon to FormMessage component for better visibility of validation errors.
- Update styleguide to demonstrate new alert components with icons for error, success, and warning messages.
- Refactor CSS for status messages and form error messages to improve layout and accessibility compliance.
---
app/components/ui/form/FormMessage.vue | 5 +-
app/pages/internal/styleguide.vue | 99 +++++++++++++++++++++++---
assets/css/tailwind.css | 57 +++++++++++----
3 files changed, 134 insertions(+), 27 deletions(-)
diff --git a/app/components/ui/form/FormMessage.vue b/app/components/ui/form/FormMessage.vue
index d91b698..ed209bf 100644
--- a/app/components/ui/form/FormMessage.vue
+++ b/app/components/ui/form/FormMessage.vue
@@ -2,6 +2,7 @@
import type { HTMLAttributes } from 'vue'
import { inject } from 'vue'
import { useFieldError } from 'vee-validate'
+import { AlertCircle } from 'lucide-vue-next'
import { cn } from '~/lib/utils'
import type { FormItemContext } from '.'
import { FORM_ITEM_INJECT_KEY } from '.'
@@ -9,6 +10,7 @@ import { FORM_ITEM_INJECT_KEY } from '.'
/**
* FormMessage component - Displays validation error messages
* Only renders when there is an error for the associated field
+ * Includes orange AlertCircle icon for better accessibility
*/
interface Props {
@@ -38,7 +40,8 @@ const error = useFieldError()
:id="`${formItemContext?.id}-message`"
:class="cn('form-error', props.class)"
>
- {{ error }}
+
+ {{ error }}
diff --git a/app/pages/internal/styleguide.vue b/app/pages/internal/styleguide.vue
index de03954..a4819d6 100644
--- a/app/pages/internal/styleguide.vue
+++ b/app/pages/internal/styleguide.vue
@@ -5,6 +5,8 @@
* Protected by Basic Auth via server/middleware/internal-auth.ts
*/
+import { AlertCircle, CheckCircle } from 'lucide-vue-next'
+
definePageMeta({
layout: 'styleguide',
})
@@ -442,9 +444,21 @@ const copyCode = async (code: string) => {
Fehlermeldungen (.form-error)
-
Dies ist eine Fehlermeldung mit gutem Kontrast
-
Required
-
Das Passwort muss mindestens 8 Zeichen lang sein
+
+ Orange Border (WCAG AA konform) mit Icon für bessere Barrierefreiheit. Icon optional.
+
+
+
+ Dies ist eine Fehlermeldung mit gutem Kontrast
+
+
+
+ Dieses Feld ist erforderlich
+
+
+
+ Das Passwort muss mindestens 8 Zeichen lang sein
+
@@ -495,26 +509,29 @@ const copyCode = async (code: string) => {
Status Indicators
+
+ Einheitlicher Stil mit orange/grünem Border für bessere Barrierefreiheit. Alle verwenden den gleichen Hintergrund mit farbigem Icon.
+
-
✓
-
Success message
+
+
Erfolgsmeldung - Aktion wurde ausgeführt
-
⚠
-
Warning message
+
+
Warnung - Bitte beachten
- ✕
- Error message
+
+ Fehlermeldung - Etwas ist schiefgelaufen
-
ⓘ
-
Info message
+
+
Information - Nützlicher Hinweis
@@ -528,6 +545,66 @@ const copyCode = async (code: string) => {
+
+
+ Alert Components
+
+
+
shadcn-nuxt Alert Variants
+
+ Alert-Komponenten für Benachrichtigungen und Fehlermeldungen. Die "error" Variante verwendet Orange für bessere Barrierefreiheit (WCAG AA konform).
+
+
+
+
+
+
+
+ Ungültige E-Mail-Adresse oder Passwort
+
+
+
+
+
+
+ Registrierung erfolgreich!
+
+ Bitte bestätige deine E-Mail-Adresse über den Link, den wir dir gesendet haben.
+
+
+
+
+
+
+ Warnung
+
+ Dies ist die ursprüngliche "destructive" Variante mit rotem Border.
+
+
+
+
+
+ Show Code
+ <!-- Error Alert (empfohlen für Fehler) -->
+<Alert variant="error">
+ <AlertCircle class="h-6 w-6" />
+ <AlertDescription>
+ Ungültige E-Mail-Adresse oder Passwort
+ </AlertDescription>
+</Alert>
+
+<!-- Success Alert -->
+<Alert class="bg-white/15 border-l-4 border-success text-white">
+ <CheckCircle class="h-6 w-6 text-success" />
+ <AlertTitle class="text-success font-medium">Erfolg!</AlertTitle>
+ <AlertDescription>
+ Deine Nachricht...
+ </AlertDescription>
+</Alert>
+
+
+
+
Progress Bars
diff --git a/assets/css/tailwind.css b/assets/css/tailwind.css
index 3c76525..6ac8162 100644
--- a/assets/css/tailwind.css
+++ b/assets/css/tailwind.css
@@ -496,28 +496,52 @@
/* Status Messages */
.status-message {
- @apply flex items-center gap-4;
+ @apply flex items-center gap-3;
+ padding: 0.75rem 1rem;
+ border-radius: 0.5rem;
+ background-color: rgba(255, 255, 255, 0.15); /* White with 15% opacity */
+ color: #ffffff; /* White text */
+ font-size: 0.875rem;
+ font-weight: 500;
}
.status-icon {
@apply flex items-center justify-center;
- @apply w-25 h-25 rounded-full;
- @apply text-6xl text-white;
- @apply animate-pulse;
+ @apply flex-shrink-0;
+ width: 1.5rem;
+ height: 1.5rem;
}
- @media (max-width: 480px) {
- .status-icon {
- @apply text-5xl;
- }
+ .status-success {
+ @apply border-l-4 border-success;
}
.status-success .status-icon {
- @apply bg-success;
+ @apply text-success;
+ }
+
+ .status-error {
+ @apply border-l-4 border-warning;
}
.status-error .status-icon {
- @apply bg-error;
+ @apply text-warning;
+ }
+
+ .status-warning {
+ @apply border-l-4 border-warning;
+ }
+
+ .status-warning .status-icon {
+ @apply text-warning;
+ }
+
+ .status-info {
+ @apply border-l-4 border-accent;
+ }
+
+ .status-info .status-icon {
+ @apply text-accent;
}
/* Progress Bar */
@@ -606,17 +630,20 @@
@apply outline-none ring-2 ring-accent;
}
- /* Form Error Message - High contrast for readability */
+ /* Form Error Message - High contrast with orange accent */
.form-error {
margin-top: 0.5rem;
font-size: 0.875rem;
font-weight: 500;
- padding: 0.5rem 0.75rem;
+ padding: 0.75rem 1rem;
border-radius: 0.5rem;
- border: 1px solid rgba(248, 113, 113, 0.4); /* red-400 with 40% opacity */
- background-color: rgba(239, 68, 68, 0.2); /* red-500 with 20% opacity */
- color: #fecaca; /* red-200 for better contrast */
+ border-left: 4px solid var(--color-warning); /* Orange left border for accessibility */
+ background-color: rgba(255, 255, 255, 0.15); /* White with 15% opacity */
+ color: #ffffff; /* White text */
transition: all 0.2s;
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
}
.form-checkbox {