openreplay/frontend/app/components/ui/Popover/Popover.tsx
Delirium d604f9920b
feat ui: dashboards redesign (#2230)
* feat ui: dashboards redesign start

* more cards

* fix ui: more different cards...

* feat ui: finish cards, all trigger, all icons

* change(ui): added missin const

* feature(ui): new dashboard modal

* feature(ui): new dashboard modal

* change(ui): new cards

* change(ui): dashboard redesign

* change(ui): dashboard redesign

* change(ui): dashboard redesign

* change(ui): modal context and alert form

* change(ui): table card show more with modal

* change(ui): examples

* change(ui): example categorize and other improvements

* change(ui): example categorize and other improvements

* change(ui): performance cards

* change(ui): insights card

* Various style updates in dashboards and other pages. (#2308)

* Various minor style updates

* Various style improvements

* Update ExampleCards.tsx

* change(ui): fixed an issue with card create

* change(ui): fixed an issue with card create

* change(ui): default filters and events order

* change(ui): random data

* Dashboards redesign - improvments (#2313)

* Various minor style updates

* Various style improvements

* Update ExampleCards.tsx

* various minor improvements in dashbaords.

* revised dashboard widget header

* change(ui): sessions by user

* change(ui): funnel example

* change(ui): modal height and scroll

* change(ui): example cards with data

* change(ui): example cards with data

* change(ui): funnel bar text color

* change(ui): example cards overlay click

* change(ui): path analysis filter card

---------

Co-authored-by: Shekar Siri <sshekarsiri@gmail.com>
Co-authored-by: Sudheer Salavadi <connect.uxmaster@gmail.com>
2024-06-27 19:47:34 +02:00

96 lines
2.3 KiB
TypeScript

import React, { cloneElement, useEffect, useMemo, useState } from 'react';
import {
Placement,
offset,
flip,
shift,
autoUpdate,
useFloating,
useInteractions,
useRole,
useDismiss,
useId,
useClick,
FloatingFocusManager,
} from '@floating-ui/react-dom-interactions';
import { mergeRefs } from 'react-merge-refs';
import { INDEXES } from 'App/constants/zindex';
interface Props {
render: (data: { close: () => void; labelId: string; descriptionId: string }) => React.ReactNode;
placement?: Placement;
children: JSX.Element;
onOpen?: () => void;
onClose?: () => void;
}
const Popover = ({ children, render, placement = 'bottom-end', onOpen, onClose }: Props) => {
const [open, setOpen] = useState(false);
useEffect(() => {
if (open) {
onOpen?.();
} else {
onClose?.();
}
}, [open, onOpen, onClose]);
const { x, y, reference, floating, strategy, context } = useFloating({
open,
onOpenChange: setOpen,
middleware: [offset(5), flip(), shift()],
placement,
whileElementsMounted: autoUpdate,
});
const id = useId();
const labelId = `${id}-label`;
const descriptionId = `${id}-description`;
const { getReferenceProps, getFloatingProps } = useInteractions([
useClick(context),
useRole(context),
useDismiss(context),
]);
// Preserve the consumer's ref
const ref = useMemo(() => mergeRefs([reference, (children as any).ref]), [reference, children]);
return (
<>
{cloneElement(children, getReferenceProps({ ref, ...children.props }))}
{open && (
<FloatingFocusManager
context={context}
modal={true}
order={['reference', 'content']}
returnFocus={false}
>
<div
ref={floating}
className="rounded-lg"
style={{
position: strategy,
top: y ?? 0,
left: x ?? 0,
zIndex: INDEXES.TOOLTIP,
}}
aria-labelledby={labelId}
aria-describedby={descriptionId}
{...getFloatingProps()}
>
{render({
labelId,
descriptionId,
close: () => {
setOpen(false);
},
})}
</div>
</FloatingFocusManager>
)}
</>
);
};
export default Popover;