From dab3119ac9d2614a1fb4523b27ab8d30807f6a6d Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Tue, 22 Oct 2019 14:12:06 -0500 Subject: [PATCH 01/10] Convert `EuiSwitch` to TS (#2243) * convert euiswitch to ts * remove test file * euiswitchevent; store id in state * change interface to type * CL --- src-docs/src/views/form_controls/switch.js | 4 +- src/components/form/_variables.scss | 1 + src/components/form/index.d.ts | 1 - .../switch/__snapshots__/switch.test.js.snap | 81 -------- .../switch/__snapshots__/switch.test.tsx.snap | 97 ++++++++++ src/components/form/switch/_switch.scss | 178 +++++------------- src/components/form/switch/index.d.ts | 16 -- src/components/form/switch/index.js | 1 - src/components/form/switch/index.ts | 1 + src/components/form/switch/switch.js | 89 --------- .../{switch.test.js => switch.test.tsx} | 12 +- src/components/form/switch/switch.tsx | 103 ++++++++++ src/global_styling/reset/_reset.scss | 7 +- 13 files changed, 272 insertions(+), 319 deletions(-) delete mode 100644 src/components/form/switch/__snapshots__/switch.test.js.snap create mode 100644 src/components/form/switch/__snapshots__/switch.test.tsx.snap delete mode 100644 src/components/form/switch/index.d.ts delete mode 100644 src/components/form/switch/index.js create mode 100644 src/components/form/switch/index.ts delete mode 100644 src/components/form/switch/switch.js rename src/components/form/switch/{switch.test.js => switch.test.tsx} (65%) create mode 100644 src/components/form/switch/switch.tsx diff --git a/src-docs/src/views/form_controls/switch.js b/src-docs/src/views/form_controls/switch.js index d47a81a244e..69ea2b4c741 100644 --- a/src-docs/src/views/form_controls/switch.js +++ b/src-docs/src/views/form_controls/switch.js @@ -11,9 +11,9 @@ export default class extends Component { }; } - onChange = e => { + onChange = () => { this.setState({ - checked: e.target.checked, + checked: !this.state.checked, }); }; diff --git a/src/components/form/_variables.scss b/src/components/form/_variables.scss index c556fec274e..fb1272ceb07 100644 --- a/src/components/form/_variables.scss +++ b/src/components/form/_variables.scss @@ -31,3 +31,4 @@ $euiFormControlDisabledColor: $euiColorMediumShade !default; $euiFormControlBoxShadow: 0 1px 1px -1px transparentize($euiShadowColor, .8), 0 3px 2px -2px transparentize($euiShadowColor, .8) !default; $euiFormInputGroupLabelBackground: tintOrShade($euiColorLightShade, 65%, 40%) !default; $euiFormInputGroupBorder: 1px solid shadeOrTint($euiFormInputGroupLabelBackground, 6%, 8%) !default; +$euiSwitchOffColor: lightOrDarkTheme(transparentize($euiColorMediumShade, .8), transparentize($euiColorMediumShade, .3)) !default; diff --git a/src/components/form/index.d.ts b/src/components/form/index.d.ts index 366419d36f9..a31e554069b 100644 --- a/src/components/form/index.d.ts +++ b/src/components/form/index.d.ts @@ -9,7 +9,6 @@ import { CommonProps } from '../common'; /// /// /// -/// /// import { FunctionComponent, FormHTMLAttributes, ReactNode } from 'react'; diff --git a/src/components/form/switch/__snapshots__/switch.test.js.snap b/src/components/form/switch/__snapshots__/switch.test.js.snap deleted file mode 100644 index 7d5d582e468..00000000000 --- a/src/components/form/switch/__snapshots__/switch.test.js.snap +++ /dev/null @@ -1,81 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`EuiSwitch assigns automatically generated ID to label 1`] = ` -
- - - - - - - - -
-`; - -exports[`EuiSwitch is rendered 1`] = ` -
- - - - - - - - -
-`; diff --git a/src/components/form/switch/__snapshots__/switch.test.tsx.snap b/src/components/form/switch/__snapshots__/switch.test.tsx.snap new file mode 100644 index 00000000000..b05767ccc4d --- /dev/null +++ b/src/components/form/switch/__snapshots__/switch.test.tsx.snap @@ -0,0 +1,97 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EuiSwitch assigns automatically generated ID to label 1`] = ` +
+ + +
+`; + +exports[`EuiSwitch is rendered 1`] = ` +
+ + +
+`; diff --git a/src/components/form/switch/_switch.scss b/src/components/form/switch/_switch.scss index 39da09d6202..a143b66ffee 100644 --- a/src/components/form/switch/_switch.scss +++ b/src/components/form/switch/_switch.scss @@ -4,30 +4,63 @@ min-height: $euiSwitchHeight; .euiSwitch__label { + cursor: pointer; padding-left: $euiSizeS; line-height: $euiSwitchHeight; font-size: $euiFontSizeS; vertical-align: middle; } - /** - * 1. The input is "hidden" but still focusable. - * 2. Make sure it's still hidden when [disabled]. - */ - .euiSwitch__input, - .euiSwitch__input[disabled] /* 2 */ { - position: absolute; - opacity: 0; /* 1 */ - width: 100%; - height: 100%; - cursor: pointer; - } - - .euiSwitch__input:focus + .euiSwitch__body { + .euiSwitch__button { + line-height: 0; // ensures button takes height of switch inside - .euiSwitch__thumb { + &:focus .euiSwitch__thumb { @include euiCustomControlFocused; } + + &:disabled { + &:hover, + ~ .euiSwitch__label:hover { + cursor: not-allowed; + } + + .euiSwitch__body { + background-color: $euiSwitchOffColor; + } + + .euiSwitch__thumb { + @include euiCustomControlDisabled; + background-color: $euiSwitchOffColor; + } + + .euiSwitch__icon { + fill: $euiFormCustomControlDisabledIconColor; + } + + + .euiSwitch__label { + color: $euiFormControlDisabledColor; + } + } + + &[aria-checked='false'] { + .euiSwitch__body { + background-color: $euiSwitchOffColor; + } + + // When input is not checked, we shift around the positioning of the thumb and the icon + .euiSwitch__thumb { // move the thumb left + left: 0; + } + + .euiSwitch__icon { // move the icon right + right: -$euiSizeS; + + &.euiSwitch__icon--checked { + right: auto; + left: -($euiSwitchWidth - ($euiSwitchThumbSize / 2)); + } + } + } } .euiSwitch__body { @@ -77,120 +110,13 @@ fill: $euiColorEmptyShade; } - /** - * The thumb is slightly scaled when in use, unless it's disabled. - */ - &:hover { - .euiSwitch__input:not(:disabled) ~ .euiSwitch__body { - .euiSwitch__thumb { - transform: scale(1.05); - } + &:hover .euiSwitch__button { + &:not(:disabled) .euiSwitch__thumb { + transform: scale(1.05); } - } - &:active { - .euiSwitch__thumb { + &:active .euiSwitch__thumb { transform: scale(.95); } } - - .euiSwitch__input:disabled:hover { - cursor: not-allowed; - } - - .euiSwitch__input:disabled ~ .euiSwitch__body, - .euiSwitch__input:checked:disabled ~ .euiSwitch__body { - background-color: lightOrDarkTheme(transparentize($euiColorMediumShade, .8), transparentize($euiColorMediumShade, .3)); - - .euiSwitch__thumb { - @include euiCustomControlDisabled; - - border-color: $euiFormBorderColor; - background-color: lightOrDarkTheme(transparentize($euiColorMediumShade, .8), transparentize($euiColorMediumShade, .3)); - } - - .euiSwitch__icon { - fill: $euiFormCustomControlDisabledIconColor; - } - - + label { - color: $euiFormControlDisabledColor; - } - } - - .euiSwitch__input:checked:disabled ~ .euiSwitch__body { - background-color: lightOrDarkTheme(transparentize($euiColorMediumShade, .7), transparentize($euiColorMediumShade, .4)); - } - - // Slightly darker background when in a checked state. - .euiSwitch__input:not(:checked):not(:disabled) ~ .euiSwitch__body { - background-color: lightOrDarkTheme(transparentize($euiColorMediumShade, .8), transparentize($euiColorMediumShade, .3)); - } - - /** - * When input is not checked, we shift around the positioning of sibling/child selectors. - */ - .euiSwitch__input:not(:checked) ~ .euiSwitch__body { - .euiSwitch__thumb { - left: 0; - } - - .euiSwitch__icon { - right: -$euiSizeS; - - &.euiSwitch__icon--checked { - right: auto; - left: -($euiSwitchWidth - ($euiSwitchThumbSize / 2)); - } - } - } - - // Compressed switches operate very similar to the normal versions, but are smaller, contain no icon signifiers - &.euiSwitch--compressed { - min-height: $euiSwitchHeightCompressed; - - .euiSwitch__label { - line-height: $euiSwitchHeightCompressed; - } - - .euiSwitch__body { - width: $euiSwitchWidthCompressed; - height: $euiSwitchHeightCompressed; - border-radius: $euiSwitchHeightCompressed; - } - - .euiSwitch__thumb { - @include euiCustomControl($type: 'round', $size: ($euiSwitchThumbSizeCompressed) - 2px); - - left: ($euiSwitchWidthCompressed) - (($euiSwitchThumbSizeCompressed) - 2px) - 1px; - top: 1px; - transition: border-color $euiAnimSpeedNormal $euiAnimSlightBounce, background-color $euiAnimSpeedNormal $euiAnimSlightBounce, left $euiAnimSpeedNormal $euiAnimSlightBounce, transform $euiAnimSpeedNormal $euiAnimSlightBounce; - } - - .euiSwitch__track { - border-radius: $euiSwitchHeightCompressed; - } - - .euiSwitch__input:not(:checked) ~ .euiSwitch__body { - .euiSwitch__thumb { - left: 1px; - } - } - - // Compressed switches need slightly darker borders since they don't have icons - .euiSwitch__input:not(:checked) ~ .euiSwitch__body, - .euiSwitch__input:checked:disabled ~ .euiSwitch__body { - .euiSwitch__thumb { - border-color: $euiFormCustomControlBorderColor; - } - } - - // Similar additional treatment needed while checked - .euiSwitch__input:checked ~ .euiSwitch__body { - .euiSwitch__thumb { - border-color: $euiColorPrimary; - } - } - - } } diff --git a/src/components/form/switch/index.d.ts b/src/components/form/switch/index.d.ts deleted file mode 100644 index 3afc67edcb7..00000000000 --- a/src/components/form/switch/index.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { CommonProps } from '../../common'; - -import { FunctionComponent, InputHTMLAttributes, ReactNode } from 'react'; - -declare module '@elastic/eui' { - /** - * @see './switch.js' - */ - export type EuiSwitchProps = CommonProps & - InputHTMLAttributes & { - label?: ReactNode; - compressed?: boolean; - }; - - export const EuiSwitch: FunctionComponent; -} diff --git a/src/components/form/switch/index.js b/src/components/form/switch/index.js deleted file mode 100644 index 893cd7f7f6c..00000000000 --- a/src/components/form/switch/index.js +++ /dev/null @@ -1 +0,0 @@ -export { EuiSwitch } from './switch'; diff --git a/src/components/form/switch/index.ts b/src/components/form/switch/index.ts new file mode 100644 index 00000000000..6c4ce9a8635 --- /dev/null +++ b/src/components/form/switch/index.ts @@ -0,0 +1 @@ +export { EuiSwitch, EuiSwitchEvent, EuiSwitchProps } from './switch'; diff --git a/src/components/form/switch/switch.js b/src/components/form/switch/switch.js deleted file mode 100644 index 06c490887e9..00000000000 --- a/src/components/form/switch/switch.js +++ /dev/null @@ -1,89 +0,0 @@ -import React, { Component, Fragment } from 'react'; - -import PropTypes from 'prop-types'; -import classNames from 'classnames'; - -import makeId from '../../form/form_row/make_id'; -import { EuiIcon } from '../../icon'; - -export class EuiSwitch extends Component { - constructor(props) { - super(props); - - this.state = { - switchId: props.id || makeId(), - }; - } - - render() { - const { - label, - id, - name, - checked, - disabled, - compressed, - onChange, - className, - ...rest - } = this.props; - - const { switchId } = this.state; - - const classes = classNames( - 'euiSwitch', - { - 'euiSwitch--compressed': compressed, - }, - className - ); - - return ( -
- - - - - - {!compressed && ( - - - - - - )} - - - - {label && ( - - )} -
- ); - } -} - -EuiSwitch.propTypes = { - name: PropTypes.string, - id: PropTypes.string, - label: PropTypes.node, - checked: PropTypes.bool, - onChange: PropTypes.func, - disabled: PropTypes.bool, - compressed: PropTypes.bool, -}; diff --git a/src/components/form/switch/switch.test.js b/src/components/form/switch/switch.test.tsx similarity index 65% rename from src/components/form/switch/switch.test.js rename to src/components/form/switch/switch.test.tsx index 50927c7fa6e..a564df98ca1 100644 --- a/src/components/form/switch/switch.test.js +++ b/src/components/form/switch/switch.test.tsx @@ -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(); + const component = render( + + ); expect(component).toMatchSnapshot(); }); test('assigns automatically generated ID to label', () => { - const component = render(); + const component = render(); expect(component).toMatchSnapshot(); }); diff --git a/src/components/form/switch/switch.tsx b/src/components/form/switch/switch.tsx new file mode 100644 index 00000000000..9c7d8dde9c0 --- /dev/null +++ b/src/components/form/switch/switch.tsx @@ -0,0 +1,103 @@ +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, + EventTarget & { + checked: boolean; + } +>; + +export type EuiSwitchProps = CommonProps & + Omit, 'onChange'> & { + /** + * Whether to render the render the text label + */ + showLabel?: boolean; + /** + * Must be a string if `showLabel` prop is false + */ + label: ReactNode | string; + checked: boolean; + onChange: (event: EuiSwitchEvent) => void; + disabled?: boolean; + compressed?: boolean; + }; + +export const EuiSwitch: FunctionComponent = ({ + label, + id, + name, + checked, + disabled, + compressed, + onChange, + className, + showLabel = true, + ...rest +}) => { + const [switchId] = useState(id || makeId()); + + const onClick = (e: React.MouseEvent) => { + const event = (e as unknown) as EuiSwitchEvent; + event.target.checked = !checked; + onChange(event); + }; + + const classes = classNames( + 'euiSwitch', + { + 'euiSwitch--compressed': compressed, + }, + className + ); + + if (showLabel === false && typeof label !== 'string') { + console.warn( + 'EuiSwitch `label` must be a string when `showLabel` is false.' + ); + } + + return ( +
+ + + {showLabel && ( + + )} +
+ ); +}; diff --git a/src/global_styling/reset/_reset.scss b/src/global_styling/reset/_reset.scss index 0824f6a834e..26d7b809ea5 100644 --- a/src/global_styling/reset/_reset.scss +++ b/src/global_styling/reset/_reset.scss @@ -71,6 +71,11 @@ body { *:focus { outline: none; + + // sass-lint:disable no-vendor-prefixes + &::-moz-focus-inner { + border: none; + } } a { @@ -136,4 +141,4 @@ hr { fieldset { min-inline-size: auto; -} \ No newline at end of file +} From 849e0be680a20287171079033085660591b3dd0e Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Thu, 24 Oct 2019 18:10:30 -0500 Subject: [PATCH 02/10] type for button --- src/components/form/switch/__snapshots__/switch.test.tsx.snap | 2 ++ src/components/form/switch/switch.tsx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/components/form/switch/__snapshots__/switch.test.tsx.snap b/src/components/form/switch/__snapshots__/switch.test.tsx.snap index b05767ccc4d..7f947d80ce5 100644 --- a/src/components/form/switch/__snapshots__/switch.test.tsx.snap +++ b/src/components/form/switch/__snapshots__/switch.test.tsx.snap @@ -9,6 +9,7 @@ exports[`EuiSwitch assigns automatically generated ID to label 1`] = ` class="euiSwitch__button" id="generated-id" role="switch" + type="button" > = ({ onChange, className, showLabel = true, + type = 'button', ...rest }) => { const [switchId] = useState(id || makeId()); @@ -75,6 +76,7 @@ export const EuiSwitch: FunctionComponent = ({ aria-checked={checked} className="euiSwitch__button" role="switch" + type={type} disabled={disabled} onClick={onClick} aria-label={showLabel === false ? (label as string) : undefined} From d17e396b2b88d6502ce001e5eb1d9f43b15c6186 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Thu, 24 Oct 2019 18:11:38 -0500 Subject: [PATCH 03/10] showLabel=false example --- src-docs/src/views/form_controls/switch.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src-docs/src/views/form_controls/switch.js b/src-docs/src/views/form_controls/switch.js index 69ea2b4c741..5b5b7aa1664 100644 --- a/src-docs/src/views/form_controls/switch.js +++ b/src-docs/src/views/form_controls/switch.js @@ -53,6 +53,15 @@ export default class extends Component { compressed disabled /> + + + + ); } From aa064f791538f6b8e384b5e8467c170ebd691935 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Thu, 24 Oct 2019 18:30:22 -0500 Subject: [PATCH 04/10] fix misc docs proptype warnings --- src-docs/src/views/context_menu/context_menu.js | 4 ++++ .../src/views/date_picker/super_date_picker.js | 2 +- .../src/views/form_compressed/form_horizontal.js | 2 ++ src-docs/src/views/form_controls/switch.js | 4 ++-- src-docs/src/views/popover/trap_focus.js | 14 ++++++++++++-- src-docs/src/views/tables/paginated/paginated.js | 1 + 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src-docs/src/views/context_menu/context_menu.js b/src-docs/src/views/context_menu/context_menu.js index 1b724641ca3..531ec2e7449 100644 --- a/src-docs/src/views/context_menu/context_menu.js +++ b/src-docs/src/views/context_menu/context_menu.js @@ -79,6 +79,8 @@ export default class extends Component { name="switch" id="asdf" label="Snapshot data" + checked={true} + onChange={() => {}} /> @@ -86,6 +88,8 @@ export default class extends Component { name="switch" id="asdf2" label="Current time range" + checked={true} + onChange={() => {}} /> diff --git a/src-docs/src/views/date_picker/super_date_picker.js b/src-docs/src/views/date_picker/super_date_picker.js index d92324ef9c6..7710d32bb2c 100644 --- a/src-docs/src/views/date_picker/super_date_picker.js +++ b/src-docs/src/views/date_picker/super_date_picker.js @@ -22,7 +22,7 @@ function MyCustomQuickSelectPanel({ applyTime }) { export default class extends Component { state = { recentlyUsedRanges: [], - isDiasabled: false, + isDisabled: false, isLoading: false, showUpdateButton: true, isAutoRefreshOnly: false, diff --git a/src-docs/src/views/form_compressed/form_horizontal.js b/src-docs/src/views/form_compressed/form_horizontal.js index a69d5931ac0..8e28f4ddd63 100644 --- a/src-docs/src/views/form_compressed/form_horizontal.js +++ b/src-docs/src/views/form_compressed/form_horizontal.js @@ -91,6 +91,8 @@ export default class extends Component { { + onChange = e => { this.setState({ - checked: !this.state.checked, + checked: e.target.checked, }); }; diff --git a/src-docs/src/views/popover/trap_focus.js b/src-docs/src/views/popover/trap_focus.js index 7d69f04ceb5..d8dde77ae6c 100644 --- a/src-docs/src/views/popover/trap_focus.js +++ b/src-docs/src/views/popover/trap_focus.js @@ -48,11 +48,21 @@ export default class extends Component { closePopover={this.closePopover.bind(this)} initialFocus="[id=asdf2]"> - + {}} + /> - + {}} + /> diff --git a/src-docs/src/views/tables/paginated/paginated.js b/src-docs/src/views/tables/paginated/paginated.js index a2d8fa76ec2..d658a6c3714 100644 --- a/src-docs/src/views/tables/paginated/paginated.js +++ b/src-docs/src/views/tables/paginated/paginated.js @@ -154,6 +154,7 @@ export class Table extends Component { return (
Hide per page options with{' '} From 631a5806b03ce530ce630fdc26dcd18aadb73fa6 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Fri, 25 Oct 2019 09:39:53 -0500 Subject: [PATCH 05/10] reintroduce compressed and mini styles --- src/components/form/switch/_switch.scss | 81 +++++++++++++++++++++++++ src/components/form/switch/switch.tsx | 16 +++-- 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/src/components/form/switch/_switch.scss b/src/components/form/switch/_switch.scss index a143b66ffee..ffc6e9a8009 100644 --- a/src/components/form/switch/_switch.scss +++ b/src/components/form/switch/_switch.scss @@ -119,4 +119,85 @@ transform: scale(.95); } } + + // Compressed switches operate very similar to the normal versions, but are smaller, contain no icon signifiers + &.euiSwitch--compressed { + min-height: $euiSwitchHeightCompressed; + + .euiSwitch__label { + line-height: $euiSwitchHeightCompressed; + } + + .euiSwitch__body { + width: $euiSwitchWidthCompressed; + height: $euiSwitchHeightCompressed; + border-radius: $euiSwitchHeightCompressed; + } + + .euiSwitch__thumb { + @include euiCustomControl($type: 'round', $size: ($euiSwitchThumbSizeCompressed) - 2px); + + left: ($euiSwitchWidthCompressed) - (($euiSwitchThumbSizeCompressed) - 2px) - 1px; + top: 1px; + transition: border-color $euiAnimSpeedNormal $euiAnimSlightBounce, background-color $euiAnimSpeedNormal $euiAnimSlightBounce, left $euiAnimSpeedNormal $euiAnimSlightBounce, transform $euiAnimSpeedNormal $euiAnimSlightBounce; + } + + .euiSwitch__track { + border-radius: $euiSwitchHeightCompressed; + } + } + + // Mini styling is similar to compressed, but even smaller. It's undocumented because it has very specific uses. + &.euiSwitch--mini { + min-height: $euiSwitchHeightMini; + + .euiSwitch__label { + line-height: $euiSwitchHeightMini; + font-size: $euiFontSizeXS; + } + + .euiSwitch__body { + width: $euiSwitchWidthMini; + height: $euiSwitchHeightMini; + border-radius: $euiSwitchHeightMini; + } + + .euiSwitch__thumb { + @include euiCustomControl($type: 'round', $size: ($euiSwitchThumbSizeMini) - 2px); + + left: ($euiSwitchWidthMini) - (($euiSwitchThumbSizeMini) - 2px) - 1px; + top: 1px; + transition: border-color $euiAnimSpeedNormal $euiAnimSlightBounce, background-color $euiAnimSpeedNormal $euiAnimSlightBounce, left $euiAnimSpeedNormal $euiAnimSlightBounce, transform $euiAnimSpeedNormal $euiAnimSlightBounce; + } + + .euiSwitch__track { + border-radius: $euiSwitchHeightMini; + } + } + + // Compressed and mini switches have some style overlap + &.euiSwitch--compressed, + &.euiSwitch--mini { + + .euiSwitch__button[aria-checked='false'] { + .euiSwitch__thumb { + left: 1px; + } + } + + // Compressed and mini switches need slightly darker borders since they don't have icons + .euiSwitch__button[aria-checked='false'], + .euiSwitch__button[aria-checked='true']:disabled { + .euiSwitch__thumb { + border-color: $euiFormCustomControlBorderColor; + } + } + + // Similar additional treatment needed while checked + .euiSwitch__button[aria-checked='true'] { + .euiSwitch__thumb { + border-color: $euiColorPrimary; + } + } + } } diff --git a/src/components/form/switch/switch.tsx b/src/components/form/switch/switch.tsx index fe829eddc5f..7460c535cd3 100644 --- a/src/components/form/switch/switch.tsx +++ b/src/components/form/switch/switch.tsx @@ -84,13 +84,17 @@ export const EuiSwitch: FunctionComponent = ({ - + {!compressed && ( + + - + + + )} From a12c9415c1de3830e6282ca6b266a6edf0ac4d3d Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Fri, 25 Oct 2019 10:04:14 -0500 Subject: [PATCH 06/10] another example --- src-docs/src/views/form_controls/switch.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src-docs/src/views/form_controls/switch.js b/src-docs/src/views/form_controls/switch.js index 1cfbdd9e3e4..eab0ffd7e42 100644 --- a/src-docs/src/views/form_controls/switch.js +++ b/src-docs/src/views/form_controls/switch.js @@ -37,6 +37,15 @@ export default class extends Component { + + + + ); From c0cf4b44f0003c4e15e70429016b900378715b56 Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Fri, 25 Oct 2019 14:07:03 -0500 Subject: [PATCH 07/10] CL --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d202b08001..b49972e8164 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,15 @@ ## [`master`](https://github.com/elastic/eui/tree/master) - Added `euiXScrollWithShadows()` mixin and `.eui-xScrollWithShadows` utility class ([#2458](https://github.com/elastic/eui/pull/2458)) +- Improved `EuiSwitch` a11y by aligning to aria roles ([#2491](https://github.com/elastic/eui/pull/2491)) +- Converted `EuiSwitch` to Typescript ([#2491](https://github.com/elastic/eui/pull/2491)) +- Added an accessible label-less `EuiSwitch` variation ([#2491](https://github.com/elastic/eui/pull/2491)) **Bug fixes** - Normalized button `moz-focus-inner` ([#2445](https://github.com/elastic/eui/pull/2445)) - Fixed typo to correct `aria-modal` attribute in`EuiPopover` ([#2488](https://github.com/elastic/eui/pull/2488)) +- Fixed `EuiSwitch` form behavior by adding a default button `type` of 'button' ([#2491](https://github.com/elastic/eui/pull/2491)) ## [`14.8.0`](https://github.com/elastic/eui/tree/v14.8.0) From 5358dda11611b8fe6cad896c1dc874e850a8daca Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Fri, 25 Oct 2019 14:08:51 -0500 Subject: [PATCH 08/10] cleanup --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b49972e8164..d908e3e4288 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ - Added `euiXScrollWithShadows()` mixin and `.eui-xScrollWithShadows` utility class ([#2458](https://github.com/elastic/eui/pull/2458)) - Improved `EuiSwitch` a11y by aligning to aria roles ([#2491](https://github.com/elastic/eui/pull/2491)) -- Converted `EuiSwitch` to Typescript ([#2491](https://github.com/elastic/eui/pull/2491)) +- Converted `EuiSwitch` to TypeScript ([#2491](https://github.com/elastic/eui/pull/2491)) - Added an accessible label-less `EuiSwitch` variation ([#2491](https://github.com/elastic/eui/pull/2491)) **Bug fixes** From 8cc5c9c7a16640271545ef1f1db01053bfbe405a Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Mon, 28 Oct 2019 10:28:13 -0500 Subject: [PATCH 09/10] use p with aria-describedby --- .../form/switch/__snapshots__/switch.test.tsx.snap | 14 ++++++++------ src/components/form/switch/_switch.scss | 1 + src/components/form/switch/switch.tsx | 8 +++++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/components/form/switch/__snapshots__/switch.test.tsx.snap b/src/components/form/switch/__snapshots__/switch.test.tsx.snap index 7f947d80ce5..a6eecef15c4 100644 --- a/src/components/form/switch/__snapshots__/switch.test.tsx.snap +++ b/src/components/form/switch/__snapshots__/switch.test.tsx.snap @@ -6,6 +6,7 @@ exports[`EuiSwitch assigns automatically generated ID to label 1`] = ` > - +

