Skip to content

Commit

Permalink
Enchantment Dark Mode Toggle shows a popup (#735)
Browse files Browse the repository at this point in the history
* Refactor DarkModeToggle component to include a
theme selection dropdown

* Refactor DarkModeToggle component to include a
theme selection dropdown

Fix dark mode toggle icon rendering issue
  • Loading branch information
JeelRajodiya authored Jul 16, 2024
1 parent eda0dcf commit a842501
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 44 deletions.
117 changes: 89 additions & 28 deletions components/DarkModeToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,100 @@ import { useTheme } from 'next-themes';
import { useEffect, useState } from 'react';
import React from 'react';

export default function DarkModeToggle() {
const { theme, setTheme } = useTheme();
const [isDarkMode, setIsDarkMode] = useState(theme === 'dark');
const [isClickable, setIsClickable] = useState(true);
const [img, setImg] = useState('/icons/moon.svg');

const toggleDarkMode = () => {
if (!isClickable) return;

setIsClickable(false);
const newTheme = isDarkMode ? 'light' : 'dark';
setTheme(newTheme);
setIsDarkMode(!isDarkMode);
function ListItem({
children,
onClick,
}: {
children: React.ReactNode;
onClick: () => void;
}) {
return (
<div
onClick={onClick}
className='p-2 hover:bg-gray-200 dark:hover:bg-gray-700 cursor-pointer rounded-md transition duration-150 flex row gap-2 w-full text-sm'
>
{children}
</div>
);
}

setTimeout(() => {
setIsClickable(true);
}, 500);
};
export default function DarkModeToggle() {
const { theme, setTheme, resolvedTheme } = useTheme();
const [isDarkMode, setIsDarkMode] = useState(false);

useEffect(() => {
if (!theme) setTheme('light');
setIsDarkMode(resolvedTheme === 'dark');
}, [resolvedTheme]);

const img = theme === 'dark' ? '/icons/sun.svg' : '/icons/moon.svg';
setImg(img);
}, [theme, setTheme]);
const [showSelect, setShowSelect] = useState(false);
const [activeThemeIcon, setActiveThemeIcon] = useState('');
useEffect(() => {
switch (theme) {
case 'system':
return setActiveThemeIcon('/icons/theme-switch.svg');
case 'light':
return setActiveThemeIcon('/icons/sun.svg');
case 'dark':
return setActiveThemeIcon('/icons/moon.svg');
}
}, [theme, resolvedTheme]);

return (
<button
onClick={toggleDarkMode}
className='dark-mode-toggle rounded-md dark:hover:bg-gray-700 p-1.5 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none transition duration-150'
disabled={!isClickable}
>
<img src={img} alt='Dark Mode' width={25} height={25} />
</button>
<div className='relative w-10 h-10 dark-mode-toggle-container'>
<button
onClick={() => setShowSelect(!showSelect)}
className='dark-mode-toggle rounded-md dark:hover:bg-gray-700 p-1.5 hover:bg-gray-100 transition duration-150 '
>
<img
src={activeThemeIcon}
alt='Dark Mode'
width={25}
height={25}
style={{
// Invert the icon color based on the theme, theme of the light mode is dark
filter: isDarkMode ? 'invert(1)' : 'invert(0)',
}}
/>
</button>
<div
className='absolute right-0 p-2 bg-white dark:bg-gray-800 rounded-lg border dark:border-gray-700 z-10 w-max'
style={{ display: showSelect ? 'block' : 'none' }}
onMouseLeave={() => {
setShowSelect(false);
}}
tabIndex={0}
>
<ListItem onClick={() => setTheme('system')}>
<img
src={'/icons/theme-switch.svg'}
alt='System theme'
width={18}
height={18}
style={{ filter: isDarkMode ? 'invert(1)' : 'invert(0)' }}
/>
System
</ListItem>
<ListItem onClick={() => setTheme('light')}>
<img
src={'/icons/sun.svg'}
alt='System theme'
width={18}
height={18}
style={{ filter: isDarkMode ? 'invert(1)' : 'invert(0)' }}
/>
Light
</ListItem>
<ListItem onClick={() => setTheme('dark')}>
<img
src={'/icons/moon.svg'}
alt='System theme'
width={18}
height={18}
style={{ filter: isDarkMode ? 'invert(1)' : 'invert(0)' }}
/>
Dark
</ListItem>
</div>
</div>
);
}
21 changes: 12 additions & 9 deletions components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,26 +164,29 @@ const MainNavigation = () => {
const section = useContext(SectionContext);
const showMobileNav = useStore((s: any) => s.overlayNavigation === 'docs');

const { theme } = useTheme();
const { resolvedTheme, theme } = useTheme();
const [icon, setIcon] = useState('');
const [menu, setMenu] = useState('bg-black');
const [closeMenu, setCLoseMenu] = useState('url("/icons/cancel.svg")');

useEffect(() => {
const icon = theme === 'dark' ? 'herobtn' : '';
const menu = theme === 'dark' ? 'bg-white' : 'bg-black';
const dataTheme = theme === 'dark' ? 'dark' : 'light';
const menu = resolvedTheme === 'dark' ? 'bg-white' : 'bg-black';
const dataTheme = resolvedTheme === 'dark' ? 'dark' : 'light';
const closeMenu =
theme === 'dark'
resolvedTheme === 'dark'
? 'url("/icons/cancel-dark.svg")'
: 'url("/icons/cancel.svg")';
document.documentElement.setAttribute('data-theme', dataTheme);
document.documentElement.setAttribute('class', 'keygrad keyshadow');
document.documentElement.setAttribute(
'class',
`keygrad keyshadow ${dataTheme}`,
);

setIcon(icon);
setMenu(menu);
setCLoseMenu(closeMenu);
}, [theme]);
}, [theme, resolvedTheme]);

