Add support for "outside elements" (Popups, Drawers, ...)

+ Add Drawer
+ Add new root in the HTML (should be included in production)
This commit is contained in:
Stephan
2022-10-05 22:17:33 +02:00
parent 137ecd6518
commit 340521e4bb
8 changed files with 129 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
<div id="detleph-fg-context"></div>
+19
View File
@@ -1,3 +1,22 @@
<script>
window.global = window;
</script>
<style>
body {
height: 100vh;
}
#detleph-fg-context {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
}
#detleph-fg-context:empty {
width: 0;
height: 0;
}
</style>
+15
View File
@@ -0,0 +1,15 @@
import React from "react";
import { ComponentStory, ComponentMeta } from "@storybook/react";
import Drawer from "../util/Drawer";
export default { title: "Drawer", component: Drawer } as ComponentMeta<typeof Drawer>;
const Template: ComponentStory<typeof Drawer> = (args) => <Drawer {...args} />;
export const DefaultDrawer = Template.bind({});
DefaultDrawer.args = {
children: "Test",
};
+13
View File
@@ -0,0 +1,13 @@
.drawer {
background: white;
border-top-left-radius: 30px;
border-top-right-radius: 30px;
position: absolute;
width: 100%;
height: 50%;
bottom: 0;
margin: 0;
}
+36
View File
@@ -0,0 +1,36 @@
import React from "react";
import ReactDOM from "react-dom";
import { AnimatePresence, motion } from "framer-motion";
import styles from "./Drawer.module.scss";
import { OutsideElement } from "../OutsideElement/OutsideElement";
interface DrawerProps {
open: boolean;
children: React.ReactNode;
onClose?: () => unknown;
}
const Drawer: React.FC<DrawerProps> = ({ open, children, onClose }) => {
return (
<OutsideElement open={open} onClose={onClose}>
<UIDrawer>{children}</UIDrawer>
</OutsideElement>
);
};
const UIDrawer: React.FC<{ children: React.ReactNode }> = ({ children }) => {
return (
<motion.div
className={styles.drawer}
initial={{ y: "100vh" }}
animate={{ y: "0%" }}
exit={{ y: "100vh" }}
transition={{ type: "tween" }}
>
{children}
</motion.div>
);
};
export default Drawer;
+3
View File
@@ -0,0 +1,3 @@
import Drawer from "./Drawer";
export default Drawer;
@@ -0,0 +1,9 @@
.backdrop {
height: 100%;
width: 100%;
position: absolute;
background: #0000003f;
top: 0;
}
@@ -0,0 +1,33 @@
import React from "react";
import ReactDOM from "react-dom";
import { AnimatePresence, motion } from "framer-motion";
import styles from "./OutsideElement.module.scss";
interface OutsideElementProps {
children: React.ReactNode;
open: boolean;
onClose?: () => unknown;
}
export const OutsideElement: React.FC<OutsideElementProps> = ({ children, open, onClose }) => {
return ReactDOM.createPortal(
<AnimatePresence>
{open && (
<>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className={styles.backdrop}
key="backdrop"
onClick={() => onClose?.()}
></motion.div>
{children}
</>
)}
</AnimatePresence>,
document.querySelector("#detleph-fg-context")!
);
};