diff --git a/packages/timo-design-system/src/components/index.ts b/packages/timo-design-system/src/components/index.ts index 7917669..da88237 100644 --- a/packages/timo-design-system/src/components/index.ts +++ b/packages/timo-design-system/src/components/index.ts @@ -5,3 +5,4 @@ export { Tag } from "@components/tag/Tag"; export { PriorityIcon } from "@components/priority-icon/PriorityIcon"; export { CreateButton } from "@components/button/create-button/CreateButton"; export { TodayBadge } from "@components/badge/today-badge/TodayBadge"; +export { Tab } from "@components/tab/Tab"; diff --git a/packages/timo-design-system/src/components/tab/Tab.stories.tsx b/packages/timo-design-system/src/components/tab/Tab.stories.tsx new file mode 100644 index 0000000..207ecb5 --- /dev/null +++ b/packages/timo-design-system/src/components/tab/Tab.stories.tsx @@ -0,0 +1,161 @@ +import { + ChartHoverIcon, + ChartOffIcon, + ChartOnIcon, + HomeHoverIcon, + HomeOffIcon, + HomeOnIcon, + SettingHoverIcon, + SettingOffIcon, + SettingOnIcon, + TimerHoverIcon, + TimerOffIcon, + TimerOnIcon, + TodayHoverIcon, + TodayOffIcon, + TodayOnIcon, +} from "@icons"; +import { useState } from "react"; + +import { Tab } from "./Tab"; + +import type { Meta, StoryObj } from "@storybook/react"; +import type { ComponentProps } from "react"; + +const meta = { + title: "Components/Tab", + component: Tab, + parameters: { + layout: "centered", + }, + argTypes: { + label: { + control: "text", + }, + isSelected: { + control: "boolean", + }, + onClick: { + action: "clicked", + }, + }, + args: { + label: "홈", + icon: , + hoverIcon: , + isSelected: false, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const AllStates: Story = { + parameters: { + controls: { disable: true }, + }, + render: () => ( +
+
+ } + isSelected + /> + } + hoverIcon={} + /> + } /> +
+ +
+ } + isSelected + /> + } + hoverIcon={} + /> + } /> +
+ +
+ } + isSelected + /> + } + hoverIcon={} + /> + } /> +
+ +
+ } + isSelected + /> + } + hoverIcon={} + /> + } /> +
+ +
+ } + isSelected + /> + } + hoverIcon={} + /> + } /> +
+
+ ), +}; + +const InteractiveHomeTab = (args: ComponentProps) => { + const [isSelected, setIsSelected] = useState(false); + + return ( + + ) : ( + + ) + } + hoverIcon={} + isSelected={isSelected} + onClick={() => { + args.onClick?.(); + setIsSelected((prevIsSelected) => !prevIsSelected); + }} + /> + ); +}; + +export const Interactive: Story = { + parameters: { + controls: { disable: true }, + }, + render: (args) => , +}; diff --git a/packages/timo-design-system/src/components/tab/Tab.tsx b/packages/timo-design-system/src/components/tab/Tab.tsx new file mode 100644 index 0000000..d1273df --- /dev/null +++ b/packages/timo-design-system/src/components/tab/Tab.tsx @@ -0,0 +1,51 @@ +import { cn } from "@lib"; + +import type { ReactNode } from "react"; + +type TabVariant = "default" | "selected"; + +const TAB_VARIANT_CLASS_NAME: Record = { + default: "text-timo-gray-800 hover:bg-timo-gray-500", + selected: "bg-timo-blue-65 text-timo-blue-300", +}; + +export interface TabProps { + label: string; + icon: ReactNode; + hoverIcon?: ReactNode; + isSelected?: boolean; + onClick?: () => void; +} + +export const Tab = ({ + label, + icon, + hoverIcon, + isSelected = false, + onClick, +}: TabProps) => { + const baseButtonClassName = + "group flex w-45 items-center gap-2 rounded-8 px-3 py-1"; + + const variant: TabVariant = isSelected ? "selected" : "default"; + + const hasHoverIcon = hoverIcon && !isSelected; + + return ( + + ); +};