github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/src/views/shared/components/popover/index.tsx (about)

     1  // Copyright 2019 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  import React from "react";
    12  import classNames from "classnames";
    13  
    14  import { OutsideEventHandler } from "src/components/outsideEventHandler";
    15  
    16  import "./popover.styl";
    17  
    18  export interface PopoverProps {
    19    content: JSX.Element;
    20    visible: boolean;
    21    onVisibleChange: (nextState: boolean) => void;
    22    children: any;
    23  }
    24  
    25  export default class Popover extends React.Component<PopoverProps> {
    26    // contentRef is used to pass as element to avoid handling outside event handler
    27    // on its instance.
    28    contentRef: React.RefObject<HTMLDivElement> = React.createRef();
    29  
    30    render() {
    31      const { content, children, visible, onVisibleChange } = this.props;
    32  
    33      const popoverClasses = classNames("popover", {
    34        "popover--visible": visible,
    35      });
    36  
    37      return (
    38        <React.Fragment>
    39          <div
    40            ref={this.contentRef}
    41            className="popover__content"
    42            onClick={() => onVisibleChange(!visible)}>
    43            { content }
    44          </div>
    45          <OutsideEventHandler
    46            onOutsideClick={() => onVisibleChange(false)}
    47            mountNodePosition={"fixed"}
    48            ignoreClickOnRefs={[this.contentRef]}>
    49            <div className={popoverClasses}>
    50              { children }
    51            </div>
    52          </OutsideEventHandler>
    53        </React.Fragment>
    54      );
    55    }
    56  }