`; @@ -54,6 +55,7 @@ exports[`EuiSwitch is rendered 1`] = ` > - +

`; diff --git a/src/components/form/switch/_switch.scss b/src/components/form/switch/_switch.scss index ffc6e9a8009..800938ae35b 100644 --- a/src/components/form/switch/_switch.scss +++ b/src/components/form/switch/_switch.scss @@ -9,6 +9,7 @@ line-height: $euiSwitchHeight; font-size: $euiFontSizeS; vertical-align: middle; + display: inline-block; } .euiSwitch__button { diff --git a/src/components/form/switch/switch.tsx b/src/components/form/switch/switch.tsx index 7460c535cd3..8c134c0f2ac 100644 --- a/src/components/form/switch/switch.tsx +++ b/src/components/form/switch/switch.tsx @@ -48,6 +48,7 @@ export const EuiSwitch: FunctionComponent = ({ ...rest }) => { const [switchId] = useState(id || makeId()); + const [labelId] = useState(makeId()); const onClick = (e: React.MouseEvent) => { const event = (e as unknown) as EuiSwitchEvent; @@ -79,7 +80,8 @@ export const EuiSwitch: FunctionComponent = ({ type={type} disabled={disabled} onClick={onClick} - aria-label={showLabel === false ? (label as string) : undefined} + aria-label={showLabel ? undefined : (label as string)} + aria-describedby={showLabel ? labelId : undefined} {...rest}> @@ -100,9 +102,9 @@ export const EuiSwitch: FunctionComponent = ({ {showLabel && ( -