Skip to content

Commit

Permalink
feat: bottom nav 컴포넌트 개발
Browse files Browse the repository at this point in the history
  • Loading branch information
ptq124 committed Jan 19, 2025
1 parent f24c3ce commit 947dcb3
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/ui/bottom-navigation/bottom-navigation.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { style } from '@vanilla-extract/css';
import { globalVars } from '../theme.css.ts';
import { typography } from './../typography.css.ts';

export const bottomNav = style({
width: '375px',
height: '84px',
display: 'flex',
justifyContent: 'center',
gap: '47px',
padding: '8px 0px 0px 0px',
backgroundColor: globalVars.color.white,
border: `0.5px solid ${globalVars.color.grey200}`,
});

export const menuItem = style({
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'flex-start',
cursor: 'pointer',
transition: 'color 0.2s ease-in-out',
width: '50px',
height: '50px',
gap: '2px',
backgroundColor: globalVars.color.white,
border: 'none',
});

export const active = style({
color: globalVars.color.mainblue500,
});

export const icon = style({
width: '24px',
height: '24px',
});

export const label = style([
typography('caption_2_10_r'),
{ textAlign: 'center', whiteSpace: 'nowrap' },
]);
42 changes: 42 additions & 0 deletions src/ui/bottom-navigation/bottom-navigation.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { BottomNavigation, MenuItem } from './bottom-navigation.tsx';

const meta: Meta<typeof BottomNavigation> = {
title: 'ui/BottomNavigation',
component: BottomNavigation,
parameters: {
layout: 'fullscreen',
},
argTypes: {
selected: {
control: 'select',
options: ['home', 'pill', 'consultation', 'mypage', null],
},
},
tags: ['autodocs'],
} satisfies Meta<typeof BottomNavigation>;

export default meta;
type Story = StoryObj<typeof BottomNavigation>;

export const Default: Story = {
args: {
selected: null,
},
};

export const SelectedHome: Story = {
args: {
selected: 'home',
},
};

const BottomNavigationWithState = () => {
const [selected, setSelected] = useState<MenuItem | null>(null);
return <BottomNavigation selected={selected} onSelect={setSelected} />;
};

export const WithState: Story = {
render: () => <BottomNavigationWithState />,
};
71 changes: 71 additions & 0 deletions src/ui/bottom-navigation/bottom-navigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { useState } from 'react';
import {
Chat,
ChatActive,
MyHome,
MyHomeActive,
MyPage,
MyPageActive,
MyPill,
MyPillActive,
} from '../../assets/index.ts';
import { cx } from '../util.ts';
import * as styles from './bottom-navigation.css.ts';

export type MenuItem = 'home' | 'pill' | 'consultation' | 'mypage';

interface BottomNavigationProps {
selected?: MenuItem | null;
onSelect?: (id: MenuItem) => void;
}

const renderIcon = (id: MenuItem, isActive: boolean) => {
const icons = {
home: isActive ? MyHomeActive : MyHome,
pill: isActive ? MyPillActive : MyPill,
consultation: isActive ? ChatActive : Chat,
mypage: isActive ? MyPageActive : MyPage,
};

const IconComponent = icons[id];
return <IconComponent className={styles.icon} />;
};

export const BottomNavigation = ({
selected,
onSelect,
}: BottomNavigationProps) => {
const [internalSelected, setInternalSelected] = useState<MenuItem | null>(
selected ?? null,
);

const menuItems = [
{ id: 'home', label: '홈' },
{ id: 'pill', label: '내약통' },
{ id: 'consultation', label: '상담' },
{ id: 'mypage', label: '마이페이지' },
] as const;

const handleClick = (id: MenuItem) => {
setInternalSelected(id);
onSelect?.(id);
};

return (
<nav className={styles.bottomNav}>
{menuItems.map(({ id, label }) => (
<button
key={id}
className={cx(
styles.menuItem,
internalSelected === id && styles.active,
)}
onClick={() => handleClick(id)}
>
{renderIcon(id, internalSelected === id)}
<span className={styles.label}>{label}</span>
</button>
))}
</nav>
);
};
1 change: 1 addition & 0 deletions src/ui/bottom-navigation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { BottomNavigation } from './bottom-navigation.tsx';

0 comments on commit 947dcb3

Please sign in to comment.