diff --git a/src/components/Backdrop/Backdrop.tsx b/src/components/Backdrop/Backdrop.tsx
index 36b3cd5..bd83f1d 100644
--- a/src/components/Backdrop/Backdrop.tsx
+++ b/src/components/Backdrop/Backdrop.tsx
@@ -21,9 +21,17 @@ type Props = {
* Default: true
*/
removeScroll?: boolean;
+
+ className?: string;
};
-export function Backdrop({ open, onClose, style, removeScroll = true }: Props) {
+export function Backdrop({
+ open,
+ onClose,
+ style,
+ className = "",
+ removeScroll = true,
+}: Props) {
const attr = attributes({ "aria-expanded": open });
useEffect(() => {
@@ -33,6 +41,11 @@ export function Backdrop({ open, onClose, style, removeScroll = true }: Props) {
}, [open, removeScroll]);
return (
-
+
);
}
diff --git a/src/components/Sheets/Sheets.tsx b/src/components/Sheets/Sheets.tsx
new file mode 100644
index 0000000..f927eef
--- /dev/null
+++ b/src/components/Sheets/Sheets.tsx
@@ -0,0 +1,24 @@
+import { ReactElement } from "react";
+import { Backdrop } from "../Backdrop/Backdrop";
+import "./sheets.css";
+import { attributes } from "../../utils/attributes";
+
+type Props = {
+ open: boolean;
+ onClose: () => void;
+ children: ReactElement;
+};
+
+export function Sheets({ open, onClose, children }: Props) {
+ const attr = attributes({ "aria-expanded": open });
+
+ return (
+
+ );
+}
diff --git a/src/components/Sheets/sheets.css b/src/components/Sheets/sheets.css
new file mode 100644
index 0000000..49bc2ea
--- /dev/null
+++ b/src/components/Sheets/sheets.css
@@ -0,0 +1,48 @@
+.sheets {
+ position: fixed;
+ transition: transform 0.25s;
+ background-color: var(--codex-background-secondary);
+ z-index: 2;
+ justify-content: space-between;
+}
+
+.sheets-container {
+ position: relative;
+}
+
+.sheets-backdrop {
+ z-index: 2;
+}
+
+@media (min-width: 1000px) {
+ .sheets {
+ width: 300px;
+ height: 100%;
+ bottom: 0;
+ top: 0;
+ transform: translatex(300px);
+ right: 0;
+ }
+
+ .sheets[aria-expanded] {
+ transform: translatex(0);
+ z-index: 10;
+ }
+}
+
+@media (max-width: 999px) {
+ .sheets {
+ width: 100%;
+ height: auto;
+ bottom: 0;
+ top: auto;
+ transform: translatey(1000px);
+ left: 0;
+ padding-bottom: 1.5rem;
+ }
+
+ .sheets[aria-expanded] {
+ transform: translatey(0);
+ z-index: 10;
+ }
+}
diff --git a/src/index.ts b/src/index.ts
index 1800eea..95742f6 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -32,4 +32,5 @@ export { NetworkIndicator } from "./components/NetworkIndicator/NetworkIndicator
export { Tooltip } from "./components/Tooltip/Tooltip";
export { Collapse } from "./components/Collapse/Collapse";
export { Placeholder } from "./components/Placeholder/Placeholder";
+export { Sheets } from "./components/Sheets/Sheets";
export { Tabs } from "./components/Tabs/Tabs";
diff --git a/stories/Sheets.stories.tsx b/stories/Sheets.stories.tsx
new file mode 100644
index 0000000..d79d1f1
--- /dev/null
+++ b/stories/Sheets.stories.tsx
@@ -0,0 +1,53 @@
+import type { Meta } from "@storybook/react";
+import { useState } from "react";
+import { Sheets } from "../src/components/Sheets/Sheets";
+import { fn } from "@storybook/test";
+
+const meta = {
+ title: "Overlays/Sheets",
+ component: Sheets,
+ parameters: {
+ layout: "centered",
+ inlineStories: false,
+ },
+ tags: ["autodocs"],
+ argTypes: {},
+ args: {
+ onClose: fn(),
+ },
+} satisfies Meta;
+
+export default meta;
+
+const DefaultTemplate = (props: { onClose: () => void }) => {
+ const [open, setOpen] = useState(false);
+
+ const onClick = () => setOpen(true);
+
+ const onClose = () => {
+ props.onClose();
+ setOpen(false);
+ };
+
+ return (
+
+
+
+
+
+ Hello world
+
+
+
+ );
+};
+
+export const Default = DefaultTemplate.bind({});