UNPKG

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