diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml
new file mode 100644
index 0000000..0250327
--- /dev/null
+++ b/.github/workflows/chromatic.yml
@@ -0,0 +1,24 @@
+# Workflow name
+name: "Chromatic Deployment"
+
+# Event for the workflow
+on: push
+
+# List of jobs
+jobs:
+ test:
+ # Operating System
+ runs-on: ubuntu-latest
+ # Job steps
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - run: npm
+ #๐ Adds Chromatic as a step in the workflow
+ - uses: chromaui/action@v1
+ # Options required for Chromatic's GitHub Action
+ with:
+ #๐ Chromatic projectToken, see https://storybook.js.org/tutorials/intro-to-storybook/react/en/deploy/ to obtain it
+ projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
+ token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/README.md b/README.md
index 9d8301d..3ee7cd9 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,9 @@
- ํค๋ณด๋๋ง์ผ๋ก ์ถ์ฒ ๊ฒ์์ด๋ค๋ก ์ด๋ ๊ฐ๋ฅํ๋๋ก ๊ตฌํ
- ๊ฒ์์ฐฝ์์ onKeyDown ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ event.key ๊ฐ์ด ArrowDown, ArrowUp์ผ ๊ฒฝ์ฐ selectedIndex๊ฐ ๋ณ๊ฒฝ๋๊ฒ ํ๊ณ ์ถ์ฒ ๊ฒ์์ด์ index์ selectedIndex๊ฐ ๊ฐ์ ๋ background-color๊ฐ ๋ณ๊ฒฝ๋๋๋ก ๊ตฌํ.
+
+### ๊ฒ์์ฐฝ
+=======
### ๊ฒ์์ฐฝ
![2024-05-1010 09 48-ezgif com-video-to-gif-converter](https://github.com/Leeseunghwan7305/Infinite_Challenge_FE/assets/78102507/378ec5b8-452d-4c64-8147-4f8a909deea7)
diff --git a/package-lock.json b/package-lock.json
index ec487dd..4474517 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
"@tanstack/react-query": "^5.34.2",
"@tanstack/react-query-devtools": "^5.35.1",
"axios": "^1.6.8",
+ "chromatic": "^11.3.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.23.0",
@@ -6255,7 +6256,6 @@
"version": "11.3.2",
"resolved": "https://registry.npmjs.org/chromatic/-/chromatic-11.3.2.tgz",
"integrity": "sha512-0PuHl49VvBMoDHEfmNjC/bim9YYNhWF3axTZlFuatC0avwr2Xw4GDqJDG9fArEWN8oM8VtYHkE9D7qc87dmz2w==",
- "dev": true,
"bin": {
"chroma": "dist/bin.js",
"chromatic": "dist/bin.js",
diff --git a/package.json b/package.json
index 3823366..bcc653b 100644
--- a/package.json
+++ b/package.json
@@ -9,12 +9,14 @@
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"storybook": "storybook dev -p 6006",
- "build-storybook": "storybook build"
+ "build-storybook": "storybook build",
+ "chromatic": "npx chromatic --project-token=chpt_bc436d25f0df202"
},
"dependencies": {
"@tanstack/react-query": "^5.34.2",
"@tanstack/react-query-devtools": "^5.35.1",
"axios": "^1.6.8",
+ "chromatic": "^11.3.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.23.0",
diff --git a/src/common/Nav.stories.ts b/src/common/Nav.stories.ts
new file mode 100644
index 0000000..4b6e52a
--- /dev/null
+++ b/src/common/Nav.stories.ts
@@ -0,0 +1,34 @@
+// Nav.stories.tsx
+import { Meta, StoryObj } from "@storybook/react";
+import Nav from "./Nav";
+import { fn } from "@storybook/test";
+
+const meta = {
+ title: "Common/Nav",
+ component: Nav,
+ parameters: {
+ layout: "centered",
+ },
+ tages: ["autodocs"],
+ // decorators: [
+ // (Story) => (
+ //
+ //
+ //
+ // ),
+ // ],
+ args: { onClick: fn() },
+} as Meta;
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Basic: Story = {};
diff --git a/src/components/main/DropBox.stories.tsx b/src/components/main/DropBox.stories.tsx
index e69de29..b61159e 100644
--- a/src/components/main/DropBox.stories.tsx
+++ b/src/components/main/DropBox.stories.tsx
@@ -0,0 +1,89 @@
+import { Meta, StoryObj } from "@storybook/react";
+import { fn } from "@storybook/test";
+import DropBox from "./DropBox";
+
+const meta = {
+ title: "Components/DropBox",
+ component: DropBox,
+ parameters: {
+ layout: "centered",
+ },
+ tags: ["autodocs"],
+ // argTypes: {
+ // type: "์ถ์ฒ๊ฒ์์ด",
+ // },
+ args: { onClick: fn() },
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+} as Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const RecommendedSearch: Story = {
+ args: {
+ type: "์ถ์ฒ๊ฒ์์ด",
+ searchLists: [
+ { name: "Search Term 1", id: 1 },
+ { name: "Search Term 2", id: 2 },
+ { name: "Search Term 3", id: 3 },
+ ],
+ selectedIndex: -1,
+ },
+};
+
+export const RecentSearch: Story = {
+ args: {
+ type: "์ต๊ทผ๊ฒ์์ด",
+ searchLists: [
+ { name: "Search Term 1", id: 1 },
+ { name: "Search Term 2", id: 2 },
+ { name: "Search Term 3", id: 3 },
+ ],
+ selectedIndex: -1,
+ },
+};
+
+// import React, { useState } from "react";
+// import { Story } from "@storybook/react";
+// import DropBox, { DropBoxProps } from "./DropBox";
+
+// export default {
+// title: "Components/DropBox",
+// component: DropBox,
+// };
+
+// const Template: Story = (args) => {
+// const [value, setValue] = useState("");
+// return ;
+// };
+
+// export const RecommendedSearch = Template.bind({});
+// RecommendedSearch.args = {
+// type: "์ถ์ฒ๊ฒ์์ด",
+// searchLists: [
+// { name: "Search Term 1", id: 1 },
+// { name: "Search Term 2", id: 2 },
+// { name: "Search Term 3", id: 3 },
+// ],
+// selectedIndex: -1,
+// };
+
+// export const RecentSearch = Template.bind({});
+// RecentSearch.args = {
+// type: "์ต๊ทผ๊ฒ์์ด",
+// searchLists: [],
+// selectedIndex: -1,
+// };
diff --git a/src/components/main/NoResult.stories.tsx b/src/components/main/NoResult.stories.tsx
new file mode 100644
index 0000000..ec7aa2c
--- /dev/null
+++ b/src/components/main/NoResult.stories.tsx
@@ -0,0 +1,33 @@
+import { Meta, StoryObj } from "@storybook/react";
+import NoResult from "./NoResult";
+
+const meta = {
+ title: "Components/NoResult",
+ component: NoResult,
+ parameters: {
+ layout: "centered",
+ },
+ tags: ["autodocs"],
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+} as Meta;
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Basic: Story = {
+ args: {
+ title: "๊ฒ์๊ฒฐ๊ณผ๊ฐ ์์ต๋๋ค.",
+ description: "๊ฒ์์ด๋ฅผ ๋ค์ ํ์ธํด์ฃผ์ธ์.",
+ },
+};
diff --git a/src/components/main/ResultList.stories.tsx b/src/components/main/ResultList.stories.tsx
new file mode 100644
index 0000000..85d4a16
--- /dev/null
+++ b/src/components/main/ResultList.stories.tsx
@@ -0,0 +1,58 @@
+import { Meta, StoryObj } from "@storybook/react";
+import ResultList from "./ResultList";
+import { ResultListType } from "@/src/types/searchResult";
+import { fn } from "@storybook/test";
+
+const meta = {
+ title: "Components/ResultList",
+ component: ResultList,
+ parameters: {
+ layout: "centered",
+ },
+ tags: ["autodocs"],
+ args: { onClick: fn() },
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+} as Meta;
+
+export default meta;
+
+type Story = StoryObj;
+
+const sampleResults: ResultListType = {
+ from_type: 1,
+ url: "http://example.com",
+ id: 123,
+ ct_id: "NCT123456",
+ locations: [{ city: "San Francisco" }],
+ phases: ["Phase 1", "Phase 2"],
+ minimum_age_display: "18 Years",
+ maximum_age_display: "65 Years",
+ title: "Study of Something Important",
+ start_date: "2021-01-01",
+ completion_date: "2023-01-01",
+ lead_sponsor_name: "Big Pharma Inc.",
+ brief_summary: "This study investigates something important.",
+ gender: "All",
+ is_sponsor: true,
+ survey_id: null,
+ is_new: true,
+ created_at: "2020-12-31",
+};
+
+export const Basic: Story = {
+ args: {
+ searchResult: sampleResults,
+ toggleFavorites: () => {},
+ location: "main",
+ },
+};
diff --git a/src/components/main/SearchBar.stories.tsx b/src/components/main/SearchBar.stories.tsx
new file mode 100644
index 0000000..0627ea8
--- /dev/null
+++ b/src/components/main/SearchBar.stories.tsx
@@ -0,0 +1,61 @@
+import { Meta, StoryObj } from "@storybook/react";
+import SearchBar from "./SearchBar";
+import { useState } from "react";
+import { fn, userEvent, within } from "@storybook/test";
+
+const meta = {
+ title: "Components/SearchBar",
+ component: SearchBar,
+ parameters: {
+ layout: "centered",
+ },
+ tags: ["autodocs"],
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+ args: { onClick: fn() },
+} as Meta;
+
+export default meta;
+
+type Story = StoryObj;
+
+const Render = (args: typeof meta) => {
+ const [value, setValue] = useState("");
+ const onChange = (e: React.ChangeEvent) => {
+ setValue(e.target.value);
+ };
+ const refetch = () => {};
+
+ return (
+
+ );
+};
+
+export const Basic: Story = {
+ render: () => ,
+ play: async ({ canvasElement }) => {
+ const canvas = within(canvasElement);
+
+ const input = canvas.getAllByRole("textbox")[0];
+
+ await userEvent.type(input, "๊ฐ์์ ", {
+ delay: 100,
+ });
+ await userEvent.click(input);
+ },
+};
diff --git a/src/components/main/SearchBar.tsx b/src/components/main/SearchBar.tsx
index d71f610..17c4312 100644
--- a/src/components/main/SearchBar.tsx
+++ b/src/components/main/SearchBar.tsx
@@ -91,7 +91,6 @@ const Input = styled.input`
border: none;
font-size: 16px;
background-color: transparent;
- pointer-events: none;
input::placeholder {
color: #bbbbbb;
}
diff --git a/src/stories/Button.stories.ts b/src/stories/Button.stories.ts
deleted file mode 100644
index 2bfb143..0000000
--- a/src/stories/Button.stories.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-import { fn } from "@storybook/test";
-import { Button } from "./Button";
-
-// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
-const meta = {
- title: "Example/Button",
- component: Button,
- 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: {
- backgroundColor: { control: "color" },
- },
- // 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 Primary: Story = {
- args: {
- primary: true,
- label: "Button",
- },
-};
-
-export const Secondary: Story = {
- args: {
- label: "Button",
- },
-};
-
-export const Large: Story = {
- args: {
- size: "large",
- label: "Button",
- },
-};
-
-export const Small: Story = {
- args: {
- size: "small",
- label: "Button",
- },
-};
-
-export const Warning: Story = {
- args: {
- primary: true,
- label: "Delete now",
- backgroundColor: "red",
- },
-};
diff --git a/src/stories/Button.tsx b/src/stories/Button.tsx
deleted file mode 100644
index 12ade3a..0000000
--- a/src/stories/Button.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import "./button.css";
-
-interface ButtonProps {
- /**
- * Is this the principal call to action on the page?
- */
- primary?: boolean;
- /**
- * What background color to use
- */
- backgroundColor?: string;
- /**
- * How large should the button be?
- */
- size?: "small" | "medium" | "large";
- /**
- * Button contents
- */
- label: string;
- /**
- * Optional click handler
- */
- onClick?: () => void;
-}
-
-/**
- * Primary UI component for user interaction
- */
-export const Button = ({
- primary = false,
- size = "medium",
- backgroundColor,
- label,
- ...props
-}: ButtonProps) => {
- const mode = primary
- ? "storybook-button--primary"
- : "storybook-button--secondary";
- return (
-
- {label}
-
- );
-};
diff --git a/src/stories/Header.stories.ts b/src/stories/Header.stories.ts
deleted file mode 100644
index 80c71d0..0000000
--- a/src/stories/Header.stories.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-import { fn } from '@storybook/test';
-
-import { Header } from './Header';
-
-const meta = {
- title: 'Example/Header',
- component: Header,
- // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
- tags: ['autodocs'],
- parameters: {
- // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
- layout: 'fullscreen',
- },
- args: {
- onLogin: fn(),
- onLogout: fn(),
- onCreateAccount: fn(),
- },
-} satisfies Meta;
-
-export default meta;
-type Story = StoryObj;
-
-export const LoggedIn: Story = {
- args: {
- user: {
- name: 'Jane Doe',
- },
- },
-};
-
-export const LoggedOut: Story = {};
diff --git a/src/stories/Header.tsx b/src/stories/Header.tsx
deleted file mode 100644
index c06836b..0000000
--- a/src/stories/Header.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import { Button } from "./Button";
-import "./header.css";
-
-type User = {
- name: string;
-};
-
-interface HeaderProps {
- user?: User;
- onLogin?: () => void;
- onLogout?: () => void;
- onCreateAccount?: () => void;
-}
-
-export const Header = ({
- user,
- onLogin,
- onLogout,
- onCreateAccount,
-}: HeaderProps) => (
-
-);
diff --git a/src/stories/Page.stories.ts b/src/stories/Page.stories.ts
deleted file mode 100644
index f7a0681..0000000
--- a/src/stories/Page.stories.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import type { Meta, StoryObj } from '@storybook/react';
-import { within, userEvent, expect } from '@storybook/test';
-
-import { Page } from './Page';
-
-const meta = {
- title: 'Example/Page',
- component: Page,
- parameters: {
- // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
- layout: 'fullscreen',
- },
-} satisfies Meta;
-
-export default meta;
-type Story = StoryObj;
-
-export const LoggedOut: Story = {};
-
-// More on interaction testing: https://storybook.js.org/docs/writing-tests/interaction-testing
-export const LoggedIn: Story = {
- play: async ({ canvasElement }) => {
- const canvas = within(canvasElement);
- const loginButton = canvas.getByRole('button', { name: /Log in/i });
- await expect(loginButton).toBeInTheDocument();
- await userEvent.click(loginButton);
- await expect(loginButton).not.toBeInTheDocument();
-
- const logoutButton = canvas.getByRole('button', { name: /Log out/i });
- await expect(logoutButton).toBeInTheDocument();
- },
-};
diff --git a/src/stories/Page.tsx b/src/stories/Page.tsx
deleted file mode 100644
index e117483..0000000
--- a/src/stories/Page.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import React from 'react';
-
-import { Header } from './Header';
-import './page.css';
-
-type User = {
- name: string;
-};
-
-export const Page: React.FC = () => {
- const [user, setUser] = React.useState();
-
- return (
-
- setUser({ name: 'Jane Doe' })}
- onLogout={() => setUser(undefined)}
- onCreateAccount={() => setUser({ name: 'Jane Doe' })}
- />
-
-
- Pages in Storybook
-
- We recommend building UIs with a{' '}
-
- component-driven
- {' '}
- process starting with atomic components and ending with pages.
-
-
- Render pages with mock data. This makes it easy to build and review page states without
- needing to navigate to them in your app. Here are some handy patterns for managing page
- data in Storybook:
-
-
-
- Use a higher-level connected component. Storybook helps you compose such data from the
- "args" of child component stories
-
-
- Assemble data in the page component from your services. You can mock these services out
- using Storybook.
-
-
-
- Get a guided tutorial on component-driven development at{' '}
-
- Storybook tutorials
-
- . Read more in the{' '}
-
- docs
-
- .
-
-
-
Tip Adjust the width of the canvas with the{' '}
-
-
-
-
-
- Viewports addon in the toolbar
-
-
-
- );
-};
diff --git a/src/stories/button.css b/src/stories/button.css
deleted file mode 100644
index dc91dc7..0000000
--- a/src/stories/button.css
+++ /dev/null
@@ -1,30 +0,0 @@
-.storybook-button {
- font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
- font-weight: 700;
- border: 0;
- border-radius: 3em;
- cursor: pointer;
- display: inline-block;
- line-height: 1;
-}
-.storybook-button--primary {
- color: white;
- background-color: #1ea7fd;
-}
-.storybook-button--secondary {
- color: #333;
- background-color: transparent;
- box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
-}
-.storybook-button--small {
- font-size: 12px;
- padding: 10px 16px;
-}
-.storybook-button--medium {
- font-size: 14px;
- padding: 11px 20px;
-}
-.storybook-button--large {
- font-size: 16px;
- padding: 12px 24px;
-}
diff --git a/src/stories/header.css b/src/stories/header.css
deleted file mode 100644
index d9a7052..0000000
--- a/src/stories/header.css
+++ /dev/null
@@ -1,32 +0,0 @@
-.storybook-header {
- font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
- border-bottom: 1px solid rgba(0, 0, 0, 0.1);
- padding: 15px 20px;
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
-
-.storybook-header svg {
- display: inline-block;
- vertical-align: top;
-}
-
-.storybook-header h1 {
- font-weight: 700;
- font-size: 20px;
- line-height: 1;
- margin: 6px 0 6px 10px;
- display: inline-block;
- vertical-align: top;
-}
-
-.storybook-header button + button {
- margin-left: 10px;
-}
-
-.storybook-header .welcome {
- color: #333;
- font-size: 14px;
- margin-right: 10px;
-}
diff --git a/src/stories/page.css b/src/stories/page.css
deleted file mode 100644
index 098dad1..0000000
--- a/src/stories/page.css
+++ /dev/null
@@ -1,69 +0,0 @@
-.storybook-page {
- font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
- font-size: 14px;
- line-height: 24px;
- padding: 48px 20px;
- margin: 0 auto;
- max-width: 600px;
- color: #333;
-}
-
-.storybook-page h2 {
- font-weight: 700;
- font-size: 32px;
- line-height: 1;
- margin: 0 0 4px;
- display: inline-block;
- vertical-align: top;
-}
-
-.storybook-page p {
- margin: 1em 0;
-}
-
-.storybook-page a {
- text-decoration: none;
- color: #1ea7fd;
-}
-
-.storybook-page ul {
- padding-left: 30px;
- margin: 1em 0;
-}
-
-.storybook-page li {
- margin-bottom: 8px;
-}
-
-.storybook-page .tip {
- display: inline-block;
- border-radius: 1em;
- font-size: 11px;
- line-height: 12px;
- font-weight: 700;
- background: #e7fdd8;
- color: #66bf3c;
- padding: 4px 12px;
- margin-right: 10px;
- vertical-align: top;
-}
-
-.storybook-page .tip-wrapper {
- font-size: 13px;
- line-height: 20px;
- margin-top: 40px;
- margin-bottom: 40px;
-}
-
-.storybook-page .tip-wrapper svg {
- display: inline-block;
- height: 12px;
- width: 12px;
- margin-right: 4px;
- vertical-align: top;
- margin-top: 3px;
-}
-
-.storybook-page .tip-wrapper svg path {
- fill: #1ea7fd;
-}