Skip to content

Commit

Permalink
Convert EuiSwitch to TS (elastic#2243)
Browse files Browse the repository at this point in the history
* convert euiswitch to ts

* remove test file

* euiswitchevent; store id in state

* change interface to type

* CL
  • Loading branch information
thompsongl committed Sep 10, 2019
1 parent 7620fff commit dd5f087
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 113 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Converted `EuiSwitch` to TypeScript ([#2243](https://github.com/elastic/eui/pull/2243))

**Bug fixes**

- Added missing `viewBox` attribute to Docker, Kubernetes, and Redis logos ([#2240](https://github.com/elastic/eui/pull/2240))
Expand Down
1 change: 0 additions & 1 deletion src/components/form/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { CommonProps } from '../common';
/// <reference path="./range/index.d.ts" />
/// <reference path="./select/index.d.ts" />
/// <reference path="./super_select/index.d.ts" />
/// <reference path="./switch/index.d.ts" />
/// <reference path="./text_area/index.d.ts" />

import { FunctionComponent, FormHTMLAttributes, ReactNode } from 'react';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ exports[`EuiSwitch assigns automatically generated ID to label 1`] = `
class="euiSwitch"
>
<button
aria-checked="false"
class="euiSwitch__button"
id="generated-id"
role="switch"
Expand Down Expand Up @@ -40,7 +41,9 @@ exports[`EuiSwitch assigns automatically generated ID to label 1`] = `
<label
class="euiSwitch__label"
for="generated-id"
/>
>
Label
</label>
</div>
`;

Expand All @@ -49,6 +52,7 @@ exports[`EuiSwitch is rendered 1`] = `
class="euiSwitch testClass1 testClass2"
>
<button
aria-checked="false"
aria-label="aria-label"
class="euiSwitch__button"
data-test-subj="test subject string"
Expand Down Expand Up @@ -86,6 +90,8 @@ exports[`EuiSwitch is rendered 1`] = `
<label
class="euiSwitch__label"
for="test"
/>
>
Label
</label>
</div>
`;
21 changes: 0 additions & 21 deletions src/components/form/switch/index.d.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/components/form/switch/index.js

This file was deleted.

1 change: 1 addition & 0 deletions src/components/form/switch/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { EuiSwitch, EuiSwitchEvent, EuiSwitchProps } from './switch';
86 changes: 0 additions & 86 deletions src/components/form/switch/switch.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,25 @@ import { requiredProps } from '../../../test/required_props';

import { EuiSwitch } from './switch';

const props = {
checked: false,
label: 'Label',
onChange: () => {},
};

jest.mock('../form_row/make_id', () => () => 'generated-id');

describe('EuiSwitch', () => {
test('is rendered', () => {
const component = render(<EuiSwitch id="test" {...requiredProps} />);
const component = render(
<EuiSwitch id="test" {...props} {...requiredProps} />
);

expect(component).toMatchSnapshot();
});

test('assigns automatically generated ID to label', () => {
const component = render(<EuiSwitch />);
const component = render(<EuiSwitch {...props} />);

expect(component).toMatchSnapshot();
});
Expand Down
86 changes: 86 additions & 0 deletions src/components/form/switch/switch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React, {
ButtonHTMLAttributes,
FunctionComponent,
ReactNode,
useState,
} from 'react';
import classNames from 'classnames';

import { CommonProps, Omit } from '../../common';
import makeId from '../../form/form_row/make_id';
import { EuiIcon } from '../../icon';

export type EuiSwitchEvent = React.BaseSyntheticEvent<
React.MouseEvent<HTMLButtonElement>,
HTMLButtonElement,
EventTarget & {
checked: boolean;
}
>;

export type EuiSwitchProps = CommonProps &
Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange'> & {
label: ReactNode;
checked: boolean;
onChange: (event: EuiSwitchEvent) => void;
disabled?: boolean;
compressed?: boolean;
};

export const EuiSwitch: FunctionComponent<EuiSwitchProps> = ({
label,
id,
name,
checked,
disabled,
compressed,
onChange,
className,
...rest
}) => {
const [switchId] = useState(id || makeId());

const onClick = (e: React.MouseEvent<HTMLButtonElement>) => {
const event = (e as unknown) as EuiSwitchEvent;
event.target.checked = !checked;
onChange(event);
};

const classes = classNames(
'euiSwitch',
{
'euiSwitch--compressed': compressed,
},
className
);

return (
<div className={classes}>
<button
id={switchId}
aria-checked={checked}
className="euiSwitch__button"
role="switch"
disabled={disabled}
onClick={onClick}
{...rest}>
<span className="euiSwitch__body">
<span className="euiSwitch__thumb" />
<span className="euiSwitch__track">
<EuiIcon type="cross" size="m" className="euiSwitch__icon" />

<EuiIcon
type="check"
size="m"
className="euiSwitch__icon euiSwitch__icon--checked"
/>
</span>
</span>
</button>

<label className="euiSwitch__label" htmlFor={switchId}>
{label}
</label>
</div>
);
};

0 comments on commit dd5f087

Please sign in to comment.