1 | import { __rest } from "tslib";
|
2 |
|
3 | import * as React from 'react';
|
4 | import { KEY_CODES } from '../../helpers/constants';
|
5 | import styles from '@patternfly/react-styles/css/components/Popover/popover';
|
6 | import { css } from '@patternfly/react-styles';
|
7 | import { PopoverContext } from './PopoverContext';
|
8 | import { PopoverContent } from './PopoverContent';
|
9 | import { PopoverBody } from './PopoverBody';
|
10 | import { PopoverHeader } from './PopoverHeader';
|
11 | import { PopoverFooter } from './PopoverFooter';
|
12 | import { PopoverCloseButton } from './PopoverCloseButton';
|
13 | import { PopoverArrow } from './PopoverArrow';
|
14 | import popoverMaxWidth from '@patternfly/react-tokens/dist/esm/c_popover_MaxWidth';
|
15 | import popoverMinWidth from '@patternfly/react-tokens/dist/esm/c_popover_MinWidth';
|
16 | import { FocusTrap } from '../../helpers';
|
17 | import { Popper, getOpacityTransition } from '../../helpers/Popper/Popper';
|
18 | import { getUniqueId } from '../../helpers/util';
|
19 | export var PopoverPosition;
|
20 | (function (PopoverPosition) {
|
21 | PopoverPosition["auto"] = "auto";
|
22 | PopoverPosition["top"] = "top";
|
23 | PopoverPosition["bottom"] = "bottom";
|
24 | PopoverPosition["left"] = "left";
|
25 | PopoverPosition["right"] = "right";
|
26 | PopoverPosition["topStart"] = "top-start";
|
27 | PopoverPosition["topEnd"] = "top-end";
|
28 | PopoverPosition["bottomStart"] = "bottom-start";
|
29 | PopoverPosition["bottomEnd"] = "bottom-end";
|
30 | PopoverPosition["leftStart"] = "left-start";
|
31 | PopoverPosition["leftEnd"] = "left-end";
|
32 | PopoverPosition["rightStart"] = "right-start";
|
33 | PopoverPosition["rightEnd"] = "right-end";
|
34 | })(PopoverPosition || (PopoverPosition = {}));
|
35 | const alertStyle = {
|
36 | default: styles.modifiers.default,
|
37 | info: styles.modifiers.info,
|
38 | success: styles.modifiers.success,
|
39 | warning: styles.modifiers.warning,
|
40 | danger: styles.modifiers.danger
|
41 | };
|
42 | export const Popover = (_a) => {
|
43 | var { children, position = 'top', enableFlip = true, className = '', isVisible = null, shouldClose = () => null, shouldOpen = () => null, 'aria-label': ariaLabel = '', bodyContent, headerContent = null, headerComponent = 'h6', headerIcon = null, alertSeverityVariant, alertSeverityScreenReaderText, footerContent = null, appendTo = () => document.body, hideOnOutsideClick = true, onHide = () => null, onHidden = () => null, onShow = () => null, onShown = () => null, onMount = () => null, zIndex = 9999, minWidth = popoverMinWidth && popoverMinWidth.value, maxWidth = popoverMaxWidth && popoverMaxWidth.value, closeBtnAriaLabel = 'Close', showClose = true, distance = 25,
|
44 |
|
45 | flipBehavior = ['top', 'right', 'bottom', 'left', 'top', 'right', 'bottom'], animationDuration = 300, id, withFocusTrap: propWithFocusTrap, boundary, tippyProps, reference, hasNoPadding = false, hasAutoWidth = false } = _a, rest = __rest(_a, ["children", "position", "enableFlip", "className", "isVisible", "shouldClose", "shouldOpen", 'aria-label', "bodyContent", "headerContent", "headerComponent", "headerIcon", "alertSeverityVariant", "alertSeverityScreenReaderText", "footerContent", "appendTo", "hideOnOutsideClick", "onHide", "onHidden", "onShow", "onShown", "onMount", "zIndex", "minWidth", "maxWidth", "closeBtnAriaLabel", "showClose", "distance", "flipBehavior", "animationDuration", "id", "withFocusTrap", "boundary", "tippyProps", "reference", "hasNoPadding", "hasAutoWidth"]);
|
46 | if (process.env.NODE_ENV !== 'production') {
|
47 | boundary !== undefined &&
|
48 | console.warn('The Popover boundary prop has been deprecated. If you want to constrain the popper to a specific element use the appendTo prop instead.');
|
49 | tippyProps !== undefined && console.warn('The Popover tippyProps prop has been deprecated and is no longer used.');
|
50 | }
|
51 |
|
52 |
|
53 | const uniqueId = id || getUniqueId();
|
54 | const triggerManually = isVisible !== null;
|
55 | const [visible, setVisible] = React.useState(false);
|
56 | const [opacity, setOpacity] = React.useState(0);
|
57 | const [focusTrapActive, setFocusTrapActive] = React.useState(Boolean(propWithFocusTrap));
|
58 | const transitionTimerRef = React.useRef(null);
|
59 | const showTimerRef = React.useRef(null);
|
60 | const hideTimerRef = React.useRef(null);
|
61 | React.useEffect(() => {
|
62 | onMount();
|
63 | }, []);
|
64 | React.useEffect(() => {
|
65 | if (triggerManually) {
|
66 | if (isVisible) {
|
67 | show();
|
68 | }
|
69 | else {
|
70 | hide();
|
71 | }
|
72 | }
|
73 | }, [isVisible, triggerManually]);
|
74 | const show = (withFocusTrap) => {
|
75 | onShow();
|
76 | if (transitionTimerRef.current) {
|
77 | clearTimeout(transitionTimerRef.current);
|
78 | }
|
79 | if (hideTimerRef.current) {
|
80 | clearTimeout(hideTimerRef.current);
|
81 | }
|
82 | showTimerRef.current = setTimeout(() => {
|
83 | setVisible(true);
|
84 | setOpacity(1);
|
85 | propWithFocusTrap !== false && withFocusTrap && setFocusTrapActive(true);
|
86 | onShown();
|
87 | }, 0);
|
88 | };
|
89 | const hide = () => {
|
90 | onHide();
|
91 | if (showTimerRef.current) {
|
92 | clearTimeout(showTimerRef.current);
|
93 | }
|
94 | hideTimerRef.current = setTimeout(() => {
|
95 | setVisible(false);
|
96 | setOpacity(0);
|
97 | setFocusTrapActive(false);
|
98 | transitionTimerRef.current = setTimeout(() => {
|
99 | onHidden();
|
100 | }, animationDuration);
|
101 | }, 0);
|
102 | };
|
103 | const positionModifiers = {
|
104 | top: styles.modifiers.top,
|
105 | bottom: styles.modifiers.bottom,
|
106 | left: styles.modifiers.left,
|
107 | right: styles.modifiers.right,
|
108 | 'top-start': styles.modifiers.topLeft,
|
109 | 'top-end': styles.modifiers.topRight,
|
110 | 'bottom-start': styles.modifiers.bottomLeft,
|
111 | 'bottom-end': styles.modifiers.bottomRight,
|
112 | 'left-start': styles.modifiers.leftTop,
|
113 | 'left-end': styles.modifiers.leftBottom,
|
114 | 'right-start': styles.modifiers.rightTop,
|
115 | 'right-end': styles.modifiers.rightBottom
|
116 | };
|
117 | const hasCustomMinWidth = minWidth !== popoverMinWidth.value;
|
118 | const hasCustomMaxWidth = maxWidth !== popoverMaxWidth.value;
|
119 | const onDocumentKeyDown = (event) => {
|
120 | if (event.keyCode === KEY_CODES.ESCAPE_KEY && visible) {
|
121 | if (triggerManually) {
|
122 | shouldClose(null, hide, event);
|
123 | }
|
124 | else {
|
125 | hide();
|
126 | }
|
127 | }
|
128 | };
|
129 | const onDocumentClick = (event, triggerElement, popperElement) => {
|
130 | if (hideOnOutsideClick && visible) {
|
131 |
|
132 | const isChild = popperElement && popperElement.contains(event.target);
|
133 | if (isChild) {
|
134 |
|
135 | return;
|
136 | }
|
137 | if (triggerManually) {
|
138 | shouldClose(null, hide, event);
|
139 | }
|
140 | else {
|
141 | hide();
|
142 | }
|
143 | }
|
144 | };
|
145 | const onTriggerClick = (event) => {
|
146 | if (triggerManually) {
|
147 | if (visible) {
|
148 | shouldClose(null, hide, event);
|
149 | }
|
150 | else {
|
151 | shouldOpen(show, event);
|
152 | }
|
153 | }
|
154 | else {
|
155 | if (visible) {
|
156 | hide();
|
157 | }
|
158 | else {
|
159 | show(true);
|
160 | }
|
161 | }
|
162 | };
|
163 | const onContentMouseDown = () => {
|
164 | if (focusTrapActive) {
|
165 | setFocusTrapActive(false);
|
166 | }
|
167 | };
|
168 | const closePopover = (event) => {
|
169 | event.stopPropagation();
|
170 | if (triggerManually) {
|
171 | shouldClose(null, hide, event);
|
172 | }
|
173 | else {
|
174 | hide();
|
175 | }
|
176 | };
|
177 | const content = (React.createElement(FocusTrap, Object.assign({ active: focusTrapActive, focusTrapOptions: {
|
178 | returnFocusOnDeactivate: true,
|
179 | clickOutsideDeactivates: true,
|
180 | fallbackFocus: () => {
|
181 |
|
182 |
|
183 |
|
184 |
|
185 | let node = null;
|
186 | if (document && document.activeElement) {
|
187 | node = document.activeElement;
|
188 | }
|
189 | return node;
|
190 | }
|
191 | }, preventScrollOnDeactivate: true, className: css(styles.popover, alertSeverityVariant && alertStyle[alertSeverityVariant], hasNoPadding && styles.modifiers.noPadding, hasAutoWidth && styles.modifiers.widthAuto, className), role: "dialog", "aria-modal": "true", "aria-label": headerContent ? undefined : ariaLabel, "aria-labelledby": headerContent ? `popover-${uniqueId}-header` : undefined, "aria-describedby": `popover-${uniqueId}-body`, onMouseDown: onContentMouseDown, style: {
|
192 | minWidth: hasCustomMinWidth ? minWidth : null,
|
193 | maxWidth: hasCustomMaxWidth ? maxWidth : null,
|
194 | opacity,
|
195 | transition: getOpacityTransition(animationDuration)
|
196 | } }, rest),
|
197 | React.createElement(PopoverArrow, null),
|
198 | React.createElement(PopoverContent, null,
|
199 | showClose && React.createElement(PopoverCloseButton, { onClose: closePopover, "aria-label": closeBtnAriaLabel }),
|
200 | headerContent && (React.createElement(PopoverHeader, { id: `popover-${uniqueId}-header`, icon: headerIcon, alertSeverityVariant: alertSeverityVariant, alertSeverityScreenReaderText: alertSeverityScreenReaderText || `${alertSeverityVariant} alert:`, titleHeadingLevel: headerComponent }, typeof headerContent === 'function' ? headerContent(hide) : headerContent)),
|
201 | React.createElement(PopoverBody, { id: `popover-${uniqueId}-body` }, typeof bodyContent === 'function' ? bodyContent(hide) : bodyContent),
|
202 | footerContent && (React.createElement(PopoverFooter, { id: `popover-${uniqueId}-footer` }, typeof footerContent === 'function' ? footerContent(hide) : footerContent)))));
|
203 | return (React.createElement(PopoverContext.Provider, { value: { headerComponent } },
|
204 | React.createElement(Popper, { trigger: children, reference: reference, popper: content, popperMatchesTriggerWidth: false, appendTo: appendTo, isVisible: visible, positionModifiers: positionModifiers, distance: distance, placement: position, onTriggerClick: onTriggerClick, onDocumentClick: onDocumentClick, onDocumentKeyDown: onDocumentKeyDown, enableFlip: enableFlip, zIndex: zIndex, flipBehavior: flipBehavior })));
|
205 | };
|
206 | Popover.displayName = 'Popover';
|
207 |
|
\ | No newline at end of file |