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

[#9] 공통 dialog 컴포넌트 및 아이디어 개요 dialog #12

Merged
merged 14 commits into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
479 changes: 475 additions & 4 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"format:fix": "prettier --write --ignore-path .gitignore ."
},
"dependencies": {
"@radix-ui/react-dialog": "^1.0.5",
"@tanstack/react-query": "^5.34.1",
"axios": "^1.6.8",
"dayjs": "^1.11.11",
Expand All @@ -24,6 +25,7 @@
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.51.4",
"react-icons": "^5.2.1",
"styled-components": "^6.1.9"
},
"devDependencies": {
Expand Down
120 changes: 120 additions & 0 deletions src/components/IbulDialog/IdeaOutline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
'use client'

import React from 'react'
import {
DialogClose,
DialogContent,
DialogDescription,
DialogOverlay,
DialogPortal,
DialogRoot,
DialogTitle,
DialogTrigger,
} from '../common/Dialog'
import styled from 'styled-components'
import { FaX } from 'react-icons/fa6'
import { theme } from '@/styles/theme'

const IdeaOutlineContainer = styled.div`
display: flex;
flex-direction: column;
gap: 18px;
margin-bottom: 15px;
`
const MarketFailureContainer = styled.div`
display: flex;
flex-direction: column;
gap: 7px;
margin-bottom: 34px;
`
const StyledBottomBtn = styled.button`
03hoho03 marked this conversation as resolved.
Show resolved Hide resolved
font-family: inherit;
border-radius: 100%;
height: 28px;
width: 28px;
display: inline-flex;
align-items: center;
justify-content: center;
color: ${theme.color.grey500};
background-color: ${theme.color.grey200};
position: absolute;
top: 10px;
right: 10px;
cursor: pointer;
`
const StyleBottomClosedBtn = styled.button`
position: absolute;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
height: 54px;
width: 353px;
background-color: ${theme.color.purple700};
color: ${theme.color.white};
border-bottom-left-radius: 14px;
border-bottom-right-radius: 14px;
&:hover {
cursor: pointer;
}
`
const StyledDescriptionWrapper = styled.div`
display: flex;
flex-direction: column;
gap: 5px;
`

const IdeaOutline = () => {
return (
<DialogRoot>
<DialogTrigger asChild>
<button>버튼</button>
</DialogTrigger>
<DialogPortal>
<DialogOverlay />
<DialogContent>
<IdeaOutlineContainer>
<DialogTitle size="medium">아이디어 개요</DialogTitle>
<DialogDescription>
해당 파트는 자신이 생각하는 아이디어를 마음껏 펼쳐보는 시간입니다.
아이디어를 펼치기 전 시장 실패의 법칙에 대해 알아볼까요?
</DialogDescription>
</IdeaOutlineContainer>
<MarketFailureContainer>
<DialogTitle size="small">시장 실패의 법칙</DialogTitle>
<StyledDescriptionWrapper>
<DialogDescription>
실패(Fail)는 출시(Launch), 운영(Operation) 또는 전제(Premise)
때문입니다.
</DialogDescription>
<DialogDescription>
코카콜라나 디즈니, 구글처럼 전 세계에서 가장 성공한 기업들 조차
신제품이 시장에서 실패하는 이유는 3번째 요인, 전제(Premise)
때문입니다.
</DialogDescription>
<DialogDescription>
아무리 디자인이 뛰어나고 엔지니어링이 절묘하고 마케팅이 화려해도
‘안 될 놈’이 실패라는 괴수에 잡아먹히는 것을 막을 수 없습니다.
</DialogDescription>
<DialogDescription>
아이디어의 불패 법칙은 ‘유능하게 실행 했을 경우 성공할 아이디어’
즉, 될놈을 찾아 나서는 과정입니다.
</DialogDescription>
</StyledDescriptionWrapper>
</MarketFailureContainer>
<DialogClose asChild>
<StyledBottomBtn>
<FaX size={12} />
</StyledBottomBtn>
</DialogClose>
<DialogClose asChild>
<StyleBottomClosedBtn>닫기</StyleBottomClosedBtn>
</DialogClose>
</DialogContent>
</DialogPortal>
</DialogRoot>
)
}

export default IdeaOutline

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

export default 를 쓰면 자동완성이나 ctrl + click할때 잘 동작하지 않아서 요즘은 export const로 쓰는 편입니다~

https://dev.to/phuocng/avoid-using-default-exports-a1c

12 changes: 12 additions & 0 deletions src/components/common/Dialog/Close.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use client'

import * as DialogPrimitive from '@radix-ui/react-dialog'

const DialogClose = ({
children,
...props
}: DialogPrimitive.DialogCloseProps) => {
return <DialogPrimitive.Close {...props}>{children}</DialogPrimitive.Close>
}

export default DialogClose
45 changes: 45 additions & 0 deletions src/components/common/Dialog/Content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use client'

import * as DialogPrimitive from '@radix-ui/react-dialog'
import styled from 'styled-components'

const StyledContent = styled(DialogPrimitive.Content)`
/* 기본값 */
position: relative;
background-color: white;
border-radius: 14px;
box-shadow:
hsl(206 22% 7% / 35%) 0px 10px 38px -10px,
hsl(206 22% 7% / 20%) 0px 10px 20px -15px;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 90vw;
max-width: 353px;
min-height: 320px;
max-height: 85vh;
padding: 60px 20px 54px;
outline: none;
animation: contentShow 150ms cubic-bezier(0.16, 1, 0.3, 1);

@keyframes contentShow {
from {
opacity: 0;
transform: translate(-50%, -48%) scale(0.96);
}
to {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
}
`

const DialogContent = ({
children,
...props
}: DialogPrimitive.DialogContentProps) => {
return <StyledContent {...props}>{children}</StyledContent>
}

export default DialogContent
88 changes: 88 additions & 0 deletions src/components/common/Dialog/Description.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
'use client'

import { theme } from '@/styles/theme'
import * as DialogPrimitive from '@radix-ui/react-dialog'
import styled, { css } from 'styled-components'

const DialogDescriptionSizes: DialogDescriptionSize = {
small: {
fontSize: '0.75rem',
},
medium: {
fontSize: '0.875rem',
},
large: {
fontSize: '1rem',
},
}
const DialogDescriptionThemes: DialogDescriptionTheme = {
primary: {
color: theme.color.black,
},
red: {
color: theme.color.red,
},
}

const sizeStyles = css<StyledDescriptionProps>`
${({ size }) => css`
font-size: ${DialogDescriptionSizes[size].fontSize};
`}
`
const themeStyles = css<StyledDescriptionProps>`
${({ theme }) => css`
color: ${DialogDescriptionThemes[theme].color};
`}
`

const StyledDescription = styled(
DialogPrimitive.Description,
)<StyledDescriptionProps>`
/* 기본값 */
margin: 0;
color: ${theme.color.black};
line-height: 120%;
letter-spacing: -0.05em;
white-space: pre-wrap;
/* size */
${sizeStyles}
/* theme */
${themeStyles}
`

interface DialogDescriptionSize {
[key: string]: {
fontSize: string
padding?: string
}
}
interface DialogDescriptionTheme {
[key: string]: {
color: string
backgroundColor?: string
bolderColor?: string
}
}

/**
* **size**: large, medium, small(default)
*
* **theme**: primary(default), color
*/
interface StyledDescriptionProps {
size: string
theme: string
}
interface DialogDescriptionProps
extends DialogPrimitive.DialogDescriptionProps,
StyledDescriptionProps {}

const DialogDescription = ({ children, ...props }: DialogDescriptionProps) => {
return <StyledDescription {...props}>{children}</StyledDescription>
}
DialogDescription.defaultProps = {
size: 'small',
theme: 'primary',
}

export default DialogDescription
29 changes: 29 additions & 0 deletions src/components/common/Dialog/Overlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client'

import * as DialogPrimitive from '@radix-ui/react-dialog'
import styled from 'styled-components'

const StyledOverlay = styled(DialogPrimitive.Overlay)`
position: fixed;
inset: 0;
background-color: rgba(0, 0, 0, 0.5);
animation: overlayShow 150ms cubic-bezier(0.16, 1, 0.3, 1);

@keyframes overlayShow {
03hoho03 marked this conversation as resolved.
Show resolved Hide resolved
from {
opacity: 0;
}
to {
opacity: 1;
}
}
`

const DialogOverlay = ({
children,
...props
}: DialogPrimitive.DialogOverlayProps) => {
return <StyledOverlay {...props}>{children}</StyledOverlay>
}

export default DialogOverlay
12 changes: 12 additions & 0 deletions src/components/common/Dialog/Portal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use client'

import * as DialogPrimitive from '@radix-ui/react-dialog'

const DialogPortal = ({
children,
...props
}: DialogPrimitive.DialogPortalProps) => {
return <DialogPrimitive.Portal {...props}>{children}</DialogPrimitive.Portal>
}

export default DialogPortal
7 changes: 7 additions & 0 deletions src/components/common/Dialog/Root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use client'

import * as DialogPrimitive from '@radix-ui/react-dialog'

const DialogRoot = DialogPrimitive.Root

export default DialogRoot
58 changes: 58 additions & 0 deletions src/components/common/Dialog/Title.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use client'

import { theme } from '@/styles/theme'
import * as DialogPrimitive from '@radix-ui/react-dialog'
import styled, { css } from 'styled-components'

const DialogTitleSizes: DialogTitleSize = {
small: {
fontSize: '1rem',
fontFamily: theme.NanumFontFamily.bold,
},
medium: {
fontSize: '1.25rem',
fontFamily: theme.NanumFontFamily.extraBold,
},
large: { fontSize: '2rem', fontFamily: theme.NanumFontFamily.extraBold },
}

const DialogTitleSizeStyles = css<StyledTitleProps>`
${({ size }) => css`
font-size: ${DialogTitleSizes[size].fontSize};
font-family: ${DialogTitleSizes[size].fontFamily};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나눔글꼴 이렇게 해야 하다니 ... 왜지 ..?!

`}
`

const StyledTitle = styled(DialogPrimitive.Title)<StyledTitleProps>`
line-height: 140%;
letter-spacing: -0.05em;
color: ${theme.color.black};

${DialogTitleSizeStyles}
`

interface DialogTitleSize {
[key: string]: {
fontSize: string
fontFamily?: string
}
}

/**
* **size** : small, medium(default), large
*/
interface StyledTitleProps {
size: string
}
interface DialogTitleProps
extends DialogPrimitive.DialogTitleProps,
StyledTitleProps {}

const DialogTitle = ({ children, ...props }: DialogTitleProps) => {
return <StyledTitle {...props}>{children}</StyledTitle>
}
DialogTitle.defaultProps = {
size: 'medium',
}

export default DialogTitle
Loading
Loading