diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-01-17 22:26:16 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-01-17 22:54:17 +0100 |
| commit | a6233863da4203bec781e817963ac3733279cab5 (patch) | |
| tree | b075753c4336b737d41c178451551c40c1016951 /src/components | |
| parent | 68138f0dcd8b3db2c23b31a20508726f245b5ba5 (diff) | |
refactor(settings): make toggle reusable
Toggle will be used for others settings so I extract the functionnality
from ThemeToggle.
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/Form/Form.module.scss | 8 | ||||
| -rw-r--r-- | src/components/Form/Toggle/Toggle.module.scss (renamed from src/components/ThemeToggle/ThemeToggle.module.scss) | 2 | ||||
| -rw-r--r-- | src/components/Form/Toggle/Toggle.tsx | 46 | ||||
| -rw-r--r-- | src/components/Form/index.tsx | 3 | ||||
| -rw-r--r-- | src/components/Settings/Settings.tsx | 2 | ||||
| -rw-r--r-- | src/components/Settings/ThemeToggle/ThemeToggle.tsx | 36 | ||||
| -rw-r--r-- | src/components/ThemeToggle/ThemeToggle.tsx | 45 |
7 files changed, 94 insertions, 48 deletions
diff --git a/src/components/Form/Form.module.scss b/src/components/Form/Form.module.scss index e464293..e805c52 100644 --- a/src/components/Form/Form.module.scss +++ b/src/components/Form/Form.module.scss @@ -4,9 +4,15 @@ width: 100%; &--search, - &--theme { + &--toggle { display: flex; flex-flow: row nowrap; + align-items: center; + } + + &--toggle { + position: relative; + margin: var(--spacing-sm) 0; } &--centered { diff --git a/src/components/ThemeToggle/ThemeToggle.module.scss b/src/components/Form/Toggle/Toggle.module.scss index 74fb542..e860b5e 100644 --- a/src/components/ThemeToggle/ThemeToggle.module.scss +++ b/src/components/Form/Toggle/Toggle.module.scss @@ -45,9 +45,11 @@ .checkbox { position: absolute; opacity: 0; + cursor: pointer; &:checked ~ .label { .toggle::after { + position: absolute; left: calc(100% - (var(--toggle-width) / 2) + #{fun.convert-px(2)}); } } diff --git a/src/components/Form/Toggle/Toggle.tsx b/src/components/Form/Toggle/Toggle.tsx new file mode 100644 index 0000000..36636e4 --- /dev/null +++ b/src/components/Form/Toggle/Toggle.tsx @@ -0,0 +1,46 @@ +import { FormEvent, ReactElement } from 'react'; +import { Form } from '..'; +import styles from './Toggle.module.scss'; + +const Toggle = ({ + id, + label, + value, + changeHandler, + leftChoice, + rightChoice, + name, +}: { + id: string; + label: string; + value: boolean; + changeHandler: (value: boolean) => void; + leftChoice: ReactElement | string; + rightChoice: ReactElement | string; + name?: string; +}) => { + const onSubmit = (e: FormEvent) => { + e.preventDefault(); + }; + + return ( + <Form modifier="toggle" submitHandler={onSubmit}> + <input + className={styles.checkbox} + type="checkbox" + id={id} + name={name ? name : id} + checked={value} + onChange={() => changeHandler(!value)} + /> + <label htmlFor={id} className={styles.label}> + <span className={styles.title}>{label}</span> + {leftChoice} + <span className={styles.toggle}></span> + {rightChoice} + </label> + </Form> + ); +}; + +export default Toggle; diff --git a/src/components/Form/index.tsx b/src/components/Form/index.tsx index 987e013..0908e9b 100644 --- a/src/components/Form/index.tsx +++ b/src/components/Form/index.tsx @@ -2,5 +2,6 @@ import Form from './Form'; import FormItem from './FormItem/FormItem'; import Input from './Input/Input'; import TextArea from './TextArea/TextArea'; +import Toggle from './Toggle/Toggle'; -export { Form, FormItem, Input, TextArea }; +export { Form, FormItem, Input, TextArea, Toggle }; diff --git a/src/components/Settings/Settings.tsx b/src/components/Settings/Settings.tsx index bfef851..7d5516c 100644 --- a/src/components/Settings/Settings.tsx +++ b/src/components/Settings/Settings.tsx @@ -1,5 +1,5 @@ import { CogIcon } from '@components/Icons'; -import ThemeToggle from '@components/ThemeToggle/ThemeToggle'; +import ThemeToggle from '@components/Settings/ThemeToggle/ThemeToggle'; import { t } from '@lingui/macro'; import styles from './Settings.module.scss'; diff --git a/src/components/Settings/ThemeToggle/ThemeToggle.tsx b/src/components/Settings/ThemeToggle/ThemeToggle.tsx new file mode 100644 index 0000000..e14f39a --- /dev/null +++ b/src/components/Settings/ThemeToggle/ThemeToggle.tsx @@ -0,0 +1,36 @@ +import { Toggle } from '@components/Form'; +import { MoonIcon, SunIcon } from '@components/Icons'; +import Spinner from '@components/Spinner/Spinner'; +import { t } from '@lingui/macro'; +import { useTheme } from 'next-themes'; +import { useEffect, useState } from 'react'; + +const ThemeToggle = () => { + const [isMounted, setIsMounted] = useState<boolean>(false); + const { resolvedTheme, setTheme } = useTheme(); + + useEffect(() => { + setIsMounted(true); + }, []); + + if (!isMounted) return <Spinner />; + + const isDarkTheme = resolvedTheme === 'dark'; + + const updateTheme = () => { + setTheme(isDarkTheme ? 'light' : 'dark'); + }; + + return ( + <Toggle + id="dark-theme" + label={t`Theme:`} + leftChoice={<SunIcon />} + rightChoice={<MoonIcon />} + value={isDarkTheme} + changeHandler={updateTheme} + /> + ); +}; + +export default ThemeToggle; diff --git a/src/components/ThemeToggle/ThemeToggle.tsx b/src/components/ThemeToggle/ThemeToggle.tsx deleted file mode 100644 index c44f6df..0000000 --- a/src/components/ThemeToggle/ThemeToggle.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { Form } from '@components/Form'; -import { MoonIcon, SunIcon } from '@components/Icons'; -import Spinner from '@components/Spinner/Spinner'; -import { t } from '@lingui/macro'; -import { useTheme } from 'next-themes'; -import { FormEvent, useEffect, useState } from 'react'; -import styles from './ThemeToggle.module.scss'; - -const ThemeToggle = () => { - const [isMounted, setIsMounted] = useState<boolean>(false); - const { resolvedTheme, setTheme } = useTheme(); - - useEffect(() => { - setIsMounted(true); - }, []); - - const onSubmit = (e: FormEvent) => { - e.preventDefault(); - }; - - if (!isMounted) return <Spinner />; - - const isDarkTheme = resolvedTheme === 'dark'; - - return ( - <Form modifier="theme" submitHandler={onSubmit}> - <input - className={styles.checkbox} - type="checkbox" - id="dark-theme" - name="dark-theme" - checked={isDarkTheme} - onChange={() => setTheme(isDarkTheme ? 'light' : 'dark')} - /> - <label htmlFor="dark-theme" className={styles.label}> - <span className={styles.title}>{t`Theme:`}</span> - <SunIcon /> - <span className={styles.toggle}></span> - <MoonIcon /> - </label> - </Form> - ); -}; - -export default ThemeToggle; |
