(null);
+
+ const handleOutSideClick = (event: MouseEvent) => {
+ const { target } = event;
+
+ if (!(target instanceof HTMLElement)) {
+ return;
+ }
+
+ if (
+ ref.current &&
+ target &&
+ !ref.current.contains(target) &&
+ target.dataset.component !== 'DropdownTrigger'
+ ) {
+ setIsOpen(false);
+ }
+ };
+
+ useEffect(() => {
+ document.addEventListener('click', handleOutSideClick);
+ return () => {
+ document.removeEventListener('click', handleOutSideClick);
+ };
+ }, []);
+
+ return (
+ isOpen && (
+
+ )
+ );
+};
diff --git a/frontend/src/component/common/dropdown/DropdownTrigger.tsx b/frontend/src/component/common/dropdown/DropdownTrigger.tsx
new file mode 100644
index 00000000..75e2d2cc
--- /dev/null
+++ b/frontend/src/component/common/dropdown/DropdownTrigger.tsx
@@ -0,0 +1,33 @@
+import { ReactNode, useContext } from 'react';
+import classNames from 'classnames';
+import { ToggleContext } from '@/component/common/dropdown/Dropdown.tsx';
+
+interface IDropdownTriggerProps {
+ children: ReactNode;
+}
+
+export const DropdownTrigger = (props: IDropdownTriggerProps) => {
+ const { setIsOpen } = useContext(ToggleContext);
+
+ const handleOnClick = () => {
+ setIsOpen(prevIsOpen => !prevIsOpen);
+ };
+
+ return (
+
+ );
+};
diff --git a/frontend/src/component/header/HeaderDropdown.tsx b/frontend/src/component/header/HeaderDropdown.tsx
new file mode 100644
index 00000000..d2dfd760
--- /dev/null
+++ b/frontend/src/component/header/HeaderDropdown.tsx
@@ -0,0 +1,38 @@
+import { Dropdown } from '@/component/common/dropdown/Dropdown.tsx';
+import { MdMenu, MdLocationOn } from 'react-icons/md';
+import { DropdownItem } from '@/component/common/dropdown/DropdownItem.tsx';
+import classNames from 'classnames';
+
+// interface IDropdownContainerProps {}
+
+// TDDO : props로 전달되면 해석되도록 로직 변경 (props:props: IDropdownContainerProps)
+export const HeaderDropdown = () => {
+ return (
+
+
+
+
+
+
+ {[
+ '사용자 1 보기',
+ '사용자 2 보기',
+ '사용자 3 보기',
+ '사용자 4 보기',
+ '사용자 5 보기',
+ ].map((e, i) => {
+ return (
+
+ {e}
+
+ {/* 아이콘 색 변경 로직 찾기, 현재는 아이콘색이 반영이 안됨 수정할 사 */}
+
+ );
+ })}
+
+
+
+ );
+};
diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx
index 3177f1a3..b1e5cba1 100644
--- a/frontend/src/main.tsx
+++ b/frontend/src/main.tsx
@@ -2,7 +2,7 @@ import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
-import { App } from './App';
+import { App } from './App2';
// 우선은 폰트 다 포함시켰는데, 나중에 사용할 것들만 따로 뺴자.
import '@fontsource/pretendard/100.css';
import '@fontsource/pretendard/200.css';
diff --git a/frontend/src/stories/DropdownButton.stories.tsx b/frontend/src/stories/DropdownButton.stories.tsx
deleted file mode 100644
index 46745bee..00000000
--- a/frontend/src/stories/DropdownButton.stories.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-import { fn } from '@storybook/test';
-
-import { DropdownButton } from '@/component/common/dropdown/DropdownButton.tsx';
-
-import { MdDensityMedium } from 'react-icons/md';
-
-// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
-const meta = {
- title: 'Dropdown/Button',
- component: DropdownButton,
- parameters: {
- // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
- layout: 'centered',
- },
- // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
- tags: ['autodocs'],
- // More on argTypes: https://storybook.js.org/docs/api/argtypes
- argTypes: {
- children: {
- control: 'object',
- description: '자식 컴포넌트로 항상 리액트 노드를 넘겨준다.',
- table: {
- type: { summary: 'ReactNode' },
- },
- required: true, // 설명 목적으로 required 여부는 table 필드로 작성함
- },
- className: {
- control: 'text',
- description: '테일 윈드 기반의 클래스 이름을 넘겨준다.',
- },
- },
- // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
- args: { onClick: fn() },
-} satisfies Meta;
-
-export default meta;
-type Story = StoryObj;
-
-// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
-export const Default: Story = {
- args: {
- children: ,
- className: '',
- },
-};
diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js
index 95613736..1ee4edd1 100644
--- a/frontend/tailwind.config.js
+++ b/frontend/tailwind.config.js
@@ -47,6 +47,16 @@ module.exports = {
float: '0 4px 20px rgba(0, 0, 0, 0.13)',
basic: 'inset 0 0 3px rgba(0, 0, 0, 0.11)',
},
+ keyframes: {
+ smoothAppear: {
+ '0%': { opacity: '0', transform: 'translateY(-5%)' },
+ '100%': { opacity: '1', transform: 'translateY(0)' },
+ },
+ },
+ animation: {
+ smoothAppear: 'smoothAppear 0.5s ease-out', // 0.5s는 원하는 지속 시간
+ smoothDisappear: 'smoothAppear 0.5s reverse ease-out', // 0.5s는 원하는 지속 시간
+ },
}, // 필요한 커스터마이징을 여기서 설정 가능
},
plugins: [],