Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions src/components/Switch/Switch.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// import { action } from '@storybook/addon-actions';
import React from 'react';
import Switch from './Switch';

export default {
title: 'Switch',
component: Switch,
};

export const DefaultSwitch = () => {
const [showOn, setShowOn] = React.useState(false);
const handleChange = () => {
setShowOn(!showOn);
};
return (
<Switch label="Default Switch" isChecked={showOn} onChange={handleChange} />
);
};

export const DiffSizeSwitch = () => {
const [showOn, setShowOn] = React.useState(false);
return (
<div>
<Switch
switchSize="sm"
onChange={() => setShowOn(!showOn)}
isChecked={showOn}
label="Small Switch with default color"
/>

<Switch switchSize="lg" label="Large Switch with default color" />
</div>
);
};

export const DiffColorSwitch = () => {
const [showOnP, setShowOnP] = React.useState(false);
const [showOnS, setShowOnS] = React.useState(false);

console.log(showOnP);
return (
<div>
<Switch
switchColor="primary"
onChange={() => {
setShowOnP(!showOnP);
}}
label="Primary color Switch"
isChecked={showOnP}
/>

<Switch
switchColor="secondary"
onChange={() => setShowOnS(!showOnS)}
isChecked={showOnS}
label="Secondary color Switch"
/>
</div>
);
};

export const DiffTypeSwitch = () => {
const [showOn, setShowOn] = React.useState(false);
const [defaultOn, setDefaultOn] = React.useState(true);
return (
<div>
<Switch
onChange={() => {
setShowOn(!showOn);
}}
isChecked={showOn}
label="Default Switch"
/>

<Switch label="switch with label" />

<Switch
onChange={() => {
setDefaultOn(!defaultOn);
}}
isChecked={defaultOn}
label="On as default switch"
/>

<Switch
disabled
label="Defualt disabled switch"
onChange={() => console.log('clicked')}
/>
</div>
);
};
103 changes: 103 additions & 0 deletions src/components/Switch/Switch.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import React from 'react';
import Switch, { PatSwitchProps } from './Switch';
import { render, fireEvent, screen } from '@testing-library/react';

describe('Switch', () => {
it('should match snapshot', () => {
const { asFragment } = render(<Switch label="Snapshot Switch" />);
expect(asFragment()).toMatchSnapshot();
});

it('should render default switch', () => {
render(<Switch label="Default Switch"></Switch>);
const element = screen.getByTestId('switch-element');
const checkbox = screen.getByRole('checkbox');
const label = screen.getByText('Default Switch');
const slider = screen.getByTestId('test-slider');

expect(element).toBeInTheDocument();
expect(checkbox).toBeInTheDocument();
expect(label).toBeInTheDocument();
expect(slider).toBeInTheDocument();
expect(slider).toHaveClass('switch-slider');
expect(element).toHaveClass('switch switch-sm');
expect(checkbox).not.toBeChecked();
fireEvent.click(checkbox);
expect(checkbox).toBeChecked();
expect(element).toHaveClass('switch-default');
});

it('should render corrsonding button based on props', () => {
const switchLargePrimary: PatSwitchProps = {
switchColor: 'primary',
switchSize: 'lg',
className: 'test',
};

render(
<Switch label="Large Primary Switch" {...switchLargePrimary}></Switch>
);
const element = screen.getByTestId('switch-element');
const checkbox = screen.getByRole('checkbox');
const label = screen.getByText('Large Primary Switch');
const slider = screen.getByTestId('test-slider');

expect(element).toBeInTheDocument();
expect(checkbox).toBeInTheDocument();
expect(label).toBeInTheDocument();
expect(slider).toBeInTheDocument();
expect(slider).toHaveClass('switch-slider');
expect(element).toHaveClass('switch switch-lg test');
expect(checkbox).not.toBeChecked();
fireEvent.click(checkbox);
expect(checkbox).toBeChecked();
});

it('should render on switch', () => {
const switchDefualtOn: PatSwitchProps = {
isChecked: true,
};

render(<Switch label="Default On Switch" {...switchDefualtOn}></Switch>);
const element = screen.getByTestId('switch-element');
const checkbox = screen.getByRole('checkbox');
const label = screen.getByText('Default On Switch');
const slider = screen.getByTestId('test-slider');

expect(element).toBeInTheDocument();
expect(checkbox).toBeInTheDocument();
expect(label).toBeInTheDocument();
expect(slider).toBeInTheDocument();
expect(slider).toHaveClass('switch-slider');
expect(element).toHaveClass('switch switch-default switch-sm');
fireEvent.click(checkbox);
expect(checkbox).toBeChecked();
expect(checkbox).toHaveAttribute('checked', '');
});

it('should render a disabled switch', () => {
const disabledSwitchProp: PatSwitchProps = {
disabled: true,
onClick: jest.fn(),
};
render(<Switch label="Disabled Switch" {...disabledSwitchProp}></Switch>);
const element = screen.getByTestId('switch-element');
const checkbox = screen.getByRole('checkbox');
const label = screen.getByText('Disabled Switch');
const slider = screen.getByTestId('test-slider');
expect(element).toBeInTheDocument();
expect(checkbox).toBeInTheDocument();
expect(label).toBeInTheDocument();
expect(slider).toBeInTheDocument();
expect(slider).toHaveClass('switch-slider');
expect(element).toBeInTheDocument();
expect(checkbox).toBeInTheDocument();
expect(label).toBeInTheDocument();
expect(slider).toBeInTheDocument();
expect(element).toHaveClass('switch switch-default switch-sm');
expect(disabledSwitchProp.onClick).toHaveBeenCalledTimes(0);
fireEvent.click(element);
expect(disabledSwitchProp.onClick).toHaveBeenCalledTimes(0);
expect(slider).toHaveClass('disabled');
});
});
85 changes: 85 additions & 0 deletions src/components/Switch/Switch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { FC, InputHTMLAttributes } from 'react';

