Skip to content

Commit

Permalink
[#362] TopNavigation 컴포넌트 리팩터링 (#393)
Browse files Browse the repository at this point in the history
  • Loading branch information
minjongbaek authored Aug 18, 2023
1 parent 7484e93 commit f261e1b
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 56 deletions.
2 changes: 1 addition & 1 deletion public/icons/close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion public/icons/hamburger.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
123 changes: 100 additions & 23 deletions src/stories/Base/TopNavigation.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { Meta, StoryObj } from '@storybook/react';
import TopNavigation from '@/ui/Base/TopNavigation';
import { IconPost, IconShare } from '@public/icons';
import {
IconPost,
IconShare,
IconArrowLeft,
IconHamburger,
IconClose,
} from '@public/icons';

const meta: Meta<typeof TopNavigation> = {
title: 'Base/TopNavigation',
Expand All @@ -13,26 +19,97 @@ export default meta;
type Story = StoryObj<typeof TopNavigation>;

export const Default: Story = {
args: {
title: 'Refactoring 2nd(리팩터링 2판)',
},
render: args => <TopNavigation {...args} />,
};

export const BookshelfPage: Story = {
args: {
titleAlign: 'center',
children: <IconShare />,
},
render: args => <TopNavigation {...args} />,
};

export const GroupPage: Story = {
args: {
titleAlign: 'left',
title: '프롱이 리팩터링 스터디',
isOwner: true,
children: <IconPost />,
},
render: args => <TopNavigation {...args} />,
render: () => (
<TopNavigation>
<TopNavigation.LeftItem>
<IconArrowLeft />
</TopNavigation.LeftItem>
<TopNavigation.CenterItem>
Refactoring 2nd(리팩터링 2판)
</TopNavigation.CenterItem>
<TopNavigation.RightItem>
<IconShare />
</TopNavigation.RightItem>
</TopNavigation>
),
};

export const OnlySide: Story = {
render: () => (
<TopNavigation>
<TopNavigation.LeftItem>
<IconArrowLeft />
</TopNavigation.LeftItem>
<TopNavigation.RightItem>
<IconShare />
</TopNavigation.RightItem>
</TopNavigation>
),
};

export const OnlyCenter: Story = {
render: () => (
<TopNavigation>
<TopNavigation.CenterItem textAlign="left">
Refactoring 2nd(리팩터링 2판)
</TopNavigation.CenterItem>
</TopNavigation>
),
};

export const CenterWithLeft: Story = {
render: () => (
<TopNavigation>
<TopNavigation.LeftItem>
<IconArrowLeft />
</TopNavigation.LeftItem>
<TopNavigation.CenterItem textAlign="left">
Refactoring 2nd(리팩터링 2판)
</TopNavigation.CenterItem>
</TopNavigation>
),
};

export const CenterWithRight: Story = {
render: () => (
<TopNavigation>
<TopNavigation.CenterItem>
Refactoring 2nd(리팩터링 2판)
</TopNavigation.CenterItem>
<TopNavigation.RightItem>
<IconShare />
</TopNavigation.RightItem>
</TopNavigation>
),
};

export const TextLeft: Story = {
render: () => (
<TopNavigation>
<TopNavigation.LeftItem>
<IconArrowLeft />
</TopNavigation.LeftItem>
<TopNavigation.CenterItem textAlign="left">
프롱이 리팩터링 스터디
</TopNavigation.CenterItem>
<TopNavigation.RightItem>
<IconPost />
<IconHamburger />
</TopNavigation.RightItem>
</TopNavigation>
),
};

export const PostWrite: Story = {
render: () => (
<TopNavigation>
<TopNavigation.LeftItem>
<IconClose />
</TopNavigation.LeftItem>
<TopNavigation.CenterItem>글 작성하기</TopNavigation.CenterItem>
<TopNavigation.RightItem>
<button className="font-bold text-main-900">완료</button>
</TopNavigation.RightItem>
</TopNavigation>
),
};
75 changes: 44 additions & 31 deletions src/ui/Base/TopNavigation.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,53 @@
import { IconArrowLeft, IconHamburger } from '@public/icons';
import Link from 'next/link';
import { PropsWithChildren } from 'react';

interface Props extends PropsWithChildren {
titleAlign?: 'center' | 'left';
title?: string;
isOwner?: boolean;
import { PropsWithChildren, ReactNode } from 'react';

interface TopNavigationProps {
children?: ReactNode;
}

const TopNavigation = ({
children,
titleAlign = 'center',
title = '',
isOwner = false,
}: Props) => {
type ItemProps = TopNavigationProps;

const TopNavigation = ({ children }: TopNavigationProps) => {
return (
<div className="relative flex h-[5.4rem] w-full gap-[1.5rem] bg-opacity-0 px-[2rem] py-[1.7rem]">
<Link href=".">
<IconArrowLeft className="hover:cursor-pointer" />
</Link>
<div
className={`flex w-full pr-[3.5rem] text-md font-normal leading-[1.9rem] ${TITLE_ALIGN_CLASSES[titleAlign]}`}
>
{title}
</div>
<div className="absolute right-[2rem] flex gap-[1rem]">
{children}
{isOwner && <IconHamburger className="hover:cursor-pointer" />}
</div>
<div className="relative flex h-[2.4rem] w-full items-center justify-center bg-opacity-0 px-[2rem] py-[1.7rem] text-md">
{children}
</div>
);
};

export default TopNavigation;
const LeftItem = ({ children }: ItemProps) => {
return (
<div className="absolute left-[2rem] [&_svg]:h-[2rem] [&_svg]:w-[2rem] [&_svg]:cursor-pointer">
{children}
</div>
);
};

type CenterItemProps = PropsWithChildren<{ textAlign?: 'left' | 'center' }>;

const textAligns = {
left: 'text-left',
center: 'text-center',
} as const;

const TITLE_ALIGN_CLASSES = {
center: 'justify-center',
left: 'justify-start',
const CenterItem = ({ children, textAlign = 'center' }: CenterItemProps) => {
const alignClassName = textAligns[textAlign];
return (
<div className={`w-full px-[3.5rem] ${alignClassName}`}>{children}</div>
);
};

const RightItem = ({ children }: ItemProps) => {
return (
<div className="absolute right-[2rem] flex gap-[1rem] [&_svg]:h-[2rem] [&_svg]:w-[2rem] [&_svg]:cursor-pointer">
{children}
</div>
);
};

TopNavigation.LeftItem = LeftItem;

TopNavigation.CenterItem = CenterItem;

TopNavigation.RightItem = RightItem;

export default TopNavigation;

0 comments on commit f261e1b

Please sign in to comment.