Skip to content
This repository has been archived by the owner on Oct 19, 2021. It is now read-only.

Commit

Permalink
fix(Toggle): hide on/off test for screen readers (#1865)
Browse files Browse the repository at this point in the history
* fix(Toggle): hide on/off test for screen readers

Refs carbon-design-system/carbon#1794.

* fix(Toggle): replace fieldset/legend with div

* chore(Toggle): turn to class and use setupGetInstanceId
  • Loading branch information
asudoh authored Feb 27, 2019
1 parent c7a37b8 commit 50a0177
Showing 1 changed file with 121 additions and 105 deletions.
226 changes: 121 additions & 105 deletions src/components/Toggle/Toggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,113 +9,129 @@ import PropTypes from 'prop-types';
import React from 'react';
import classNames from 'classnames';
import { settings } from 'carbon-components';
import setupGetInstanceId from '../../tools/setupGetInstanceId';

const { prefix } = settings;

const Toggle = ({
className,
defaultToggled,
toggled,
onChange,
onToggle,
id,
labelText,
labelA,
labelB,
...other
}) => {
let input;
const wrapperClasses = classNames({
[`${prefix}--form-item`]: true,
[className]: className,
});

const checkedProps = {};

if (typeof toggled !== 'undefined') {
checkedProps.checked = toggled;
} else {
checkedProps.defaultChecked = defaultToggled;
const getInstanceId = setupGetInstanceId();

class Toggle extends React.Component {
static propTypes = {
/**
* Specify a custom className to apply to the form-item node
*/
className: PropTypes.string,

/**
* Specify whether the toggle should be on by default
*/
defaultToggled: PropTypes.bool,

/**
* Provide an optional hook that is called when the control is toggled
*/
onToggle: PropTypes.func,

/**
* Provide an id that unique represents the underlying <input>
*/
id: PropTypes.string.isRequired,

/**
* Specify whether the control is toggled
*/
toggled: PropTypes.bool,

/**
* Specify the label for the "off" position
*/
labelA: PropTypes.string.isRequired,

/**
* Specify the label for the "on" position
*/
labelB: PropTypes.string.isRequired,
};

static defaultProps = {
defaultToggled: false,
label: '',
labelA: 'Off',
labelB: 'On',
onToggle: () => {},
};

render() {
const {
className,
defaultToggled,
toggled,
onChange,
onToggle,
id = (this.inputId =
this.inputId || `__carbon-toggle_${getInstanceId()}`),
labelText,
labelA,
labelB,
...other
} = this.props;

let input;
const wrapperClasses = classNames({
[`${prefix}--form-item`]: true,
[className]: className,
});

const checkedProps = {};

if (typeof toggled !== 'undefined') {
checkedProps.checked = toggled;
} else {
checkedProps.defaultChecked = defaultToggled;
}

const labelTextId = !labelText ? undefined : `${id}-label`;

return (
<>
{labelText && (
<div id={labelTextId} className={`${prefix}--label`}>
{labelText}
</div>
)}
<div className={wrapperClasses}>
<input
{...other}
{...checkedProps}
type="checkbox"
id={id}
className={`${prefix}--toggle`}
aria-labelledby={labelTextId}
onChange={evt => {
onChange && onChange(evt);
onToggle(input.checked, id, evt);
}}
ref={el => {
input = el;
}}
/>

<label className={`${prefix}--toggle__label`} htmlFor={id}>
<span
className={`${prefix}--toggle__text--left`}
aria-hidden="true">
{labelA}
</span>
<span className={`${prefix}--toggle__appearance`} />
<span
className={`${prefix}--toggle__text--right`}
aria-hidden="true">
{labelB}
</span>
</label>
</div>
</>
);
}

const ToggleBody = () => (
<div className={wrapperClasses}>
<input
{...other}
{...checkedProps}
type="checkbox"
id={id}
className={`${prefix}--toggle`}
onChange={evt => {
onChange && onChange(evt);
onToggle(input.checked, id, evt);
}}
ref={el => {
input = el;
}}
/>

<label className={`${prefix}--toggle__label`} htmlFor={id}>
<span className={`${prefix}--toggle__text--left`}>{labelA}</span>
<span className={`${prefix}--toggle__appearance`} />
<span className={`${prefix}--toggle__text--right`}>{labelB}</span>
</label>
</div>
);

return labelText ? (
<fieldset className={`${prefix}--fieldset`}>
<legend className={`${prefix}--label`}>{labelText}</legend>
<ToggleBody />
</fieldset>
) : (
<ToggleBody />
);
};

Toggle.propTypes = {
/**
* Specify a custom className to apply to the form-item node
*/
className: PropTypes.string,

/**
* Specify whether the toggle should be on by default
*/
defaultToggled: PropTypes.bool,

/**
* Provide an optional hook that is called when the control is toggled
*/
onToggle: PropTypes.func,

/**
* Provide an id that unique represents the underlying <input>
*/
id: PropTypes.string.isRequired,

/**
* Specify whether the control is toggled
*/
toggled: PropTypes.bool,

/**
* Specify the label for the "off" position
*/
labelA: PropTypes.string.isRequired,

/**
* Specify the label for the "on" position
*/
labelB: PropTypes.string.isRequired,
};

Toggle.defaultProps = {
defaultToggled: false,
label: '',
labelA: 'Off',
labelB: 'On',
onToggle: () => {},
};
}

export default Toggle;

0 comments on commit 50a0177

Please sign in to comment.