Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Implement bare minimum modal component
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinpalkovic committed May 30, 2023
1 parent 0b11d0c commit f874b95
Show file tree
Hide file tree
Showing 5 changed files with 330 additions and 3 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
"readme": "ERROR: No README data found!",
"homepage": "https://github.com/storybookjs/addon-onboarding#readme",
"dependencies": {
"react-confetti": "^6.1.0"
"react-confetti": "^6.1.0",
"@radix-ui/react-dialog": "^1.0.4"
}
}
22 changes: 22 additions & 0 deletions src/components/Modal/Modal.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Meta } from "@storybook/react";
import { Modal } from "./Modal";
import React from "react";

const meta: Meta<typeof Modal> = {
component: Modal,
};

export default meta;

export const Default = () => (
<Modal defaultOpen width="740px">
{({ Title, Description, Close }) => (
<>
Hello world
<Title>Modal Title</Title>
<Description>Modal Description</Description>
<Close>Close</Close>
</>
)}
</Modal>
);
46 changes: 46 additions & 0 deletions src/components/Modal/Modal.styled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { css, keyframes, styled } from "@storybook/theming";
import {
Overlay,
Content,
Title,
Description,
Close,
} from "@radix-ui/react-dialog";
import React from "react";

export const StyledOverlay = styled(Overlay)`
background-color: rgba(0, 0, 0, 0.25);
position: fixed;
inset: 0px;
width: 100%;
height: 100%;
})`;

export const StyledContent = styled.div<{ width: string }>(
({ width }) => css`
background-color: white;
border-radius: 6px;
box-shadow: rgba(14, 18, 22, 0.35) 0px 10px 38px -10px;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: ${width ?? "calc(100% - 40px)"};
max-width: calc(100% - 40px);
max-height: 85vh;
`
);

export const ContentWrapper = React.forwardRef<
HTMLDivElement,
React.ComponentProps<typeof StyledContent> &
React.ComponentProps<typeof Content>
>(({ width, children, ...contentProps }, ref) => (
<Content ref={ref} asChild {...contentProps}>
<StyledContent width={width}>{children}</StyledContent>
</Content>
));

export const StyledTitle = styled(Title)``;
export const StyledDescription = styled(Description)``;
export const StyledClose = styled(Close)``;
42 changes: 42 additions & 0 deletions src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from "react";

import * as Dialog from "@radix-ui/react-dialog";
import {
ContentWrapper,
StyledClose,
StyledDescription,
StyledOverlay,
StyledTitle,
} from "./Modal.styled";

interface ModalProps
extends Omit<React.ComponentProps<typeof Dialog.Root>, "children"> {
width?: string;
children: (props: {
Title: typeof StyledTitle;
Description: typeof StyledDescription;
Close: typeof StyledClose;
}) => React.ReactNode;
}

export function Modal({ children, width, ...rootProps }: ModalProps) {
return (
<Dialog.Root {...rootProps}>
<Dialog.Portal>
<StyledOverlay />
<ContentWrapper
width={width}
onInteractOutside={(event) => {
event.preventDefault();
}}
>
{children({
Title: StyledTitle,
Description: StyledDescription,
Close: StyledClose,
})}
</ContentWrapper>
</Dialog.Portal>
</Dialog.Root>
);
}
Loading

0 comments on commit f874b95

Please sign in to comment.