1 | import * as React from 'react';
|
2 | import * as PropTypes from 'prop-types';
|
3 | import { PopoverProps as ReakitPopoverProps } from 'reakit/ts/Popover/Popover';
|
4 |
|
5 | import { InlineBlock } from '../primitives';
|
6 | import Pane from '../Pane';
|
7 | import { isFunction } from '../_utils/assert';
|
8 | import { Omit } from '../types';
|
9 |
|
10 | import PopoverContainer, { PopoverContainerProps, PopoverContainerRenderProps } from './PopoverContainer';
|
11 | import PopoverClose, { PopoverCloseProps } from './PopoverClose';
|
12 | import PopoverPopover, {
|
13 | LocalPopoverPopoverProps,
|
14 | PopoverPopoverProps,
|
15 | popoverPopoverDefaultProps,
|
16 | popoverPopoverPropTypes
|
17 | } from './PopoverPopover';
|
18 | import PopoverShow, { PopoverShowProps } from './PopoverShow';
|
19 | import PopoverHide, { PopoverHideProps } from './PopoverHide';
|
20 | import PopoverToggle, { PopoverToggleProps } from './PopoverToggle';
|
21 |
|
22 | export type LocalPopoverProps = LocalPopoverPopoverProps & {
|
23 | children:
|
24 | | React.ReactNode
|
25 | | (({ use, ...args }: PopoverContainerRenderProps & { use: React.ReactElement<any> }) => React.ReactNode);
|
26 | className?: string;
|
27 | content:
|
28 | | string
|
29 | | React.ReactElement<any>
|
30 | | (({
|
31 | initialFocusRef,
|
32 | ...args
|
33 | }: { initialFocusRef?: React.RefObject<any> } & PopoverContainerRenderProps) => React.ReactNode);
|
34 | isFullWidth?: boolean;
|
35 | /** Displays a cross button in the top right corner of the popover content. */
|
36 | showCloseButton?: boolean;
|
37 | };
|
38 | export type PopoverProps = Omit<ReakitPopoverProps, 'content'> & LocalPopoverProps;
|
39 | export type PopoverComponents = {
|
40 | Popover: React.FunctionComponent<PopoverPopoverProps>;
|
41 | Container: React.FunctionComponent<PopoverContainerProps>;
|
42 | Close: React.FunctionComponent<PopoverCloseProps>;
|
43 | Hide: React.FunctionComponent<PopoverHideProps>;
|
44 | Show: React.FunctionComponent<PopoverShowProps>;
|
45 | Toggle: React.FunctionComponent<PopoverToggleProps>;
|
46 | };
|
47 |
|
48 | export const Popover: React.FunctionComponent<LocalPopoverProps> & PopoverComponents = ({
|
49 | children,
|
50 | content,
|
51 | isFullWidth,
|
52 | showCloseButton,
|
53 | ...props
|
54 | }) => (
|
55 | <PopoverContainer>
|
56 | {popover => (
|
57 | <InlineBlock relative width={isFullWidth ? '100%' : undefined}>
|
58 | {isFunction(children)
|
59 | ? |
60 |
|
61 | children({ use: PopoverToggle, ...popover })
|
62 | : children
|
63 | ? React.cloneElement(children as React.ReactElement<any>, { use: PopoverToggle, ...popover })
|
64 | : null}
|
65 | <PopoverPopover elevation="200" {...props} {...popover} use={Pane}>
|
66 | {({ initialFocusRef }) => (
|
67 | <React.Fragment>
|
68 | {showCloseButton && <PopoverClose elementRef={initialFocusRef} {...popover} />}
|
69 | {}
|
70 | {typeof content === 'function' ? content({ initialFocusRef, ...popover }) : content}
|
71 | </React.Fragment>
|
72 | )}
|
73 | </PopoverPopover>
|
74 | </InlineBlock>
|
75 | )}
|
76 | </PopoverContainer>
|
77 | );
|
78 |
|
79 | Popover.Popover = PopoverPopover;
|
80 | Popover.Container = PopoverContainer;
|
81 | Popover.Close = PopoverClose;
|
82 | Popover.Hide = PopoverHide;
|
83 | Popover.Show = PopoverShow;
|
84 | Popover.Toggle = PopoverToggle;
|
85 |
|
86 | export const popoverPropTypes = {
|
87 | ...popoverPopoverPropTypes,
|
88 | className: PropTypes.string,
|
89 | children: PropTypes.oneOfType([PropTypes.element, PropTypes.func]).isRequired as PropTypes.Validator<
|
90 | LocalPopoverProps['children']
|
91 | >,
|
92 | content: PropTypes.oneOfType([PropTypes.string, PropTypes.element, PropTypes.func]) as PropTypes.Validator<
|
93 | LocalPopoverProps['content']
|
94 | >,
|
95 | isFullWidth: PropTypes.bool,
|
96 | showCloseButton: PropTypes.bool
|
97 | };
|
98 | Popover.propTypes = popoverPropTypes;
|
99 |
|
100 | export const popoverDefaultProps = {
|
101 | ...popoverPopoverDefaultProps,
|
102 | children: undefined,
|
103 | className: undefined,
|
104 | isFullWidth: false,
|
105 | showCloseButton: false
|
106 | };
|
107 | Popover.defaultProps = popoverDefaultProps;
|
108 |
|
109 |
|
110 | const C: React.FunctionComponent<PopoverProps> & PopoverComponents = Popover;
|
111 | export default C;
|