Как обнаружить `onClickOutside` и` onEscapeKeyPress` в пользовательском модале React, созданном как стилизованный компонент - PullRequest
0 голосов
/ 13 декабря 2018

Теперь я потратил значительное количество времени на это.Но я не могу понять это, поскольку я новичок в использовании styled-components .

Я создал компонент в модальном стиле в React.Единственное, что осталось сделать, это добавить функциональность onClickOutside и onEscapeKeyPress.

Но, на мой взгляд, я не могу добавить прослушиватели событий в элемент Modal (или влежащий в основе div элемент).

Вот ссылка на демо коды и коробки

Вот идеальный способ, которым я бы хотел, чтобы пользователь использовал мойкомпонент:

<Modal
    show={this.state.isOpen}
    onBackgroundClick={this.toggleModal}
    onEscapeKeydown={this.toggleModal}
    >
    <Modal.Wrapper>
        <Modal.Header>
            <!-- ignore this -->
        </Modal.Header>
        <Modal.Body>
            <!-- ignore this -->
        </Modal.Body>
        <Modal.Footer>
            <!-- ignore this -->
        </Modal.Footer>
    </Modal.Wrapper>
</Modal>

ИЛИ

<Modal
    show={this.state.isOpen}
    closeOnEscape
    closeOnClickOutside
    >
    <Modal.Wrapper>
        <Modal.Header>
            <!-- ignore this -->
        </Modal.Header>
        <Modal.Body>
            <!-- ignore this -->
        </Modal.Body>
        <Modal.Footer>
            <!-- ignore this -->
        </Modal.Footer>
    </Modal.Wrapper>
</Modal>

Любая помощь высоко ценится.

1 Ответ

0 голосов
/ 19 декабря 2018

Пока я ждал помощи от SO-сообщества, мне удалось найти решение самостоятельно.

Короче говоря, для тех, кто, как и я, относительно плохо знаком со стилевыми компонентами: Стилизованный компонент - это просто «стилизованный» компонент.Вы не можете перегружать его любым скриптом.Чтобы обнаружить onClickOutside и onEscapePress, мне пришлось создать новый компонент оболочки Modal, который использует компонент StyledModal под капотом.Именно здесь находится код для обнаружения нажатия клавиши и мыши.

Вот несколько фрагментов кода, объясняющих мой подход:

Modal.js (фрагменты)

componentDidMount() {
  this.props.closeOnClickOutside &&
    document.addEventListener("mousedown", this.handleClick, false);
  this.props.closeOnEscape &&
    document.addEventListener("keyup", this.handleKeyPress, false);
}
render() {
  return (
    <StyledModal
      style={{ display: this.props.show ? "block" : "none" }}
      ref={this.modal}
    >
      <Wrapper>{this.props.children}</Wrapper>
    </StyledModal>
  );
}

StyledModal.jsx

import styled from "styled-components";

const StyledModal = styled.div`
  position: fixed;
  padding: 0;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100vh;
  background-color: grey;
  z-index: 1;
`;

export default StyledModal;

index.js (использование по назначению)

<Modal
  show={this.state.isOpen}
  closeOnEscape
  onClose={() => this.setState({ isOpen: false })}
>
  <Header>I have a nice title</Header>
  <Body>But not much to say...</Body>
  <Footer>
    <button onClick={this.toggleModal}>Cancel</button>
    <button onClick={this.toggleModal}>OK</button>
  </Footer>
</Modal>

Рабочая демоверсия

...