Skip to content

Commit

Permalink
[Style] Modal 컴포넌트 제작 (#52)
Browse files Browse the repository at this point in the history
* chore : zustand 설치 및 store 폴더 생성

* feat : 모달창 전역 상태 추가

* style : 모달창 컴포넌트 제작

* fix: package.json 쉼표 오류

* �fix: package-lock.json 쉼표 오류

* fix : 모달창 type 받아 분기 처리

* fix : type 에러 수정

* chore : 주석 제거

* fix: isDarkMode 옵셔널로 수정

---------

Co-authored-by: Changuk Woo <[email protected]>
Co-authored-by: wukddang <[email protected]>
  • Loading branch information
3 people authored Oct 30, 2023
1 parent cc07575 commit 1560475
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 10 deletions.
46 changes: 42 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
"react-hook-form": "^7.47.0",
"react-icons": "^4.11.0",
"react-router-dom": "^6.16.0",
"react-spinners": "^0.13.8",
"react-toastify": "^9.1.3"
"react-toastify": "^9.1.3",
"zustand": "^4.4.4",
"zustand-persist": "^0.4.0",
"react-spinners": "^0.13.8"
},
"devDependencies": {
"@rushstack/eslint-config": "^3.4.1",
Expand Down
5 changes: 5 additions & 0 deletions src/assets/icons/Exclamation.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icons/Warning.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/components/common/Buttons/NormalButton/NormalButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { NormalButtonStyles, NormalButtonType } from './NormalButtonStyles'

const NormalButton = styled.button<{
normalButtonType: NormalButtonType
isDarkMode: boolean
isDarkMode?: boolean
}>`
${({ normalButtonType, isDarkMode }) => {
${({ normalButtonType, isDarkMode = false }) => {
const processedTypeKey = isDarkMode ? `${normalButtonType}-dark` : normalButtonType
const processedType = (
NormalButtonStyles[processedTypeKey as NormalButtonType] ? processedTypeKey : normalButtonType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export const NormalButtonStyles: Record<NormalButtonType, NormalButtonStyle> = {
width: 85,
height: 40,
fontColor: palette.GRAY400,
backgroundColor: palette.GRAY100,
backgroundColor: palette.GRAY200,
font: 'Body_14',
fontWeight: 600,
letterSpacing: -2,
Expand Down
124 changes: 124 additions & 0 deletions src/components/common/Modal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import styled from '@emotion/styled'

import ExclamationIcon from '@/assets/icons/Exclamation.svg'
import WarningIcon from '@/assets/icons/Warning.svg'
import NormalButton from '@/components/common/Buttons/NormalButton/NormalButton'
import useModalStore from '@/store/ModalStore'
import { palette } from '@/styles/palette'
import { typo } from '@/styles/typo'

const Modal = () => {
const { modalState, setModalState, okFunc, mainText, subText, type } = useModalStore()
const OkAndClose = () => {
okFunc()
closeModal()
}
const closeModal = () => {
setModalState(false)
}
return (
<>
{modalState ? (
<StyleModalWrapper>
<StyleModal type={type}>
{type == 'confirm' ? (
<StyleIcon src={ExclamationIcon} />
) : (
<StyleIcon src={WarningIcon} />
)}

<StyleMainText subTrue={subText == undefined ? false : true}>{mainText}</StyleMainText>
<StyleSubText type={type}>{subText}</StyleSubText>
{type === 'confirm' ? (
<StyleButtonWrapper>
<NormalButton
normalButtonType={'modal-accept'}
style={{ margin: 10 }}
onClick={OkAndClose}
>
{'확인'}
</NormalButton>
<NormalButton
normalButtonType={'modal-deny'}
style={{ margin: 10 }}
onClick={closeModal}
>
{'취소'}
</NormalButton>
</StyleButtonWrapper>
) : (
<StyleButtonWrapper>
<NormalButton
normalButtonType={'warning-accept'}
style={{ margin: 10 }}
onClick={OkAndClose}
>
{'예, 나가겠습니다.'}
</NormalButton>
<NormalButton
normalButtonType={'warning-deny'}
style={{ margin: 10 }}
onClick={closeModal}
>
{'아니오, 돌아가겠습니다.'}
</NormalButton>
</StyleButtonWrapper>
)}
</StyleModal>
</StyleModalWrapper>
) : (
''
)}
</>
)
}

const StyleModalWrapper = styled.div`
z-index: 999;
display: flex;
position: absolute;
justify-content: center;
align-items: center;
width: 100%;
background-color: rgba(0, 0, 0, 0.4);
border-radius: 10px;
top: 0;
left: 0;
right: 0;
bottom: 0;
`
const StyleModal = styled.div<{ type: string }>`
width: 344px;
height: ${({ type }) => (type == 'warn' ? '195.6px' : '246px')};
z-index: 1;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
border-radius: 10px;
box-shadow: 3px 3px 3px ${palette.GRAY400};
text-align: center;
`

const StyleButtonWrapper = styled.span`
justify-content: center;
margin: 10px;
display: flex;
`
const StyleMainText = styled.div<{ subTrue: boolean }>`
color: ${palette.BLACK};
text-align: center;
font-size: ${typo.Body_20()};
margin-top: ${({ subTrue }) => (subTrue ? '' : '10px')};
margin-bottom: ${({ subTrue }) => (subTrue ? '20px' : '30px')};
`
const StyleSubText = styled.span<{ type: string }>`
color: ${palette.GRAY500};
text-align: center;
font-size: ${typo.Body_14()};
`
const StyleIcon = styled.img`
margin: 22px;
`
export default Modal
2 changes: 2 additions & 0 deletions src/components/layouts/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import styled from '@emotion/styled'
import { Outlet } from 'react-router-dom'
import { ToastContainer } from 'react-toastify'

import Modal from '@/components/common/Modal'
import { theme } from '@/styles/theme'

const Layout = () => {
return (
<MainContainer>
<Modal />
<Outlet />
<ToastContainer />
</MainContainer>
Expand Down
22 changes: 22 additions & 0 deletions src/hooks/useModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Modal from '@/components/common/Modal'
import useModalStore from '@/store/ModalStore'

type ModalConfirmPropsType = {
type: 'warn' | 'confirm'
okFunc: () => void
mainText: string
subText?: string
}
export const useModal = () => {
const { setModalState, setOkFunc, setMainText, setSubText, setType } = useModalStore()

const openModal = ({ mainText, subText, okFunc, type }: ModalConfirmPropsType) => {
setModalState(true)
setType(type)
setMainText(mainText)
setSubText(subText)
setOkFunc(okFunc)
}

return { openModal, Modal }
}
28 changes: 28 additions & 0 deletions src/store/ModalStore.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { create } from 'zustand'

type ModalState = {
modalState: boolean
type: 'confirm' | 'warn'
okFunc: () => void
mainText: string
subText?: string | undefined
setType: (type: 'confirm' | 'warn') => void
setSubText: (text: string | undefined) => void
setModalState: (state: boolean) => void
setMainText: (text: string) => void
setOkFunc: (func: () => void) => void
}

const useModalStore = create<ModalState>((set) => ({
modalState: false,
okFunc: () => {},
mainText: '',
subText: '',
type: 'confirm',
setType: (type) => set({ type: type }),
setSubText: (text) => set({ subText: text }),
setModalState: (state) => set({ modalState: state }),
setMainText: (text) => set({ mainText: text }),
setOkFunc: (func) => set({ okFunc: func }),
}))
export default useModalStore
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"@/hooks/*": ["src/hooks/*"],
"@/assets/*": ["src/assets/*"],
"@/styles/*": ["src/styles/*"],
"@/mocks/*": ["src/mocks/*"]
"@/mocks/*": ["src/mocks/*"],
"@/store/*": ["src/store/*"]
}
},
"include": ["src"],
Expand Down

0 comments on commit 1560475

Please sign in to comment.