Skip to content

Commit

Permalink
Merge pull request #29 from sopt-makers/feat/#20-dialogs
Browse files Browse the repository at this point in the history
faet: 다이얼로그 구현
  • Loading branch information
sohee-K authored Dec 7, 2023
2 parents 8448f73 + 082e83c commit 664fc64
Show file tree
Hide file tree
Showing 7 changed files with 310 additions and 0 deletions.
100 changes: 100 additions & 0 deletions apps/docs/src/stories/Dialog.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { Meta, StoryObj } from '@storybook/react';

import Dialog from 'ui/Dialog';

import { useState } from 'react';


export default {
title: 'Example/Dialog',
component: Dialog,
parameters: {
layout: 'centered',
},
tags: ['autodocs'],
} as Meta;


export const Desktop:StoryObj = {
render: function Render() {
const [isOpen, setIsOpen] = useState<boolean>(false);

const onOpen = () => {
setIsOpen(true);
};
const onClose = () => {
setIsOpen(false);
};

return (
<>
<button onClick={onOpen}>클릭하여 모달 열기</button>
<Dialog isOpen={isOpen} onClose={onClose} device={'desktop'}>
<Dialog.Title>타이틀 자리입니다</Dialog.Title>
<Dialog.Description>
안녕하세요! makers입니다.
이번 업데이트에서는 아래와 같은 내용들이 반영되었습니다.

공지 기능 추가
솝트 내 공지를 한 곳에서 확인하세요.
출석 기능 추가
솝트 출석을 더 편하게 관리하세요.
많은 관심 부탁드리며
피드백은 언제나 환영입니다!
피드백은 언제나 환영입니다!
피드백은 언제나 환영입니다!
</Dialog.Description>
<Dialog.Footer align='right'>
<button>버튼1</button>
<button>버튼2</button>
</Dialog.Footer>
</Dialog>
</>
);
},

name: '다이얼로그 데스크탑',
};


export const Mobile:StoryObj = {
render: function Render() {
const [isOpen, setIsOpen] = useState<boolean>(false);

const onOpen = () => {
setIsOpen(true);
};
const onClose = () => {
setIsOpen(false);
};

return (
<>
<button onClick={onOpen}>클릭하여 모달 열기</button>
<Dialog isOpen={isOpen} onClose={onClose} device={'mobile'}>
<Dialog.Title>타이틀 자리입니다</Dialog.Title>
<Dialog.Description>
안녕하세요! makers입니다.
이번 업데이트에서는 아래와 같은 내용들이 반영되었습니다.

공지 기능 추가
솝트 내 공지를 한 곳에서 확인하세요.
출석 기능 추가
솝트 출석을 더 편하게 관리하세요.
많은 관심 부탁드리며
피드백은 언제나 환영입니다!
피드백은 언제나 환영입니다!
피드백은 언제나 환영입니다!
</Dialog.Description>
<Dialog.Footer align='center'>
<button>버튼1</button>
<button>버튼2</button>
</Dialog.Footer>
</Dialog>
</>
);
},

name: '다이얼로그 모바일',
};

22 changes: 22 additions & 0 deletions packages/ui/Dialog/components/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ReactNode } from 'react';
import { description, footer, title } from './style.css';

interface ChildrenProp {
children?: ReactNode | string;
}

export function DialogTitle({ children }: ChildrenProp) {
return <div className={title}>{children}</div>;
}

export function DialogDescription({ children }: ChildrenProp) {
return <div className={description}>{children}</div>;
}

interface DialogFooterProp extends ChildrenProp {
align: 'center' | 'left' | 'right';
}

export function DialogFooter({ children, align }: DialogFooterProp) {
return <div className={footer[align]}>{children}</div>;
}
67 changes: 67 additions & 0 deletions packages/ui/Dialog/components/style.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { style, styleVariants } from '@vanilla-extract/css';
import theme from '../../theme.css';

export const title = style({
// TODO: css 객체로 폰트 나오면 수정 예정입니다
fontFamily: 'SUIT',
fontSize: '20px',
fontStyle: 'normal',
fontWeight: '600',
lineHeight: '30px',
letterSpacing: '-0.4px',

color: `${theme.colors.gray10}`,
marginBottom: 12,

'@media': {
'screen and (min-width: 768px)': {
// TODO: css 객체로 폰트 나오면 수정 예정입니다
fontFamily: 'SUIT',
fontSize: '18px',
fontStyle: 'normal',
fontWeight: '600',
lineHeight: '28px',
letterSpacing: '-0.36px',
marginBottom: 8,
},
},
});

