diff --git a/app/soapbox/components/ui/index.ts b/app/soapbox/components/ui/index.ts index dd92354cf..9bbc4ad87 100644 --- a/app/soapbox/components/ui/index.ts +++ b/app/soapbox/components/ui/index.ts @@ -30,5 +30,6 @@ export { default as Stack } from './stack/stack'; export { default as Tabs } from './tabs/tabs'; export { default as Text } from './text/text'; export { default as Textarea } from './textarea/textarea'; +export { default as Toggle } from './toggle/toggle'; export { default as Tooltip } from './tooltip/tooltip'; export { default as Widget } from './widget/widget'; diff --git a/app/soapbox/components/ui/toggle/toggle.tsx b/app/soapbox/components/ui/toggle/toggle.tsx new file mode 100644 index 000000000..466a207f8 --- /dev/null +++ b/app/soapbox/components/ui/toggle/toggle.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import ReactToggle, { ToggleProps } from 'react-toggle'; + +/** A glorified checkbox. Wrapper around react-toggle. */ +const Toggle: React.FC = ({ icons = false, ...rest }) => { + return ( + + ); +}; + +export default Toggle; diff --git a/app/soapbox/features/edit_profile/index.tsx b/app/soapbox/features/edit_profile/index.tsx index 647bb98e3..a8af56390 100644 --- a/app/soapbox/features/edit_profile/index.tsx +++ b/app/soapbox/features/edit_profile/index.tsx @@ -4,16 +4,12 @@ import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import { updateNotificationSettings } from 'soapbox/actions/accounts'; import { patchMe } from 'soapbox/actions/me'; import snackbar from 'soapbox/actions/snackbar'; -import { - Checkbox, -} from 'soapbox/features/forms'; +import List, { ListItem } from 'soapbox/components/list'; import { useAppSelector, useAppDispatch, useOwnAccount, useFeatures } from 'soapbox/hooks'; import { normalizeAccount } from 'soapbox/normalizers'; import resizeImage from 'soapbox/utils/resize_image'; -import { Button, Column, Form, FormActions, FormGroup, Input, Textarea } from '../../components/ui'; -import HStack from '../../components/ui/hstack/hstack'; -import Stack from '../../components/ui/stack/stack'; +import { Button, Column, Form, FormActions, FormGroup, Input, Textarea, HStack, Toggle } from '../../components/ui'; import Streamfield, { StreamfieldComponent } from '../../components/ui/streamfield/streamfield'; import ProfilePreview from './components/profile-preview'; @@ -394,63 +390,79 @@ const EditProfile: React.FC = () => { - {/* HACK: wrap these checkboxes in a .simple_form container so they get styled (for now) */} - {/* Need a either move, replace, or refactor these checkboxes. */} - + {features.followRequests && ( - } hint={} - checked={data.locked} - onChange={handleCheckboxChange('locked')} - /> + > + + )} {features.hideNetwork && ( - } hint={} - checked={account ? hidesNetwork(account): false} - onChange={handleHideNetworkChange} - /> + > + + )} {features.bots && ( - } hint={} - checked={data.bot} - onChange={handleCheckboxChange('bot')} - /> + > + + )} {features.muteStrangers && ( - } hint={} - checked={muteStrangers} - onChange={(e) => setMuteStrangers(e.target.checked)} - /> + > + setMuteStrangers(e.target.checked)} + /> + )} {features.profileDirectory && ( - } hint={} - checked={data.discoverable} - onChange={handleCheckboxChange('discoverable')} - /> + > + + )} {features.emailList && ( - } hint={} - checked={data.accepts_email_list} - onChange={handleCheckboxChange('accepts_email_list')} - /> + > + + )} - + {features.profileFields && ( { - this.props.onChange(this.props.settingPath, target.checked); - } - - render() { - const { id, settings, settingPath } = this.props; - - return ( - - ); - } - -} diff --git a/app/soapbox/features/notifications/components/setting_toggle.tsx b/app/soapbox/features/notifications/components/setting_toggle.tsx new file mode 100644 index 000000000..3cd9c65a2 --- /dev/null +++ b/app/soapbox/features/notifications/components/setting_toggle.tsx @@ -0,0 +1,35 @@ +import React from 'react'; + +import { Toggle } from 'soapbox/components/ui'; + +import type { Map as ImmutableMap } from 'immutable'; + +interface ISettingToggle { + /** Unique identifier for the Toggle. */ + id?: string, + /** The full user settings map. */ + settings: ImmutableMap, + /** Array of key names leading into the setting map. */ + settingPath: string[], + /** Callback when the setting is toggled. */ + onChange: (settingPath: string[], checked: boolean) => void, + +} + +/** Stateful toggle to change user settings. */ +const SettingToggle: React.FC = ({ id, settings, settingPath, onChange }) => { + + const handleChange: React.ChangeEventHandler = ({ target }) => { + onChange(settingPath, target.checked); + }; + + return ( + + ); +}; + +export default SettingToggle; diff --git a/app/soapbox/features/preferences/index.tsx b/app/soapbox/features/preferences/index.tsx index 9f02734f7..ccbd23498 100644 --- a/app/soapbox/features/preferences/index.tsx +++ b/app/soapbox/features/preferences/index.tsx @@ -101,7 +101,7 @@ const Preferences = () => { // dispatch(changeSetting(['defaultContentType'], event.target.value)); // }; - const onToggleChange = (key: string, checked: boolean) => { + const onToggleChange = (key: string[], checked: boolean) => { dispatch(changeSetting(key, checked, intl)); }; diff --git a/app/soapbox/features/soapbox_config/index.tsx b/app/soapbox/features/soapbox_config/index.tsx index e734f1b87..bd9977ea2 100644 --- a/app/soapbox/features/soapbox_config/index.tsx +++ b/app/soapbox/features/soapbox_config/index.tsx @@ -1,7 +1,6 @@ import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; import React, { useState, useEffect, useMemo } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import Toggle from 'react-toggle'; import { updateConfig } from 'soapbox/actions/admin'; import { uploadMedia } from 'soapbox/actions/media'; @@ -17,6 +16,7 @@ import { Input, Textarea, Button, + Toggle, } from 'soapbox/components/ui'; import Streamfield from 'soapbox/components/ui/streamfield/streamfield'; import ThemeSelector from 'soapbox/features/ui/components/theme-selector'; diff --git a/app/styles/components/react-toggle.scss b/app/styles/components/react-toggle.scss index 7a75e696f..3f3ef49e4 100644 --- a/app/styles/components/react-toggle.scss +++ b/app/styles/components/react-toggle.scss @@ -28,7 +28,7 @@ } .react-toggle-track { - @apply bg-gray-200 w-[50px] p-0 rounded-full transition-colors; + @apply bg-gray-300 dark:bg-slate-700 w-[50px] p-0 rounded-full transition-colors; height: var(--input-height); }