Sheets component (#11)
This commit is contained in:
parent
66f8207be8
commit
e2b3479e37
|
@ -21,9 +21,17 @@ type Props = {
|
||||||
* Default: true
|
* Default: true
|
||||||
*/
|
*/
|
||||||
removeScroll?: boolean;
|
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 });
|
const attr = attributes({ "aria-expanded": open });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -33,6 +41,11 @@ export function Backdrop({ open, onClose, style, removeScroll = true }: Props) {
|
||||||
}, [open, removeScroll]);
|
}, [open, removeScroll]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div {...attr} className="backdrop" onClick={onClose} style={style}></div>
|
<div
|
||||||
|
{...attr}
|
||||||
|
className={"backdrop " + className}
|
||||||
|
onClick={onClose}
|
||||||
|
style={style}
|
||||||
|
></div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 (
|
||||||
|
<div className="sheets-container">
|
||||||
|
<Backdrop onClose={onClose} open={open} className={"sheets-backdrop"} />
|
||||||
|
|
||||||
|
<div className="sheets" {...attr}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,4 +32,5 @@ export { NetworkIndicator } from "./components/NetworkIndicator/NetworkIndicator
|
||||||
export { Tooltip } from "./components/Tooltip/Tooltip";
|
export { Tooltip } from "./components/Tooltip/Tooltip";
|
||||||
export { Collapse } from "./components/Collapse/Collapse";
|
export { Collapse } from "./components/Collapse/Collapse";
|
||||||
export { Placeholder } from "./components/Placeholder/Placeholder";
|
export { Placeholder } from "./components/Placeholder/Placeholder";
|
||||||
|
export { Sheets } from "./components/Sheets/Sheets";
|
||||||
export { Tabs } from "./components/Tabs/Tabs";
|
export { Tabs } from "./components/Tabs/Tabs";
|
||||||
|
|
|
@ -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<typeof Sheets>;
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
|
||||||
|
const DefaultTemplate = (props: { onClose: () => void }) => {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
const onClick = () => setOpen(true);
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
props.onClose();
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: "2rem" }}>
|
||||||
|
<button onClick={onClick}>Make Sheets</button>
|
||||||
|
|
||||||
|
<Sheets open={open} onClose={onClose}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: "100%",
|
||||||
|
width: "100%",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span>Hello world</span>
|
||||||
|
</div>
|
||||||
|
</Sheets>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Default = DefaultTemplate.bind({});
|
Loading…
Reference in New Issue