UNPKG

16 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4Object.defineProperty(exports, "__esModule", {
5 value: true
6});
7exports.default = void 0;
8var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
10var React = _interopRequireWildcard(require("react"));
11var _utils = require("@mui/utils");
12var _core = require("@popperjs/core");
13var _propTypes = _interopRequireDefault(require("prop-types"));
14var _composeClasses = _interopRequireDefault(require("../composeClasses"));
15var _Portal = _interopRequireDefault(require("../Portal"));
16var _popperClasses = require("./popperClasses");
17var _utils2 = require("../utils");
18var _ClassNameConfigurator = require("../utils/ClassNameConfigurator");
19var _jsxRuntime = require("react/jsx-runtime");
20const _excluded = ["anchorEl", "children", "direction", "disablePortal", "modifiers", "open", "placement", "popperOptions", "popperRef", "slotProps", "slots", "TransitionProps", "ownerState"],
21 _excluded2 = ["anchorEl", "children", "container", "direction", "disablePortal", "keepMounted", "modifiers", "open", "placement", "popperOptions", "popperRef", "style", "transition", "slotProps", "slots"];
22function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
23function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
24function flipPlacement(placement, direction) {
25 if (direction === 'ltr') {
26 return placement;
27 }
28 switch (placement) {
29 case 'bottom-end':
30 return 'bottom-start';
31 case 'bottom-start':
32 return 'bottom-end';
33 case 'top-end':
34 return 'top-start';
35 case 'top-start':
36 return 'top-end';
37 default:
38 return placement;
39 }
40}
41function resolveAnchorEl(anchorEl) {
42 return typeof anchorEl === 'function' ? anchorEl() : anchorEl;
43}
44function isHTMLElement(element) {
45 return element.nodeType !== undefined;
46}
47function isVirtualElement(element) {
48 return !isHTMLElement(element);
49}
50const useUtilityClasses = () => {
51 const slots = {
52 root: ['root']
53 };
54 return (0, _composeClasses.default)(slots, (0, _ClassNameConfigurator.useClassNamesOverride)(_popperClasses.getPopperUtilityClass));
55};
56const defaultPopperOptions = {};
57const PopperTooltip = /*#__PURE__*/React.forwardRef(function PopperTooltip(props, forwardedRef) {
58 var _slots$root;
59 const {
60 anchorEl,
61 children,
62 direction,
63 disablePortal,
64 modifiers,
65 open,
66 placement: initialPlacement,
67 popperOptions,
68 popperRef: popperRefProp,
69 slotProps = {},
70 slots = {},
71 TransitionProps
72 // @ts-ignore internal logic
73 // prevent from spreading to DOM, it can come from the parent component e.g. Select.
74 } = props,
75 other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
76 const tooltipRef = React.useRef(null);
77 const ownRef = (0, _utils.unstable_useForkRef)(tooltipRef, forwardedRef);
78 const popperRef = React.useRef(null);
79 const handlePopperRef = (0, _utils.unstable_useForkRef)(popperRef, popperRefProp);
80 const handlePopperRefRef = React.useRef(handlePopperRef);
81 (0, _utils.unstable_useEnhancedEffect)(() => {
82 handlePopperRefRef.current = handlePopperRef;
83 }, [handlePopperRef]);
84 React.useImperativeHandle(popperRefProp, () => popperRef.current, []);
85 const rtlPlacement = flipPlacement(initialPlacement, direction);
86 /**
87 * placement initialized from prop but can change during lifetime if modifiers.flip.
88 * modifiers.flip is essentially a flip for controlled/uncontrolled behavior
89 */
90 const [placement, setPlacement] = React.useState(rtlPlacement);
91 const [resolvedAnchorElement, setResolvedAnchorElement] = React.useState(resolveAnchorEl(anchorEl));
92 React.useEffect(() => {
93 if (popperRef.current) {
94 popperRef.current.forceUpdate();
95 }
96 });
97 React.useEffect(() => {
98 if (anchorEl) {
99 setResolvedAnchorElement(resolveAnchorEl(anchorEl));
100 }
101 }, [anchorEl]);
102 (0, _utils.unstable_useEnhancedEffect)(() => {
103 if (!resolvedAnchorElement || !open) {
104 return undefined;
105 }
106 const handlePopperUpdate = data => {
107 setPlacement(data.placement);
108 };
109 if (process.env.NODE_ENV !== 'production') {
110 if (resolvedAnchorElement && isHTMLElement(resolvedAnchorElement) && resolvedAnchorElement.nodeType === 1) {
111 const box = resolvedAnchorElement.getBoundingClientRect();
112 if (process.env.NODE_ENV !== 'test' && box.top === 0 && box.left === 0 && box.right === 0 && box.bottom === 0) {
113 console.warn(['MUI: The `anchorEl` prop provided to the component is invalid.', 'The anchor element should be part of the document layout.', "Make sure the element is present in the document or that it's not display none."].join('\n'));
114 }
115 }
116 }
117 let popperModifiers = [{
118 name: 'preventOverflow',
119 options: {
120 altBoundary: disablePortal
121 }
122 }, {
123 name: 'flip',
124 options: {
125 altBoundary: disablePortal
126 }
127 }, {
128 name: 'onUpdate',
129 enabled: true,
130 phase: 'afterWrite',
131 fn: ({
132 state
133 }) => {
134 handlePopperUpdate(state);
135 }
136 }];
137 if (modifiers != null) {
138 popperModifiers = popperModifiers.concat(modifiers);
139 }
140 if (popperOptions && popperOptions.modifiers != null) {
141 popperModifiers = popperModifiers.concat(popperOptions.modifiers);
142 }
143 const popper = (0, _core.createPopper)(resolvedAnchorElement, tooltipRef.current, (0, _extends2.default)({
144 placement: rtlPlacement
145 }, popperOptions, {
146 modifiers: popperModifiers
147 }));
148 handlePopperRefRef.current(popper);
149 return () => {
150 popper.destroy();
151 handlePopperRefRef.current(null);
152 };
153 }, [resolvedAnchorElement, disablePortal, modifiers, open, popperOptions, rtlPlacement]);
154 const childProps = {
155 placement: placement
156 };
157 if (TransitionProps !== null) {
158 childProps.TransitionProps = TransitionProps;
159 }
160 const classes = useUtilityClasses();
161 const Root = (_slots$root = slots.root) != null ? _slots$root : 'div';
162 const rootProps = (0, _utils2.useSlotProps)({
163 elementType: Root,
164 externalSlotProps: slotProps.root,
165 externalForwardedProps: other,
166 additionalProps: {
167 role: 'tooltip',
168 ref: ownRef
169 },
170 ownerState: props,
171 className: classes.root
172 });
173 return /*#__PURE__*/(0, _jsxRuntime.jsx)(Root, (0, _extends2.default)({}, rootProps, {
174 children: typeof children === 'function' ? children(childProps) : children
175 }));
176});
177
178/**
179 * Poppers rely on the 3rd party library [Popper.js](https://popper.js.org/docs/v2/) for positioning.
180 *
181 * Demos:
182 *
183 * - [Popper](https://mui.com/base/react-popper/)
184 *
185 * API:
186 *
187 * - [Popper API](https://mui.com/base/react-popper/components-api/#popper)
188 */
189const Popper = /*#__PURE__*/React.forwardRef(function Popper(props, forwardedRef) {
190 const {
191 anchorEl,
192 children,
193 container: containerProp,
194 direction = 'ltr',
195 disablePortal = false,
196 keepMounted = false,
197 modifiers,
198 open,
199 placement = 'bottom',
200 popperOptions = defaultPopperOptions,
201 popperRef,
202 style,
203 transition = false,
204 slotProps = {},
205 slots = {}
206 } = props,
207 other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded2);
208 const [exited, setExited] = React.useState(true);
209 const handleEnter = () => {
210 setExited(false);
211 };
212 const handleExited = () => {
213 setExited(true);
214 };
215 if (!keepMounted && !open && (!transition || exited)) {
216 return null;
217 }
218
219 // If the container prop is provided, use that
220 // If the anchorEl prop is provided, use its parent body element as the container
221 // If neither are provided let the Modal take care of choosing the container
222 let container;
223 if (containerProp) {
224 container = containerProp;
225 } else if (anchorEl) {
226 const resolvedAnchorEl = resolveAnchorEl(anchorEl);
227 container = resolvedAnchorEl && isHTMLElement(resolvedAnchorEl) ? (0, _utils.unstable_ownerDocument)(resolvedAnchorEl).body : (0, _utils.unstable_ownerDocument)(null).body;
228 }
229 const display = !open && keepMounted && (!transition || exited) ? 'none' : undefined;
230 const transitionProps = transition ? {
231 in: open,
232 onEnter: handleEnter,
233 onExited: handleExited
234 } : undefined;
235 return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Portal.default, {
236 disablePortal: disablePortal,
237 container: container,
238 children: /*#__PURE__*/(0, _jsxRuntime.jsx)(PopperTooltip, (0, _extends2.default)({
239 anchorEl: anchorEl,
240 direction: direction,
241 disablePortal: disablePortal,
242 modifiers: modifiers,
243 ref: forwardedRef,
244 open: transition ? !exited : open,
245 placement: placement,
246 popperOptions: popperOptions,
247 popperRef: popperRef,
248 slotProps: slotProps,
249 slots: slots
250 }, other, {
251 style: (0, _extends2.default)({
252 // Prevents scroll issue, waiting for Popper.js to add this style once initiated.
253 position: 'fixed',
254 // Fix Popper.js display issue
255 top: 0,
256 left: 0,
257 display
258 }, style),
259 TransitionProps: transitionProps,
260 children: children
261 }))
262 });
263});
264process.env.NODE_ENV !== "production" ? Popper.propTypes /* remove-proptypes */ = {
265 // ----------------------------- Warning --------------------------------
266 // | These PropTypes are generated from the TypeScript type definitions |
267 // | To update them edit TypeScript types and run "yarn proptypes" |
268 // ----------------------------------------------------------------------
269 /**
270 * An HTML element, [virtualElement](https://popper.js.org/docs/v2/virtual-elements/),
271 * or a function that returns either.
272 * It's used to set the position of the popper.
273 * The return value will passed as the reference object of the Popper instance.
274 */
275 anchorEl: (0, _utils.chainPropTypes)(_propTypes.default.oneOfType([_utils.HTMLElementType, _propTypes.default.object, _propTypes.default.func]), props => {
276 if (props.open) {
277 const resolvedAnchorEl = resolveAnchorEl(props.anchorEl);
278 if (resolvedAnchorEl && isHTMLElement(resolvedAnchorEl) && resolvedAnchorEl.nodeType === 1) {
279 const box = resolvedAnchorEl.getBoundingClientRect();
280 if (process.env.NODE_ENV !== 'test' && box.top === 0 && box.left === 0 && box.right === 0 && box.bottom === 0) {
281 return new Error(['MUI: The `anchorEl` prop provided to the component is invalid.', 'The anchor element should be part of the document layout.', "Make sure the element is present in the document or that it's not display none."].join('\n'));
282 }
283 } else if (!resolvedAnchorEl || typeof resolvedAnchorEl.getBoundingClientRect !== 'function' || isVirtualElement(resolvedAnchorEl) && resolvedAnchorEl.contextElement != null && resolvedAnchorEl.contextElement.nodeType !== 1) {
284 return new Error(['MUI: The `anchorEl` prop provided to the component is invalid.', 'It should be an HTML element instance or a virtualElement ', '(https://popper.js.org/docs/v2/virtual-elements/).'].join('\n'));
285 }
286 }
287 return null;
288 }),
289 /**
290 * Popper render function or node.
291 */
292 children: _propTypes.default /* @typescript-to-proptypes-ignore */.oneOfType([_propTypes.default.node, _propTypes.default.func]),
293 /**
294 * An HTML element or function that returns one.
295 * The `container` will have the portal children appended to it.
296 *
297 * By default, it uses the body of the top-level document object,
298 * so it's simply `document.body` most of the time.
299 */
300 container: _propTypes.default /* @typescript-to-proptypes-ignore */.oneOfType([_utils.HTMLElementType, _propTypes.default.func]),
301 /**
302 * Direction of the text.
303 * @default 'ltr'
304 */
305 direction: _propTypes.default.oneOf(['ltr', 'rtl']),
306 /**
307 * The `children` will be under the DOM hierarchy of the parent component.
308 * @default false
309 */
310 disablePortal: _propTypes.default.bool,
311 /**
312 * Always keep the children in the DOM.
313 * This prop can be useful in SEO situation or
314 * when you want to maximize the responsiveness of the Popper.
315 * @default false
316 */
317 keepMounted: _propTypes.default.bool,
318 /**
319 * Popper.js is based on a "plugin-like" architecture,
320 * most of its features are fully encapsulated "modifiers".
321 *
322 * A modifier is a function that is called each time Popper.js needs to
323 * compute the position of the popper.
324 * For this reason, modifiers should be very performant to avoid bottlenecks.
325 * To learn how to create a modifier, [read the modifiers documentation](https://popper.js.org/docs/v2/modifiers/).
326 */
327 modifiers: _propTypes.default.arrayOf(_propTypes.default.shape({
328 data: _propTypes.default.object,
329 effect: _propTypes.default.func,
330 enabled: _propTypes.default.bool,
331 fn: _propTypes.default.func,
332 name: _propTypes.default.any,
333 options: _propTypes.default.object,
334 phase: _propTypes.default.oneOf(['afterMain', 'afterRead', 'afterWrite', 'beforeMain', 'beforeRead', 'beforeWrite', 'main', 'read', 'write']),
335 requires: _propTypes.default.arrayOf(_propTypes.default.string),
336 requiresIfExists: _propTypes.default.arrayOf(_propTypes.default.string)
337 })),
338 /**
339 * If `true`, the component is shown.
340 */
341 open: _propTypes.default.bool.isRequired,
342 /**
343 * Popper placement.
344 * @default 'bottom'
345 */
346 placement: _propTypes.default.oneOf(['auto-end', 'auto-start', 'auto', 'bottom-end', 'bottom-start', 'bottom', 'left-end', 'left-start', 'left', 'right-end', 'right-start', 'right', 'top-end', 'top-start', 'top']),
347 /**
348 * Options provided to the [`Popper.js`](https://popper.js.org/docs/v2/constructors/#options) instance.
349 * @default {}
350 */
351 popperOptions: _propTypes.default.shape({
352 modifiers: _propTypes.default.array,
353 onFirstUpdate: _propTypes.default.func,
354 placement: _propTypes.default.oneOf(['auto-end', 'auto-start', 'auto', 'bottom-end', 'bottom-start', 'bottom', 'left-end', 'left-start', 'left', 'right-end', 'right-start', 'right', 'top-end', 'top-start', 'top']),
355 strategy: _propTypes.default.oneOf(['absolute', 'fixed'])
356 }),
357 /**
358 * A ref that points to the used popper instance.
359 */
360 popperRef: _utils.refType,
361 /**
362 * The props used for each slot inside the Popper.
363 * @default {}
364 */
365 slotProps: _propTypes.default.shape({
366 root: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.object])
367 }),
368 /**
369 * The components used for each slot inside the Popper.
370 * Either a string to use a HTML element or a component.
371 * @default {}
372 */
373 slots: _propTypes.default.shape({
374 root: _propTypes.default.elementType
375 }),
376 /**
377 * Help supporting a react-transition-group/Transition component.
378 * @default false
379 */
380 transition: _propTypes.default.bool
381} : void 0;
382var _default = Popper;
383exports.default = _default;
\No newline at end of file