Skip to content
Merged
Show file tree
Hide file tree
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
18 changes: 3 additions & 15 deletions src/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,9 @@ const Navbar: React.FC = () => {
aria-label="Toggle Theme"
>
{mode === "dark" ? (
<Sun
className={`h-5 w-5 text-yellow-400 transition-all duration-300 ${
isThemeToggling ? 'rotate-180 scale-0' : 'rotate-0 scale-100'
}`}
/>
<Sun key="sun-icon" className="theme-toggle-icon h-5 w-5 text-yellow-400" />
) : (
<Moon
className={`h-5 w-5 text-slate-700 transition-all duration-300 ${
isThemeToggling ? 'rotate-180 scale-0' : 'rotate-0 scale-100'
}`}
/>
<Moon key="moon-icon" className="theme-toggle-icon h-5 w-5 text-slate-700 dark:text-white" />
)}
</button>
</div>
Expand All @@ -116,11 +108,7 @@ const Navbar: React.FC = () => {
}`}
/>
) : (
<Moon
className={`h-5 w-5 text-white transition-all duration-300 ${
isThemeToggling ? 'rotate-180 scale-0' : 'rotate-0 scale-100'
}`}
/>
<Moon key="moon-icon-mobile" className="theme-toggle-icon h-5 w-5 text-slate-700 dark:text-white" />
)}
</button>

Expand Down
12 changes: 9 additions & 3 deletions src/context/ThemeContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,15 @@ const ThemeWrapper = ({ children }: { children: ReactNode }) => {
return () => clearTimeout(timer);
}, [mode]);

const toggleTheme = () => {
setMode((prevMode) => (prevMode === 'light' ? 'dark' : 'light'));
};
const toggleTheme = () => {
document.documentElement.classList.add("theme-transitioning");

window.setTimeout(() => {
document.documentElement.classList.remove("theme-transitioning");
}, 650);

setMode((prevMode) => (prevMode === "light" ? "dark" : "light"));
};
Comment thread
coderabbitai[bot] marked this conversation as resolved.

const muiTheme: Theme = useMemo(
() => createTheme({ palette: { mode } }),
Expand Down
34 changes: 34 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,37 @@
.icon-issue-closed {
color: #cf222e;
}

html.theme-transitioning,
html.theme-transitioning *,
html.theme-transitioning *::before,
html.theme-transitioning *::after {
transition-property: background-color, border-color, color, fill, stroke, box-shadow, opacity, transform;
transition-duration: 600ms;
transition-timing-function: ease-in-out;
}

@media (prefers-reduced-motion: reduce) {
html.theme-transitioning,
html.theme-transitioning *,
html.theme-transitioning *::before,
html.theme-transitioning *::after {
transition-duration: 0ms;
}
}
Comment on lines +102 to +109
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Disable icon keyframe animation for reduced-motion users.

The reduced-motion block only cancels transitions, but .theme-toggle-icon still runs theme-icon-pop (Line 124). That bypasses the accessibility preference.

💡 Suggested fix
 `@media` (prefers-reduced-motion: reduce) {
   html.theme-transitioning,
   html.theme-transitioning *,
   html.theme-transitioning *::before,
   html.theme-transitioning *::after {
     transition-duration: 0ms;
   }
+
+  .theme-toggle-icon {
+    animation: none !important;
+  }
 }

Also applies to: 123-125

🤖 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/index.css` around lines 102 - 109, The reduced-motion media rule only
sets transition-duration to 0ms but doesn't disable keyframe animations like
theme-icon-pop; update the prefers-reduced-motion block to also disable
animations by targeting .theme-toggle-icon (and its pseudo-elements if used) and
setting animation: none and animation-duration: 0ms so the theme-toggle-icon and
any theme-icon-pop keyframe animation are suppressed for users who prefer
reduced motion.


@keyframes theme-icon-pop {
0% {
opacity: 0;
transform: rotate(-90deg) scale(0.75);
}

100% {
opacity: 1;
transform: rotate(0deg) scale(1);
}
}

.theme-toggle-icon {
animation: theme-icon-pop 500ms ease-out;
}
Loading