Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/components/WritingPad.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -441,35 +441,40 @@ const WritingPad = () => {
{/* Tools */}
<div className="px-4 mt-4 space-y-3">
{/* Color picker */}
<div className="flex items-center justify-center gap-2">
<div className="flex items-center justify-center gap-2" role="group" aria-label="Stroke color">
{STROKE_COLORS.map(color => (
<button
key={color.value}
onClick={() => setStrokeColor(color.value)}
className={`w-8 h-8 rounded-full border-2 transition-transform ${strokeColor === color.value
className={`w-8 h-8 rounded-full border-2 transition-transform focus-visible:ring-2 focus-visible:ring-purple-400 focus-visible:outline-none ${strokeColor === color.value

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

# First, verify the code exists and check lines 449 and 467
if [ -f "src/components/WritingPad.jsx" ]; then
  echo "=== Lines around 449 ==="
  sed -n '445,453p' src/components/WritingPad.jsx
  echo ""
  echo "=== Lines around 467 ==="
  sed -n '463,471p' src/components/WritingPad.jsx
else
  echo "File not found"
fi

Repository: RileyTheRiler/French-Game

Length of output: 1389


🌐 Web query:

Tailwind CSS v4 outline-none vs outline-hidden forced-colors HCM

💡 Result:

In Tailwind CSS v4, the key difference is how the utilities behave under forced colors mode (CSS @media (forced-colors: active)). 1) outline-hidden - Tailwind docs describe it as “hide the default browser outline on focused elements, while still preserving the outline in forced colors mode” [1]. - Mechanically, it makes the outline style effectively “hidden” by default in normal rendering, but in forced-colors it still allows focus indication instead of fully removing it (Tailwind’s docs and the original PR explain this accessibility goal) [1][2]. 2) outline-none - In v4, Tailwind has a simplified outline-none which sets outline-style: none (i.e., it truly removes the outline style, rather than leaving an invisible outline that could appear in forced colors) [2][3]. - Consequently, outline-none will remove the default outline even in forced colors scenarios where you’d otherwise want the browser to still indicate focus [1][2]. Practical takeaway for “HCM” (high contrast / forced colors): - Prefer outline-hidden when you want to suppress the default focus outline for most users but still retain focus visibility for high-contrast / forced-colors users [1]. - Use outline-none only if you intentionally want to remove the outline entirely, knowing that forced-colors focus visibility may be impacted [2][3]. If you’re upgrading from Tailwind v3: - The Tailwind team renamed the old behavior by moving the v3-style “don’t fully remove outline; keep it for forced colors” into outline-hidden, and added a new outline-none that matches the intuitive “set outline-style: none” expectation [2][3].

Citations:


🌐 Web query:

Tailwind CSS v4 upgrade codemod outline-none outline-hidden

💡 Result:

Tailwind CSS v4 upgrade codemod: it should rename outline-none to outline-hidden. What the upgrade is supposed to do - Tailwind’s official upgrade guide says to replace any usage of outline-none with outline-hidden when migrating to v4 (including variants like focus:outline-nonefocus:outline-hidden) [1]. - The rationale is that outline-none previously didn’t actually set outline-style: none and instead produced an invisible outline to keep it visible in forced-colors mode for accessibility; Tailwind renamed it to outline-hidden and introduced a new outline-none that truly sets outline-style: none [1]. How the codemod behaves (evidence from implementation + community reports) - A Tailwind v3→v4 codemod repository documents the “Outline Migration” mapping across all variants, including outline-noneoutline-hidden and focus:outline-none/focus-visible:outline-none variants [2]. - Tailwind issue discussion confirms the intended behavior: the upgrade guidance maps to outline-hidden for accessibility in forced-colors mode, while outline-none exists in v4 to actually remove the outline (outline-style: none) [3]. - Some third-party codebases have observed cases where not all outline-none usages were migrated, indicating this rename is a common codemod expectation but can depend on how/what the upgrade tool scans and applies [4]. Recommended search/verification step in your codebase - After running the upgrade, verify whether any legacy utility remains: - grep for outline-none and ensure it’s been replaced with outline-hidden where appropriate [1]. How to run the official upgrade codemod (high level) - Tailwind’s v4 upgrade tool is provided as @tailwindcss/upgrade and is run via npx @tailwindcss/upgrade`` [5] / [6].

Citations:


Use focus-visible:outline-hidden instead of focus-visible:outline-none for Windows High Contrast Mode compatibility

In Tailwind CSS v4, outline-none sets outline-style: none and does not preserve the transparent outline that enables focus visibility under @media (forced-colors: active) (Windows High Contrast Mode). outline-hidden produces the same visual result in standard rendering but additionally preserves a visible outline in forced-colors mode. The official Tailwind v4 upgrade guide explicitly maps outline-noneoutline-hidden for this reason.

Since this PR specifically targets accessibility, this affects HCM users on both button groups.

♿ Proposed fix for both button groups
- className={`... focus-visible:ring-2 focus-visible:ring-purple-400 focus-visible:outline-none ...`}
+ className={`... focus-visible:ring-2 focus-visible:ring-purple-400 focus-visible:outline-hidden ...`}

Apply the same change to the stroke width buttons (line 467).

Also applies to: 467-467

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/WritingPad.jsx` at line 449, Replace the Tailwind utility
focus-visible:outline-none with focus-visible:outline-hidden in the button group
className strings inside the WritingPad component to preserve forced-colors
(Windows High Contrast Mode) focus outlines; specifically update the className
used for the stroke color buttons (the JSX element that builds the color
swatches where strokeColor === color.value is checked) and the stroke width
buttons (the similar JSX element around the stroke width controls) so both use
focus-visible:outline-hidden instead of focus-visible:outline-none.

? 'border-white scale-110'
: 'border-transparent hover:scale-105'
}`}
style={{ backgroundColor: color.value }}
title={color.name}
aria-label={`Select ${color.name} color`}
aria-pressed={strokeColor === color.value}
/>
))}
</div>

{/* Stroke width */}
<div className="flex items-center justify-center gap-3">
<div className="flex items-center justify-center gap-3" role="group" aria-label="Stroke width">
{STROKE_WIDTHS.map(width => (
<button
key={width}
onClick={() => setStrokeWidth(width)}
className={`flex items-center justify-center w-10 h-10 rounded-lg transition-colors ${strokeWidth === width
className={`flex items-center justify-center w-10 h-10 rounded-lg transition-colors focus-visible:ring-2 focus-visible:ring-purple-400 focus-visible:outline-none ${strokeWidth === width
? 'bg-purple-500'
: 'bg-slate-800 hover:bg-slate-700'
}`}
aria-label={`Set stroke width to ${width} pixels`}
aria-pressed={strokeWidth === width}
>
<div
className="bg-white rounded-full"
style={{ width: width * 2, height: width * 2 }}
aria-hidden="true"
/>
</button>
))}
Expand Down
Loading