From 2f10fcf59b5531b1979b72a44c3ca435b96f4ae3 Mon Sep 17 00:00:00 2001 From: wookki Date: Wed, 17 Jan 2024 20:40:33 +0900 Subject: [PATCH 1/4] =?UTF-8?q?assets:=20Expand=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EC=BD=98=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=A0=9C?= =?UTF-8?q?=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/assets/icons/expand.svg | 3 +++ src/components/icons/Expand.tsx | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 public/assets/icons/expand.svg create mode 100644 src/components/icons/Expand.tsx diff --git a/public/assets/icons/expand.svg b/public/assets/icons/expand.svg new file mode 100644 index 00000000..3ca34000 --- /dev/null +++ b/public/assets/icons/expand.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/icons/Expand.tsx b/src/components/icons/Expand.tsx new file mode 100644 index 00000000..d778f46f --- /dev/null +++ b/src/components/icons/Expand.tsx @@ -0,0 +1,21 @@ +import { Colors, colors } from '@styles/colorPalette'; + +interface ExpandProps { + width?: number + height?: number + isRotate: boolean + color?: Colors +} + +function Expand({ + width = 10, height = 6, color = 'black', isRotate, +}: ExpandProps) { + return ( + + + + + ); +} + +export default Expand; From bdf7c36bb2bc6c80de71302d8be57363f0a1c434 Mon Sep 17 00:00:00 2001 From: wookki Date: Wed, 17 Jan 2024 20:41:25 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20Dropdown=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/dropdown/Dropdown.module.scss | 56 +++++++++++++++ src/components/shared/dropdown/Dropdown.tsx | 70 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 src/components/shared/dropdown/Dropdown.module.scss create mode 100644 src/components/shared/dropdown/Dropdown.tsx diff --git a/src/components/shared/dropdown/Dropdown.module.scss b/src/components/shared/dropdown/Dropdown.module.scss new file mode 100644 index 00000000..a3f06a1c --- /dev/null +++ b/src/components/shared/dropdown/Dropdown.module.scss @@ -0,0 +1,56 @@ +.container { + position: relative; + + &.favorite { + width: 80px; + } + + .selectedValue { + display: flex; + align-items: center; + justify-content: space-between; + + &.favorite { + width: 80px; + padding: 4px 4px 4px 8px; + border-radius: 8px; + background-color: var(--tertiary-400); + } + } + + .menu { + position: absolute; + z-index: 3; + top: 34px; + width: 80px; + border: 1px solid var(--tertiary-100); + border-radius: 8px; + + &.favorite { + background-color: var(--tertiary-400); + color: var(--tertiary-200); + } + + .item { + &.favorite { + padding: 4px 8px; + border-bottom: 1px solid var(--tertiary-100); + font-size: 14px; + } + + &:last-child { + border: none; + } + } + + label { + &.favorite { + font-size: inherit; + } + } + + .input[type="radio"] { + display: none; + } + } +} diff --git a/src/components/shared/dropdown/Dropdown.tsx b/src/components/shared/dropdown/Dropdown.tsx new file mode 100644 index 00000000..6f7ee75c --- /dev/null +++ b/src/components/shared/dropdown/Dropdown.tsx @@ -0,0 +1,70 @@ +'use client'; + +import { InputHTMLAttributes, forwardRef, useState } from 'react'; + +import classNames from 'classnames/bind'; + +import useOutsideClick from '@/hooks/useOutsideClick'; +import Expand from '@components/icons/Expand'; +import Text from '@shared/text/Text'; + +import styles from './Dropdown.module.scss'; + +const cx = classNames.bind(styles); + +interface Option { + label: string + value: string | number | undefined +} + +interface DropdownProps extends InputHTMLAttributes { + options: Option[] + label: string | number + value: string | number + type: 'favorite' +} + +const Dropdown = forwardRef(({ + label, + type, + options, + value, + ...props +}, ref) => { + const [isOpen, setIsOpen] = useState(false); + + const openDropdownMenu = () => { + setIsOpen((prev) => { return !prev; }); + }; + + const closeDropdownMenu = () => { + setIsOpen(false); + }; + + const containerRef = useOutsideClick(closeDropdownMenu); + + return ( +
+ + {isOpen && ( +
    + {options.map((option) => { + return ( +
  • + + +
  • + ); + })} +
+ )} +
+ ); +}); + +export default Dropdown; From b8d17d649150af9f77b79a9e37ca8083ab776617 Mon Sep 17 00:00:00 2001 From: wookki Date: Wed, 17 Jan 2024 20:41:44 +0900 Subject: [PATCH 3/4] =?UTF-8?q?test:=20Dropdown=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=8A=A4=ED=86=A0=EB=A6=AC=EB=B6=81=20?= =?UTF-8?q?=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shared/dropdown/Dropdown.stories.tsx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/components/shared/dropdown/Dropdown.stories.tsx diff --git a/src/components/shared/dropdown/Dropdown.stories.tsx b/src/components/shared/dropdown/Dropdown.stories.tsx new file mode 100644 index 00000000..f0065d4a --- /dev/null +++ b/src/components/shared/dropdown/Dropdown.stories.tsx @@ -0,0 +1,29 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import Dropdown from './Dropdown'; + +const meta = { + title: 'Shared/Dropdown', + component: Dropdown, + tags: ['autodocs'], + argTypes: { + options: { + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const YoutubeVideo: Story = { + args: { + type: 'favorite', + label: '최신순', + options: [ + { label: '최신순', value: 'latest' }, + { label: '오래된순', value: 'oldest' }, + ], + placeholder: '최신순', + value: 'latest', + }, +}; From c23ad2519dd7e53f5c23a1e9b3fa4448db879865 Mon Sep 17 00:00:00 2001 From: wookki Date: Wed, 17 Jan 2024 20:46:23 +0900 Subject: [PATCH 4/4] =?UTF-8?q?design:=20=ED=8C=94=EB=A0=88=ED=8A=B8=20?= =?UTF-8?q?=EC=83=89=EC=83=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/globals.css | 3 +++ src/components/shared/dropdown/Dropdown.module.scss | 6 +++--- src/components/shared/dropdown/Dropdown.tsx | 4 ++-- src/styles/colorPalette.ts | 3 +++ 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 67437e92..aeac30fb 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -8,6 +8,9 @@ --gray-300: #72777A; --gray-400: #404446; --tertiary: #7A7A7A; + --tertiary-100: #EAEAEA; + --tertiary-200: #F6F6F6; + --tertiary-400: #7C7A7A; --black: #090A0A; --white: #FFF; --white-100: #F3F5F8; diff --git a/src/components/shared/dropdown/Dropdown.module.scss b/src/components/shared/dropdown/Dropdown.module.scss index a3f06a1c..aba14c71 100644 --- a/src/components/shared/dropdown/Dropdown.module.scss +++ b/src/components/shared/dropdown/Dropdown.module.scss @@ -14,7 +14,7 @@ width: 80px; padding: 4px 4px 4px 8px; border-radius: 8px; - background-color: var(--tertiary-400); + background-color: var(--tertiary-200); } } @@ -27,8 +27,8 @@ border-radius: 8px; &.favorite { - background-color: var(--tertiary-400); - color: var(--tertiary-200); + background-color: var(--tertiary-200); + color: var(--tertiary-400); } .item { diff --git a/src/components/shared/dropdown/Dropdown.tsx b/src/components/shared/dropdown/Dropdown.tsx index 6f7ee75c..9d31bb72 100644 --- a/src/components/shared/dropdown/Dropdown.tsx +++ b/src/components/shared/dropdown/Dropdown.tsx @@ -46,8 +46,8 @@ const Dropdown = forwardRef(({ return (
{isOpen && (
    diff --git a/src/styles/colorPalette.ts b/src/styles/colorPalette.ts index 50001ed7..bebcc6e9 100644 --- a/src/styles/colorPalette.ts +++ b/src/styles/colorPalette.ts @@ -8,6 +8,9 @@ export const colors = { gray300: 'var(--gray-300)', gray400: 'var(--gray-400)', tertiary: 'var(--tertiary)', + tertiary100: 'var(--tertiary-100)', + tertiary200: 'var(--tertiary-200)', + tertiary400: 'var(--tertiary-400)', black: 'var(--black)', white: 'var(--white)', white100: 'var(--white-100)',