@popperjs/core#Modifier TypeScript Examples
The following examples show how to use
@popperjs/core#Modifier.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Popup.tsx From posthog-foss with MIT License | 4 votes |
/** This is a custom popup control that uses `react-popper` to position DOM nodes */
export function Popup({
children,
overlay,
visible,
onClickOutside,
onClickInside,
placement = 'bottom-start',
fallbackPlacements = ['bottom-end', 'top-start', 'top-end'],
className,
actionable = false,
sameWidth = false,
}: PopupProps): JSX.Element {
const [referenceElement, setReferenceElement] = useState<HTMLDivElement | null>(null)
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null)
const popupId = useMemo(() => uniqueMemoizedIndex++, [])
const localRefs = [popperElement, referenceElement]
useOutsideClickHandler(localRefs, (event) => visible && onClickOutside?.(event), [visible])
const modifiers = useMemo<Partial<Modifier<any, any>>[]>(
() => [
{
name: 'offset',
options: {
offset: [0, 4],
},
},
fallbackPlacements
? {
name: 'flip',
options: {
fallbackPlacements: fallbackPlacements,
},
}
: {},
sameWidth
? {
name: 'sameWidth',
enabled: true,
fn: ({ state }) => {
state.styles.popper.width = `${state.rects.reference.width}px`
},
phase: 'beforeWrite',
requires: ['computeStyles'],
}
: {},
],
[]
)
const { styles, attributes } = usePopper(referenceElement, popperElement, {
placement: placement,
modifiers,
})
const clonedChildren =
typeof children === 'function'
? children({
setRef: setReferenceElement as (ref: HTMLElement | null) => void,
})
: React.Children.toArray(children).map((child) =>
React.cloneElement(child as ReactElement, {
ref: setReferenceElement,
})
)
return (
<>
{clonedChildren}
{visible
? ReactDOM.createPortal(
<div
className={clsx('Popup', actionable && 'Popup--actionable', className)}
ref={setPopperElement}
style={styles.popper}
onClick={onClickInside}
{...attributes.popper}
>
<PopupContext.Provider value={popupId}>{overlay}</PopupContext.Provider>
</div>,
document.querySelector('body') as HTMLElement
)
: null}
</>
)
}
Example #2
Source File: index.tsx From exevo-pan with The Unlicense | 4 votes |
Popover = ({
className,
children,
content,
placement = 'top',
trigger = 'hover',
visible,
offset = [0, 0],
...props
}: PopoverProps) => {
const {
translations: { common },
} = useTranslations()
const [isVisible, setVisible] = useState<boolean>(visible ?? false)
const derivedVisibility =
trigger === 'none' ? visible ?? isVisible : isVisible
const [referenceElement, setReferenceElement] =
useState<PopperReferenceElement>(null)
const [popperElement, setPopperElement] =
useState<PopperReferenceElement>(null)
const modifiers: Partial<Modifier<string, Record<string, unknown>>>[] =
useMemo(
() => [
{
name: 'flip',
enabled: true,
options: {
allowedAutoPlacements: ['top', 'bottom'],
},
},
{
name: 'offset',
options: {
offset,
},
},
],
[offset],
)
const { styles, attributes } = usePopper(referenceElement, popperElement, {
placement,
modifiers,
})
const triggers = useMemo(() => {
switch (trigger) {
case 'click':
return {
tabIndex: 0,
onClick: () => setVisible((prev) => !prev),
onKeyPress: (event: React.KeyboardEvent) => {
if (checkKeyboardTrigger(event.code)) {
event.preventDefault()
setVisible((prev) => !prev)
}
},
}
case 'hover':
return {
tabIndex: 0,
onMouseEnter: () => setVisible(true),
onMouseLeave: () => setVisible(false),
onFocus: () => setVisible(true),
onBlur: () => setVisible(false),
}
case 'none':
default:
return {}
}
}, [trigger])
const increaseHoverArea = trigger === 'hover' && derivedVisibility
return (
<>
<div
ref={setReferenceElement}
className="child:z-1 child:relative relative inline-block cursor-pointer"
{...triggers}
>
{increaseHoverArea && (
<div
role="none"
className="top-1/2 left-1/2"
style={{
position: 'absolute',
transform: 'translate(-50%, -50%)',
width: `calc(100% + ${offset[0] + 8}px)`,
height: `calc(100% + ${offset[1] + 8}px)`,
}}
/>
)}
{children}
</div>
{derivedVisibility && (
<div
ref={setPopperElement}
style={styles.popper}
{...attributes.popper}
className={clsx(
'z-51 animate-fadeIn',
className,
attributes.popper?.className,
)}
{...props}
{...(trigger === 'hover' ? { ...triggers, tabIndex: undefined } : {})}
>
{Children.map(content, (contentChild) => {
if (!isValidElement(contentChild)) return contentChild
if (typeof contentChild.type === 'string') return contentChild
return cloneElement(contentChild, {
'aria-hidden': false,
disabled: false,
hidden: false,
})
})}
</div>
)}
{trigger === 'click' && derivedVisibility && (
<button
type="button"
className="bg-backdrop animate-fadeIn fixed top-0 left-0 z-50 h-screen w-screen"
aria-label={common.PopoverCloseLabel}
onClick={() => setVisible(false)}
/>
)}
</>
)
}