return (
<div className='flex justify-end md:mr-8 w-full '>
Expand Down Expand Up @@ -402,16 +405,16 @@ const Footer = () => (
);

const Logo = () => {
const { theme } = useTheme();
const { resolvedTheme } = useTheme();
const [imageSrc, setImageSrc] = useState('/img/logos/logo-blue.svg'); // Default to match the server-side render

useEffect(() => {
const src =
theme === 'dark'
resolvedTheme === 'dark'
? '/img/logos/logo-white.svg'
: '/img/logos/logo-blue.svg';
setImageSrc(src);
}, [theme]);
}, [resolvedTheme]);

return (
<div>
Expand Down
6 changes: 3 additions & 3 deletions components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -281,15 +281,15 @@ export const DocsNav = ({
const rotateR = active.getReference ? 'rotate(180deg)' : 'rotate(0)';
const rotateSpec = active.getSpecification ? 'rotate(180deg)' : 'rotate(0)';

const { theme } = useTheme();
const { resolvedTheme } = useTheme();

const [learn_icon, setLearn_icon] = useState('');
const [reference_icon, setReference_icon] = useState('');
const [spec_icon, setSpec_icon] = useState('');
const [overview_icon, setOverview_icon] = useState('');

useEffect(() => {
if (theme === 'dark') {
if (resolvedTheme === 'dark') {
setOverview_icon('/icons/eye-dark.svg');
setLearn_icon('/icons/compass-dark.svg');
setReference_icon('/icons/book-dark.svg');
Expand All @@ -300,7 +300,7 @@ export const DocsNav = ({
setReference_icon('/icons/book.svg');
setSpec_icon('/icons/clipboard.svg');
}
}, [theme]);
}, [resolvedTheme]);

return (
<div id='sidebar' className='lg:mt-8 w-4/5 mx-auto lg:ml-4'>
Expand Down
6 changes: 3 additions & 3 deletions pages/index.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ export function AlgoliaSearch() {
const Home = (props: any) => {
const blogPosts = props.blogPosts;
const timeToRead = Math.ceil(readingTime(blogPosts[0].content).minutes);
const { theme } = useTheme();
const { resolvedTheme } = useTheme();

const [asyncapi_logo, setAsyncapi_logo] = useState('');
const [vpsserver_logo, setVPSserver_logo] = useState('');
Expand All @@ -207,7 +207,7 @@ const Home = (props: any) => {
const [slack_logo, setSlack_logo] = useState('');

useEffect(() => {
if (theme === 'dark') {
if (resolvedTheme === 'dark') {
setAsyncapi_logo('/img/logos/dark-mode/asyncapi_white.svg');
setAirbnb_logo('/img/logos/dark-mode/airbnb_white.png');
setPostman_logo('/img/logos/usedby/postman-white.png');
Expand All @@ -228,7 +228,7 @@ const Home = (props: any) => {
setVPSserver_logo('/img/logos/sponsors/vps-server-logo.svg');
setItflashcards_logo('/img/logos/sponsors/it_flashcards.svg');
}
}, [theme]);
}, [resolvedTheme]);
return (
<div>
<div className='flex flex-col items-center'>
Expand Down
2 changes: 1 addition & 1 deletion public/icons/sun.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/icons/theme-switch.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit a842501

Please sign in to comment.