173 lines
4.0 KiB
Markdown
173 lines
4.0 KiB
Markdown
# Popper
|
|
|
|
A React hooks wrapper for popper.js to dynamic positioning of containers around
|
|
a reference.
|
|
|
|
> This is an internal hook of Chakra-UI, and it's not covered by semver, and may
|
|
> cause unexpected or broken application behavior. Use them at your own risk.
|
|
|
|
## Installation
|
|
|
|
```sh
|
|
yarn add @chakra-ui/popper
|
|
```
|
|
|
|
## Basic usage
|
|
|
|
By default, the `usePopper` hook returns props for the popper, reference and
|
|
arrow.
|
|
|
|
```jsx
|
|
import { Box } from "@chakra-ui/layout"
|
|
import { Button } from "@chakra-ui/button"
|
|
import { useDisclosure } from "@chakra-ui/hooks"
|
|
import { usePopper } from "@chakra-ui/popper"
|
|
|
|
function Example() {
|
|
const { isOpen, onToggle } = useDisclosure()
|
|
const { popperRef, referenceRef, getArrowProps } = usePopper()
|
|
return (
|
|
<>
|
|
<Button ref={referenceRef} onClick={onToggle} mb={2}>
|
|
{isOpen ? "Click me to see less" : "Click me to see more"}
|
|
</Button>
|
|
{isOpen && (
|
|
<Box ref={popperRef} bg="red">
|
|
<div
|
|
{...getArrowProps({
|
|
style: {
|
|
background: "red",
|
|
},
|
|
})}
|
|
/>
|
|
This is a popover for the button!
|
|
</Box>
|
|
)}
|
|
</>
|
|
)
|
|
}
|
|
```
|
|
|
|
## Parameters
|
|
|
|
### Changing the placement
|
|
|
|
You can change the placement of the popper by passing the `placement` option to
|
|
`usePopper` and set it to the `popper.js` placement.
|
|
|
|
```jsx
|
|
const { popperRef, referenceRef } = usePopper({
|
|
placement: "right-start",
|
|
})
|
|
```
|
|
|
|
### Match reference's width
|
|
|
|
In some cases, you might want to allow the popper take the width of the
|
|
reference. For example, autocomplete, select, etc.
|
|
|
|
To achieve this, pass the `matchWidth` option and set it to `true`
|
|
|
|
```jsx
|
|
const { popperRef, referenceRef } = usePopper({
|
|
matchWidth: true,
|
|
})
|
|
```
|
|
|
|
### Place the popper next to the reference
|
|
|
|
You can place the popper next to the reference without margin or distance
|
|
between them. Useful to create an autocomplete or typeahead feature.
|
|
|
|
```jsx
|
|
const { popperRef, referenceRef } = usePopper({
|
|
gutter: 0,
|
|
})
|
|
```
|
|
|
|
### Using inside a fixed container
|
|
|
|
If the reference element is inside a fixed container, you should use the `fixed`
|
|
strategy.
|
|
|
|
```jsx
|
|
const { popperRef, referenceRef } = usePopper({
|
|
strategy: "fixed",
|
|
})
|
|
```
|
|
|
|
## Adding transition
|
|
|
|
When add transitions to a popper component, it is usually advised to apply
|
|
popper and transition to different elements.
|
|
|
|
```tsx
|
|
// 1. Import components
|
|
import { useDisclosure } from "@chakra-ui/hooks"
|
|
import { usePopper } from "@chakra-ui/popper"
|
|
import { motion, AnimatePresence, Variants } from "framer-motion"
|
|
|
|
export function Example() {
|
|
// 2. Create toggle state
|
|
const { isOpen, onToggle } = useDisclosure()
|
|
|
|
// 3. Create motion variants
|
|
const slide: Variants = {
|
|
exit: {
|
|
y: -2,
|
|
opacity: 0,
|
|
},
|
|
enter: {
|
|
y: 0,
|
|
opacity: 1,
|
|
},
|
|
}
|
|
|
|
// 4. Consume the `usePopper` hook
|
|
const { getPopperProps, getReferenceProps, getArrowProps, transformOrigin } =
|
|
usePopper({
|
|
placement: "bottom-start",
|
|
})
|
|
|
|
return (
|
|
<>
|
|
<button {...getReferenceProps({ onClick: onToggle })}>Toggle</button>
|
|
<div {...getPopperProps()}>
|
|
<AnimatePresence>
|
|
{isOpen && (
|
|
<motion.div
|
|
transition={{
|
|
type: "spring",
|
|
duration: 0.2,
|
|
}}
|
|
variants={slide}
|
|
initial="exit"
|
|
animate="enter"
|
|
exit="exit"
|
|
style={{
|
|
background: "red",
|
|
width: 200,
|
|
transformOrigin,
|
|
borderRadius: 4,
|
|
}}
|
|
>
|
|
Testing
|
|
<div
|
|
{...getArrowProps({
|
|
style: {
|
|
background: "red",
|
|
},
|
|
})}
|
|
/>
|
|
</motion.div>
|
|
)}
|
|
</AnimatePresence>
|
|
</div>
|
|
</>
|
|
)
|
|
}
|
|
```
|
|
|
|
> When not rendering the popper conditionally, we recommend using
|
|
> `visibility: hidden` instead of `hidden` or `display: none`
|