Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add slideover component #711

Merged
merged 14 commits into from
Jul 4, 2023
24 changes: 24 additions & 0 deletions apps/design-system/src/components/SlideOver.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useState } from "react";
import { SlideOver } from "ui";

export default {
component: SlideOver,
princerajpoot20 marked this conversation as resolved.
Show resolved Hide resolved
};

export const Example = () => {
const [isOpen, setIsOpen] = useState(false);

const handleOpen = () => setIsOpen(true);
const handleClose = () => setIsOpen(false);

return (
<div>
<button onClick={handleOpen}>Open SlideOver</button>

<SlideOver isOpen={isOpen} onClose={handleClose}>
<h2>Content of the SlideOver</h2>
{/* Other contents... */}
fmvilas marked this conversation as resolved.
Show resolved Hide resolved
</SlideOver>
</div>
);
};
46 changes: 46 additions & 0 deletions packages/ui/components/SlideOver.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";

interface SlideOverProps {
isOpen: boolean;
onClose: () => void;
children: React.ReactNode;
}

const CloseIcon: React.FC = () => (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 18L18 6M6 6L18 18" stroke="#94A3B8" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
);
fmvilas marked this conversation as resolved.
Show resolved Hide resolved

export const SlideOver: React.FC<SlideOverProps> = ({ isOpen, onClose, children }) => {
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
onClose();
}
};
window.addEventListener('keydown', handleKeyDown);

return () => {
window.removeEventListener('keydown', handleKeyDown);
fmvilas marked this conversation as resolved.
Show resolved Hide resolved
};
}, [onClose]);

if (!isOpen) return null;

return ReactDOM.createPortal(
<div className="fixed inset-0 flex items-center justify-end z-50">
<div className="fixed inset-0 bg-black opacity-50" onClick={onClose} />
fmvilas marked this conversation as resolved.
Show resolved Hide resolved
<div className="w-full max-w-lg bg-gray-950 text-gray-200 rounded-md shadow-lg overflow-auto relative p-2.5">
fmvilas marked this conversation as resolved.
Show resolved Hide resolved
<button className="absolute top-2 right-2" onClick={onClose}>
fmvilas marked this conversation as resolved.
Show resolved Hide resolved
<CloseIcon />
</button>
{children}
</div>
</div>,
document.body
fmvilas marked this conversation as resolved.
Show resolved Hide resolved
);
};

export default SlideOver;
1 change: 1 addition & 0 deletions packages/ui/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export * from "./Logo"
export * from "./Modal"
export * from "./OperationIcon"
export * from "./Sidebar"
export * from "./SlideOver"
export * from "./Toolbar"
export { default as Tooltip } from "./Tooltip"