From 1cbcb74e82e831c9f6b1a73b5634e79bbd61d653 Mon Sep 17 00:00:00 2001 From: baegofda Date: Tue, 24 Sep 2024 21:59:52 +0900 Subject: [PATCH] DESIGN-7 --- .../DropdownBase/Dropdown.stories.tsx | 31 ++++++++ .../Dropdown/DropdownBase/DropdownItems.tsx | 44 +++++++++-- .../Dropdown/DropdownBase/types/index.ts | 5 ++ .../DropdownFilter/DropdownFilterItems.tsx | 5 +- .../DropdownMultiple.stories.tsx | 75 +++++++++++++++++++ .../DropdownSelect/DropdownSelectItems.tsx | 5 +- 6 files changed, 149 insertions(+), 16 deletions(-) diff --git a/src/core/components/Dropdown/DropdownBase/Dropdown.stories.tsx b/src/core/components/Dropdown/DropdownBase/Dropdown.stories.tsx index 1aeae64..79e5574 100644 --- a/src/core/components/Dropdown/DropdownBase/Dropdown.stories.tsx +++ b/src/core/components/Dropdown/DropdownBase/Dropdown.stories.tsx @@ -65,3 +65,34 @@ export const DropdownBaseWithIcon = () => { /> ); }; + +export const DropdownBaseWithSearch = () => { + const [currentValue, setCurrentValue] = useState(''); + + const data = ['A반', 'B반', 'C반', 'D반', 'E반']; + + const items = data.map((item, idx) => ( + setCurrentValue(item)}> + {item} + + )); + + return ( + + {({ isToggle }) => ( +
+ {currentValue || '옵션을 선택해주세요'} + +
+ )} + + } + content={} + /> + ); +}; diff --git a/src/core/components/Dropdown/DropdownBase/DropdownItems.tsx b/src/core/components/Dropdown/DropdownBase/DropdownItems.tsx index eabc2a2..f4c492a 100644 --- a/src/core/components/Dropdown/DropdownBase/DropdownItems.tsx +++ b/src/core/components/Dropdown/DropdownBase/DropdownItems.tsx @@ -2,24 +2,52 @@ import clsx from 'clsx'; import { forwardRef } from 'react'; import { DropdownItemsProps } from './types'; +import InputSearch from '@/core/components/Input/InputSearch'; const DropdownItems = forwardRef( ( - { className, items, ...props }: DropdownItemsProps, + { + rootClassName, + className, + items, + useSearch, + inputProps, + ...props + }: DropdownItemsProps, ref: React.Ref, ) => { + const { + rounded, + rootClassName: inputRootClassName, + placeholder, + ...restInputProps + } = inputProps ?? {}; + return ( -
    - {items} -
+ {useSearch && ( + + )} +
    + {items} +
+ ); }, ); diff --git a/src/core/components/Dropdown/DropdownBase/types/index.ts b/src/core/components/Dropdown/DropdownBase/types/index.ts index 10b333a..a44103c 100644 --- a/src/core/components/Dropdown/DropdownBase/types/index.ts +++ b/src/core/components/Dropdown/DropdownBase/types/index.ts @@ -12,6 +12,7 @@ import DropdownItem from '../DropdownItem'; import DropdownItems from '../DropdownItems'; import DropdownTrigger from '../DropdownTrigger'; import { FormLabelProps } from '@/core/components/FormLabel/types'; +import { InputSearchProps } from '@/core/components/Input/InputSearch/types'; export interface DropdownProps extends Partial { className?: string; @@ -33,7 +34,11 @@ export interface DropdownContextValue export interface DropdownItemProps extends HTMLAttributes {} export interface DropdownItemsProps extends HTMLAttributes { + rootClassName?: string; items: ReactNode[]; + useSearch?: boolean; + inputProps?: Omit, 'rootElement' | 'rounded'> & + Partial, 'rounded'>>; } export interface DropdownTriggerProps diff --git a/src/core/components/Dropdown/DropdownFilter/DropdownFilterItems.tsx b/src/core/components/Dropdown/DropdownFilter/DropdownFilterItems.tsx index fb3275c..87f9243 100644 --- a/src/core/components/Dropdown/DropdownFilter/DropdownFilterItems.tsx +++ b/src/core/components/Dropdown/DropdownFilter/DropdownFilterItems.tsx @@ -12,10 +12,7 @@ const DropdownFilterItems = forwardRef( return ( ); diff --git a/src/core/components/Dropdown/DropdownMultiple/DropdownMultiple.stories.tsx b/src/core/components/Dropdown/DropdownMultiple/DropdownMultiple.stories.tsx index d5bee95..ddad3aa 100644 --- a/src/core/components/Dropdown/DropdownMultiple/DropdownMultiple.stories.tsx +++ b/src/core/components/Dropdown/DropdownMultiple/DropdownMultiple.stories.tsx @@ -74,3 +74,78 @@ export const Default = () => { /> ); }; + +export const DropdownMultipleWithSearch = () => { + const [searchValue, setSearchValue] = useState(''); + const [currentValues, setCurrentValues] = useState[]>( + [], + ); + const data = [ + { value: 0, label: '2024년 5월 선정산' }, + { value: 1, label: '5월 BIZ 본정산' }, + { value: 2, label: '5월 비즈 선정산 진짜' }, + { value: 3, label: '5월 비즈 선정산 진짜 진짜' }, + ]; + + const handleDelete = (value: ValueWithLabelType) => { + setCurrentValues((prev) => prev.filter(({ value: v }) => v !== value)); + }; + + const onSearchChange = (e: ChangeEvent) => { + setSearchValue(e.target.value); + }; + + const filteredData = data.filter((item) => + item['label'].includes(searchValue), + ); + + const items = filteredData.map((item, idx) => { + const { value, label } = item; + const isChecked = currentValues.some(({ value: v }) => v === value); + + return ( + ) => { + e.stopPropagation(); + + const { checked } = e.target; + + if (checked) { + setCurrentValues((prev) => [...prev, item]); + } else { + setCurrentValues((prev) => + prev.filter((prevItem) => prevItem.value !== item.value), + ); + } + }} + > + {label} + + ); + }); + + return ( + + } + content={ + + } + className={'w-[500px]'} + required + /> + ); +}; diff --git a/src/core/components/Dropdown/DropdownSelect/DropdownSelectItems.tsx b/src/core/components/Dropdown/DropdownSelect/DropdownSelectItems.tsx index a8d548e..3608294 100644 --- a/src/core/components/Dropdown/DropdownSelect/DropdownSelectItems.tsx +++ b/src/core/components/Dropdown/DropdownSelect/DropdownSelectItems.tsx @@ -12,10 +12,7 @@ const DropdownSelectItems = forwardRef( return ( );