diff --git a/apps/team-styled/public/mg.png b/apps/team-styled/public/mg.png new file mode 100644 index 0000000..4206275 Binary files /dev/null and b/apps/team-styled/public/mg.png differ diff --git a/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.stories.tsx b/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.stories.tsx index e8f4535..c8a1fae 100644 --- a/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.stories.tsx +++ b/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.stories.tsx @@ -2,10 +2,11 @@ import Accordion from './Accordion'; import styled from 'styled-components'; import { ReactNode } from 'react'; -export type accordionType = { - state: boolean; - title?: string; - text?: string; +export type AccordionType = { + state?: boolean; + title: string; + text: string; + size: '6xl' | '5xl' | '4xl' | '3xl' | '2xl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; children?: ReactNode; }; @@ -13,53 +14,50 @@ export default { title: 'chakra-ui-styled/components/disclosure/accordion', component: Accordion, parameter: { controls: { expanded: true } }, + argTypes: { - state: { - control: { - type: 'boolean', - title: 'Accordion Button', - text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.' - } + size: { control: { type: 'select', options: ['6xl', '5xl', '4xl', '3xl', '2xl', 'xl', 'lg', 'md', 'sm', 'xs'] } }, + state: { control: { type: 'boolean' } }, + title: { control: { type: 'text' }, description: '제목입니다.' }, + text: { control: { type: 'text' } }, + arg: { + size: 'md', // 기본 size 값 + state: true, // 기본 state 값 + title: '기본 제목', // 기본 title 문구 + text: '기본 텍스트' // 기본 text 문구 } } }; -const Container = styled.div``; -export const AccordionComponent = (args: accordionType) => { +export const AccordionComponent = (args: AccordionType) => { return ( <>

Accordion Demo

+

스토리북 설정

- - + +


- - + + - - + + - - - + + +
); }; +const Container = styled.div``; + AccordionComponent.storyName = 'Accordion'; diff --git a/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.tsx b/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.tsx index 6853063..c1cae79 100644 --- a/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.tsx +++ b/packages/chakra-ui-styled/src/components/disclosure/accordion/Accordion.tsx @@ -1,18 +1,37 @@ -import { accordionType } from './Accordion.stories'; -import { createContext, ReactNode, useContext, useState } from 'react'; +import { AccordionType } from './Accordion.stories'; +import { createContext, ReactNode, useContext, useEffect, useReducer } from 'react'; import styled, { css } from 'styled-components'; +import { BaseText } from '../../../foundation/typography/Text'; -const AccordionContext = createContext({ - isOpen: false, - setIsOpen: (value: boolean) => {} +type AccordionContextType = AccordionType & { + isOpen: boolean; + setIsOpen: () => void; +}; +const AccordionContext = createContext({ + isOpen: true, + setIsOpen: () => {}, + title: '', + text: '', + size: 'md' }); -const Accordion = ({ state, children }: accordionType) => { - const [isOpen, setIsOpen] = useState(state); +const Accordion = ({ state = true, children, size, title, text }: AccordionType) => { + // const [isOpen, setIsOpen] = useState(state); + // boolean useReducer 이용하여 관리, + const [isOpen, setIsOpen] = useReducer((state) => !state, state); const providerValue = { isOpen, - setIsOpen + setIsOpen, + title, + size, + text }; + + // 스토리북 arg 작동을 위한 useEffect + useEffect(() => { + setIsOpen(); + }, [state]); + return ( {children} @@ -20,28 +39,31 @@ const Accordion = ({ state, children }: accordionType) => { ); }; -const Toggle = ({ title, children }: { title: string; children?: ReactNode }) => { - const { isOpen, setIsOpen } = useContext(AccordionContext); +const Toggle = ({ children }: { children?: ReactNode }) => { + const { isOpen, setIsOpen, title, size = 'md' } = useContext(AccordionContext); return ( -
setIsOpen(!isOpen)}> +
+ {/*isOpen 통해 svg 방향 바꿈*/}
{title}
+ {/* 아이콘 */}
-

{children}

+ + {children}
); }; -const Panel = ({ text }: { text: string }) => { - const { isOpen } = useContext(AccordionContext); +const Panel = () => { + const { isOpen, text, size } = useContext(AccordionContext); - return isOpen && {text}; + return !isOpen && {text}; }; Accordion.Toggle = Toggle; @@ -54,31 +76,30 @@ const TitleBox = styled.div<{ isOpen: boolean }>` justify-content: space-between; flex: 1; width: inherit; - max-width: 345px; + //max-width: 345px; user-select: none; ${({ isOpen }) => - isOpen && + !isOpen && css` div { transform: rotate(180deg); } `} `; -const TextBox = styled.div` - font-size: 16px; - font-weight: 400; -`; +// const TextBox = styled.div` +// font-size: 16px; +// font-weight: 400; +// `; const Container = styled.article` display: flex; justify-content: space-between; align-items: center; - width: 403px; - border-block: 1px solid #d0d0d0; + //width: 403px; + border-block: ${({ theme }) => theme.spacing.px} solid ${({ theme }) => theme.color.gray[300]}; padding: 10px 12px; h5 { - font-size: 16px; - font-weight: 400; + ${({ theme }) => theme.typo.text.md} } > div { display: flex; @@ -86,3 +107,8 @@ const Container = styled.article` flex-direction: column; } `; + +// +// +// +//TODO : 디자인시스템 css 바꾸기 diff --git a/packages/chakra-ui-styled/src/components/form/button/Button.tsx b/packages/chakra-ui-styled/src/components/form/button/Button.tsx index 34e0498..565a242 100644 --- a/packages/chakra-ui-styled/src/components/form/button/Button.tsx +++ b/packages/chakra-ui-styled/src/components/form/button/Button.tsx @@ -9,6 +9,7 @@ export interface ButtonProps { children?: string; leftIcon?: React.ReactNode; rightIcon?: React.ReactNode; + onClick?: () => void; } const setIcon = (icon: React.ReactNode) => { return
{icon}
; @@ -21,10 +22,11 @@ const Button = ({ colorScheme, leftIcon, rightIcon, - children + children, + onClick }: ButtonProps) => { return ( - + {leftIcon && setIcon(leftIcon)} {children && ( diff --git a/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.styled.tsx b/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.styled.tsx index 55043e4..fab7117 100644 --- a/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.styled.tsx +++ b/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.styled.tsx @@ -1,10 +1,7 @@ export const CloseIconStyle = () => { return ( - + ); }; diff --git a/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.tsx b/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.tsx index 4bc5efa..c98a725 100644 --- a/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.tsx +++ b/packages/chakra-ui-styled/src/components/form/closebutton/CloseButton.tsx @@ -3,23 +3,22 @@ import styled from 'styled-components'; export interface CloseButtonProps { size: 'sm' | 'md' | 'lg'; icon?: React.ReactNode; + onClick?: () => void; + className?: string; } const ViewBoxSize = { sm: 24, md: 32, lg: 40 }; const setIcon = (icon: React.ReactNode) => { return
{icon}
; }; const CloseButtonStyle = styled.div` - display: flex; - align-items: center; - justify-content: center; width: ${({ size }) => ViewBoxSize[size]}px; height: ${({ size }) => ViewBoxSize[size]}px; aspect-ratio: 1; cursor: pointer; `; -const CloseButton = ({ size = 'sm', icon }: CloseButtonProps) => { +const CloseButton = ({ size = 'sm', icon, className, onClick }: CloseButtonProps) => { return ( - + {icon && setIcon(icon)} ) diff --git a/packages/chakra-ui-styled/src/components/form/pininput/PinInput.style.tsx b/packages/chakra-ui-styled/src/components/form/pininput/PinInput.style.tsx index 17cd90a..4060329 100644 --- a/packages/chakra-ui-styled/src/components/form/pininput/PinInput.style.tsx +++ b/packages/chakra-ui-styled/src/components/form/pininput/PinInput.style.tsx @@ -21,18 +21,21 @@ const PinInputSize = { width: ${({ theme }) => theme.spacing[12]}; border-radius: 6px; ${({ theme }) => theme.typo.text.lg} - `, + ` }; export const StylePinInput = styled.div.attrs({ autoFocus: true })` display: flex; gap: 6px; - & input{ + + & input { ${({ size }) => PinInputSize[size]} ${({ colorScheme, theme }) => css` border: 1px solid ${theme.color.gray[200]}; + &:focus { outline: 2px solid ${theme.color[colorScheme][500]}; } + &:placeholder-shown { color: ${theme.color.gray[400]}; } @@ -40,11 +43,11 @@ export const StylePinInput = styled.div.attrs({ autoFocus: true }) { - const numberOfInputs = numOfInputs; - const [inputRefsArray] = useState(() => - Array.from({ length: numberOfInputs }, () => createRef()) - ); - const [currentIndex, setCurrentIndex] = useState(0); - const handleKeyPress = () => { - setCurrentIndex((prevIndex) => { - const nextIndex = prevIndex < numberOfInputs - 1 ? prevIndex + 1 : 0; - const nextInput = inputRefsArray?.[nextIndex]?.current; //선택적 체이닝 문법 사용 - nextInput.focus(); - return nextIndex; - }); - }; - useEffect(() => { - if (inputRefsArray?.[0]?.current) { - inputRefsArray?.[0]?.current?.focus(); - } +const PinInput = ({ size = 'md', colorScheme, numOfInputs = 4 }: PinInputProps) => { + const inputArray = Array.from({ length: numOfInputs }); + const onFocusInput = (e: React.KeyboardEvent) => { + const pinInput = e.target as HTMLInputElement; + const value = pinInput.value; + const maxLength = Number(pinInput.getAttribute('maxlength')); - window.addEventListener("keyup", handleKeyPress, false); - return () => { - window.removeEventListener("keyup", handleKeyPress); - }; - }, []); + if (e.code === 'Backspace') { + if (!pinInput.previousSibling) return; + !value ? (pinInput.previousSibling as HTMLInputElement).focus() : pinInput.focus(); + } + if (value.length === maxLength && e.code !== 'Backspace') { + if (!pinInput.nextSibling) return; + (pinInput.nextSibling as HTMLInputElement).focus(); + } + }; return ( - - {inputRefsArray.map((ref, index) => { - return( - setCurrentIndex(index) } - /> - ) + + {inputArray.map((_, index) => { + return ; })} ); }; -export default PinInput; \ No newline at end of file +export default PinInput; diff --git a/packages/chakra-ui-styled/src/components/media/Avatar/Avatar.stories.tsx b/packages/chakra-ui-styled/src/components/media/Avatar/Avatar.stories.tsx new file mode 100644 index 0000000..27a37d5 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/media/Avatar/Avatar.stories.tsx @@ -0,0 +1,68 @@ +import styled from 'styled-components'; +import Avatar, { AvatarProps, AvatarSize } from './Avatar'; + +export default { + title: 'chakra-ui-styled/components/Avatar', + component: Avatar, + parameters: { controls: { expanded: true } }, + + argTypes: { + size: { control: { type: 'select' } }, + userName: { control: { type: 'text', maxLength: 2 } } + }, + args: { + size: '2xl', + img: 'https://images.unsplash.com/photo-1552058544-f2b08422138a?q=80&w=1299&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D' + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; +const AvatarWrap = styled.div` + display: flex; + gap: 45px; + align-items: center; +`; + +export const AvatarIndex = (args: AvatarProps) => { + const AvatarArr: AvatarSize[] = ['xs', 'sm', 'md', 'lg', 'xl', '2xl']; + return ( + +

Avatar

+ +

Avatar Demo

+
+ +
+ +

Avatar Index

+ + + {AvatarArr.map((size) => { + return ( + + ); + })} + + + + {AvatarArr.map((size) => { + return ; + })} + + + + {AvatarArr.map((size) => { + return ; + })} + +
+ ); +}; +AvatarIndex.storyName = 'Avatar'; diff --git a/packages/chakra-ui-styled/src/components/media/Avatar/Avatar.styled.tsx b/packages/chakra-ui-styled/src/components/media/Avatar/Avatar.styled.tsx new file mode 100644 index 0000000..e8c3aee --- /dev/null +++ b/packages/chakra-ui-styled/src/components/media/Avatar/Avatar.styled.tsx @@ -0,0 +1,161 @@ +import styled, { css } from 'styled-components'; +import { AvatarStyleProps } from './Avatar'; +import { StyleText } from '../../../foundation/typography/Text.styled'; + +const AvatarSize = { + '2xl': { + size: '128px', + typo: '48px', + badge: css` + width: 40px; + height: 40px; + border-style: solid; + border-width: 8px; + border-radius: ${({ theme }) => theme.radii.full}; + ` + }, + xl: { + size: '96px', + typo: '38px', + badge: css` + width: 24px; + height: 24px; + border-style: solid; + border-width: 5px; + border-radius: ${({ theme }) => theme.radii.full}; + ` + }, + lg: { + size: '64px', + typo: '24px', + badge: css` + width: 16px; + height: 16px; + border-style: solid; + border-width: 3px; + border-radius: ${({ theme }) => theme.radii.full}; + ` + }, + md: { + size: '48px', + typo: '20px', + badge: css` + width: 16px; + height: 16px; + border-style: solid; + border-width: 3px; + border-radius: ${({ theme }) => theme.radii.full}; + ` + }, + sm: { + size: '32px', + typo: '12px', + badge: css` + width: 8px; + height: 8px; + border-style: solid; + border-width: 2px; + border-radius: ${({ theme }) => theme.radii.full}; + ` + }, + xs: { + size: '24px', + typo: '10px', + badge: css` + width: 6px; + height: 6px; + border-style: solid; + border-width: 1px; + border-radius: ${({ theme }) => theme.radii.full}; + ` + } +}; +const AvatarText = { + lg: css` + ${({ theme }) => theme.typo.text.md}; + font-weight: ${({ theme }) => theme.typo.fontWeight.medium}; + line-height: 1.5; + `, + md: css` + ${({ theme }) => theme.typo.text.sm}; + font-weight: ${({ theme }) => theme.typo.fontWeight.medium}; + line-height: 1.3; + `, + sm: css` + ${({ theme }) => theme.typo.text.xs}; + font-weight: ${({ theme }) => theme.typo.fontWeight.medium}; + ` +}; + +export const AvatarStyle = styled.div<{ $props: AvatarStyleProps }>` + ${({ theme, $props }) => css` + position: relative; + display: inline-flex; + flex: none; + align-items: center; + justify-content: center; + width: ${AvatarSize[$props.size].size}; + height: ${AvatarSize[$props.size].size}; + border-radius: ${theme.radii.full}rem; + & ${StyleText} { + ${AvatarSize[$props.size].typo} + } + + /* img */ + ${$props.img && + css` + & img { + background-color: ${theme.color.gray[100]}; + border-radius: inherit; + } + `} + + ${$props.userName && + css` + background-color: ${theme.color.blue[300]}; + + .user-name { + font-size: ${AvatarSize[$props.size].typo}; + font-weight: 500; + line-height: 1.1; + text-transform: uppercase; + } + `} + /* avtar */ + ${!$props.img && + !$props.userName && + css` + color: white; + background-color: ${theme.color.gray[400]}; + + & svg { + width: calc(${AvatarSize[$props.size].size} / 1.5); + } + `} + + + /* badge */ + ${$props.badge && + css` + &::after { + position: absolute; + right: 0; + bottom: 0; + display: block; + content: ''; + border-radius: ${theme.radii.full}rem; + transform: translateY(10%); + ${AvatarSize[$props.size].badge}; + ${$props.badge === 'on' + ? css` + background-color: ${theme.color.green[500]}; + border-color: ${theme.color.white.white}; + ` + : css` + background-color: ${theme.color.red[500]}; + border-color: ${theme.color.red[100]}; + `} + } + `} + `} +`; diff --git a/packages/chakra-ui-styled/src/components/media/Avatar/Avatar.tsx b/packages/chakra-ui-styled/src/components/media/Avatar/Avatar.tsx new file mode 100644 index 0000000..f6b71da --- /dev/null +++ b/packages/chakra-ui-styled/src/components/media/Avatar/Avatar.tsx @@ -0,0 +1,37 @@ +import { AvatarStyle } from './Avatar.styled'; +import Image from 'next/image'; +export type AvatarSize = '2xl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; +export type AvatarStyleProps = { + size: AvatarSize; + badge?: 'on' | 'off'; + img?: string; + userName?: string; +}; +export type AvatarProps = AvatarStyleProps & {}; +const AvatarIcon = () => { + return ( + + + + ); +}; +const Avatar = ({ size, userName, img, badge = 'on' }: AvatarProps) => { + return ( + + {/* 1. userName 존재하고 이미지 없을경우 */} + {userName && !img && {userName}} + {/* 2.이미지 존재할 경우 */} + {img && {'이미지'}} + {/* 3. userName존재하지 않고 이미지 존재하지않을경우 */} + {!img && !userName && } + + ); +}; + +export default Avatar; diff --git a/packages/chakra-ui-styled/src/components/navigation/BreadCrumb/BreadCrumb.styled.tsx b/packages/chakra-ui-styled/src/components/navigation/BreadCrumb/BreadCrumb.styled.tsx new file mode 100644 index 0000000..dabf1f5 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/navigation/BreadCrumb/BreadCrumb.styled.tsx @@ -0,0 +1,29 @@ +import styled, { css } from 'styled-components'; +import { colorSchemeType } from './BreadCrumbs'; + +export const StyleBreadCrumb = styled.div<{ $color: colorSchemeType }>` + display: flex; + align-items: center; + + span[data-separator='true'] { + display: inline-flex; + align-items: center; + justify-content: center; + width: 24px; + color: ${({ theme, $color }) => theme.color[$color][800]}; + } +`; + +export const StyleBreadCrumbLink = styled.span<{ as: HTMLElementTagNameMap; $color: colorSchemeType }>` + ${({ theme, as, $color }) => css` + ${theme.typo.text.md}; + color: ${theme.color[$color][700]}; + ${as === 'a' && + css` + &:hover { + color: ${theme.color[$color][500]}; + text-decoration: underline; + } + `}; + `} +`; diff --git a/packages/chakra-ui-styled/src/components/navigation/BreadCrumb/BreadCrumbs.tsx b/packages/chakra-ui-styled/src/components/navigation/BreadCrumb/BreadCrumbs.tsx new file mode 100644 index 0000000..435b1ad --- /dev/null +++ b/packages/chakra-ui-styled/src/components/navigation/BreadCrumb/BreadCrumbs.tsx @@ -0,0 +1,46 @@ +import { StyleBreadCrumb, StyleBreadCrumbLink } from './BreadCrumb.styled'; + +type BreadCrumbsPageType = { + title: string; + href: string; + current: boolean; +}; +type BreadCrumbsVariantType = 'dash' | 'arrow' | 'slash'; +export type colorSchemeType = 'blue' | 'gray' | 'teal' | 'red' | 'orange' | 'yellow' | 'pink' | 'purple' | 'green'; + +export type BreadCrumbsType = { + variant?: BreadCrumbsVariantType; + pages: BreadCrumbsPageType[]; + $colorScheme?: colorSchemeType; +}; + +const getVariant = { + dash: '-', + slash: '/', + arrow: '›' +}; + +const BreadCrumb = ({ pages, variant = 'dash', $colorScheme = 'gray' }: BreadCrumbsType) => { + return ( + + {pages.map((item) => ( + <> + {item.current === false ? ( + <> + + {item.title} + + {getVariant[variant]} + + ) : ( + <> + {item.title} + + )} + + ))} + + ); +}; + +export default BreadCrumb; diff --git a/packages/chakra-ui-styled/src/components/navigation/BreadCrumb/Breadcrumbs.stories.tsx b/packages/chakra-ui-styled/src/components/navigation/BreadCrumb/Breadcrumbs.stories.tsx new file mode 100644 index 0000000..ab9c486 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/navigation/BreadCrumb/Breadcrumbs.stories.tsx @@ -0,0 +1,64 @@ +import styled from 'styled-components'; +import BreadCrumbs, { BreadCrumbsType, colorSchemeType } from './BreadCrumbs'; + +export default { + title: 'chakra-ui-styled/components/navigation/BreadCrumb', + component: BreadCrumbs, + parameters: { controls: { expanded: true } }, + + argTypes: { + variant: { control: { type: 'select' }, options: ['slash', 'arrow', 'dash'] }, + $colorScheme: { + control: { type: 'select' }, + options: ['blue', 'gray', 'teal', 'red', 'orange', 'yellow', 'pink', 'purple', 'green'] + } + }, + args: { + variant: 'arrow', + pages: [ + { title: 'Home', href: '/', current: false }, + { title: 'Link1', href: '/', current: false }, + { title: 'Link2', href: '/', current: false }, + { title: 'Current', href: '/', current: true } + ] + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; + +export const BreadCrumbsIndex = (args: BreadCrumbsType) => { + const pages = [ + { title: 'Home', href: '/', current: false }, + { title: 'Link1', href: '/', current: false }, + { title: 'Link2', href: '/', current: false }, + { title: 'Current', href: '/', current: true } + ]; + return ( + +

BreadCrumb

+ +

BreadCrumb Demo

+
+ +
+ +

BreadCrumb Index

+ +
+ +
+ +
+ +
+ +
+ +
+
+ ); +}; +BreadCrumbsIndex.storyName = 'BreadCrumb'; diff --git a/packages/chakra-ui-styled/src/components/overlay/menu/Menu.stories.tsx b/packages/chakra-ui-styled/src/components/overlay/menu/Menu.stories.tsx new file mode 100644 index 0000000..973501a --- /dev/null +++ b/packages/chakra-ui-styled/src/components/overlay/menu/Menu.stories.tsx @@ -0,0 +1,33 @@ +import styled from 'styled-components'; +import Menu, { MenuProps } from './Menu'; + + +export default { + title: 'chakra-ui-styled/components/overlay/menu', + component: Menu, + parameters: { controls: { expanded: true } }, + + argTypes: { + isOpen: { control: { type: 'boolean' } } + }, + args: { + isOpen: false + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; + +export const MenuIndex = (args: MenuProps) => { + return ( + +

Menu

+ +

Menu Demo

+ + + ); +}; +MenuIndex.storyName = 'Menu'; diff --git a/packages/chakra-ui-styled/src/components/overlay/menu/Menu.styled.tsx b/packages/chakra-ui-styled/src/components/overlay/menu/Menu.styled.tsx new file mode 100644 index 0000000..ca8d206 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/overlay/menu/Menu.styled.tsx @@ -0,0 +1,36 @@ +import styled from 'styled-components'; + +export const StyleMenu = styled.div` + position: relative; +`; +export const MenuList = styled.div<{ isOpen: boolean }>` + display: ${({ isOpen }) => (isOpen ? 'flex' : 'none')}; + flex-direction: column; + gap: 10px; + padding: 10px 0; + border-radius: 12px; + background-color: #fff; + position: absolute; + left: 0; + top: calc(100% + 9px); + box-shadow: 0px 1px 2px 0px rgba(0,0,0,0.05); + border: 1px solid ${({ theme }) => theme.color.gray[200]}; + min-width: 278px; +`; +export const MenuItem = styled.div` + ${({ theme }) => theme.typo.text.lg}; + display: flex; + flex: 1; + white-space: nowrap; + gap: 10px; + padding: 6px 22px; + cursor: pointer; + &:hover{ + background-color: ${({ theme }) => theme.color.gray[200]}; + } +`; +export const MenuDivider = styled.div` + height: 1px; + width: 100%; + background-color: ${({ theme }) => theme.color.gray[200]}; +`; \ No newline at end of file diff --git a/packages/chakra-ui-styled/src/components/overlay/menu/Menu.tsx b/packages/chakra-ui-styled/src/components/overlay/menu/Menu.tsx new file mode 100644 index 0000000..ddf9c84 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/overlay/menu/Menu.tsx @@ -0,0 +1,28 @@ +import { StyleMenu, MenuList, MenuItem, MenuDivider } from './Menu.styled'; +import { useState } from 'react'; +import Button from '../../form/button/Button'; + +export interface MenuProps { + isOpen: boolean; +} + +const Menu = ({ isOpen }: MenuProps) => { + const [menuIsOpen, setMenuIsOpen] = useState(false); + const openMenu = () => setMenuIsOpen(!isOpen); + + return ( + + + + + My Account + Payments + + Docs + + + ); +}; +export default Menu; diff --git a/packages/chakra-ui-styled/src/components/overlay/modal/Modal.stories.tsx b/packages/chakra-ui-styled/src/components/overlay/modal/Modal.stories.tsx new file mode 100644 index 0000000..f4a5140 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/overlay/modal/Modal.stories.tsx @@ -0,0 +1,43 @@ +import styled from 'styled-components'; +import Modal, { ModalProps } from './Modal'; + + +export default { + title: 'chakra-ui-styled/components/overlay/modal', + component: Modal, + parameters: { controls: { expanded: true } }, + + argTypes: { + title: { control: { type: 'text' } }, + contents: { control: { type: 'text' } }, + isOpen: { control: { type: 'boolean' } } + }, + args: { + title: 'Modal Title', + contents: 'Sit nulla est ex deserunt exercitation anim occaecat. Nostrud ullamco deserunt aute id consequat veniam incididunt duis in sint irure nisi. Mollit officia cillum Lorem ullamco minim nostrud elit officia tempor esse quis.', + isOpen: false + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; +const Wrap = styled.div` + display: inline-flex; + padding: 50px 80px; +`; + +export const ModalIndex = (args: ModalProps) => { + return ( + +

Modal

+ +

Modal Demo

+ + + +
+ ); +}; +ModalIndex.storyName = 'Modal'; diff --git a/packages/chakra-ui-styled/src/components/overlay/modal/Modal.styled.tsx b/packages/chakra-ui-styled/src/components/overlay/modal/Modal.styled.tsx new file mode 100644 index 0000000..7284197 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/overlay/modal/Modal.styled.tsx @@ -0,0 +1,49 @@ +import styled from 'styled-components'; +import CloseButton from '../../form/closebutton/CloseButton'; + +export const StyleModal = styled.div<{ isOpen: boolean }>` + display: ${({ isOpen }) => (isOpen ? 'flex' : 'none')}; +`; +export const ModalOverlay = styled.div` + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: ${({ theme }) => theme.color.blackAlpha[600]}; + z-index: 100; +`; +export const ModalContent = styled.div` + border-radius: 6px; + background-color: #fff; + position: absolute; + top: 40%; + left: 50%; + transform: translate(-50%, -50%); + box-shadow: 0px 4px 6px -2px rgba(0,0,0,0.05), 0px 10px 15px -3px rgba(0,0,0,0.1); + min-width: 448px; + z-index: 110; + +`; +export const ModalHeader = styled.div` + display: flex; + align-items: center; + padding: 16px 24px; + width: 100%; + ${({ theme }) => theme.typo.text.lg}; +`; +export const ModalBody = styled.div` + padding: 8px 24px; + ${({ theme }) => theme.typo.text.md}; +`; +export const ModalFooter = styled.div` + padding: 16px 24px; + display: flex; + justify-content: flex-end; + gap: 10px; +`; +export const StyledCloseButton = styled(CloseButton)` + position: absolute; + top: 8px; + right: 16px; + ` \ No newline at end of file diff --git a/packages/chakra-ui-styled/src/components/overlay/modal/Modal.tsx b/packages/chakra-ui-styled/src/components/overlay/modal/Modal.tsx new file mode 100644 index 0000000..cca2575 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/overlay/modal/Modal.tsx @@ -0,0 +1,53 @@ +import { + StyleModal, + ModalOverlay, + ModalContent, + ModalHeader, + StyledCloseButton, + ModalBody, + ModalFooter +} from './Modal.styled'; +import { useState } from 'react'; +import Button from '../../form/button/Button'; +import { CloseIconStyle } from '../../form/closebutton/CloseButton.styled'; + +export interface ModalProps { + isOpen: boolean; + title?: string; + contents?: string; +} + +const Modal = ({ isOpen, title, contents }: ModalProps) => { + const [modalIsOpen, setModalIsOpen] = useState(isOpen); + const openModal = () => setModalIsOpen(true); + const closeModal = () => setModalIsOpen(false); + + return ( + <> + {/* */} + + + + + + {title} + } /> + + {contents} + + + + + + + + + ); +}; +export default Modal; diff --git a/packages/chakra-ui-styled/src/components/overlay/tooltip/Tooltip.stories.tsx b/packages/chakra-ui-styled/src/components/overlay/tooltip/Tooltip.stories.tsx new file mode 100644 index 0000000..fac0be7 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/overlay/tooltip/Tooltip.stories.tsx @@ -0,0 +1,68 @@ +import styled from 'styled-components'; +import Tooltip, { TooltipProps, placementType } from './Tooltip'; +import { ArrowIconStyle } from './Tooltip.styled'; + + +export default { + title: 'chakra-ui-styled/components/overlay/tooltip', + component: Tooltip, + parameters: { controls: { expanded: true } }, + + argTypes: { + label: { control: { type: 'text' } }, + // placement: { control: { type: 'select' } }, + // 패널이 셀렉트박스가 구현안됨 + placement: { control: { type: 'text' } }, + }, + args: { + label: 'Hover me', + placement: 'auto-start', + arrowIcon: , + } +}; +const Wrapper = styled.div` + display: flex; + flex-direction: column; + gap: 20px; +`; +const Wrap = styled.div` + display: inline-flex; + padding: 50px 80px; +`; +const Stack = styled.div` + padding: 0 80px; + display: flex; + flex-flow: row wrap; + gap: 50px 90px; + & > div{ + display: inline-flex; + flex-direction: column; + align-items: center; + gap: 20px; + } +`; + +export const TooltipIndex = (args: TooltipProps) => { + const placementArr: placementType[] = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-start', 'bottom', 'bottom-end', 'left-start', 'left', 'left-end']; + return ( + +

Tooltip

+ +

Tooltip Demo

+ + + + +

Tooltip Index

+ + {placementArr.map((placement) => ( +
+ {placement} + } /> +
+ ))} +
+
+ ); +}; +TooltipIndex.storyName = 'Tooltip'; diff --git a/packages/chakra-ui-styled/src/components/overlay/tooltip/Tooltip.styled.tsx b/packages/chakra-ui-styled/src/components/overlay/tooltip/Tooltip.styled.tsx new file mode 100644 index 0000000..8f2b92e --- /dev/null +++ b/packages/chakra-ui-styled/src/components/overlay/tooltip/Tooltip.styled.tsx @@ -0,0 +1,190 @@ +import styled, { css } from 'styled-components'; +import { TooltipProps } from './Tooltip'; + +const tooltipPosition = { + ["auto-start"]: css` + top: 0; + right: 0; + transform: translateX(calc(100% + 8px)); + & figure{ + top: 50%; + left: 0; + transform: translate(calc(-100% + 6px), -50%) rotate(-90deg) + } + `, + ["auto"]: css` + top: 50%; + left: 0; + transform: translate(calc(-100% - 8px), -50%); + & figure{ + top: 50%; + right: 0; + transform: translate(calc(100% - 6px), -50%) rotate(90deg) + } + `, + ["auto-end"]: css` + top: 0; + left: 0; + transform: translateX(calc(-100% - 8px)); + & figure{ + top: 50%; + right: 0; + transform: translate(calc(100% - 6px), -50%) rotate(90deg) + } + `, + ["top-start"]: css` + top: 0; + left: 0; + transform: translateY(calc(-100% - 8px)); + & figure{ + bottom: 0; + left: 0; + transform: translate(8px, calc(100% - 2px)) rotate(180deg) + } + `, + ["top"]: css` + top: 0; + left: 50%; + transform: translate( -50%, calc(-100% - 8px)); + & figure{ + bottom: 0; + left: 50%; + transform: translate(-50%, calc(100% - 2px)) rotate(180deg) + } + `, + ["top-end"]: css` + top: 0; + right: 0; + transform: translateY(calc(-100% - 8px)); + & figure{ + bottom: 0; + right: 0; + transform: translate(-8px, calc(100% - 2px)) rotate(180deg) + } + `, + ["right-start"]: css` + top: 0; + right: 0; + transform: translateX(calc(100% + 8px)); + & figure{ + top: 50%; + left: 0; + transform: translate(calc(-100% + 6px), -50%) rotate(-90deg) + } + `, + ["right"]: css` + top: 50%; + right: 0; + transform: translate(calc(100% + 8px), -50%); + & figure{ + top: 50%; + left: 0; + transform: translate(calc(-100% + 6px), -50%) rotate(-90deg) + } + `, + ["right-end"]: css` + bottom: 0; + right: 0; + transform: translateX(calc(100% + 8px)); + & figure{ + top: 50%; + left: 0; + transform: translate(calc(-100% + 6px), -50%) rotate(-90deg) + } + `, + ["bottom-start"]: css` + bottom: 0; + left: 0; + transform: translateY(calc(100% + 8px)); + & figure{ + top: 0; + left: 0; + transform: translate(8px, calc(-100% + 2px)) + } + `, + ["bottom"]: css` + bottom: 0; + left: 50%; + transform: translate(-50%, calc(100% + 8px)); + & figure{ + top: 0; + left: 50%; + transform: translate(-50%, calc(-100% + 2px)) + } + `, + ["bottom-end"]: css` + bottom: 0; + right: 0; + transform: translateY(calc(100% + 8px)); + & figure{ + top: 0; + right: 0; + transform: translate(-8px, calc(-100% + 2px)) + } + `, + ["left-start"]: css` + top: 0; + left: 0; + transform: translateX(calc(-100% - 8px)); + & figure{ + top: 50%; + right: 0; + transform: translate(calc(100% - 6px), -50%) rotate(90deg) + } + `, + ["left"]: css` + top: 50%; + left: 0; + transform: translate(calc(-100% - 8px), -50%); + & figure{ + top: 50%; + right: 0; + transform: translate(calc(100% - 6px), -50%) rotate(90deg) + } + `, + ["left-end"]: css` + bottom: 0; + left: 0; + transform: translateX(calc(-100% - 8px)); + & figure{ + top: 50%; + right: 0; + transform: translate(calc(100% - 6px), -50%) rotate(90deg) + } + `, +}; +export const ArrowIconStyle = () => { + return ( + + + + ); +}; +export const StyleTooltip = styled.div` + position: relative; + display: inline-flex; + & span{ + ${({ placement }) => tooltipPosition[placement]} + } + &:hover span{ + opacity: 1; + } +`; +export const StyleText = styled.span` + position: absolute; + color: #fff; + display: inline-flex; + white-space: nowrap; + padding: 2px 8px; + border-radius: 4px; + ${({ theme }) => theme.typo.text.sm}; + background-color: ${({ theme }) => theme.color.gray[900]}; + opacity: 0; + transition: 0.3s; + & figure{ + width: 16px; + height: 8px; + position: absolute; + & svg{ position:absolute } + } +`; \ No newline at end of file diff --git a/packages/chakra-ui-styled/src/components/overlay/tooltip/Tooltip.tsx b/packages/chakra-ui-styled/src/components/overlay/tooltip/Tooltip.tsx new file mode 100644 index 0000000..8301939 --- /dev/null +++ b/packages/chakra-ui-styled/src/components/overlay/tooltip/Tooltip.tsx @@ -0,0 +1,28 @@ +import { StyleTooltip, StyleText } from './Tooltip.styled'; +import Button from '../../form/button/Button'; + +export type colorSchemeType = 'whiteAlpha' | 'blackAlpha' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink' ; +export type placementType = 'auto-start' | 'auto' | 'auto-end' | 'top-start' | 'top' | 'top-end' | 'right-start' | 'right' | 'right-end' | 'bottom-start' | 'bottom' | 'bottom-end' | 'left-start' | 'left' | 'left-end' ; +export interface TooltipProps { + colorScheme?: colorSchemeType; + placement: placementType; + label: string; + arrowIcon?: React.ReactNode; +} +const setIcon = (arrowIcon: React.ReactNode) => { + return
{arrowIcon}
; +}; +const ToolTip = ({ label, placement, arrowIcon }: TooltipProps) => { + return( + + {} + { + + {label} + {arrowIcon && setIcon(arrowIcon)} + + } + + ) +} +export default ToolTip; diff --git a/packages/chakra-ui-styled/src/foundation/typography/Heading.stories.tsx b/packages/chakra-ui-styled/src/foundation/typography/Heading.stories.tsx index 8c2673a..018db19 100644 --- a/packages/chakra-ui-styled/src/foundation/typography/Heading.stories.tsx +++ b/packages/chakra-ui-styled/src/foundation/typography/Heading.stories.tsx @@ -28,7 +28,6 @@ export const Large = (args: HeadingProps) => { return (

Heading Large

-

1. Heading Demo

diff --git a/packages/chakra-ui-styled/src/foundation/typography/Text.tsx b/packages/chakra-ui-styled/src/foundation/typography/Text.tsx index 57bef84..22ade39 100644 --- a/packages/chakra-ui-styled/src/foundation/typography/Text.tsx +++ b/packages/chakra-ui-styled/src/foundation/typography/Text.tsx @@ -1,13 +1,14 @@ import * as S from './Text.styled'; +import { ReactNode } from 'react'; export interface TextProps { - children?: React.ReactNode; + children?: ReactNode; size: '6xl' | '5xl' | '4xl' | '3xl' | '2xl' | 'xl' | 'lg' | 'md' | 'sm' | 'xs'; weight?: 'bold' | 'semibold' | 'medium' | 'normal'; lineHeight?: '150' | '130' | '120' | '100'; } -export const TextComponent = ({ size, weight, lineHeight, children }: TextProps) => { +export const BaseText = ({ size, weight, lineHeight, children }: TextProps) => { return ( <> diff --git a/packages/chakra-ui-styled/src/foundation/typography/Texts.stories.tsx b/packages/chakra-ui-styled/src/foundation/typography/Texts.stories.tsx index d3ba394..13903e4 100644 --- a/packages/chakra-ui-styled/src/foundation/typography/Texts.stories.tsx +++ b/packages/chakra-ui-styled/src/foundation/typography/Texts.stories.tsx @@ -1,9 +1,9 @@ import styled from 'styled-components'; -import { TextComponent, TextProps } from './Text'; +import { BaseText, TextProps } from './Text'; export default { title: 'chakra-ui-styled/foundation/typography/Text', - component: TextComponent, + component: Text, parameters: { controls: { expanded: true } }, argTypes: { children: { control: { type: 'text' } }, @@ -30,20 +30,20 @@ export const Texts = (args: TextProps) => {

1. Texts Demo

- +
-

2. Texts Size Demo

+

2.Texts Size Demo

- {text} - {text} - {text} - {text} - {text} - {text} - {text} - {text} - {text} - {text} + {text} + {text} + {text} + {text} + {text} + {text} + {text} + {text} + {text} + {text}
);