✨(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:
committed by
aleb_the_flash
parent
f967775fb6
commit
1d1cf81cf6
5
.changeset/spotty-moons-battle.md
Normal file
5
.changeset/spotty-moons-battle.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@openfun/cunningham-react": minor
|
||||
---
|
||||
|
||||
add a popover component
|
||||
11
packages/react/src/components/Popover/index.scss
Normal file
11
packages/react/src/components/Popover/index.scss
Normal 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);
|
||||
}
|
||||
}
|
||||
36
packages/react/src/components/Popover/index.stories.tsx
Normal file
36
packages/react/src/components/Popover/index.stories.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
28
packages/react/src/components/Popover/index.tsx
Normal file
28
packages/react/src/components/Popover/index.tsx
Normal 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>
|
||||
);
|
||||
};
|
||||
18
packages/react/src/hooks/useHandleClickOutside.ts
Normal file
18
packages/react/src/hooks/useHandleClickOutside.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { RefObject, useEffect } from "react";
|
||||
|
||||
export const useHandleClickOutside = (
|
||||
ref: RefObject<HTMLDivElement>,
|
||||
onClickOutside: any
|
||||
) => {
|
||||
useEffect(() => {
|
||||
const outsideListenerEvent = (event: MouseEvent) => {
|
||||
if (!ref.current || ref.current.contains(event.target as Node)) {
|
||||
return;
|
||||
}
|
||||
onClickOutside();
|
||||
};
|
||||
document.addEventListener("click", outsideListenerEvent, true);
|
||||
return () =>
|
||||
document.removeEventListener("click", outsideListenerEvent, true);
|
||||
}, []);
|
||||
};
|
||||
@@ -13,6 +13,7 @@
|
||||
@import './components/Forms/Switch';
|
||||
@import './components/Loader';
|
||||
@import './components/Pagination';
|
||||
@import './components/Popover';
|
||||
|
||||
* {
|
||||
font-family: var(--c--theme--font--families--base);
|
||||
|
||||
Reference in New Issue
Block a user