--- name: polish-forms description: Improve form validation across Archipelago UI with real-time feedback, input sanitization, disabled states during submission, and consistent error messaging. Use when user says "polish forms", "form validation", "input validation", or "fix forms". --- # Skill: Polish Form Validation Improve all form inputs to have real-time validation feedback, proper trimming, disabled states during submission, and consistent error messaging. ## Forms to Polish ### 1. Login.vue — Password Setup - Real-time validation as user types (debounced 300ms): - Length >= 8 chars (show checkmark/X) - Passwords match (show match indicator) - Trim input on submit - Disable submit button while `isSubmitting` - Clear error on new input ### 2. Login.vue — TOTP Verification - `inputmode="numeric"` + `pattern="[0-9]*"` - Auto-submit when 6 digits entered - Show session timeout countdown if applicable - Trim and strip non-numeric characters on paste ### 3. Settings.vue — Password Change - Real-time strength validation: - 12+ characters - Has uppercase, lowercase, digit, special char - New password matches confirmation - Show strength meter (weak/medium/strong) - Disable button during submission - Show spinner in button during async operation ### 4. Any other form inputs found across views ## Validation Pattern ```typescript const password = ref('') const confirmPassword = ref('') const isSubmitting = ref(false) const passwordErrors = computed(() => { const errors: string[] = [] if (password.value.length > 0 && password.value.length < 8) errors.push('Must be at least 8 characters') return errors }) const passwordsMatch = computed(() => confirmPassword.value.length > 0 && password.value === confirmPassword.value ) async function submit() { if (isSubmitting.value) return isSubmitting.value = true try { await rpcClient.call(...) } catch (err) { errorMessage.value = formatError(err) } finally { isSubmitting.value = false } } ``` ## Template Pattern ```vue