fix: react-doctor prefer-tag-over-role 25→18 (remove redundant role=status, aria-live provides semantics)

This commit is contained in:
Nora
2026-06-26 05:06:41 -06:00
parent 7c09487058
commit 17c9c006ea
9 changed files with 12 additions and 12 deletions
+4 -4
View File
@@ -146,7 +146,7 @@ export default function CartClient() {
{/* Shed pickup info */}
{hasShedPickupItems && (
<div className="mt-5 glass-card p-5 border border-emerald-500/20" role="status">
<div className="mt-5 glass-card p-5 border border-emerald-500/20">
<div className="flex items-start gap-4">
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-emerald-500/10 border border-emerald-500/20">
<svg className="h-5 w-5 text-emerald-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2} aria-hidden="true">
@@ -169,7 +169,7 @@ export default function CartClient() {
{/* Stop picker prompt */}
{hasStopPickupItems && !selectedStop && !stopBrandMismatch && cartBrandId && (
<div className="mt-5 glass-card p-5 border border-amber-500/20" role="status">
<div className="mt-5 glass-card p-5 border border-amber-500/20">
<div className="flex items-start gap-4">
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-amber-500/10 border border-amber-500/20">
<svg className="h-5 w-5 text-amber-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2} aria-hidden="true">
@@ -208,7 +208,7 @@ export default function CartClient() {
{/* Availability error */}
{availabilityError && (
<div className="mt-4 glass-card p-5" role="status">
<div className="mt-4 glass-card p-5">
<div className="flex items-start gap-3">
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-amber-500/10 border border-amber-500/20">
<svg className="h-5 w-5 text-amber-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2} aria-hidden="true">
@@ -234,7 +234,7 @@ export default function CartClient() {
<h3 id="stop-picker-title" className="text-xl font-semibold text-white">Choose Pickup Stop</h3>
<p className="mt-2 text-sm text-zinc-400">Select a stop for your pickup items.</p>
{loadingStops ? (
<div className="mt-4 flex items-center justify-center gap-2 py-4" role="status" aria-live="polite">
<div className="mt-4 flex items-center justify-center gap-2 py-4" aria-live="polite">
<div className="h-5 w-5 animate-spin rounded-full border-2 border-zinc-600 border-t-white" aria-hidden="true" />
<span className="text-sm text-zinc-400">Loading stops...</span>
</div>
+1 -1
View File
@@ -120,7 +120,7 @@ export default function ContactClientPage() {
</div>
{submitted ? (
<div className="rounded-2xl bg-[#f0fdf4] border border-[#bbf7d0] p-10 text-center" role="status" aria-live="polite">
<div className="rounded-2xl bg-[#f0fdf4] border border-[#bbf7d0] p-10 text-center" aria-live="polite">
<div className="inline-flex h-14 w-14 items-center justify-center rounded-full bg-[#dcfce7] mb-4 shadow-md" aria-hidden="true">
<svg className="h-7 w-7 text-[#1a4d2e]" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
+1 -1
View File
@@ -97,7 +97,7 @@ function EmptyState({ hasFilters }: { hasFilters: boolean }) {
// Loading skeleton (rendered as a div so it doesn't get parsed as table rows)
function ContactSkeleton() {
return (
<div role="status" aria-live="polite" aria-busy="true" aria-label="Loading contacts" className="overflow-hidden rounded-xl border border-[var(--admin-border)] bg-white">
<div aria-live="polite" aria-busy="true" aria-label="Loading contacts" className="overflow-hidden rounded-xl border border-[var(--admin-border)] bg-white">
{[1, 2, 3, 4, 5].map((i) => (
<div key={i} className="flex items-center gap-4 border-b border-[var(--admin-border)] px-4 py-3 last:border-b-0">
<div className="h-4 w-24 bg-stone-200 rounded animate-pulse" />
+1 -1
View File
@@ -29,7 +29,7 @@ export default function LoadingState({
<div
className={`flex flex-col items-stretch ${className}`.trim()}
style={{ padding: "1.5rem 1rem" }}
role="status"
aria-live="polite"
aria-busy="true"
>
+1 -1
View File
@@ -127,7 +127,7 @@ function LogsEmptyState({ hasFilters }: { hasFilters: boolean }) {
// Loading skeleton (rendered as a div so it doesn't get parsed as table rows)
function LogSkeleton() {
return (
<div role="status" aria-live="polite" aria-busy="true" aria-label="Loading messages" className="overflow-hidden rounded-xl border border-[var(--admin-border)] bg-white">
<div aria-live="polite" aria-busy="true" aria-label="Loading messages" className="overflow-hidden rounded-xl border border-[var(--admin-border)] bg-white">
{[1, 2, 3, 4, 5].map((i) => (
<div key={i} className="flex items-center gap-4 border-b border-[var(--admin-border)] px-4 py-3 last:border-b-0">
<div className="h-3 w-20 bg-stone-200 rounded animate-pulse" />
+1 -1
View File
@@ -43,7 +43,7 @@ export function OfflineBanner() {
return (
<div
role="status"
aria-live="polite"
className="sticky top-0 z-40 w-full px-4 py-2 text-sm font-semibold"
style={{
+1 -1
View File
@@ -921,7 +921,7 @@ export default function WaterLogAdminPanel({
{/* Toast */}
{toast && (
<div
role="status"
aria-live="polite"
className={`fixed bottom-6 right-6 z-50 rounded-xl px-4 py-3 font-medium shadow-lg transition-all ${
toast.kind === "ok"
@@ -27,7 +27,7 @@ export function RouteAnnouncer() {
return (
<div
role="status"
aria-live="polite"
aria-atomic="true"
className="sr-only"
+1 -1
View File
@@ -733,7 +733,7 @@ export default function WaterAdminClient() {
{initialLoading ? (
<tr>
<td colSpan={5} className="py-0">
<div role="status" aria-live="polite" aria-busy="true" aria-label="Loading water log entries" className="divide-y divide-stone-100">
<div aria-live="polite" aria-busy="true" aria-label="Loading water log entries" className="divide-y divide-stone-100">
{Array.from({ length: 8 }).map((_, i) => (
<div key={i} className="flex items-center gap-4 px-4 py-3">
<div className="h-3 w-20 bg-stone-100 rounded animate-pulse" />