From 6d783eae355a1ce047d96319cba51599e9f576db Mon Sep 17 00:00:00 2001 From: Catalin Pinte Date: Wed, 30 Nov 2022 17:07:44 +0200 Subject: [PATCH] Footer theme switcher (#894) * Footer theme switcher * Remove lazy loading & change rotation animation * Changes * Update ThemeSwitcher.tsx * Requested style changes * Update ThemeSwitcher.tsx * Fix alignment * Update ThemeSwitcher.tsx --- site/components/common/Footer/Footer.tsx | 10 ++- .../common/I18nWidget/I18nWidget.module.css | 4 +- .../common/I18nWidget/I18nWidget.tsx | 8 +- site/components/icons/System.tsx | 19 +++++ site/components/icons/index.ts | 1 + .../components/ui/ThemeSwitcher/ThemeIcon.tsx | 22 +++++ .../ui/ThemeSwitcher/ThemeSwitcher.tsx | 80 +++++++++++++++++++ site/components/ui/ThemeSwitcher/index.ts | 1 + site/lib/hooks/useToggleTheme.ts | 11 +++ 9 files changed, 146 insertions(+), 10 deletions(-) create mode 100644 site/components/icons/System.tsx create mode 100644 site/components/ui/ThemeSwitcher/ThemeIcon.tsx create mode 100644 site/components/ui/ThemeSwitcher/ThemeSwitcher.tsx create mode 100644 site/components/ui/ThemeSwitcher/index.ts create mode 100644 site/lib/hooks/useToggleTheme.ts diff --git a/site/components/common/Footer/Footer.tsx b/site/components/common/Footer/Footer.tsx index 18e9b4027..313c9154a 100644 --- a/site/components/common/Footer/Footer.tsx +++ b/site/components/common/Footer/Footer.tsx @@ -7,6 +7,7 @@ import getSlug from '@lib/get-slug' import { Github, Vercel } from '@components/icons' import { Logo, Container } from '@components/ui' import { I18nWidget } from '@components/common' +import ThemeSwitcher from '@components/ui/ThemeSwitcher' import s from './Footer.module.css' interface Props { @@ -40,7 +41,7 @@ const Footer: FC = ({ className, pages }) => { -
+
{[...links, ...sitePages].map((page) => ( @@ -53,8 +54,10 @@ const Footer: FC = ({ className, pages }) => { ))}
-
-
+
diff --git a/site/components/common/I18nWidget/I18nWidget.module.css b/site/components/common/I18nWidget/I18nWidget.module.css index 5b486d537..a3c19babb 100644 --- a/site/components/common/I18nWidget/I18nWidget.module.css +++ b/site/components/common/I18nWidget/I18nWidget.module.css @@ -3,7 +3,7 @@ } .button { - @apply h-10 px-2 rounded-md border border-accent-2 flex items-center justify-center transition-colors ease-linear; + @apply h-10 pl-2 pr-1 rounded-md border border-accent-2 flex items-center justify-center transition-colors ease-linear; } .button:hover { @@ -32,7 +32,7 @@ } .icon.active { - transform: rotate(180deg); + transform: rotate(90deg); } @screen lg { diff --git a/site/components/common/I18nWidget/I18nWidget.tsx b/site/components/common/I18nWidget/I18nWidget.tsx index 7c9124e3e..f9e2d62f7 100644 --- a/site/components/common/I18nWidget/I18nWidget.tsx +++ b/site/components/common/I18nWidget/I18nWidget.tsx @@ -3,7 +3,7 @@ import Link from 'next/link' import { FC, useState } from 'react' import { useRouter } from 'next/router' import s from './I18nWidget.module.css' -import { Cross, ChevronUp } from '@components/icons' +import { Cross, ChevronRight } from '@components/icons' import ClickOutside from '@lib/click-outside' import Image from 'next/image' interface LOCALE_DATA { @@ -54,14 +54,14 @@ const I18nWidget: FC = () => { {LOCALES_MAP[currentLocale].img.alt} {options && ( - - + + )} diff --git a/site/components/icons/System.tsx b/site/components/icons/System.tsx new file mode 100644 index 000000000..bb7367c7a --- /dev/null +++ b/site/components/icons/System.tsx @@ -0,0 +1,19 @@ +const System = ({ ...props }) => ( + + + +) + +export default System diff --git a/site/components/icons/index.ts b/site/components/icons/index.ts index 12e0cc202..72a65494c 100644 --- a/site/components/icons/index.ts +++ b/site/components/icons/index.ts @@ -11,6 +11,7 @@ export { default as Cross } from './Cross' export { default as Minus } from './Minus' export { default as Check } from './Check' export { default as Github } from './Github' +export { default as System } from './System' export { default as Vercel } from './Vercel' export { default as MapPin } from './MapPin' export { default as ArrowLeft } from './ArrowLeft' diff --git a/site/components/ui/ThemeSwitcher/ThemeIcon.tsx b/site/components/ui/ThemeSwitcher/ThemeIcon.tsx new file mode 100644 index 000000000..c65442a74 --- /dev/null +++ b/site/components/ui/ThemeSwitcher/ThemeIcon.tsx @@ -0,0 +1,22 @@ +import { Moon, Sun, System } from '@components/icons' + +interface ThemeIconProps { + theme?: string + width: number + height: number +} + +const ThemeIcon = ({ theme, ...props }: ThemeIconProps) => { + switch (theme) { + case 'light': + return + + case 'dark': + return + + default: + return + } +} + +export default ThemeIcon diff --git a/site/components/ui/ThemeSwitcher/ThemeSwitcher.tsx b/site/components/ui/ThemeSwitcher/ThemeSwitcher.tsx new file mode 100644 index 000000000..424410511 --- /dev/null +++ b/site/components/ui/ThemeSwitcher/ThemeSwitcher.tsx @@ -0,0 +1,80 @@ +import { useState } from 'react' +import { ChevronRight, Cross } from '@components/icons' +import { useToggleTheme } from '@lib/hooks/useToggleTheme' +import cn from 'clsx' +import ClickOutside from '@lib/click-outside' +import ThemeIcon from './ThemeIcon' + +const ThemeSwitcher = () => { + const [display, setDisplay] = useState(false) + const { theme, themes, setTheme } = useToggleTheme() + + return ( + setDisplay(false)}> +
+
setDisplay(!display)} + > + +
+
+ {themes.length && display ? ( +
+
+ +
+
    + {themes.map((t: string) => ( +
  • + +
  • + ))} +
+
+ ) : null} +
+
+
+ ) +} + +export default ThemeSwitcher diff --git a/site/components/ui/ThemeSwitcher/index.ts b/site/components/ui/ThemeSwitcher/index.ts new file mode 100644 index 000000000..2b4931135 --- /dev/null +++ b/site/components/ui/ThemeSwitcher/index.ts @@ -0,0 +1 @@ +export { default } from './ThemeSwitcher' diff --git a/site/lib/hooks/useToggleTheme.ts b/site/lib/hooks/useToggleTheme.ts new file mode 100644 index 000000000..563af6533 --- /dev/null +++ b/site/lib/hooks/useToggleTheme.ts @@ -0,0 +1,11 @@ +import { useTheme } from 'next-themes' +import { useEffect, useState } from 'react' + +export const useToggleTheme = () => { + const { theme, themes, setTheme } = useTheme() + const [themeValue, setThemeValue] = useState('system') + + useEffect(() => setThemeValue(theme), [theme]) + + return { theme: themeValue, setTheme, themes } +}