export const description = style({
// TODO: css 객체로 폰트 나오면 수정 예정입니다
fontFamily: 'SUIT',
fontSize: '16px',
fontStyle: 'normal',
fontWeight: '400',
lineHeight: '26px',
letterSpacing: '-0.24px',
color: `${theme.colors.gray100}`,
marginBottom: 36,

maxHeight: '264px',
overflowY: 'scroll',

'@media': {
'screen and (min-width: 768px)': {
// TODO: css 객체로 폰트 나오면 수정 예정입니다
fontFamily: 'SUIT',
fontSize: '14px',
fontStyle: 'normal',
fontWeight: '400',
lineHeight: '22px',
letterSpacing: '-0.21px',
marginBottom: 24,
},
},
});

export const footerBase = style({
display: 'grid',
gridAutoFlow: 'column',
});

export const footer = styleVariants({
center: [footerBase, { width: '100%', display: 'flex', justifyContent: 'space-between' }],
right: [footerBase, { width: '100%', display: 'flex', justifyContent: 'flex-end', gap: '12px' }],
left: [footerBase, { width: '100%', display: 'flex', justifyContent: 'flex-start', gap: '12px' }],
});
36 changes: 36 additions & 0 deletions packages/ui/Dialog/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { FC, ReactNode } from 'react';

import * as Dialogs from '@radix-ui/react-dialog';
import { DialogDescription, DialogFooter, DialogTitle } from './components';
import { dialogContainer, overlay } from './style.css';

interface DialogProps {
isOpen: boolean;
onClose: () => void;
device: 'desktop' | 'mobile';
children?: ReactNode;
}

const DialogComponent: FC<DialogProps> = ({ isOpen, onClose, children, device, ...restProps }) => {
return (
<Dialogs.Root open={isOpen} onOpenChange={onClose}>
<Dialogs.Portal>
<Dialogs.Overlay className={overlay}>
<div>
<Dialogs.Content className={dialogContainer[device]} asChild {...restProps}>
<div>{children}</div>
</Dialogs.Content>
</div>
</Dialogs.Overlay>
</Dialogs.Portal>
</Dialogs.Root>
);
};

const Dialog = Object.assign(DialogComponent, {
Title: DialogTitle,
Description: DialogDescription,
Footer: DialogFooter,
});

export default Dialog;
24 changes: 24 additions & 0 deletions packages/ui/Dialog/style.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { style, styleVariants } from '@vanilla-extract/css';
import theme from '../theme.css';

export const base = style({
display: 'flex',
flexDirection: 'column',
borderRadius: '14px',
backgroundColor: `${theme.colors.gray800}`,
position: 'relative',
});

export const dialogContainer = styleVariants({
desktop: [base, { width: '400px', padding: '24px' }],
mobile: [base, { maxWidth: '324px', padding: '20px', margin: '0px 36px' }],
});

export const overlay = style({
display: 'flex',
position: 'fixed',
inset: '0',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: `${theme.colors.backgroundDimmed}`,
});
1 change: 1 addition & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"typescript": "^4.5.2"
},
"dependencies": {
"@radix-ui/react-dialog": "^1.0.5",
"@sopt-makers/colors": "file:../colors",
"@sopt-makers/fonts": "file:../fonts"
}
Expand Down
60 changes: 60 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2222,6 +2222,27 @@
dependencies:
"@babel/runtime" "^7.13.10"

"@radix-ui/react-dialog@^1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz#71657b1b116de6c7a0b03242d7d43e01062c7300"
integrity sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.1"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-context" "1.0.1"
"@radix-ui/react-dismissable-layer" "1.0.5"
"@radix-ui/react-focus-guards" "1.0.1"
"@radix-ui/react-focus-scope" "1.0.4"
"@radix-ui/react-id" "1.0.1"
"@radix-ui/react-portal" "1.0.4"
"@radix-ui/react-presence" "1.0.1"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-slot" "1.0.2"
"@radix-ui/react-use-controllable-state" "1.0.1"
aria-hidden "^1.1.1"
react-remove-scroll "2.5.5"

"@radix-ui/react-direction@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.1.tgz#9cb61bf2ccf568f3421422d182637b7f47596c9b"
Expand All @@ -2241,6 +2262,18 @@
"@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-use-escape-keydown" "1.0.3"

"@radix-ui/react-dismissable-layer@1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4"
integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/primitive" "1.0.1"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-use-escape-keydown" "1.0.3"

"@radix-ui/react-focus-guards@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad"
Expand All @@ -2258,6 +2291,16 @@
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-use-callback-ref" "1.0.1"

"@radix-ui/react-focus-scope@1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525"
integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-use-callback-ref" "1.0.1"

"@radix-ui/react-id@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0"
Expand Down Expand Up @@ -2291,6 +2334,23 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "1.0.3"

"@radix-ui/react-portal@1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15"
integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "1.0.3"

"@radix-ui/react-presence@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba"
integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==
dependencies:
"@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-use-layout-effect" "1.0.1"

"@radix-ui/react-primitive@1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0"
Expand Down

0 comments on commit 664fc64

Please sign in to comment.