diff --git a/frontend/.storybook/main.js b/frontend/.storybook/main.js
index a794f234f..c616db486 100644
--- a/frontend/.storybook/main.js
+++ b/frontend/.storybook/main.js
@@ -1,11 +1,11 @@
module.exports = {
- "stories": [
- "../src/**/*.stories.mdx",
- "../src/**/*.stories.@(js|jsx|ts|tsx)"
+ stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
+ addons: [
+ '@storybook/addon-links',
+ '@storybook/addon-essentials',
+ '@storybook/preset-create-react-app',
],
- "addons": [
- "@storybook/addon-links",
- "@storybook/addon-essentials",
- "@storybook/preset-create-react-app"
- ]
-}
+ typescript: {
+ reactDocgen: 'none',
+ },
+};
diff --git a/frontend/src/components/Button/ResponsiveButton.stories.js b/frontend/src/components/Button/ResponsiveButton.stories.js
new file mode 100644
index 000000000..d12122db9
--- /dev/null
+++ b/frontend/src/components/Button/ResponsiveButton.stories.js
@@ -0,0 +1,54 @@
+/** @jsxImportSource @emotion/react */
+
+import { css } from '@emotion/react';
+import { COLOR } from '../../enumerations/color';
+import ResponsiveButton from './ResponsiveButton';
+
+export default {
+ title: 'Component/ResponsiveButton',
+ component: ResponsiveButton,
+ argTypes: {},
+};
+
+const Template = (size) => (args) => (
+
+
+
+);
+
+const SessionTemplate = Template(135);
+
+export const Session = SessionTemplate.bind({});
+
+Session.args = {
+ text: '프론트엔드 세션1',
+ color: 'white',
+ backgroundColor: COLOR.LIGHT_BLUE_900,
+ height: '36px',
+};
+
+const Depth1Template = Template(820);
+
+export const Depth1 = Depth1Template.bind({});
+
+Depth1.args = {
+ text: 'JavaScript',
+ color: 'white',
+ backgroundColor: COLOR.LIGHT_BLUE_800,
+ height: '50px',
+};
+
+const Depth2Template = Template(386);
+
+export const Depth2 = Depth2Template.bind({});
+
+Depth2.args = {
+ text: 'JavaScript',
+ color: 'white',
+ backgroundColor: COLOR.LIGHT_BLUE_500,
+ height: '50px',
+};
diff --git a/frontend/src/components/Button/ResponsiveButton.tsx b/frontend/src/components/Button/ResponsiveButton.tsx
new file mode 100644
index 000000000..16ed627ce
--- /dev/null
+++ b/frontend/src/components/Button/ResponsiveButton.tsx
@@ -0,0 +1,47 @@
+import { css } from '@emotion/react';
+import styled from '@emotion/styled';
+import React, { ButtonHTMLAttributes } from 'react';
+
+interface ResponsiveButtonProps extends ButtonHTMLAttributes {
+ text: string;
+ fontSize?: string;
+ color?: string;
+ backgroundColor?: string;
+ height?: string;
+}
+
+const ResponsiveButton = ({
+ text,
+ fontSize,
+ color,
+ backgroundColor,
+ height,
+}: ResponsiveButtonProps) => {
+ return (
+
+ {text}
+
+ );
+};
+
+export default ResponsiveButton;
+
+const StyledResponsiveButton = styled.button<
+ Pick
+>`
+ width: 100%;
+ border-radius: 12px;
+ text-align: center;
+
+ ${({ fontSize, color, backgroundColor, height }) => css`
+ font-size: ${fontSize || '16px'};
+ color: ${color};
+ background-color: ${backgroundColor};
+ height: ${height || '50px'};
+ `};
+`;
diff --git a/frontend/src/components/KeywordSection/KeywordSection.stories.js b/frontend/src/components/KeywordSection/KeywordSection.stories.js
new file mode 100644
index 000000000..f6184acd3
--- /dev/null
+++ b/frontend/src/components/KeywordSection/KeywordSection.stories.js
@@ -0,0 +1,19 @@
+import KeywordSection from './KeywordSection';
+import SomeImage from '../../assets/images/background-image.png';
+
+export default {
+ title: 'Component/KeywordSection',
+ component: KeywordSection,
+ argTypes: {},
+};
+
+const Template = (args) => ;
+
+export const Selected = Template.bind({});
+
+Selected.args = {
+ src: SomeImage,
+ alt: '이미지',
+ text: 'JavaScript',
+ isSelected: true,
+};
diff --git a/frontend/src/components/KeywordSection/KeywordSection.tsx b/frontend/src/components/KeywordSection/KeywordSection.tsx
new file mode 100644
index 000000000..c4a27e941
--- /dev/null
+++ b/frontend/src/components/KeywordSection/KeywordSection.tsx
@@ -0,0 +1,61 @@
+import styled from '@emotion/styled';
+import React, { useState } from 'react';
+import SomeImage from '../../assets/images/background-image.png';
+import { COLOR } from '../../enumerations/color';
+import LabelledImage from '../LabelledImage/LabelledImage';
+
+interface Keyword {
+ src: string;
+ alt: string;
+ text: string;
+}
+
+const keywords: Keyword[] = [
+ { src: SomeImage, alt: 'JavaScript', text: 'JavaScript' },
+ { src: SomeImage, alt: 'JavaScript', text: 'JavaScript' },
+ { src: SomeImage, alt: 'JavaScript', text: 'JavaScript' },
+ { src: SomeImage, alt: 'JavaScript', text: 'JavaScript' },
+];
+
+const KeywordSection = () => {
+ const [keywordOrder, setKeywordOrder] = useState(0);
+
+ const handleClickKeyword = (order: number) => {
+ setKeywordOrder(order);
+ };
+ return (
+
+ {keywords.map((keyword, index) => (
+
+ setKeywordOrder(index)}
+ />
+ {index + 1 !== keywords.length && }
+
+ ))}
+
+ );
+};
+
+export default KeywordSection;
+
+const StyledRoot = styled.div`
+ display: flex;
+`;
+
+const StyledArrow = styled.div`
+ width: 0;
+ height: 0;
+ border: 9px solid transparent;
+ border-top: 0;
+ border-bottom: 15px solid ${COLOR.LIGHT_BLUE_700};
+ transform: rotate(90deg);
+ margin: 0 12px;
+`;
+
+const StyledWrapper = styled.div`
+ display: flex;
+ align-items: center;
+`;
diff --git a/frontend/src/components/LabelledImage/LabelledImage.stories.js b/frontend/src/components/LabelledImage/LabelledImage.stories.js
new file mode 100644
index 000000000..05f67bc4e
--- /dev/null
+++ b/frontend/src/components/LabelledImage/LabelledImage.stories.js
@@ -0,0 +1,28 @@
+import LabelledImage from './LabelledImage';
+import SomeImage from '../../assets/images/background-image.png';
+
+export default {
+ title: 'Component/LabelledImage',
+ component: LabelledImage,
+ argTypes: {},
+};
+
+const Template = (args) => ;
+
+export const Selected = Template.bind({});
+
+Selected.args = {
+ src: SomeImage,
+ alt: '이미지',
+ text: 'JavaScript',
+ isSelected: true,
+};
+
+export const UnSelected = Template.bind({});
+
+UnSelected.args = {
+ src: SomeImage,
+ alt: '이미지',
+ text: 'JavaScript',
+ isSelected: false,
+};
diff --git a/frontend/src/components/LabelledImage/LabelledImage.tsx b/frontend/src/components/LabelledImage/LabelledImage.tsx
new file mode 100644
index 000000000..1fe2a5009
--- /dev/null
+++ b/frontend/src/components/LabelledImage/LabelledImage.tsx
@@ -0,0 +1,30 @@
+import { css } from '@emotion/react';
+import styled from '@emotion/styled';
+import React, { ImgHTMLAttributes } from 'react';
+import { COLOR } from '../../enumerations/color';
+
+interface LabelledImageProps extends ImgHTMLAttributes {
+ text: string;
+ isSelected?: boolean;
+}
+
+const LabelledImage = ({ src, alt, text, isSelected }: LabelledImageProps) => {
+ return (
+
+
+ {text}
+
+ );
+};
+
+export default LabelledImage;
+
+const StyledRoot = styled.div>`
+ text-align: center;
+ opacity: ${({ isSelected }) => (isSelected ? 1 : 0.6)};
+
+ & > img {
+ border-radius: 50%;
+ border: ${({ isSelected }) => isSelected && `4px solid ${COLOR.LIGHT_BLUE_700}`};
+ }
+`;