diff --git a/.storybook/main.ts b/.storybook/main.ts
index a567f71..9908be4 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -23,5 +23,28 @@ const config: StorybookConfig = {
name: '@storybook/nextjs',
options: {},
},
+ webpackFinal: async (config) => {
+ const imageRule = config.module?.rules?.find((rule) => {
+ const test = (rule as { test: RegExp }).test;
+
+ if (!test) {
+ return false;
+ }
+ if (Array.isArray(test)) {
+ return test.some((t) => t instanceof RegExp && t.test('.svg'));
+ }
+
+ return test instanceof RegExp && test.test('.svg');
+ }) as { [key: string]: any };
+
+ imageRule.exclude = /\.svg$/;
+
+ config.module?.rules?.push({
+ test: /\.svg$/,
+ use: ['@svgr/webpack'],
+ });
+
+ return config;
+ },
};
export default config;
diff --git a/app/page.tsx b/app/page.tsx
index 046a7d3..6e67fa7 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,39 +1,50 @@
+import IconArrowFront from '/public/assets/icon/arrow-front.svg';
+
+import { PageContainer } from '@/widgets/pageContainer/ui/PageContainer';
export default function Home() {
return (
-
-
-
White
-
Gray 01
-
Gray 02
-
Gray 03
-
Gray 04
-
Gray 05
-
Gray 06
-
Gray 07
-
+
,
+ center:
메인페이지
,
+ right:
,
+ }}
+ >
+
+
+
White
+
Gray 01
+
Gray 02
+
Gray 03
+
Gray 04
+
Gray 05
+
Gray 06
+
Gray 07
+
-
-
Red 01
-
Red 02
-
Red 03
+
+
Red 01
+
Red 02
+
Red 03
-
+
-
Yellow 01
-
Yellow 02
-
+
Yellow 01
+
Yellow 02
+
-
-
Ashblue 01
-
Ashblue 02
-
Overlay
+
+
Ashblue 01
+
Ashblue 02
+
Overlay
-
+
-
Mint 01
-
Mint 02
-
Mint 03
+
Mint 01
+
Mint 02
+
Mint 03
+
-
+
);
}
diff --git a/global.d.ts b/global.d.ts
new file mode 100644
index 0000000..006534e
--- /dev/null
+++ b/global.d.ts
@@ -0,0 +1,4 @@
+declare module '*.svg' {
+ const content: React.FunctionComponent
>;
+ export default content;
+}
diff --git a/next.config.mjs b/next.config.mjs
index 4678774..dde8ea3 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -1,4 +1,12 @@
/** @type {import('next').NextConfig} */
-const nextConfig = {};
+const nextConfig = {
+ webpack: (config) => {
+ config.module.rules.push({
+ test: /\.svg$/,
+ use: ["@svgr/webpack"],
+ });
+ return config;
+ },
+};
export default nextConfig;
diff --git a/package.json b/package.json
index 2421aec..72baeb4 100644
--- a/package.json
+++ b/package.json
@@ -23,9 +23,7 @@
},
"devDependencies": {
"@chromatic-com/storybook": "^1.9.0",
- "@eslint/js": "^9.12.0",
- "@tanstack/eslint-plugin-query": "^5.59.7",
- "@tanstack/react-query-devtools": "^5.59.4",
+ "@eslint/js": "^9.12.0",
"@storybook/addon-a11y": "^8.3.5",
"@storybook/addon-designs": "^8.0.3",
"@storybook/addon-essentials": "^8.3.5",
@@ -38,6 +36,9 @@
"@storybook/nextjs": "^8.3.5",
"@storybook/react": "^8.3.5",
"@storybook/test": "^8.3.5",
+ "@svgr/webpack": "^8.1.0",
+ "@tanstack/eslint-plugin-query": "^5.59.7",
+ "@tanstack/react-query-devtools": "^5.59.4",
"@testing-library/react": "^16.0.1",
"@types/node": "^20",
"@types/react": "^18",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6e6bac5..ccb6326 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -32,13 +32,7 @@ importers:
version: 1.9.0(react@18.3.1)
'@eslint/js':
specifier: ^9.12.0
- version: 9.12.0
- '@tanstack/eslint-plugin-query':
- specifier: ^5.59.7
- version: 5.59.7(eslint@8.57.0)(typescript@5.6.3)
- '@tanstack/react-query-devtools':
- specifier: ^5.59.4
- version: 5.59.13(@tanstack/react-query@5.59.13(react@18.3.1))(react@18.3.1)
+ version: 9.12.0
'@storybook/addon-a11y':
specifier: ^8.3.5
version: 8.3.5(storybook@8.3.5)
@@ -75,6 +69,15 @@ importers:
'@storybook/test':
specifier: ^8.3.5
version: 8.3.5(storybook@8.3.5)
+ '@svgr/webpack':
+ specifier: ^8.1.0
+ version: 8.1.0(typescript@5.6.3)
+ '@tanstack/eslint-plugin-query':
+ specifier: ^5.59.7
+ version: 5.59.7(eslint@8.57.0)(typescript@5.6.3)
+ '@tanstack/react-query-devtools':
+ specifier: ^5.59.4
+ version: 5.59.13(@tanstack/react-query@5.59.13(react@18.3.1))(react@18.3.1)
'@testing-library/react':
specifier: ^16.0.1
version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.1)(@types/react@18.3.11)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -581,6 +584,12 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
+ '@babel/plugin-transform-react-constant-elements@7.25.7':
+ resolution: {integrity: sha512-/qXt69Em8HgsjCLu7G3zdIQn7A2QwmYND7Wa0LTp09Na+Zn8L5d0A7wSXrKi18TJRc/Q5S1i1De/SU1LzVkSvA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
'@babel/plugin-transform-react-display-name@7.25.7':
resolution: {integrity: sha512-r0QY7NVU8OnrwE+w2IWiRom0wwsTbjx4+xH2RTd7AVdof3uurXOF+/mXHQDRk+2jIvWgSaCHKMgggfvM4dyUGA==}
engines: {node: '>=6.9.0'}
@@ -1688,6 +1697,84 @@ packages:
peerDependencies:
storybook: ^8.3.5
+ '@svgr/babel-plugin-add-jsx-attribute@8.0.0':
+ resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-remove-jsx-attribute@8.0.0':
+ resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0':
+ resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0':
+ resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-svg-dynamic-title@8.0.0':
+ resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-svg-em-dimensions@8.0.0':
+ resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-transform-react-native-svg@8.1.0':
+ resolution: {integrity: sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-plugin-transform-svg-component@8.0.0':
+ resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==}
+ engines: {node: '>=12'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/babel-preset@8.1.0':
+ resolution: {integrity: sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@svgr/core@8.1.0':
+ resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==}
+ engines: {node: '>=14'}
+
+ '@svgr/hast-util-to-babel-ast@8.0.0':
+ resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==}
+ engines: {node: '>=14'}
+
+ '@svgr/plugin-jsx@8.1.0':
+ resolution: {integrity: sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@svgr/core': '*'
+
+ '@svgr/plugin-svgo@8.1.0':
+ resolution: {integrity: sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ '@svgr/core': '*'
+
+ '@svgr/webpack@8.1.0':
+ resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==}
+ engines: {node: '>=14'}
+
'@swc/counter@0.1.3':
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
@@ -1745,6 +1832,10 @@ packages:
peerDependencies:
'@testing-library/dom': '>=7.21.4'
+ '@trysound/sax@0.2.0':
+ resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
+ engines: {node: '>=10.13.0'}
+
'@types/aria-query@5.0.4':
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
@@ -2386,6 +2477,10 @@ packages:
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
engines: {node: '>= 6'}
+ camelcase@6.3.0:
+ resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
+ engines: {node: '>=10'}
+
caniuse-lite@1.0.30001668:
resolution: {integrity: sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==}
@@ -2504,6 +2599,10 @@ packages:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
+ commander@7.2.0:
+ resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
+ engines: {node: '>= 10'}
+
commander@8.3.0:
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
engines: {node: '>= 12'}
@@ -2561,6 +2660,15 @@ packages:
resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==}
engines: {node: '>=10'}
+ cosmiconfig@8.3.6:
+ resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ typescript: '>=4.9.5'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
cosmiconfig@9.0.0:
resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==}
engines: {node: '>=14'}
@@ -2601,6 +2709,17 @@ packages:
css-select@4.3.0:
resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==}
+ css-select@5.1.0:
+ resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
+
+ css-tree@2.2.1:
+ resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+
+ css-tree@2.3.1:
+ resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
+
css-what@6.1.0:
resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
engines: {node: '>= 6'}
@@ -2613,6 +2732,10 @@ packages:
engines: {node: '>=4'}
hasBin: true
+ csso@5.0.5:
+ resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+
cssstyle@4.1.0:
resolution: {integrity: sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==}
engines: {node: '>=18'}
@@ -2753,6 +2876,9 @@ packages:
dom-serializer@1.4.1:
resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
+ dom-serializer@2.0.0:
+ resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
+
domain-browser@4.23.0:
resolution: {integrity: sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==}
engines: {node: '>=10'}
@@ -2764,9 +2890,16 @@ packages:
resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==}
engines: {node: '>= 4'}
+ domhandler@5.0.3:
+ resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
+ engines: {node: '>= 4'}
+
domutils@2.8.0:
resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
+ domutils@3.1.0:
+ resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
+
dot-case@3.0.4:
resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
@@ -3812,6 +3945,12 @@ packages:
md5.js@1.3.5:
resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==}
+ mdn-data@2.0.28:
+ resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
+
+ mdn-data@2.0.30:
+ resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
+
media-typer@0.3.0:
resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
engines: {node: '>= 0.6'}
@@ -4672,6 +4811,9 @@ packages:
resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==}
engines: {node: '>=18'}
+ snake-case@3.0.4:
+ resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
+
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
@@ -4848,6 +4990,14 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
+ svg-parser@2.0.4:
+ resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==}
+
+ svgo@3.3.2:
+ resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
@@ -5905,6 +6055,11 @@ snapshots:
'@babel/core': 7.25.8
'@babel/helper-plugin-utils': 7.25.7
+ '@babel/plugin-transform-react-constant-elements@7.25.7(@babel/core@7.25.8)':
+ dependencies:
+ '@babel/core': 7.25.8
+ '@babel/helper-plugin-utils': 7.25.7
+
'@babel/plugin-transform-react-display-name@7.25.7(@babel/core@7.25.8)':
dependencies:
'@babel/core': 7.25.8
@@ -7096,6 +7251,99 @@ snapshots:
dependencies:
storybook: 8.3.5
+ '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.25.8)':
+ dependencies:
+ '@babel/core': 7.25.8
+
+ '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.25.8)':
+ dependencies:
+ '@babel/core': 7.25.8
+
+ '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.25.8)':
+ dependencies:
+ '@babel/core': 7.25.8
+
+ '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.25.8)':
+ dependencies:
+ '@babel/core': 7.25.8
+
+ '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.25.8)':
+ dependencies:
+ '@babel/core': 7.25.8
+
+ '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.25.8)':
+ dependencies:
+ '@babel/core': 7.25.8
+
+ '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.25.8)':
+ dependencies:
+ '@babel/core': 7.25.8
+
+ '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.25.8)':
+ dependencies:
+ '@babel/core': 7.25.8
+
+ '@svgr/babel-preset@8.1.0(@babel/core@7.25.8)':
+ dependencies:
+ '@babel/core': 7.25.8
+ '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.25.8)
+ '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.25.8)
+ '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.25.8)
+ '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.25.8)
+ '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.25.8)
+ '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.25.8)
+ '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.25.8)
+ '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.25.8)
+
+ '@svgr/core@8.1.0(typescript@5.6.3)':
+ dependencies:
+ '@babel/core': 7.25.8
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.25.8)
+ camelcase: 6.3.0
+ cosmiconfig: 8.3.6(typescript@5.6.3)
+ snake-case: 3.0.4
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
+ '@svgr/hast-util-to-babel-ast@8.0.0':
+ dependencies:
+ '@babel/types': 7.25.8
+ entities: 4.5.0
+
+ '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.6.3))':
+ dependencies:
+ '@babel/core': 7.25.8
+ '@svgr/babel-preset': 8.1.0(@babel/core@7.25.8)
+ '@svgr/core': 8.1.0(typescript@5.6.3)
+ '@svgr/hast-util-to-babel-ast': 8.0.0
+ svg-parser: 2.0.4
+ transitivePeerDependencies:
+ - supports-color
+
+ '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.6.3))(typescript@5.6.3)':
+ dependencies:
+ '@svgr/core': 8.1.0(typescript@5.6.3)
+ cosmiconfig: 8.3.6(typescript@5.6.3)
+ deepmerge: 4.3.1
+ svgo: 3.3.2
+ transitivePeerDependencies:
+ - typescript
+
+ '@svgr/webpack@8.1.0(typescript@5.6.3)':
+ dependencies:
+ '@babel/core': 7.25.8
+ '@babel/plugin-transform-react-constant-elements': 7.25.7(@babel/core@7.25.8)
+ '@babel/preset-env': 7.25.8(@babel/core@7.25.8)
+ '@babel/preset-react': 7.25.7(@babel/core@7.25.8)
+ '@babel/preset-typescript': 7.25.7(@babel/core@7.25.8)
+ '@svgr/core': 8.1.0(typescript@5.6.3)
+ '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.6.3))
+ '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.6.3))(typescript@5.6.3)
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
'@swc/counter@0.1.3': {}
'@swc/helpers@0.5.5':
@@ -7161,6 +7409,8 @@ snapshots:
dependencies:
'@testing-library/dom': 10.4.0
+ '@trysound/sax@0.2.0': {}
+
'@types/aria-query@5.0.4': {}
'@types/babel__core@7.20.5':
@@ -7955,6 +8205,8 @@ snapshots:
camelcase-css@2.0.1: {}
+ camelcase@6.3.0: {}
+
caniuse-lite@1.0.30001668: {}
case-sensitive-paths-webpack-plugin@2.4.0: {}
@@ -8069,6 +8321,8 @@ snapshots:
commander@4.1.1: {}
+ commander@7.2.0: {}
+
commander@8.3.0: {}
common-path-prefix@3.0.0: {}
@@ -8113,6 +8367,15 @@ snapshots:
path-type: 4.0.0
yaml: 1.10.2
+ cosmiconfig@8.3.6(typescript@5.6.3):
+ dependencies:
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ parse-json: 5.2.0
+ path-type: 4.0.0
+ optionalDependencies:
+ typescript: 5.6.3
+
cosmiconfig@9.0.0(typescript@5.6.3):
dependencies:
env-paths: 2.2.1
@@ -8185,12 +8448,34 @@ snapshots:
domutils: 2.8.0
nth-check: 2.1.1
+ css-select@5.1.0:
+ dependencies:
+ boolbase: 1.0.0
+ css-what: 6.1.0
+ domhandler: 5.0.3
+ domutils: 3.1.0
+ nth-check: 2.1.1
+
+ css-tree@2.2.1:
+ dependencies:
+ mdn-data: 2.0.28
+ source-map-js: 1.2.1
+
+ css-tree@2.3.1:
+ dependencies:
+ mdn-data: 2.0.30
+ source-map-js: 1.2.1
+
css-what@6.1.0: {}
css.escape@1.5.1: {}
cssesc@3.0.0: {}
+ csso@5.0.5:
+ dependencies:
+ css-tree: 2.2.1
+
cssstyle@4.1.0:
dependencies:
rrweb-cssom: 0.7.1
@@ -8331,6 +8616,12 @@ snapshots:
domhandler: 4.3.1
entities: 2.2.0
+ dom-serializer@2.0.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ entities: 4.5.0
+
domain-browser@4.23.0: {}
domelementtype@2.3.0: {}
@@ -8339,12 +8630,22 @@ snapshots:
dependencies:
domelementtype: 2.3.0
+ domhandler@5.0.3:
+ dependencies:
+ domelementtype: 2.3.0
+
domutils@2.8.0:
dependencies:
dom-serializer: 1.4.1
domelementtype: 2.3.0
domhandler: 4.3.1
+ domutils@3.1.0:
+ dependencies:
+ dom-serializer: 2.0.0
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+
dot-case@3.0.4:
dependencies:
no-case: 3.0.4
@@ -9663,6 +9964,10 @@ snapshots:
inherits: 2.0.4
safe-buffer: 5.2.1
+ mdn-data@2.0.28: {}
+
+ mdn-data@2.0.30: {}
+
media-typer@0.3.0: {}
memfs@3.5.3:
@@ -10627,6 +10932,11 @@ snapshots:
ansi-styles: 6.2.1
is-fullwidth-code-point: 5.0.0
+ snake-case@3.0.4:
+ dependencies:
+ dot-case: 3.0.4
+ tslib: 2.7.0
+
source-map-js@1.2.1: {}
source-map-support@0.5.21:
@@ -10812,6 +11122,18 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
+ svg-parser@2.0.4: {}
+
+ svgo@3.3.2:
+ dependencies:
+ '@trysound/sax': 0.2.0
+ commander: 7.2.0
+ css-select: 5.1.0
+ css-tree: 2.3.1
+ css-what: 6.1.0
+ csso: 5.0.5
+ picocolors: 1.1.0
+
symbol-tree@3.2.4: {}
tailwindcss@3.4.13:
diff --git a/public/assets/icon/arrow-down-small.svg b/public/assets/icon/arrow-down-small.svg
new file mode 100644
index 0000000..e23586e
--- /dev/null
+++ b/public/assets/icon/arrow-down-small.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/assets/icon/arrow-front.svg b/public/assets/icon/arrow-front.svg
new file mode 100644
index 0000000..da93876
--- /dev/null
+++ b/public/assets/icon/arrow-front.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/shared/ui/dropdown/index.ts b/src/shared/ui/dropdown/index.ts
new file mode 100644
index 0000000..5ecdd1f
--- /dev/null
+++ b/src/shared/ui/dropdown/index.ts
@@ -0,0 +1 @@
+export * from './ui';
diff --git a/src/shared/ui/dropdown/ui/Dropdown.stories.tsx b/src/shared/ui/dropdown/ui/Dropdown.stories.tsx
new file mode 100644
index 0000000..0889cbe
--- /dev/null
+++ b/src/shared/ui/dropdown/ui/Dropdown.stories.tsx
@@ -0,0 +1,49 @@
+import { useState } from 'react';
+
+import { Meta, StoryObj } from '@storybook/react';
+
+import { Dropdown } from '.';
+
+import type { IOption } from '.';
+
+import ArrowDownSmall from '/public/assets/icon/arrow-down-small.svg';
+
+const options: IOption[] = [
+ { title: 'Option 1', itemTitle: 'Item 1' },
+ { title: 'Option 2', itemTitle: 'Item 2' },
+ { title: 'Option 3', itemTitle: 'Item 3' },
+];
+
+type Story = StoryObj;
+
+export default {
+ title: 'Dropdown',
+ component: Dropdown,
+ parameters: { layout: 'centered' },
+ tags: ['autodocs'],
+ args: {
+ options,
+ children: ,
+ menuPositionClass: 'top-[40px] left-1/2 -translate-x-1/2',
+ selectOption: (index: number) => {
+ console.log(index);
+ },
+ },
+} satisfies Meta;
+
+export const Default: Story = {
+ render: (args) => {
+ const [selectedOptionIndex, setSelectedOptionIndex] = useState(0);
+ const selectOption = (index: number) => {
+ setSelectedOptionIndex(index);
+ };
+ return (
+
+ {args.options[selectedOptionIndex]?.itemTitle}
+
+
+ );
+ },
+};
diff --git a/src/shared/ui/dropdown/ui/Dropdown.tsx b/src/shared/ui/dropdown/ui/Dropdown.tsx
new file mode 100644
index 0000000..91aae97
--- /dev/null
+++ b/src/shared/ui/dropdown/ui/Dropdown.tsx
@@ -0,0 +1,54 @@
+'use client';
+import { PropsWithChildren, useState } from 'react';
+
+export interface IDropdown {
+ options: Array;
+ menuPositionClass: string;
+ selectOption: (index: number) => void;
+}
+
+export interface IOption {
+ title: string;
+ itemTitle: string;
+}
+
+export function Dropdown({
+ options,
+ menuPositionClass,
+ selectOption,
+ children,
+}: PropsWithChildren) {
+ const [isOpen, setIsOpen] = useState(false);
+
+ const clickToggle = () => {
+ setIsOpen((prev) => !prev);
+ };
+
+ const clickOption = (index: number) => {
+ setIsOpen(false);
+ selectOption(index);
+ };
+
+ return (
+
+
+ {isOpen && (
+
+ {options.map((option, index) => (
+
+ ))}
+
+ )}
+
+ );
+}
diff --git a/src/shared/ui/dropdown/ui/index.ts b/src/shared/ui/dropdown/ui/index.ts
new file mode 100644
index 0000000..2f29bad
--- /dev/null
+++ b/src/shared/ui/dropdown/ui/index.ts
@@ -0,0 +1 @@
+export * from './Dropdown';
diff --git a/src/shared/ui/header/index.ts b/src/shared/ui/header/index.ts
new file mode 100644
index 0000000..5ecdd1f
--- /dev/null
+++ b/src/shared/ui/header/index.ts
@@ -0,0 +1 @@
+export * from './ui';
diff --git a/src/shared/ui/header/ui/Header.tsx b/src/shared/ui/header/ui/Header.tsx
new file mode 100644
index 0000000..0f4d7ab
--- /dev/null
+++ b/src/shared/ui/header/ui/Header.tsx
@@ -0,0 +1,15 @@
+export interface IHeader {
+ left: JSX.Element;
+ center?: JSX.Element;
+ right?: JSX.Element;
+}
+
+export function Header({ left, center, right }: IHeader) {
+ return (
+
+ {left}
+ {center}
+ {right}
+
+ );
+}
diff --git a/src/shared/ui/header/ui/index.ts b/src/shared/ui/header/ui/index.ts
new file mode 100644
index 0000000..266dec8
--- /dev/null
+++ b/src/shared/ui/header/ui/index.ts
@@ -0,0 +1 @@
+export * from './Header';
diff --git a/src/shared/ui/index.ts b/src/shared/ui/index.ts
index 4f081a0..0ad19f3 100644
--- a/src/shared/ui/index.ts
+++ b/src/shared/ui/index.ts
@@ -1,2 +1,4 @@
+export * from './dropdown';
+export * from './header';
export * from './button';
export * from './modal-wrapper';
diff --git a/src/widgets/pageContainer/index.ts b/src/widgets/pageContainer/index.ts
new file mode 100644
index 0000000..5ecdd1f
--- /dev/null
+++ b/src/widgets/pageContainer/index.ts
@@ -0,0 +1 @@
+export * from './ui';
diff --git a/src/widgets/pageContainer/ui/PageContainer.tsx b/src/widgets/pageContainer/ui/PageContainer.tsx
new file mode 100644
index 0000000..30d43bb
--- /dev/null
+++ b/src/widgets/pageContainer/ui/PageContainer.tsx
@@ -0,0 +1,21 @@
+import { PropsWithChildren } from 'react';
+
+import { Header } from '@/shared/ui';
+import type { IHeader } from '@/shared/ui';
+
+export interface IPageContainer {
+ headerProps: IHeader;
+ hasHeader?: boolean;
+}
+export function PageContainer({
+ headerProps,
+ hasHeader = true,
+ children,
+}: PropsWithChildren) {
+ return (
+
+ {hasHeader &&
}
+
{children}
+
+ );
+}
diff --git a/src/widgets/pageContainer/ui/index.ts b/src/widgets/pageContainer/ui/index.ts
new file mode 100644
index 0000000..7a798df
--- /dev/null
+++ b/src/widgets/pageContainer/ui/index.ts
@@ -0,0 +1 @@
+export * from './PageContainer';
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 4081835..dcb82b9 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -13,6 +13,7 @@ const config: Config = {
content: [
'./app/**/*.{ts,tsx}',
'./src/pages/**/*.{ts,tsx}',
+ './src/shared/**/*.{ts,tsx}',
'./src/features/**/*.{ts,tsx}',
'./src/widgets/**/*.{ts,tsx}',
'./src/shared/**/*.{ts,tsx}',
diff --git a/tsconfig.json b/tsconfig.json
index 7b28589..9d5fb99 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -18,9 +18,10 @@
}
],
"paths": {
- "@/*": ["./src/*"]
+ "@/*": ["./src/*"],
+ "/public/*" : ["./public/*"]
}
},
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "include": ["global.d.ts", "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
diff --git a/vite.config.ts b/vite.config.ts
index d23fced..2d621c7 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,5 +1,5 @@
-import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
+import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [react()],
test: {