From f28558a4335f474473110e457c3120807479ba1a Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Sat, 23 May 2026 14:58:39 +0100 Subject: [PATCH] fix(contribution): sanitize amount input and a11y polish --- app/components/ContributionAmountField.vue | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/components/ContributionAmountField.vue b/app/components/ContributionAmountField.vue index 64485d6..2f564f1 100644 --- a/app/components/ContributionAmountField.vue +++ b/app/components/ContributionAmountField.vue @@ -58,6 +58,7 @@ type="button" class="contribution-preset-chip" :class="{ active: numericAmount === preset.amount }" + :aria-pressed="numericAmount === preset.amount" @click="selectPreset(preset.amount)" > ${{ preset.amount }} @@ -97,7 +98,11 @@ import { const props = defineProps({ modelValue: { type: Number, required: true }, - cadence: { type: String, required: true }, + cadence: { + type: String, + required: true, + validator: (v) => v === 'monthly' || v === 'annual', + }, allowCadenceChange: { type: Boolean, default: true }, showSummary: { type: Boolean, default: true }, summaryNote: { type: String, default: '' }, @@ -134,15 +139,14 @@ const onAmountInput = (event) => { return } const n = Number(raw) - emit('update:modelValue', Number.isFinite(n) ? n : 0) + const sanitized = Number.isFinite(n) ? Math.max(0, Math.trunc(n)) : 0 + emit('update:modelValue', sanitized) } const selectPreset = (amount) => { emit('update:modelValue', amount) } -// Annual→monthly snap: floor(annual/12)*12 keeps the amount cleanly divisible -// before we divide, so toggling cadences never leaves fractional dollars. const onCadenceChange = (newCadence) => { if (newCadence === props.cadence) return const current = numericAmount.value