diff --git a/src/components/gauge/block-gauge.stories.tsx b/src/components/gauge/block-gauge.stories.tsx
new file mode 100644
index 00000000..17e3439c
--- /dev/null
+++ b/src/components/gauge/block-gauge.stories.tsx
@@ -0,0 +1,49 @@
+import type { Meta, StoryObj } from "@storybook/nextjs";
+import { useState } from "react";
+import BlockGauge, { type GaugeLevel } from "./block-gauge";
+
+const meta: Meta = {
+ title: "Components/BlockGauge",
+ component: BlockGauge,
+ parameters: {
+ layout: "centered",
+ docs: {
+ description: {
+ component:
+ "와인의 맛 강도를 시각적으로 표현하는 블록 게이지 컴포넌트입니다.",
+ },
+ },
+ },
+ tags: ["autodocs"],
+ argTypes: {
+ level: {
+ control: { type: "number", min: 0, max: 6 },
+ description: "게이지 레벨 (0-6)",
+ defaultValue: 3,
+ },
+ },
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const ClickTest: Story = {
+ render: () => {
+ const [level, setLevel] = useState(3);
+
+ return (
+
+ );
+ },
+};
diff --git a/src/components/gauge/block-gauge.tsx b/src/components/gauge/block-gauge.tsx
new file mode 100644
index 00000000..e7781104
--- /dev/null
+++ b/src/components/gauge/block-gauge.tsx
@@ -0,0 +1,52 @@
+"use client";
+
+import { cn } from "@/lib/utils";
+
+type GaugeLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6;
+
+interface BlockGaugeProps {
+ level: GaugeLevel; // 0-6 사이의 값 (0: 비어있음, 6: 가득 참)
+ color?: string; // 활성화된 블록 색상 (기본: bg-black)
+ onChange?: (newLevel: GaugeLevel) => void; // 클릭 시 호출될 함수
+}
+
+const BlockGauge = ({
+ level,
+ color = "bg-black",
+ onChange,
+}: BlockGaugeProps) => {
+ const handleClick = (clickedIndex: number) => {
+ if (!onChange) return;
+
+ const newLevel = (clickedIndex + 1) as GaugeLevel;
+ onChange(newLevel === level ? 0 : newLevel);
+ };
+
+ return (
+
+ {Array.from({ length: 6 }).map((_, index) => (
+
+ );
+};
+
+export default BlockGauge;
+
+export type { GaugeLevel };
diff --git a/src/components/taste/Taste.stories.tsx b/src/components/taste/Taste.stories.tsx
new file mode 100644
index 00000000..17b7e672
--- /dev/null
+++ b/src/components/taste/Taste.stories.tsx
@@ -0,0 +1,157 @@
+import type { Meta, StoryObj } from "@storybook/nextjs";
+import { useState } from "react";
+import Taste from "./Taste";
+import { cn } from "@/lib/utils";
+import { GaugeLevel } from "../gauge/block-gauge";
+
+const meta: Meta = {
+ title: "Components/Taste",
+ component: Taste,
+ parameters: {
+ layout: "centered",
+ docs: {
+ description: {
+ component:
+ "와인의 맛 특성과 강도를 표시하는 컴포넌트입니다. 모바일 : 343px, 태블릿과 PC : 480px",
+ },
+ },
+ },
+ tags: ["autodocs"],
+ argTypes: {
+ type: {
+ control: "text",
+ description: "와인 맛의 종류",
+ defaultValue: "바디감",
+ },
+ data: {
+ control: { type: "number", min: 0, max: 6 },
+ description: "맛 강도 데이터 (0-6)",
+ defaultValue: 3,
+ },
+ taste: {
+ control: "text",
+ description: "맛의 특징",
+ defaultValue: "진해요",
+ },
+ },
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+const ResponsiveTasteWrapper = ({
+ children,
+}: {
+ children: React.ReactNode;
+}) => {
+ return (
+
+ {children}
+
+ );
+};
+
+export const InteractiveWineProfile: Story = {
+ render: () => {
+ const [bodyLevel, setBodyLevel] = useState(4);
+ const [tanninLevel, setTanninLevel] = useState(2);
+ const [sweetnessLevel, setSweetnessLevel] = useState(1);
+ const [acidityLevel, setAcidityLevel] = useState(3);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* 현재 설정값 표시 */}
+
+ 현재 와인 프로필: 바디감 {bodyLevel}, 탄닌{" "}
+ {tanninLevel}, 당도 {sweetnessLevel}, 산미 {acidityLevel}
+
+
+ );
+ },
+ parameters: {
+ layout: "padded",
+ docs: {
+ description: {
+ story:
+ "블럭을 마우스로 클릭하면 게이지가 차오릅니다. 또한 어느 블럭이든 두 번 클릭하면 게이지가 0으로 됩니다.",
+ },
+ },
+ },
+};
diff --git a/src/components/taste/Taste.tsx b/src/components/taste/Taste.tsx
new file mode 100644
index 00000000..02a68982
--- /dev/null
+++ b/src/components/taste/Taste.tsx
@@ -0,0 +1,55 @@
+"use client";
+
+import { cn } from "@/lib/utils";
+import BlockGauge, { type GaugeLevel } from "../gauge/block-gauge";
+
+interface TasteProps {
+ type: string;
+ data: GaugeLevel; // 0-6 사이의 값
+ taste: string;
+ onChange?: (newLevel: GaugeLevel) => void;
+}
+
+const Taste = ({ type, data, taste, onChange }: TasteProps) => {
+ return (
+
+
+ {/* 왼쪽: type */}
+
+ {type}
+
+
+ {/* 중간: 게이지 */}
+
+
+
+
+ {/* 오른쪽: taste - data가 0일 때 색상 변경 */}
+
+ {taste}
+
+
+
+ );
+};
+
+export default Taste;
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 93070bc2..07e25202 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -18,6 +18,8 @@ export default {
gray600: "#8C8C8B",
gray800: "#484746",
primary: "#1A1918",
+ neutral200: "#F2F2F2",
+ neutral400: "#BABABA",
},
screens: {
mobile: { max: "743px" },