summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-01-17 22:26:16 +0100
committerArmand Philippot <git@armandphilippot.com>2022-01-17 22:54:17 +0100
commita6233863da4203bec781e817963ac3733279cab5 (patch)
treeb075753c4336b737d41c178451551c40c1016951
parent68138f0dcd8b3db2c23b31a20508726f245b5ba5 (diff)
refactor(settings): make toggle reusable
Toggle will be used for others settings so I extract the functionnality from ThemeToggle.
-rw-r--r--src/components/Form/Form.module.scss8
-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.tsx46
-rw-r--r--src/components/Form/index.tsx3
-rw-r--r--src/components/Settings/Settings.tsx2
-rw-r--r--src/components/Settings/ThemeToggle/ThemeToggle.tsx36
-rw-r--r--src/components/ThemeToggle/ThemeToggle.tsx45
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;