import PopperUnstyled, { PopperUnstyledProps } from '@mui/base/PopperUnstyled'; import { Direction, SxProps, useThemeWithoutDefault as useTheme } from '@mui/system'; import { HTMLElementType, refType } from '@mui/utils'; import PropTypes from 'prop-types'; import * as React from 'react'; import { styled, Theme, useThemeProps } from '../styles'; export type PopperProps = Omit & { /** * The components used for each slot inside the Popper. * Either a string to use a HTML element or a component. * @default {} */ components?: { Root?: React.ElementType; }; /** * The props used for each slot inside the Popper. * @default {} */ componentsProps?: PopperUnstyledProps['slotProps']; /** * The system prop that allows defining system overrides as well as additional CSS styles. */ sx?: SxProps; }; const PopperRoot = styled(PopperUnstyled, { name: 'MuiPopper', slot: 'Root', overridesResolver: (props, styles) => styles.root, })({}); /** * * Demos: * * - [Autocomplete](https://mui.com/material-ui/react-autocomplete/) * - [Menu](https://mui.com/material-ui/react-menu/) * - [Popper](https://mui.com/material-ui/react-popper/) * * API: * * - [Popper API](https://mui.com/material-ui/api/popper/) */ const Popper = React.forwardRef(function Popper( inProps: PopperProps, ref: React.ForwardedRef, ) { const theme = useTheme<{ direction?: Direction }>(); const props = useThemeProps({ props: inProps, name: 'MuiPopper', }); const { components, componentsProps, slots, slotProps, ...other } = props; const RootComponent = slots?.root ?? components?.Root; return ( ); }); Popper.propTypes /* remove-proptypes */ = { // ----------------------------- Warning -------------------------------- // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit TypeScript types and run "yarn proptypes" | // ---------------------------------------------------------------------- /** * An HTML element, [virtualElement](https://popper.js.org/docs/v2/virtual-elements/), * or a function that returns either. * It's used to set the position of the popper. * The return value will passed as the reference object of the Popper instance. */ anchorEl: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ HTMLElementType, PropTypes.object, PropTypes.func, ]), /** * Popper render function or node. */ children: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ PropTypes.node, PropTypes.func, ]), /** * @ignore */ component: PropTypes /* @typescript-to-proptypes-ignore */.elementType, /** * The components used for each slot inside the Popper. * Either a string to use a HTML element or a component. * @default {} */ components: PropTypes.shape({ Root: PropTypes.elementType, }), /** * The props used for each slot inside the Popper. * @default {} */ componentsProps: PropTypes.shape({ root: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), }), /** * An HTML element or function that returns one. * The `container` will have the portal children appended to it. * * By default, it uses the body of the top-level document object, * so it's simply `document.body` most of the time. */ container: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ HTMLElementType, PropTypes.func, ]), /** * The `children` will be under the DOM hierarchy of the parent component. * @default false */ disablePortal: PropTypes.bool, /** * Always keep the children in the DOM. * This prop can be useful in SEO situation or * when you want to maximize the responsiveness of the Popper. * @default false */ keepMounted: PropTypes.bool, /** * Popper.js is based on a "plugin-like" architecture, * most of its features are fully encapsulated "modifiers". * * A modifier is a function that is called each time Popper.js needs to * compute the position of the popper. * For this reason, modifiers should be very performant to avoid bottlenecks. * To learn how to create a modifier, [read the modifiers documentation](https://popper.js.org/docs/v2/modifiers/). */ modifiers: PropTypes.arrayOf( PropTypes.shape({ data: PropTypes.object, effect: PropTypes.func, enabled: PropTypes.bool, fn: PropTypes.func, name: PropTypes.any, options: PropTypes.object, phase: PropTypes.oneOf([ 'afterMain', 'afterRead', 'afterWrite', 'beforeMain', 'beforeRead', 'beforeWrite', 'main', 'read', 'write', ]), requires: PropTypes.arrayOf(PropTypes.string), requiresIfExists: PropTypes.arrayOf(PropTypes.string), }), ), /** * If `true`, the component is shown. */ open: PropTypes.bool.isRequired, /** * @ignore */ ownerState: PropTypes.any, /** * Popper placement. * @default 'bottom' */ placement: PropTypes.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', ]), /** * Options provided to the [`Popper.js`](https://popper.js.org/docs/v2/constructors/#options) instance. * @default {} */ popperOptions: PropTypes.shape({ modifiers: PropTypes.array, onFirstUpdate: PropTypes.func, placement: PropTypes.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', ]), strategy: PropTypes.oneOf(['absolute', 'fixed']), }), /** * A ref that points to the used popper instance. */ popperRef: refType, /** * The props used for each slot inside the Popper. * @default {} */ slotProps: PropTypes.shape({ root: PropTypes.oneOfType([PropTypes.func, PropTypes.object]), }), /** * The components used for each slot inside the Popper. * Either a string to use a HTML element or a component. * @default {} */ slots: PropTypes.shape({ root: PropTypes.elementType, }), /** * The system prop that allows defining system overrides as well as additional CSS styles. */ sx: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object, ]), /** * Help supporting a react-transition-group/Transition component. * @default false */ transition: PropTypes.bool, } as any; export default Popper;