import { classNames } from '../../utils/classNames';

export type SwitchSize = 'sm' | 'lg';
export type SwitchColor = 'primary' | 'secondary' | 'default';

export interface ISwitchProps {
/** set class name */
className?: string;
/** set switch size */
switchSize?: SwitchSize;
/** set switch color */
switchColor?: SwitchColor;
/** set disabled switch */
disabled?: boolean;
/** set default to checked */
isChecked?: boolean;
/** set switch label */
label?: string;
}

export type PatSwitchProps = ISwitchProps &
InputHTMLAttributes<HTMLInputElement>;

/**
* Switches toggle the state of a single setting on or off.
*
* ```js
* import {Switch} from 'pat-ui'
* ```
*
*/
const Switch: FC<PatSwitchProps> = (props) => {
const {
switchSize,
className,
disabled = false,
switchColor,
label,
isChecked,
...rest
} = props;
let styleClasses = classNames('switch', {
[`switch-${isChecked ? switchColor : 'default'}`]: true,
[`switch-${switchSize}`]: !!switchSize,
disabled: !!disabled,
});
if (className) {
styleClasses += ' ' + className;
}

let swh = (
<div className={styleClasses} data-testid="switch-element">
<label className="switch-container">
<div>
<input
disabled={disabled}
type="checkbox"
className="switch-toggle"
data-testid="switch-toggle"
checked={isChecked}
{...rest}
/>
<span
//set class name based on if switch is disabled or not
data-testid="test-slider"
className={disabled ? 'disabled switch-slider' : 'switch-slider'}
/>
</div>
</label>
<p className="switch-label">{label}</p>
</div>
);

return swh;
};

Switch.defaultProps = {
switchColor: 'default',
disabled: false,
switchSize: 'sm',
};

export default Switch;
31 changes: 31 additions & 0 deletions src/components/Switch/__snapshots__/Switch.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Switch should match snapshot 1`] = `
<DocumentFragment>
<div
class="switch switch-default switch-sm"
data-testid="switch-element"
>
<label
class="switch-container"
>
<div>
<input
class="switch-toggle"
data-testid="switch-toggle"
type="checkbox"
/>
<span
class="switch-slider"
data-testid="test-slider"
/>
</div>
</label>
<p
class="switch-label"
>
Snapshot Switch
</p>
</div>
</DocumentFragment>
`;
1 change: 1 addition & 0 deletions src/components/Switch/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './Switch';
Loading