(react) add a popover component

A design system needs a popover mecanism.
In the select component, this logic is handled by downshift.
We introduce a new component, responsible to open an element in
a popin and close it when the user click outside of it.
This commit is contained in:
Lebaud Antoine
2023-06-02 12:04:36 +02:00
committed by aleb_the_flash
parent f967775fb6
commit 1d1cf81cf6
6 changed files with 99 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
.c__popover {
position: absolute;
display: flex;
width: fit-content;
z-index: 1;
&:not(&--borderless) {
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
background-color: var(--c--components--forms-datepicker--menu-background-color);
}
}

View File

@@ -0,0 +1,36 @@
import React, { useRef, useState } from "react";
import { Meta } from "@storybook/react";
import { Button } from ":/components/Button";
import { Popover } from ":/components/Popover/index";
export default {
title: "Components/Popover",
component: Popover,
} as Meta<typeof Popover>;
export const Default = () => {
const [isOpen, setIsOpen] = useState(false);
const parentRef = useRef<HTMLDivElement>(null);
return (
<div ref={parentRef} style={{ width: "fit-content" }}>
<Button onClick={() => setIsOpen(!isOpen)}>Toggle</Button>
{isOpen && (
<Popover parentRef={parentRef} onClickOutside={() => setIsOpen(false)}>
<div
style={{
height: "200px",
width: "200px",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
I am open
</div>
</Popover>
)}
</div>
);
};

View File

@@ -0,0 +1,28 @@
import React, { PropsWithChildren, RefObject } from "react";
import classNames from "classnames";
import { useHandleClickOutside } from ":/hooks/useHandleClickOutside";
type PopoverProps = PropsWithChildren & {
parentRef: RefObject<HTMLDivElement>;
onClickOutside: () => void;
borderless?: boolean;
};
export const Popover = ({
parentRef,
children,
onClickOutside,
borderless = false,
}: PopoverProps) => {
useHandleClickOutside(parentRef, onClickOutside);
return (
<div
className={classNames("c__popover", {
"c__popover--borderless": borderless,
})}
>
{children}
</div>
);
};