fix(a11y): radiogroup semantics for AdminPromoOfferSend button groups

Wrap template-selection and send-mode button groups in role=radiogroup +
aria-labelledby; mark each option button as role=radio with aria-checked
(WCAG 4.1.2). Labels get matching id for the labelledby relationship.
This commit is contained in:
c0mrade
2026-05-26 11:28:37 +03:00
parent 8d6baf8ad0
commit 581a2ffb52

View File

@@ -300,14 +300,17 @@ export default function AdminPromoOfferSend() {
<div className="mx-auto max-w-2xl space-y-6"> <div className="mx-auto max-w-2xl space-y-6">
{/* Template Selection */} {/* Template Selection */}
<div className="rounded-xl border border-dark-700 bg-dark-800 p-6"> <div className="rounded-xl border border-dark-700 bg-dark-800 p-6">
<label className="mb-2 block text-sm font-medium text-dark-300"> <label id="po-template-label" className="mb-2 block text-sm font-medium text-dark-300">
{t('admin.promoOffers.send.offerTemplate')} {t('admin.promoOffers.send.offerTemplate')}
<span className="text-error-400">*</span> <span className="text-error-400">*</span>
</label> </label>
<div className="space-y-2"> <div className="space-y-2" role="radiogroup" aria-labelledby="po-template-label">
{activeTemplates.map((template) => ( {activeTemplates.map((template) => (
<button <button
key={template.id} key={template.id}
type="button"
role="radio"
aria-checked={selectedTemplateId === template.id}
onClick={() => setSelectedTemplateId(template.id)} onClick={() => setSelectedTemplateId(template.id)}
className={`w-full rounded-lg border p-4 text-left transition-colors ${ className={`w-full rounded-lg border p-4 text-left transition-colors ${
selectedTemplateId === template.id selectedTemplateId === template.id
@@ -345,12 +348,15 @@ export default function AdminPromoOfferSend() {
{/* Send Mode */} {/* Send Mode */}
<div className="rounded-xl border border-dark-700 bg-dark-800 p-6"> <div className="rounded-xl border border-dark-700 bg-dark-800 p-6">
<label className="mb-2 block text-sm font-medium text-dark-300"> <label id="po-sendmode-label" className="mb-2 block text-sm font-medium text-dark-300">
{t('admin.promoOffers.send.sendTo')} {t('admin.promoOffers.send.sendTo')}
<span className="text-error-400">*</span> <span className="text-error-400">*</span>
</label> </label>
<div className="mb-4 flex gap-2"> <div className="mb-4 flex gap-2" role="radiogroup" aria-labelledby="po-sendmode-label">
<button <button
type="button"
role="radio"
aria-checked={sendMode === 'segment'}
onClick={() => setSendMode('segment')} onClick={() => setSendMode('segment')}
className={`flex flex-1 items-center justify-center gap-2 rounded-lg border py-2.5 text-sm font-medium transition-colors ${ className={`flex flex-1 items-center justify-center gap-2 rounded-lg border py-2.5 text-sm font-medium transition-colors ${
sendMode === 'segment' sendMode === 'segment'
@@ -362,6 +368,9 @@ export default function AdminPromoOfferSend() {
<span>{t('admin.promoOffers.send.segment')}</span> <span>{t('admin.promoOffers.send.segment')}</span>
</button> </button>
<button <button
type="button"
role="radio"
aria-checked={sendMode === 'user'}
onClick={() => setSendMode('user')} onClick={() => setSendMode('user')}
className={`flex flex-1 items-center justify-center gap-2 rounded-lg border py-2.5 text-sm font-medium transition-colors ${ className={`flex flex-1 items-center justify-center gap-2 rounded-lg border py-2.5 text-sm font-medium transition-colors ${
sendMode === 'user' sendMode === 'user'