Skip to content

Commit

Permalink
feat(toggle): convert ToggleSmall to a variant of Toggle (#7380)
Browse files Browse the repository at this point in the history
* feat(toggle): convert ToggleSmall to a variant of Toggle

* chore(tests): remove commented out code

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
tw15egan and kodiakhq[bot] committed Dec 4, 2020
1 parent 496e11c commit 336b7de
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 66 deletions.
8 changes: 8 additions & 0 deletions packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6000,6 +6000,14 @@ Map {
"onToggle": Object {
"type": "func",
},
"size": Object {
"args": Array [
Array [
"sm",
],
],
"type": "oneOf",
},
"toggled": Object {
"type": "bool",
},
Expand Down
31 changes: 10 additions & 21 deletions packages/react/src/components/Toggle/Toggle-story.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@

import React from 'react';
import { action } from '@storybook/addon-actions';
import { withKnobs, text, boolean } from '@storybook/addon-knobs';
import { withKnobs, text, boolean, select } from '@storybook/addon-knobs';
import Toggle from '../Toggle';

const sizes = {
'Default size': undefined,
'Small size (sm)': 'sm',
};

const toggleProps = () => ({
labelText: text(
'Label toggle input control (labelText)',
Expand All @@ -21,6 +26,7 @@ const toggleProps = () => ({
disabled: boolean('Disabled (disabled)', false),
onChange: action('onChange'),
onToggle: action('onToggle'),
size: select('Field size (size)', sizes, undefined) || undefined,
});

export default {
Expand All @@ -33,7 +39,7 @@ export default {
},
};

export const Toggled = () => (
export const Default = () => (
<Toggle
defaultToggled
{...toggleProps()}
Expand All @@ -42,9 +48,9 @@ export const Toggled = () => (
/>
);

Toggled.storyName = 'toggled';
Default.storyName = 'Toggle';

Toggled.parameters = {
Default.parameters = {
info: {
text: `
Toggles are controls that are used to quickly switch between two possible states. The example below shows
Expand All @@ -54,20 +60,3 @@ Toggled.parameters = {
`,
},
};

export const Untoggled = () => (
<Toggle {...toggleProps()} className="some-class" id="toggle-1" />
);

Untoggled.storyName = 'untoggled';

Untoggled.parameters = {
info: {
text: `
Toggles are controls that are used to quickly switch between two possible states. The example below shows
an uncontrolled Toggle component. To use the Toggle component as a controlled component, set the toggled property.
Setting the toggled property will allow you to change the value dynamically, whereas setting the defaultToggled
prop will only set the value initially. This example has defaultToggled set to false.
`,
},
};
21 changes: 21 additions & 0 deletions packages/react/src/components/Toggle/Toggle-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,25 @@ describe('Toggle', () => {
expect(call[2].target).toBe(inputElement);
});
});

describe('ToggleSmall', () => {
const wrapper = mount(<Toggle id="toggle-1" size="sm" />);

it('Sets the `ToggleSmall` className', () => {
const input = wrapper.find('input');
expect(input.hasClass(`${prefix}--toggle-input--small`)).toEqual(true);
});

it('Renders a checkmark SVG', () => {
const svg = wrapper.find(`.${prefix}--toggle__check`);
expect(svg.length).toBe(1);
});

it('Does not render toggle text', () => {
const offLabel = wrapper.find(`.${prefix}--toggle__text--off`);
const onLabel = wrapper.find(`.${prefix}--toggle__text--on`);
expect(offLabel.length).toBe(0);
expect(onLabel.length).toBe(0);
});
});
});
41 changes: 34 additions & 7 deletions packages/react/src/components/Toggle/Toggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ class Toggle extends React.Component {
*/
onToggle: PropTypes.func,

/**
* Specify the size of the Toggle. Currently only supports 'sm'
*/
size: PropTypes.oneOf(['sm']),

/**
* Specify whether the control is toggled
*/
Expand All @@ -85,6 +90,7 @@ class Toggle extends React.Component {
labelText,
labelA,
labelB,
size,
...other
} = this.props;

Expand All @@ -93,6 +99,10 @@ class Toggle extends React.Component {
[className]: className,
});

const toggleClasses = classNames(`${prefix}--toggle-input`, {
[`${prefix}--toggle-input--small`]: size,
});

const checkedProps = {};

if (typeof toggled !== 'undefined') {
Expand All @@ -109,7 +119,7 @@ class Toggle extends React.Component {
aria-label={null}
type="checkbox"
id={id}
className={`${prefix}--toggle-input`}
className={toggleClasses}
onChange={(evt) => {
onChange && onChange(evt);
onToggle(input.checked, id, evt);
Expand All @@ -133,12 +143,29 @@ class Toggle extends React.Component {
}>
{labelText}
<span className={`${prefix}--toggle__switch`}>
<span className={`${prefix}--toggle__text--off`} aria-hidden="true">
{labelA}
</span>
<span className={`${prefix}--toggle__text--on`} aria-hidden="true">
{labelB}
</span>
{size && (
<svg
className={`${prefix}--toggle__check`}
width="6px"
height="5px"
viewBox="0 0 6 5">
<path d="M2.2 2.7L5 0 6 1 2.2 5 0 2.7 1 1.5z" />
</svg>
)}
{!size && (
<>
<span
className={`${prefix}--toggle__text--off`}
aria-hidden="true">
{labelA}
</span>
<span
className={`${prefix}--toggle__text--on`}
aria-hidden="true">
{labelB}
</span>
</>
)}
</span>
</label>
</div>
Expand Down
45 changes: 17 additions & 28 deletions packages/react/src/components/ToggleSmall/ToggleSmall-story.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const toggleProps = () => ({
});

export default {
title: 'ToggleSmall',
title: 'ToggleSmall [Deprecated]',
decorators: [withKnobs],

parameters: {
Expand All @@ -33,18 +33,25 @@ export default {
},
};

export const Toggled = () => (
<ToggleSmall
defaultToggled
{...toggleProps()}
className="some-class"
id="toggle-1"
/>
export const Default = () => (
<>
<h4>
This component has been deprecated, please use the `size` prop provided by
Toggle instead
</h4>
<br />
<ToggleSmall
defaultToggled
{...toggleProps()}
className="some-class"
id="toggle-1"
/>
</>
);

Toggled.storyName = 'toggled';
Default.storyName = 'toggled';

Toggled.parameters = {
Default.parameters = {
info: {
text: `
Toggles are controls that are used to quickly switch between two possible states. The example below shows
Expand All @@ -55,21 +62,3 @@ Toggled.parameters = {
`,
},
};

export const Untoggled = () => (
<ToggleSmall {...toggleProps()} className="some-class" id="toggle-1" />
);

Untoggled.storyName = 'untoggled';

Untoggled.parameters = {
info: {
text: `
Toggles are controls that are used to quickly switch between two possible states. The example below shows
an uncontrolled Toggle component. To use the Toggle component as a controlled component, set the toggled property.
Setting the toggled property will allow you to change the value dynamically, whereas setting the defaultToggled
prop will only set the value initially. Small toggles may be used when there is not enough space for a regular sized toggle. This issue is most
commonly found in tables.
`,
},
};
35 changes: 25 additions & 10 deletions packages/react/src/components/ToggleSmall/ToggleSmall-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,39 @@
*/

import React from 'react';
import ToggleSmall from '../ToggleSmall';
import ToggleSmallSkeleton from '../ToggleSmall/ToggleSmall.Skeleton';
import { mount, shallow } from 'enzyme';
import { settings } from 'carbon-components';

const { prefix } = settings;

describe('ToggleSmall', () => {
let ToggleSmall;

beforeEach(() => {
jest.mock('warning', () => {
return jest.fn();
});

ToggleSmall = require('../ToggleSmall').default;
});

describe('Renders as expected', () => {
const wrapper = mount(
<ToggleSmall
id="toggle-1"
aria-label="test label"
labelA="Off"
labelB="On"
/>
);
let input;
let wrapper;

beforeEach(() => {
wrapper = mount(
<ToggleSmall
id="toggle-1"
aria-label="test label"
labelA="Off"
labelB="On"
/>
);

const input = wrapper.find('input');
input = wrapper.find('input');
});

it('Switch and label Ids should match', () => {
const toggleLabel = wrapper.find(`.${prefix}--toggle__label`);
Expand Down
11 changes: 11 additions & 0 deletions packages/react/src/components/ToggleSmall/ToggleSmall.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ import React from 'react';
import classNames from 'classnames';
import { settings } from 'carbon-components';
import { keys, match } from '../../internal/keyboard';
import warning from 'warning';

const { prefix } = settings;

let didWarnAboutDeprecation = false;

const ToggleSmall = ({
className,
defaultToggled,
Expand All @@ -25,6 +28,14 @@ const ToggleSmall = ({
labelB,
...other
}) => {
if (__DEV__) {
warning(
didWarnAboutDeprecation,
'`<ToggleSmall>` has been deprecated in favor of `<Toggle size="sm" />` and will be removed in the next major release of `carbon-components-react`'
);
didWarnAboutDeprecation = true;
}

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

0 comments on commit 336b7de

Please sign in to comment.