-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
541baa6
commit d77d6dc
Showing
5 changed files
with
274 additions
and
0 deletions.
There are no files selected for viewing
104 changes: 104 additions & 0 deletions
104
web/src/beta/lib/reearth-ui/components/Modal/index.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import { Meta, StoryObj } from "@storybook/react"; | ||
import { FC, useCallback, useState } from "react"; | ||
|
||
import { Button } from "../Button"; | ||
import { ModalPanel } from "../ModalPanel"; | ||
|
||
import { ModalProps, Modal as ModalComponent } from "."; | ||
|
||
const meta: Meta<ModalProps> = { | ||
component: ModalComponent, | ||
}; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof ModalComponent>; | ||
|
||
const Modal: FC<ModalProps> = ({ size, children }: Omit<ModalProps, "visible">) => { | ||
const [visible, setVisible] = useState(false); | ||
|
||
const handleOpen = useCallback(() => { | ||
setVisible(true); | ||
}, []); | ||
|
||
const handleClose = useCallback(() => { | ||
setVisible(false); | ||
}, []); | ||
|
||
return ( | ||
<div style={{ height: "50vh" }}> | ||
<Button title="Open Modal" appearance="primary" onClick={handleOpen} /> | ||
{visible && ( | ||
<ModalComponent size={size} visible={visible}> | ||
{children ? ( | ||
<div style={{ padding: "24px", borderRadius: "4px", background: "#262626" }}> | ||
{children} | ||
<div | ||
style={{ | ||
justifyContent: "flex-end", | ||
display: "flex", | ||
paddingTop: "10px", | ||
}}> | ||
<Button onClick={handleClose} size="normal" title="Okay" appearance="primary" /> | ||
</div> | ||
</div> | ||
) : ( | ||
<ModalPanel | ||
title="Title modal" | ||
onCancel={handleClose} | ||
actions={ | ||
<> | ||
<Button onClick={handleClose} size="normal" title="Cancel" /> | ||
<Button size="normal" title="Apply" appearance="primary" /> | ||
</> | ||
}> | ||
<div> | ||
Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin | ||
literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin | ||
professor at Hampden-Sydney College in Virginia, looked up one of the more obscure | ||
Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of | ||
the word in classical literature, discovered the undoubtable source. | ||
</div> | ||
</ModalPanel> | ||
)} | ||
</ModalComponent> | ||
)} | ||
</div> | ||
); | ||
}; | ||
|
||
export const SmallSize: Story = { | ||
render: args => { | ||
return ( | ||
<Modal {...args} size="small"> | ||
<div> | ||
<h5 style={{ margin: 0, fontSize: "16px", lineHeight: "24px" }}>Title</h5> | ||
Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin | ||
literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin | ||
professor at Hampden-Sydney College in Virginia, looked up one of the more obscure | ||
bvncfyutghjkm, | ||
</div> | ||
</Modal> | ||
); | ||
}, | ||
args: { | ||
visible: false, | ||
}, | ||
}; | ||
|
||
export const MediumSize: Story = { | ||
render: args => { | ||
return <Modal {...args} size="medium" />; | ||
}, | ||
args: { | ||
visible: false, | ||
}, | ||
}; | ||
|
||
export const LargeSize: Story = { | ||
render: args => { | ||
return <Modal {...args} size="large" />; | ||
}, | ||
args: { | ||
visible: false, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { FC, ReactNode, useMemo, useRef } from "react"; | ||
|
||
import { styled } from "@reearth/services/theme"; | ||
|
||
export type ModalProps = { | ||
visible: boolean; | ||
children: ReactNode; | ||
size?: "small" | "medium" | "large"; | ||
}; | ||
|
||
const DEFAULT_SMALL_WIDTH = 416; | ||
const DEFAULT_MEDIUM_WIDTH = 572; | ||
const DEFAULT_LARGE_WIDTH = 778; | ||
|
||
export const Modal: FC<ModalProps> = ({ visible, children, size }) => { | ||
const ref = useRef<HTMLDivElement>(null); | ||
|
||
const modalWidth = useMemo( | ||
() => | ||
size === "small" | ||
? DEFAULT_SMALL_WIDTH | ||
: size === "large" | ||
? DEFAULT_LARGE_WIDTH | ||
: DEFAULT_MEDIUM_WIDTH, | ||
[size], | ||
); | ||
|
||
return !visible ? null : ( | ||
<Wrapper> | ||
<ContentWrapper modalWidth={modalWidth} ref={ref}> | ||
{children} | ||
</ContentWrapper> | ||
</Wrapper> | ||
); | ||
}; | ||
|
||
const Wrapper = styled("div")(({ theme }) => ({ | ||
background: theme.bg.transparentBlack, | ||
position: "fixed", | ||
left: 0, | ||
top: 0, | ||
width: "100%", | ||
height: "100%", | ||
overflow: "auto", | ||
opacity: 1, | ||
zIndex: theme.zIndexes.editor.modal.bg, | ||
})); | ||
|
||
const ContentWrapper = styled("div")<{ modalWidth?: number }>(({ modalWidth }) => ({ | ||
margin: "0 auto", | ||
height: "100%", | ||
width: `${modalWidth}px`, | ||
position: "relative", | ||
display: "flex", | ||
flexDirection: "column", | ||
justifyContent: "center", | ||
})); |
46 changes: 46 additions & 0 deletions
46
web/src/beta/lib/reearth-ui/components/ModalPanel/index.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { Meta, StoryObj } from "@storybook/react"; | ||
import { FC } from "react"; | ||
|
||
import { Button } from "../Button"; | ||
|
||
import { ModalPanel, ModalPanelProps } from "."; | ||
|
||
const meta: Meta<ModalPanelProps> = { | ||
component: ModalPanel, | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof ModalPanel>; | ||
|
||
const MockChild: FC = () => ( | ||
<div style={{ color: "#e0e0e0", fontSize: "14px", width: "417px" }}> | ||
<p> | ||
Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature | ||
from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at | ||
Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, | ||
consectetur, from a Lorem Ipsum passage, | ||
</p> | ||
</div> | ||
); | ||
|
||
export const Default: Story = { | ||
args: { | ||
title: "Modal Panel Title", | ||
children: <MockChild />, | ||
actions: <Button title="Ok" appearance="primary" />, | ||
}, | ||
}; | ||
|
||
export const MultipleActions: Story = { | ||
args: { | ||
title: "Modal Panel Title", | ||
children: <MockChild />, | ||
actions: ( | ||
<> | ||
<Button size="normal" title="Cancel" /> | ||
<Button size="normal" title="Apply" appearance="primary" /> | ||
</> | ||
), | ||
}, | ||
}; |
65 changes: 65 additions & 0 deletions
65
web/src/beta/lib/reearth-ui/components/ModalPanel/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { FC, ReactNode } from "react"; | ||
|
||
import { Button } from "@reearth/beta/lib/reearth-ui"; | ||
import { fonts, styled } from "@reearth/services/theme"; | ||
|
||
export type ModalPanelProps = { | ||
title?: string; | ||
children: ReactNode; | ||
actions?: ReactNode; | ||
onCancel?: () => void; | ||
}; | ||
|
||
export const ModalPanel: FC<ModalPanelProps> = ({ title, children, actions, onCancel }) => { | ||
return ( | ||
<Wrapper> | ||
<HeaderWrapper> | ||
<Title>{title}</Title> | ||
<Button iconButton icon="close" size="small" onClick={onCancel} appearance="simple" /> | ||
</HeaderWrapper> | ||
<Content>{children}</Content> | ||
{actions && <ActionWrapper>{actions}</ActionWrapper>} | ||
</Wrapper> | ||
); | ||
}; | ||
|
||
const Wrapper = styled("div")(({ theme }) => ({ | ||
width: "fit-content", | ||
display: "flex", | ||
flexDirection: "column", | ||
background: theme.bg.transparentBlack, | ||
})); | ||
|
||
const HeaderWrapper = styled("div")(({ theme }) => ({ | ||
display: "flex", | ||
justifyContent: "space-between", | ||
alignItems: "center", | ||
alignSelf: "stretch", | ||
padding: `${theme.spacing.normal}px`, | ||
color: theme.content.main, | ||
background: theme.bg[2], | ||
borderTopRightRadius: theme.radius.large, | ||
borderTopLeftRadius: theme.radius.large, | ||
})); | ||
|
||
const Title = styled("div")(() => ({ | ||
flex: "1 0 0", | ||
fontSize: fonts.sizes.body, | ||
lineHeight: `${fonts.lineHeights.body}px`, | ||
})); | ||
|
||
const Content = styled("div")(({ theme }) => ({ | ||
padding: theme.spacing.super, | ||
alignSelf: "stretch", | ||
})); | ||
|
||
const ActionWrapper = styled("div")(({ theme }) => ({ | ||
padding: theme.spacing.normal, | ||
background: theme.bg[2], | ||
borderBottomRightRadius: theme.radius.large, | ||
borderBottomLeftRadius: theme.radius.large, | ||
justifyContent: "flex-end", | ||
display: "flex", | ||
alignItems: "flex-start", | ||
gap: theme.spacing.normal, | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters