mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-06-13 21:02:08 +08:00
fix(a11y): settings toggles (#49664)
Co-authored-by: Sboonny <muhammedelruby@gmail.com> Co-authored-by: Sboonny <muhammed@freecodecamp.org>
This commit is contained in:
parent
f76a376b20
commit
e0088db2b3
@ -1,63 +1,56 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
function ToggleCheck(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<span className='sr-only'>{t('icons.toggle')}</span>
|
||||
<svg
|
||||
className='tick'
|
||||
height='50'
|
||||
viewBox='-10 -45 200 200'
|
||||
width='50'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<g>
|
||||
<title>{t('icons.toggle')}</title>
|
||||
<rect
|
||||
fill='white'
|
||||
height='60'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(-45, 66.75, 123.75)'
|
||||
width='148.85878'
|
||||
x='65.57059'
|
||||
y='75.32089'
|
||||
/>
|
||||
<rect
|
||||
fill='white'
|
||||
height='60'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(45, 66.75, 123.75)'
|
||||
width='120.66548'
|
||||
x='-42.41726'
|
||||
y='99.75'
|
||||
/>
|
||||
<rect
|
||||
fill='black'
|
||||
height='30'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(-45, 66.75, 123.75)'
|
||||
width='128.85878'
|
||||
x='65.57059'
|
||||
y='92.32089'
|
||||
/>
|
||||
<rect
|
||||
fill='black'
|
||||
height='30'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(-135, 66.75, 123.75)'
|
||||
width='88.85878'
|
||||
x='68.57059'
|
||||
y='103.32089'
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</>
|
||||
<svg
|
||||
className='tick'
|
||||
height='50'
|
||||
viewBox='-10 -45 200 200'
|
||||
width='50'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
aria-hidden='true'
|
||||
{...props}
|
||||
>
|
||||
<g>
|
||||
<rect
|
||||
fill='white'
|
||||
height='60'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(-45, 66.75, 123.75)'
|
||||
width='148.85878'
|
||||
x='65.57059'
|
||||
y='75.32089'
|
||||
/>
|
||||
<rect
|
||||
fill='white'
|
||||
height='60'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(45, 66.75, 123.75)'
|
||||
width='120.66548'
|
||||
x='-42.41726'
|
||||
y='99.75'
|
||||
/>
|
||||
<rect
|
||||
fill='black'
|
||||
height='30'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(-45, 66.75, 123.75)'
|
||||
width='128.85878'
|
||||
x='65.57059'
|
||||
y='92.32089'
|
||||
/>
|
||||
<rect
|
||||
fill='black'
|
||||
height='30'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(-135, 66.75, 123.75)'
|
||||
width='88.85878'
|
||||
x='68.57059'
|
||||
y='103.32089'
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ import BlockSaveButton from '../helpers/form/block-save-button';
|
||||
import FullWidthRow from '../helpers/full-width-row';
|
||||
import Spacer from '../helpers/spacer';
|
||||
import SectionHeader from './section-header';
|
||||
import ToggleSetting from './toggle-setting';
|
||||
import ToggleButtonSetting from './toggle-button-setting';
|
||||
|
||||
const mapStateToProps = () => ({});
|
||||
const mapDispatchToProps = (dispatch: Dispatch) =>
|
||||
@ -228,7 +228,7 @@ function EmailSettings({
|
||||
<Spacer size='medium' />
|
||||
<FullWidthRow>
|
||||
<form id='form-quincy-email' onSubmit={handleSubmit}>
|
||||
<ToggleSetting
|
||||
<ToggleButtonSetting
|
||||
action={t('settings.email.weekly')}
|
||||
flag={sendQuincyEmail}
|
||||
flagName='sendQuincyEmail'
|
||||
|
||||
@ -2,7 +2,7 @@ import { Form } from '@freecodecamp/react-bootstrap';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import ToggleSetting from './toggle-setting';
|
||||
import ToggleButtonSetting from './toggle-button-setting';
|
||||
|
||||
type KeyboardShortcutsProps = {
|
||||
keyboardShortcuts: boolean;
|
||||
@ -21,7 +21,7 @@ export default function KeyboardShortcutsSettings({
|
||||
onSubmit={(e: React.FormEvent) => e.preventDefault()}
|
||||
data-testid='fcc-enable-shortcuts-setting'
|
||||
>
|
||||
<ToggleSetting
|
||||
<ToggleButtonSetting
|
||||
action={t('settings.labels.keyboard-shortcuts')}
|
||||
flag={keyboardShortcuts}
|
||||
flagName='keyboard-shortcuts'
|
||||
|
||||
@ -13,7 +13,7 @@ import { submitProfileUI } from '../../redux/settings/actions';
|
||||
import FullWidthRow from '../helpers/full-width-row';
|
||||
import Spacer from '../helpers/spacer';
|
||||
import SectionHeader from './section-header';
|
||||
import ToggleSetting from './toggle-setting';
|
||||
import ToggleRadioSetting from './toggle-radio-setting';
|
||||
|
||||
const mapStateToProps = createSelector(userSelector, user => ({
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
@ -46,6 +46,7 @@ function PrivacySettings({ submitProfileUI, user }: PrivacyProps): JSX.Element {
|
||||
|
||||
function submitNewProfileSettings(e: React.FormEvent) {
|
||||
e.preventDefault();
|
||||
if (!madeChanges) return;
|
||||
submitProfileUI(privacyValues);
|
||||
setMadeChanges(false);
|
||||
}
|
||||
@ -57,7 +58,7 @@ function PrivacySettings({ submitProfileUI, user }: PrivacyProps): JSX.Element {
|
||||
<p>{t('settings.privacy')}</p>
|
||||
<Form inline={true} onSubmit={submitNewProfileSettings}>
|
||||
<div role='group' aria-label={t('settings.headings.privacy')}>
|
||||
<ToggleSetting
|
||||
<ToggleRadioSetting
|
||||
action={t('settings.labels.my-profile')}
|
||||
explain={t('settings.disabled')}
|
||||
flag={privacyValues['isLocked']}
|
||||
@ -66,7 +67,7 @@ function PrivacySettings({ submitProfileUI, user }: PrivacyProps): JSX.Element {
|
||||
onLabel={t('buttons.private')}
|
||||
toggleFlag={toggleFlag('isLocked')}
|
||||
/>
|
||||
<ToggleSetting
|
||||
<ToggleRadioSetting
|
||||
action={t('settings.labels.my-name')}
|
||||
explain={t('settings.private-name')}
|
||||
flag={!privacyValues['showName']}
|
||||
@ -75,7 +76,7 @@ function PrivacySettings({ submitProfileUI, user }: PrivacyProps): JSX.Element {
|
||||
onLabel={t('buttons.private')}
|
||||
toggleFlag={toggleFlag('showName')}
|
||||
/>
|
||||
<ToggleSetting
|
||||
<ToggleRadioSetting
|
||||
action={t('settings.labels.my-location')}
|
||||
flag={!privacyValues['showLocation']}
|
||||
flagName='showLocation'
|
||||
@ -83,7 +84,7 @@ function PrivacySettings({ submitProfileUI, user }: PrivacyProps): JSX.Element {
|
||||
onLabel={t('buttons.private')}
|
||||
toggleFlag={toggleFlag('showLocation')}
|
||||
/>
|
||||
<ToggleSetting
|
||||
<ToggleRadioSetting
|
||||
action={t('settings.labels.my-about')}
|
||||
flag={!privacyValues['showAbout']}
|
||||
flagName='showAbout'
|
||||
@ -91,7 +92,7 @@ function PrivacySettings({ submitProfileUI, user }: PrivacyProps): JSX.Element {
|
||||
onLabel={t('buttons.private')}
|
||||
toggleFlag={toggleFlag('showAbout')}
|
||||
/>
|
||||
<ToggleSetting
|
||||
<ToggleRadioSetting
|
||||
action={t('settings.labels.my-points')}
|
||||
flag={!privacyValues['showPoints']}
|
||||
flagName='showPoints'
|
||||
@ -99,7 +100,7 @@ function PrivacySettings({ submitProfileUI, user }: PrivacyProps): JSX.Element {
|
||||
onLabel={t('buttons.private')}
|
||||
toggleFlag={toggleFlag('showPoints')}
|
||||
/>
|
||||
<ToggleSetting
|
||||
<ToggleRadioSetting
|
||||
action={t('settings.labels.my-heatmap')}
|
||||
flag={!privacyValues['showHeatMap']}
|
||||
flagName='showHeatMap'
|
||||
@ -107,7 +108,7 @@ function PrivacySettings({ submitProfileUI, user }: PrivacyProps): JSX.Element {
|
||||
onLabel={t('buttons.private')}
|
||||
toggleFlag={toggleFlag('showHeatMap')}
|
||||
/>
|
||||
<ToggleSetting
|
||||
<ToggleRadioSetting
|
||||
action={t('settings.labels.my-certs')}
|
||||
explain={t('settings.disabled')}
|
||||
flag={!privacyValues['showCerts']}
|
||||
@ -116,7 +117,7 @@ function PrivacySettings({ submitProfileUI, user }: PrivacyProps): JSX.Element {
|
||||
onLabel={t('buttons.private')}
|
||||
toggleFlag={toggleFlag('showCerts')}
|
||||
/>
|
||||
<ToggleSetting
|
||||
<ToggleRadioSetting
|
||||
action={t('settings.labels.my-portfolio')}
|
||||
flag={!privacyValues['showPortfolio']}
|
||||
flagName='showPortfolio'
|
||||
@ -124,7 +125,7 @@ function PrivacySettings({ submitProfileUI, user }: PrivacyProps): JSX.Element {
|
||||
onLabel={t('buttons.private')}
|
||||
toggleFlag={toggleFlag('showPortfolio')}
|
||||
/>
|
||||
<ToggleSetting
|
||||
<ToggleRadioSetting
|
||||
action={t('settings.labels.my-timeline')}
|
||||
explain={t('settings.disabled')}
|
||||
flag={!privacyValues['showTimeLine']}
|
||||
@ -133,10 +134,10 @@ function PrivacySettings({ submitProfileUI, user }: PrivacyProps): JSX.Element {
|
||||
onLabel={t('buttons.private')}
|
||||
toggleFlag={toggleFlag('showTimeLine')}
|
||||
/>
|
||||
<ToggleSetting
|
||||
<ToggleRadioSetting
|
||||
action={t('settings.labels.my-donations')}
|
||||
flag={!privacyValues['showDonation']}
|
||||
flagName='showPortfolio'
|
||||
flagName='showDonation'
|
||||
offLabel={t('buttons.public')}
|
||||
onLabel={t('buttons.private')}
|
||||
toggleFlag={toggleFlag('showDonation')}
|
||||
|
||||
@ -6,7 +6,7 @@ import { Spacer } from '../helpers';
|
||||
|
||||
import './sound.css';
|
||||
import { playTone } from '../../utils/tone';
|
||||
import ToggleSetting from './toggle-setting';
|
||||
import ToggleButtonSetting from './toggle-button-setting';
|
||||
|
||||
type SoundProps = {
|
||||
sound: boolean;
|
||||
@ -41,7 +41,7 @@ export default function SoundSettings({
|
||||
|
||||
return (
|
||||
<Form inline={true} onSubmit={(e: React.FormEvent) => e.preventDefault()}>
|
||||
<ToggleSetting
|
||||
<ToggleButtonSetting
|
||||
action={t('settings.labels.sound-mode')}
|
||||
explain={t('settings.sound-mode')}
|
||||
flag={sound}
|
||||
|
||||
@ -2,7 +2,7 @@ import { Form } from '@freecodecamp/react-bootstrap';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import ToggleSetting from './toggle-setting';
|
||||
import ToggleButtonSetting from './toggle-button-setting';
|
||||
|
||||
export enum Themes {
|
||||
Night = 'night',
|
||||
@ -25,7 +25,7 @@ export default function ThemeSettings({
|
||||
inline={true}
|
||||
onSubmit={(e: React.FormEvent): void => e.preventDefault()}
|
||||
>
|
||||
<ToggleSetting
|
||||
<ToggleButtonSetting
|
||||
action={t('settings.labels.night-mode')}
|
||||
flag={currentTheme === Themes.Night}
|
||||
flagName='currentTheme'
|
||||
|
||||
66
client/src/components/settings/toggle-button-setting.tsx
Normal file
66
client/src/components/settings/toggle-button-setting.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import React from 'react';
|
||||
import ToggleCheck from '../../assets/icons/toggle-check';
|
||||
import type { ToggleSettingProps } from './toggle-radio-setting';
|
||||
import '../helpers/toggle-button.css';
|
||||
import './toggle-setting.css';
|
||||
|
||||
const checkIconStyle = {
|
||||
height: '1rem',
|
||||
width: '1.25rem'
|
||||
};
|
||||
|
||||
export default function ToggleButtonSetting({
|
||||
action,
|
||||
explain,
|
||||
flag,
|
||||
flagName,
|
||||
toggleFlag,
|
||||
...restProps
|
||||
}: ToggleSettingProps): JSX.Element {
|
||||
return (
|
||||
<div className='toggle-setting-container'>
|
||||
<fieldset
|
||||
{...(explain && {
|
||||
'aria-labelledby': `legend${flagName} desc${flagName}`
|
||||
})}
|
||||
>
|
||||
<legend
|
||||
className='sr-only'
|
||||
{...(explain && { id: `legend${flagName}` })}
|
||||
>
|
||||
{action}
|
||||
</legend>
|
||||
<div className='toggle-description'>
|
||||
<p aria-hidden={true}>{action}</p>
|
||||
{explain ? <p id={`desc${flagName}`}>{explain}</p> : null}
|
||||
</div>
|
||||
<div className='toggle-button-group'>
|
||||
<button
|
||||
aria-pressed={flag}
|
||||
{...(!flag && { onClick: toggleFlag })}
|
||||
value='1'
|
||||
className='toggle-button-right'
|
||||
>
|
||||
<span>
|
||||
{restProps.onLabel}
|
||||
{flag ? <ToggleCheck style={checkIconStyle} /> : null}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
aria-pressed={!flag}
|
||||
{...(flag && { onClick: toggleFlag })}
|
||||
value='2'
|
||||
className='toggle-button-left'
|
||||
>
|
||||
<span>
|
||||
{restProps.offLabel}
|
||||
{!flag ? <ToggleCheck style={checkIconStyle} /> : null}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
ToggleButtonSetting.displayName = 'ToggleButtonSetting';
|
||||
72
client/src/components/settings/toggle-radio-setting.tsx
Normal file
72
client/src/components/settings/toggle-radio-setting.tsx
Normal file
@ -0,0 +1,72 @@
|
||||
import React from 'react';
|
||||
import '../helpers/toggle-button.css';
|
||||
import './toggle-setting.css';
|
||||
|
||||
export type ToggleSettingProps = {
|
||||
action: string;
|
||||
explain?: string;
|
||||
flag: boolean;
|
||||
flagName: string;
|
||||
toggleFlag: () => void;
|
||||
offLabel: string;
|
||||
onLabel: string;
|
||||
};
|
||||
|
||||
export default function ToggleRadioSetting({
|
||||
action,
|
||||
explain,
|
||||
flag,
|
||||
flagName,
|
||||
toggleFlag,
|
||||
...restProps
|
||||
}: ToggleSettingProps): JSX.Element {
|
||||
const firstRadioId = `radioA${flagName}`;
|
||||
const secondRadioId = `radioB${flagName}`;
|
||||
|
||||
return (
|
||||
<div className='toggle-setting-container'>
|
||||
<fieldset
|
||||
{...(explain && {
|
||||
'aria-labelledby': `legend${flagName} desc${flagName}`
|
||||
})}
|
||||
>
|
||||
<legend
|
||||
className='sr-only'
|
||||
{...(explain && { id: `legend${flagName}` })}
|
||||
>
|
||||
{action}
|
||||
</legend>
|
||||
<div className='toggle-description'>
|
||||
<p aria-hidden={true}>{action}</p>
|
||||
{explain ? <p id={`desc${flagName}`}>{explain}</p> : null}
|
||||
</div>
|
||||
<div className='toggle-radio-group'>
|
||||
<label htmlFor={firstRadioId} data-checked={flag}>
|
||||
<input
|
||||
id={firstRadioId}
|
||||
type='radio'
|
||||
{...(flag && { defaultChecked: true })}
|
||||
{...(!flag && { onChange: toggleFlag })}
|
||||
name={flagName}
|
||||
value='1'
|
||||
/>
|
||||
<span>{restProps.onLabel}</span>
|
||||
</label>
|
||||
<label htmlFor={secondRadioId} data-checked={!flag}>
|
||||
<input
|
||||
id={secondRadioId}
|
||||
type='radio'
|
||||
{...(!flag && { defaultChecked: true })}
|
||||
{...(flag && { onChange: toggleFlag })}
|
||||
name={flagName}
|
||||
value='2'
|
||||
/>
|
||||
<span>{restProps.offLabel}</span>
|
||||
</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
ToggleRadioSetting.displayName = 'ToggleRadioSetting';
|
||||
@ -1,49 +1,142 @@
|
||||
.toggle-setting-container {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.toggle-setting-container .form-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.toggle-setting-container .toggle-label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.toggle-setting-container .btn-group {
|
||||
padding-inline: 5px;
|
||||
}
|
||||
|
||||
.toggle-setting-container > .form-group > * {
|
||||
flex: 1 1 0;
|
||||
}
|
||||
|
||||
.toggle-setting-container .btn-group {
|
||||
.toggle-description {
|
||||
max-width: 50%;
|
||||
}
|
||||
|
||||
.toggle-description > p:first-child {
|
||||
font-weight: 700;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.toggle-description > p:not(:first-child) {
|
||||
font-style: italic;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.toggle-setting-container fieldset {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
@media (max-width: 440px) {
|
||||
.toggle-setting-container .form-group {
|
||||
.toggle-button-group {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: min-content;
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
.toggle-button-group button {
|
||||
padding: 5px 1.5rem;
|
||||
border: 3px solid var(--secondary-color);
|
||||
white-space: nowrap;
|
||||
display: grid;
|
||||
align-items: baseline;
|
||||
justify-content: center;
|
||||
min-width: 6rem;
|
||||
}
|
||||
|
||||
.toggle-button-group button[aria-pressed='true'] {
|
||||
background-color: var(--secondary-color);
|
||||
color: var(--secondary-background);
|
||||
}
|
||||
|
||||
.toggle-button-group button > span {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.toggle-button-group button > span > svg {
|
||||
position: absolute;
|
||||
right: -1.5rem;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.toggle-button-group button:first-of-type > span > svg,
|
||||
[dir='rtl'] .toggle-button-group button > span > svg {
|
||||
right: unset;
|
||||
left: -1.25rem;
|
||||
}
|
||||
|
||||
[dir='rtl'] .toggle-button-group button:first-of-type > span > svg {
|
||||
left: unset;
|
||||
right: -1.5rem;
|
||||
}
|
||||
|
||||
.toggle-button-group button[aria-pressed='true']:hover {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.toggle-radio-group {
|
||||
display: flex;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.toggle-radio-group label {
|
||||
font-weight: normal;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toggle-radio-group input {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
height: 0.8rem;
|
||||
width: 0.8rem;
|
||||
border-radius: 50%;
|
||||
background: transparent;
|
||||
border: 2px solid var(--secondary-color);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.toggle-radio-group [data-checked='true'] input {
|
||||
background: var(--secondary-color);
|
||||
}
|
||||
|
||||
.toggle-radio-group [data-checked='true'] span {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.toggle-radio-group input:focus-visible {
|
||||
outline-offset: 1px;
|
||||
}
|
||||
|
||||
.toggle-radio-group label[data-checked='false']:hover,
|
||||
.toggle-radio-group label[data-checked='false'] input:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toggle-radio-group label + label {
|
||||
margin-inline-start: 2rem;
|
||||
}
|
||||
|
||||
.toggle-radio-group input {
|
||||
margin-inline-end: 0.35rem;
|
||||
accent-color: var(--secondary-color);
|
||||
}
|
||||
|
||||
@media (max-width: 35rem) {
|
||||
.toggle-setting-container fieldset {
|
||||
flex-direction: column;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.toggle-setting-container > .form-group > * {
|
||||
flex: 0 1 auto;
|
||||
.toggle-description {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.toggle-setting-container .toggle-label {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.toggle-setting-container .help-block {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.toggle-setting-container .btn-group {
|
||||
justify-content: flex-start;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
.toggle-description > p:not(:first-child) {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
import {
|
||||
FormGroup,
|
||||
ControlLabel,
|
||||
HelpBlock
|
||||
} from '@freecodecamp/react-bootstrap';
|
||||
import React from 'react';
|
||||
|
||||
import { Spacer } from '../helpers';
|
||||
import TB from '../helpers/toggle-button';
|
||||
|
||||
import './toggle-setting.css';
|
||||
|
||||
type ToggleSettingProps = {
|
||||
action: string;
|
||||
explain?: string;
|
||||
flag: boolean;
|
||||
flagName: string;
|
||||
toggleFlag: () => void;
|
||||
offLabel: string;
|
||||
onLabel: string;
|
||||
};
|
||||
|
||||
export default function ToggleSetting({
|
||||
action,
|
||||
explain,
|
||||
flag,
|
||||
flagName,
|
||||
toggleFlag,
|
||||
...restProps
|
||||
}: ToggleSettingProps): JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<div className='toggle-setting-container'>
|
||||
<FormGroup>
|
||||
<ControlLabel className='toggle-label' htmlFor={flagName}>
|
||||
<strong>{action}</strong>
|
||||
{explain ? (
|
||||
<HelpBlock>
|
||||
<em>{explain}</em>
|
||||
</HelpBlock>
|
||||
) : null}
|
||||
</ControlLabel>
|
||||
<TB
|
||||
name={flagName}
|
||||
onChange={toggleFlag}
|
||||
value={flag}
|
||||
{...restProps}
|
||||
/>
|
||||
</FormGroup>
|
||||
</div>
|
||||
<Spacer size='small' />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
ToggleSetting.displayName = 'ToggleSetting';
|
||||
@ -15,9 +15,9 @@ const preserveSession = () => {
|
||||
|
||||
const setPrivacyTogglesToPublic = () => {
|
||||
cy.get('#privacy-settings')
|
||||
.find('.toggle-not-active')
|
||||
.find('[type=radio][value=2]')
|
||||
.each(element => {
|
||||
cy.wrap(element).click().should('have.class', 'toggle-active');
|
||||
cy.wrap(element).click().should('be.checked');
|
||||
});
|
||||
cy.get('[data-cy=save-privacy-settings]').click();
|
||||
cy.get('#honesty-policy').find('button').click();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user