Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed src/assets/icons/.gitkeep
Empty file.
3 changes: 3 additions & 0 deletions src/assets/icons/dropdown.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file removed src/components/common/.gitkeep
Empty file.
82 changes: 82 additions & 0 deletions src/components/common/Dropdown.tsx
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
❓ figma 디자인과 다른 것 같아요

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 그렇네요! 바로 바꿀게요

Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { useEffect, useRef, useState } from 'react';
import Down from '@/assets/icons/dropdown.svg';

interface DropdownProps {
items: string[];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 items 가 선택 사항들을 말하는 prop일까요? 그렇다면 상수 naming과 맞춰서 options라고 이름 붙이는 게 좋지 않을까 싶습니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 좋은 것 같습니다 바꿔볼게요!

selected: string;
onSelect: (value: string) => void;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓ 혹시 onSelectselected state의 set함수거나 그런 건가요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위에 selected는 드롭다운 아이템 부분을 프롭으로 넣는거고 아래 onSelect는 직접적인 set 함수는 아니고 상위에 set함수를 호출하는 콜백입니다!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set 함수를 호출하는 callback이라는 게 어떤 뜻인가요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상위에서 state 값을 정의하고 실행되면 드롭다운 컴포넌트에 onSelect에서 그 기능을 실행한다고 보시면 좋을 것 같습니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

state에 대한 set 함수가 맞다면 state set 함수에 대한 type이 따로 있는 걸로 알고 있습니다 그리고 selected로 state를, onSelect로 set 함수를 받는 거라면 setSelected와 같이 이름을 설정하는 게 이해하기 쉽지 않을까 싶습니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

타입이 따로 있군요 이 부분은 변경해보겠습니다. 네이밍도 수정할게요!

placeholder?: string;
variant: 'form' | 'filter';
}

export default function Dropdown({
items,
selected,
onSelect,
placeholder = '선택',
variant,
}: DropdownProps) {
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);

const toggleDropdown = () => {
setIsOpen((prev) => !prev);
};

const closeDropdown = () => {
setIsOpen(false);
};

const handleSelect = (item: string) => {
onSelect(item);
closeDropdown();
};

// 외부 클릭 시 닫힘
useEffect(() => {
const handleClickOutside = (e: MouseEvent) => {
if (!dropdownRef.current?.contains(e.target as Node)) {
closeDropdown();
}
};
document.addEventListener('click', handleClickOutside);
return () => {
document.removeEventListener('click', handleClickOutside);
};
}, []);

return (
<div ref={dropdownRef} className="relative">
<button
type="button"
onClick={toggleDropdown}
className={`flex cursor-pointer items-center justify-between rounded-md border border-gray-30 bg-white ${variant === 'form' ? 'w-full px-5 py-4 text-base' : 'bg-gray-10px-3 rounded-[5px]px-3 h-[30px] w-[105px] gap-[6px] px-2.5 text-sm'}`}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
className={`flex cursor-pointer items-center justify-between rounded-md border border-gray-30 bg-white ${variant === 'form' ? 'w-full px-5 py-4 text-base' : 'bg-gray-10px-3 rounded-[5px]px-3 h-[30px] w-[105px] gap-[6px] px-2.5 text-sm'}`}
className={`flex cursor-pointer items-center justify-between rounded-md border border-gray-30 bg-white ${variant === 'form' ? 'w-full px-5 py-4 text-base' : 'bg-gray-10px-3 rounded-[5px] px-3 h-[30px] w-[105px] gap-[6px] px-2.5 text-sm'}`}

❗ 띄어쓰기가 빠진 거 같아요

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 못봤는데 감사합니다!

>
<span className={selected ? 'text-black' : 'text-gray-40'}>
{selected || placeholder}
</span>
<img
src={Down}
alt="arrow down"
className={`${isOpen ? '' : 'rotate-180'} ${variant === 'form' ? 'h-4 w-4' : 'h-[10px] w-[10px]'}`}
/>
</button>

{isOpen && (
<ul
className={`absolute right-0 left-0 mt-2 flex cursor-pointer flex-col rounded-md border border-gray-20 bg-white text-black ${variant === 'form' ? 'h-[230px] w-full overflow-y-auto' : 'h-[160px] w-[105px]'}`}
>
{items.map((item) => (
<li
key={item}
onClick={() => handleSelect(item)}
className={`flex w-full cursor-pointer justify-center border-b border-gray-20 text-sm leading-[22px] font-regular text-black last:border-b-0 ${variant === 'form' ? 'py-3' : 'py-2'}`}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

text-sm 은 14px을 의미하는데, 저희는 스타일 변수로 text-body2를 14px로 지정해두었습니다.
저희가 프로젝트에서 사용할 텍스트 크기를 따로 변수로 지정해둔 것이기 때문에 웬만하면 그걸 사용하시는게 가독성 면에서도 좋고, 사용하기도 편하실거에요!😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 감사합니다 몰랐는데 바로 적용해야겠네요

>
{item}
</li>
))}
</ul>
)}
</div>
);
}
Empty file removed src/constants/.gitkeep
Empty file.
45 changes: 45 additions & 0 deletions src/constants/dropdownOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
export const ADDRESS_OPTIONS = [
'서울시 종로구',
'서울시 중구',
'서울시 용산구',
'서울시 성동구',
'서울시 광진구',
'서울시 동대문구',
'서울시 중랑구',
'서울시 성북구',
'서울시 강북구',
'서울시 도봉구',
'서울시 노원구',
'서울시 은평구',
'서울시 서대문구',
'서울시 마포구',
'서울시 양천구',
'서울시 강서구',
'서울시 구로구',
'서울시 금천구',
'서울시 영등포구',
'서울시 동작구',
'서울시 관악구',
'서울시 서초구',
'서울시 강남구',
'서울시 송파구',
'서울시 강동구',
];

export const CATEGORY_OPTIONS = [
'한식',
'중식',
'일식',
'양식',
'분식',
'카페',
'편의점',
'기타',
];

export const SORT_OPTIONS = [
'마감임박순',
'시급많은순',
'시간적은순',
'가나다순',
];