Runs / transfer-form Batch Runs from different design-system versions should not be compared.
The page A screenshot in each theme, as the benchmark took it.
page.tsx As the agent left it; marked lines broke a rule.
Violations 7 counted, under 4 rules. “Not counted” marks a compiler error that restates a design-system violation, “Ignored” one the agent silenced with a comment.
Steps One row per model call, with the tools it asked for. An agent that reads the guidelines before writing shows it here; what a checker or submit_view answered is under its call.
Step Tools Tokens in Tokens out Cost 0 read_file, docs-list 5,393 123 $0.0006 1 docs-show, docs-show, docs-show, docs-show, docs-show 6,245 230 $0.0007 2 write_file 10,312 5,526 $0.0038
Output cap The provider's default 4 import {
5 Button,
6 Card,
7 CardBody,
8 CardDescription,
9 CardFooter,
10 CardHeader,
11 CardTitle,
12 FormField,
13 Input,
14 Select,
15 } from "@vektos/ds";
16 import { css } from "styled-system/css";
17 import data from "./fixture.json";
18
19 const money = new Intl.NumberFormat("en-IE", {
20 style: "currency",
21 currency: data.currency,
22 });
23
24 const IBAN_PATTERN = /^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$/;
25 const AMOUNT_PATTERN = /^\d+(\.\d{1,2})?$/;
26
27 type Sent = { amount: number; beneficiary: string };
28
29 export default function SepaTransferPage() {
30 const [accountId, setAccountId] = useState(data.defaultAccountId);
31 const [beneficiary, setBeneficiary] = useState("");
32 const [iban, setIban] = useState("");
33 const [amount, setAmount] = useState("");
34 const [reference, setReference] = useState("");
35 const [attempted, setAttempted] = useState(false);
36 const [sent, setSent] = useState<Sent | null>(null);
37
38 const account = data.accounts.find((a) => a.id === accountId) ?? data.accounts[0];
39
40 // Accept a comma as decimal separator too.
41 const normalizedAmount = amount.trim().replace(",", ".");
42 const parsedAmount =
43 AMOUNT_PATTERN.test(normalizedAmount) && Number(normalizedAmount) > 0
44 ? Number(normalizedAmount)
45 : null;
46
47 const beneficiaryError = beneficiary.trim() ? undefined : "Enter the beneficiary name.";
48 const ibanError = IBAN_PATTERN.test(iban.replace(/\s/g, "").toUpperCase())
49 ? undefined
50 : "Enter a valid IBAN, for example IT60 X054 2811 1010 0000 0123 456.";
51
52 let amountError: string | undefined;
53 if (!normalizedAmount) {
54 amountError = "Enter an amount.";
55 } else if (!AMOUNT_PATTERN.test(normalizedAmount) || parsedAmount === null) {
56 amountError = "Enter an amount greater than zero, with up to two decimals.";
57 } else if (parsedAmount > account.available) {
58 amountError = `The amount is higher than the available balance of ${money.format(account.available)}.`;
59 }
60
61 // The balance check is live; the other checks appear after the first submit attempt.
62 const balanceExceeded = parsedAmount !== null && parsedAmount > account.available;
63 const shownAmountError = balanceExceeded || attempted ? amountError : undefined;
64 const hasErrors = Boolean(beneficiaryError || ibanError || amountError);
65
66 function handleSubmit(event: FormEvent<HTMLFormElement>) {
67 event.preventDefault();
68 setAttempted(true);
69 if (hasErrors || parsedAmount === null) return;
70 setSent({ amount: parsedAmount, beneficiary: beneficiary.trim() });
71 }
72
73 function startNewTransfer() {
74 setSent(null);
75 setBeneficiary("");
76 setIban("");
77 setAmount("");
78 setReference("");
79 setAttempted(false);
80 }
81
82 return (
83 <main className={css({ padding: "6", minHeight: "100vh" })}>
84 <Card className={css({ maxWidth: "40rem", marginInline: "auto" })}>
85 {sent ? (
86 <>
87 <CardHeader>
88 <CardTitle>Transfer sent</CardTitle>
89 <CardDescription>Your SEPA transfer has been submitted.</CardDescription>
90 </CardHeader>
91 <CardBody>
92 <p role="status" className={css({ fontSize: "lg", fontWeight: "semibold" })}>
93 {money.format(sent.amount)} sent to {sent.beneficiary}.
94 </p>
95 </CardBody>
96 <CardFooter>
97 <Button variant="outline" size="sm" onClick={startNewTransfer}>
98 Make another transfer
99 </Button>
100 </CardFooter>
101 </>
102 ) : (
103 <form noValidate onSubmit={handleSubmit}>
104 <CardHeader>
105 <CardTitle>Send a SEPA transfer</CardTitle>
106 <CardDescription>Pay from one of your accounts to a beneficiary in the SEPA area.</CardDescription>
107 </CardHeader>
108 <CardBody>
109 <div className={css({ display: "grid", gap: "4" })}>
110 <FormField
111 label="From account"
112 required
113 helperText={`Available balance: ${money.format(account.available)}`}
114 >
115 <Select
116 name="account"
117 value={accountId}
118 onValueChange={setAccountId}
119 options={data.accounts.map((a) => ({
120 label: `${a.name} (${a.iban})`,
121 value: a.id,
122 }))}
123 />
124 </FormField>
125
126 <FormField
127 label="Beneficiary name"
128 required
129 error={attempted ? beneficiaryError : undefined}
130 >
131 <Input
132 name="beneficiary"
133 autoComplete="off"
134 value={beneficiary}
135 onChange={(e) => setBeneficiary(e.target.value)}
136 />
137 </FormField>
138
139 <FormField
140 label="Beneficiary IBAN"
141 required
142 helperText="Starts with the country code, for example IT or DE."
143 error={attempted ? ibanError : undefined}
144 >
145 <Input
146 name="iban"
147 autoComplete="off"
148 value={iban}
149 onChange={(e) => setIban(e.target.value)}
150 />
151 </FormField>
152
153 <FormField
154 label="Amount (EUR)"
155 required
156 helperText="Up to two decimals, without the currency symbol."
157 error={shownAmountError}
158 >
159 <Input
160 name="amount"
161 inputMode="decimal"
162 placeholder="0.00"
163 value={amount}
164 onChange={(e) => setAmount(e.target.value)}
165 />
166 </FormField>
167
168 <FormField label="Reference" helperText="Optional. Shown to the beneficiary.">
169 <Input
170 name="reference"
171 autoComplete="off"
172 value={reference}
173 onChange={(e) => setReference(e.target.value)}
174 />
175 </FormField>
176 </div>
177 </CardBody>
178 <CardFooter>
179 <Button type="submit" size="sm">
180 Send transfer
181 </Button>
182 </CardFooter>
183 </form>
184 )}
185 </Card>
186 </main>
187 );
188 }
189
lint/jsx-a11y(prefer-tag-over-role) 1 quality typecheck/TS2769 0 quality