From b78e76d2cb2f728ec31d96e7ff3defe6a36e49cc Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Mon, 4 Jun 2018 21:37:06 -0700 Subject: [PATCH] Fix focus state regression of icons in EuiFormControlLayout. (#898) * Fix focus state regression of icons in EuiFormControlLayout. * Refactor EuiFormControlLayout for readability and clarity. * Break up SCSS into multiple files and improve class names. * Normalize DOM structure of EuiFormControlLayoutCustomIcon. --- CHANGELOG.md | 6 +- .../form/file_picker/_file_picker.scss | 2 +- .../form_control_layout.test.js.snap | 178 +++++++++-------- .../_form_control_layout.scss | 51 +---- .../_form_control_layout_clear_button.scss | 3 + .../_form_control_layout_custom_icon.scss | 20 ++ .../_form_control_layout_icons.scss | 18 ++ .../form/form_control_layout/_index.scss | 3 + .../form/form_control_layout/_mixins.scss | 3 +- .../form_control_layout.js | 189 +++--------------- .../form_control_layout_clear_button.js | 32 +++ .../form_control_layout_custom_icon.js | 58 ++++++ .../form_control_layout_icons.js | 114 +++++++++++ 13 files changed, 390 insertions(+), 287 deletions(-) create mode 100644 src/components/form/form_control_layout/_form_control_layout_clear_button.scss create mode 100644 src/components/form/form_control_layout/_form_control_layout_custom_icon.scss create mode 100644 src/components/form/form_control_layout/_form_control_layout_icons.scss create mode 100644 src/components/form/form_control_layout/form_control_layout_clear_button.js create mode 100644 src/components/form/form_control_layout/form_control_layout_custom_icon.js create mode 100644 src/components/form/form_control_layout/form_control_layout_icons.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 394477b5987..b94d5411f7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,11 @@ - Added `restrictWidth` to `EuiPage` ([#896](https://github.com/elastic/eui/pull/896)) **Bug fixes** + - Removed `.nvmrc` file from published npm package ([#892](https://github.com/elastic/eui/pull/892)) - `EuiComboBox` no longer shows the _clear_ icon when it's a no-op ([#890](https://github.com/elastic/eui/pull/890)) - `EuiIcon` no longer takes focus in Edge and IE unless `tabIndex` is defined as a value other than `"-1"` ([#900](https://github.com/elastic/eui/pull/900)) +- Fixed regression introduced in `0.0.50` in which the form control icons blocked users from clicking the control ([#898](https://github.com/elastic/eui/pull/898)) ## [`0.0.51`](https://github.com/elastic/eui/tree/v0.0.51) @@ -16,10 +18,12 @@ **Bug fixes** -- Moved `EuiFieldSearch`'s and `EuiValidateControl`'s ref out of render into setClass methods. ([#883](https://github.com/elastic/eui/pull/883)) +- Moved `EuiFieldSearch`'s and `EuiValidateControl`'s ref out of render into `setRef` methods. ([#883](https://github.com/elastic/eui/pull/883)) ## [`0.0.50`](https://github.com/elastic/eui/tree/v0.0.50) +**Note: this release creates a minor regression to form controls containing icons, in which the icon blocks the user from clicking the control. This is fixed in `0.0.52`.** + - Created `EuiToggle`, `EuiButtonToggle`, and `EuiButtonGroup` ([#872](https://github.com/elastic/eui/pull/872)) - `EuiBasicTable` and `EuiInMemoryTable` now accept `rowProps` and `cellProps` callbacks, - Added `offine` and `online` icons ([#881](https://github.com/elastic/eui/pull/881)) diff --git a/src/components/form/file_picker/_file_picker.scss b/src/components/form/file_picker/_file_picker.scss index ecde7966349..5bc860389bc 100644 --- a/src/components/form/file_picker/_file_picker.scss +++ b/src/components/form/file_picker/_file_picker.scss @@ -110,7 +110,7 @@ position: absolute; top: $euiSizeM/2; right: $euiSizeM; - @include euiFormControlLayout__clear('.euiFilePicker__clearIcon'); + @include euiFormControlLayoutClearIcon('.euiFilePicker__clearIcon'); } } } diff --git a/src/components/form/form_control_layout/__snapshots__/form_control_layout.test.js.snap b/src/components/form/form_control_layout/__snapshots__/form_control_layout.test.js.snap index c76bcdcbd75..bbf5493b167 100644 --- a/src/components/form/form_control_layout/__snapshots__/form_control_layout.test.js.snap +++ b/src/components/form/form_control_layout/__snapshots__/form_control_layout.test.js.snap @@ -15,15 +15,15 @@ exports[`EuiFormControlLayout props clear onClick is rendered 1`] = ` class="euiFormControlLayout" >
`; @@ -89,29 +93,33 @@ exports[`EuiFormControlLayout props icon is rendered as an object 1`] = ` class="euiFormControlLayout" >
- + + + + + +
`; @@ -121,28 +129,32 @@ exports[`EuiFormControlLayout props icon side left is rendered 1`] = ` class="euiFormControlLayout" >
- + + + + + +
`; @@ -152,28 +164,32 @@ exports[`EuiFormControlLayout props icon side right is rendered 1`] = ` class="euiFormControlLayout" >
- + + + + + +
`; @@ -183,7 +199,7 @@ exports[`EuiFormControlLayout props isLoading is rendered 1`] = ` class="euiFormControlLayout" >
* + * { - margin-left: $euiFormControlPadding; - } - } - - .euiFormControlLayout__icons--right { - left: auto; - right: $euiFormControlPadding; - } - - .euiFormControlLayout__clear { - @include euiFormControlLayout__clear('.euiFormControlLayout__clearIcon'); - } +.euiFormControlLayout--fullWidth { + width: 100%; + max-width: 100%; } diff --git a/src/components/form/form_control_layout/_form_control_layout_clear_button.scss b/src/components/form/form_control_layout/_form_control_layout_clear_button.scss new file mode 100644 index 00000000000..0dc57d56668 --- /dev/null +++ b/src/components/form/form_control_layout/_form_control_layout_clear_button.scss @@ -0,0 +1,3 @@ +.euiFormControlLayoutClearButton { + @include euiFormControlLayoutClearIcon('.euiFormControlLayoutClearButton__icon'); +} diff --git a/src/components/form/form_control_layout/_form_control_layout_custom_icon.scss b/src/components/form/form_control_layout/_form_control_layout_custom_icon.scss new file mode 100644 index 00000000000..84a440577a7 --- /dev/null +++ b/src/components/form/form_control_layout/_form_control_layout_custom_icon.scss @@ -0,0 +1,20 @@ +.euiFormControlLayoutCustomIcon { + pointer-events: none; +} + +.euiFormControlLayoutCustomIcon--clickable { + pointer-events: all; + height: $euiSize; + width: $euiSize; + @include size($euiSize); + + .euiFormControlLayoutCustomIcon__clickableIcon { + vertical-align: baseline; + } + + &:focus { + background: $euiColorPrimary; + border-radius: 100%; + color: $euiColorGhost; + } +} diff --git a/src/components/form/form_control_layout/_form_control_layout_icons.scss b/src/components/form/form_control_layout/_form_control_layout_icons.scss new file mode 100644 index 00000000000..dd060e611c7 --- /dev/null +++ b/src/components/form/form_control_layout/_form_control_layout_icons.scss @@ -0,0 +1,18 @@ +.euiFormControlLayoutIcons { + pointer-events: none; + position: absolute; + top: 0; + bottom: 0; + left: $euiFormControlPadding; + display: flex; + align-items: center; + + > * + * { + margin-left: $euiFormControlPadding; + } +} + +.euiFormControlLayoutIcons--right { + left: auto; + right: $euiFormControlPadding; +} diff --git a/src/components/form/form_control_layout/_index.scss b/src/components/form/form_control_layout/_index.scss index 35ed9059c7b..f5a9b5d33bc 100644 --- a/src/components/form/form_control_layout/_index.scss +++ b/src/components/form/form_control_layout/_index.scss @@ -1,2 +1,5 @@ @import 'mixins'; @import 'form_control_layout'; +@import 'form_control_layout_icons'; +@import 'form_control_layout_clear_button'; +@import 'form_control_layout_custom_icon'; diff --git a/src/components/form/form_control_layout/_mixins.scss b/src/components/form/form_control_layout/_mixins.scss index 30828beea91..f15510638f8 100644 --- a/src/components/form/form_control_layout/_mixins.scss +++ b/src/components/form/form_control_layout/_mixins.scss @@ -1,5 +1,6 @@ -@mixin euiFormControlLayout__clear($iconClass) { +@mixin euiFormControlLayoutClearIcon($iconClass) { $clearSize: $euiSize; + pointer-events: all; @include size($clearSize); background-color: transparentize($euiColorMediumShade, .5); diff --git a/src/components/form/form_control_layout/form_control_layout.js b/src/components/form/form_control_layout/form_control_layout.js index a5222c85906..f8c0ce3de1b 100644 --- a/src/components/form/form_control_layout/form_control_layout.js +++ b/src/components/form/form_control_layout/form_control_layout.js @@ -1,165 +1,42 @@ -import React, { Fragment, Component } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import { EuiIcon } from '../../icon'; -import { EuiLoadingSpinner } from '../../loading'; +import { EuiFormControlLayoutIcons } from './form_control_layout_icons' export const ICON_SIDES = ['left', 'right']; -export class EuiFormControlLayout extends Component { - render() { - const { - children, - icon, // eslint-disable-line no-unused-vars - clear, // eslint-disable-line no-unused-vars - fullWidth, - isLoading, // eslint-disable-line no-unused-vars - compressed, - className, - ...rest - } = this.props; - - const classes = classNames( - 'euiFormControlLayout', - { - 'euiFormControlLayout--fullWidth': fullWidth, - 'euiFormControlLayout--compressed': compressed, - }, - className - ); - - return ( -
- {children} - {this.renderIcons()} -
- ); - } - - renderIcons() { - const { - isLoading, - icon, - clear, - } = this.props; - - let optionalLoader; - if (isLoading) { - optionalLoader = ( - - ); - } - - let optionalIconSide; - let optionalIcon; - if (icon) { - // Normalize the icon to an object if it's a string. - const iconProps = typeof icon === 'string' ? { - type: icon, - } : icon; - - const { - className: iconClassName, - type: iconType, - side: iconSide = 'left', - onClick: onIconClick, - ref: iconRef, - ...iconRest - } = iconProps - - optionalIconSide = iconSide - - const iconClasses = classNames( - 'euiFormControlLayout__icon', - iconClassName, - { - 'euiFormControlLayout__icon--button': onIconClick, - }, - ); - - if (onIconClick) { - optionalIcon = ( - - ) - } else { - optionalIcon = ( -