Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EuiComboBox, EuiPopover] Update esc logic #4336

Merged
merged 4 commits into from
Dec 7, 2020

Conversation

thompsongl
Copy link
Contributor

@thompsongl thompsongl commented Dec 3, 2020

Summary

Fixes #4306, in which an EuiComboBox inside an EuiPopover would close both the options list and the popover when hitting escape. Adds additional logic to the key press handler.

The reason for the change is the move to having react-focus-on (via EuiFocusTrap) handle escape (previously EuiFocusTrap had its own logic). react-focus-on attaches the onKeyDown event to the document and uses !event.defaultPrevented as its prevention logic.

Checklist

- [ ] Check against all themes for compatibility in both light and dark modes
- [ ] Checked in mobile
- [ ] Checked in Chrome, Safari, Edge, and Firefox
- [ ] Props have proper autodocs
- [ ] Added documentation
- [ ] Checked Code Sandbox works for the any docs examples
- [ ] Added or updated jest tests

  • Checked for breaking changes and labeled appropriately
  • Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_4336/

@chandlerprall
Copy link
Contributor

One other case to handle (which wasn't listed in #4306) - something about esc in a popover within a flyout closes the popover.

I modified expression.js to the following to reproduce:

import React, { useState } from 'react';

import {
  EuiButton,
  EuiFlexItem,
  EuiFlexGroup,
  EuiPopover,
  EuiFlyout,
  EuiSelect,
  EuiFieldNumber,
  EuiExpression,
} from '../../../../src/components';

// Rise the popovers above GuidePageSideNav
const POPOVER_STYLE = { zIndex: '200' };

export default () => {
  const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);

  const [example2, setExample2] = useState({
    value: 100,
    description: 'Is above',
  });

  const openExample2 = () => {
    setExample2({
      ...example2,
      isOpen: true,
    });
  };

  const closeExample2 = () => {
    setExample2({
      ...example2,
      isOpen: false,
    });
  };

  const changeExample2Value = (e) => {
    const sanitizedValue = parseInt(e.target.value, 10);
    setExample2({
      ...example2,
      value: isNaN(sanitizedValue) ? '' : sanitizedValue,
    });
  };

  const changeExample2Description = (event) => {
    setExample2({
      ...example2,
      description: event.target.value,
    });
  };

  const renderExpressionPopover = () => (
    <EuiPopover
      id="popover2"
      panelPaddingSize="s"
      button={
        <EuiExpression
          description={example2.description}
          value={example2.value}
          isActive={example2.isOpen}
          onClick={openExample2}
        />
      }
      isOpen={example2.isOpen}
      closePopover={closeExample2}
      ownFocus
      anchorPosition="downLeft">
      {renderPopover2()}
    </EuiPopover>
  );

  const renderPopover2 = () => (
    <div style={POPOVER_STYLE}>
      <EuiFlexGroup gutterSize="s">
        <EuiFlexItem grow={false} style={{ width: 150 }}>
          <EuiSelect
            compressed
            value={example2.description}
            onChange={changeExample2Description}
            options={[
              { value: 'Is above', text: 'Is above' },
              { value: 'Is below', text: 'Is below' },
              { value: 'Is exactly', text: 'Is exactly' },
            ]}
          />
        </EuiFlexItem>

        <EuiFlexItem grow={false} style={{ width: 100 }}>
          <EuiFieldNumber
            compressed
            value={example2.value}
            onChange={changeExample2Value}
          />
        </EuiFlexItem>
      </EuiFlexGroup>
    </div>
  );

  return (
    <>
      <EuiButton onClick={() => setIsFlyoutOpen(true)}>Open flyout</EuiButton>
      {
        isFlyoutOpen && (
          <EuiFlyout
            onClose={() => setIsFlyoutOpen(false)}
          >
            {renderExpressionPopover()}
          </EuiFlyout>
        )
      }
    </>
  );
};

@thompsongl
Copy link
Contributor Author

One other case to handle

Updated to fix. Should be a more broadly applicable update.

@thompsongl thompsongl changed the title [EuiComboBox] Update esc logic [EuiComboBox, EuiPopover] Update esc logic Dec 3, 2020
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_4336/

Copy link
Contributor

@chandlerprall chandlerprall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested the various problem states locally, everything looks good 👍

Needs a changelog before merging.

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_4336/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[EuiComboBox] escape key to close options list also closes wrapping popover
3 participants