diff --git a/package-lock.json b/package-lock.json index 0816733..76801b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,10 +11,12 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "classnames": "^2.5.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.22.3", "react-scripts": "5.0.1", + "react-select": "^5.8.0", "sass": "^1.74.1", "scss": "^0.2.4", "styled-reset": "^4.5.2", @@ -2328,6 +2330,75 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache/node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, "node_modules/@emotion/is-prop-valid": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", @@ -2340,8 +2411,52 @@ "node_modules/@emotion/memoize": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", - "peer": true + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.4.tgz", + "integrity": "sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/serialize/node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" }, "node_modules/@emotion/unitless": { "version": "0.8.0", @@ -2349,6 +2464,24 @@ "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==", "peer": true }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2442,6 +2575,28 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -4556,6 +4711,14 @@ "@types/react": "*" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -6214,6 +6377,11 @@ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, "node_modules/clean-css": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", @@ -7254,6 +7422,15 @@ "utila": "~0.4" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dom-serializer": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", @@ -8696,6 +8873,11 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -9360,6 +9542,19 @@ "he": "bin/he" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -12746,6 +12941,11 @@ "node": ">= 4.0.0" } }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -15413,6 +15613,41 @@ } } }, + "node_modules/react-select": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.0.tgz", + "integrity": "sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA==", + "dependencies": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.8.1", + "@floating-ui/dom": "^1.0.1", + "@types/react-transition-group": "^4.4.0", + "memoize-one": "^6.0.0", + "prop-types": "^15.6.0", + "react-transition-group": "^4.3.0", + "use-isomorphic-layout-effect": "^1.1.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -17706,6 +17941,19 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 6eb6f6d..fa5a924 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "classnames": "^2.5.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.22.3", diff --git a/src/App.js b/src/App.js index c58d6bc..341d9fe 100644 --- a/src/App.js +++ b/src/App.js @@ -3,12 +3,14 @@ import "./global.scss"; import "./reset.scss"; import { BrowserRouter, Routes, Route } from "react-router-dom"; import Home from "./pages/Home/Home"; +import FromMsgPage from "./pages/Msg/FromMsg/FromMsgPage"; function App() { return ( } /> + } /> ); diff --git a/src/assets/dropdown_down.png b/src/assets/dropdown_down.png new file mode 100644 index 0000000..d0385cf Binary files /dev/null and b/src/assets/dropdown_down.png differ diff --git a/src/assets/dropdown_top.png b/src/assets/dropdown_top.png new file mode 100644 index 0000000..251b5b9 Binary files /dev/null and b/src/assets/dropdown_top.png differ diff --git a/src/components/Header.module.scss b/src/components/Header.module.scss index 46ef19a..61c9baa 100644 --- a/src/components/Header.module.scss +++ b/src/components/Header.module.scss @@ -14,7 +14,7 @@ $headerH: 65px; display: flex; justify-content: space-between; align-items: center; - max-width: 1248px; + max-width: 1200px; width: 100%; } @@ -26,8 +26,8 @@ $headerH: 65px; font-size: 19.971px; line-height: normal; &::before { - content: ''; - background-image: url('../assets/Rolling_icon.png'); + content: ""; + background-image: url("../assets/Rolling_icon.png"); display: inline-block; width: 27.818px; height: 27.658px; diff --git a/src/components/Msg/Dropdown.jsx b/src/components/Msg/Dropdown.jsx new file mode 100644 index 0000000..56f6366 --- /dev/null +++ b/src/components/Msg/Dropdown.jsx @@ -0,0 +1,48 @@ +// Dropdown.jsx +import { useState } from "react"; +import styles from "./Dropdown.module.scss"; +import topIcon from "../../assets/dropdown_top.png"; +import downIcon from "../../assets/dropdown_down.png"; + +function Dropdown({ options, value, onChange }) { + const [isOpen, setIsOpen] = useState(false); + + const toggleDropdown = () => { + setIsOpen(!isOpen); + }; + + const handleOptionClick = (optionValue) => { + onChange(optionValue); + setIsOpen(false); + }; + + return ( +
+
+ {value} + dropdown icon +
+ {isOpen && ( + + )} +
+ ); +} + +export default Dropdown; diff --git a/src/components/Msg/Dropdown.module.scss b/src/components/Msg/Dropdown.module.scss new file mode 100644 index 0000000..50cde6b --- /dev/null +++ b/src/components/Msg/Dropdown.module.scss @@ -0,0 +1,71 @@ +@import "../../global.scss"; + +.dropdown_wrapper { + width: 320px; + height: auto; +} + +.dropdown { + width: auto; + height: 50px; + background-color: $white; + border: 1px solid $gray3; + border-radius: 8px; + font-size: 16px; + color: $gray5; + padding: 12px 16px; + outline: none; + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; +} + +.dropdown:focus { + // focus on + border: 2px solid $gray5; + color: $gray9; +} + +.dropdown:not(:placeholder-shown) { + // 값이 있는 상태 + border: 1px solid $gray5; + color: $gray9; +} + +.dropdown.disabled { + // 비활성화 + background-color: $gray1; + color: $gray4; + border-color: $gray3; +} + +.dropdown.error { + // 에러 상태 + border-color: $error; + color: $gray9; +} + +.options { + margin-top: 10px; + padding: 15px 0; + width: 100%; + height: auto; + border-radius: 8px; + border: 1px solid $gray3; + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); + color: $gray9; + cursor: pointer; +} + +.option { + padding: 12px 16px; + width: auto; + height: 50px; + display: flex; + align-items: center; +} + +.option:hover { + background-color: $gray1; +} diff --git a/src/components/Msg/FromMsg/FromMsg.jsx b/src/components/Msg/FromMsg/FromMsg.jsx new file mode 100644 index 0000000..323173a --- /dev/null +++ b/src/components/Msg/FromMsg/FromMsg.jsx @@ -0,0 +1,67 @@ +// FromMsg.jsx +import { useState } from "react"; +import styles from "./FromMsg.module.scss"; +import Input from "../Input"; +import Dropdown from "../Dropdown"; + +function FromMsg() { + const isError = false; + const isDisabled = false; + + const [selectedRelation, setSelectedRelation] = useState("지인"); + const [selectedFont, setSelectedFont] = useState("Noto Sans"); + + const relationOptions = [ + { value: "친구", label: "친구" }, + { value: "지인", label: "지인" }, + { value: "동료", label: "동료" }, + { value: "가족", label: "가족" }, + ]; + + const fontOptions = [ + { value: "Noto Sans", label: "Noto Sans" }, + { value: "font2", label: "font2" }, + { value: "font3", label: "font3" }, + { value: "font4", label: "font4" }, + ]; + + const handleRelationChange = (value) => { + setSelectedRelation(value); + }; + + const handleFontChange = (value) => { + setSelectedFont(value); + }; + + return ( + <> +
+
+

From.

+ +
+
+

프로필 이미지

+
+
+

상대와의 관계

+ +
+
+

내용을 입력해 주세요

+
+
+

폰트 선택

+ +
+
+ + + ); +} + +export default FromMsg; diff --git a/src/components/Msg/FromMsg/FromMsg.module.scss b/src/components/Msg/FromMsg/FromMsg.module.scss new file mode 100644 index 0000000..b20780b --- /dev/null +++ b/src/components/Msg/FromMsg/FromMsg.module.scss @@ -0,0 +1,19 @@ +@import "../../../global.scss"; + +.container { + display: flex; + flex-direction: column; + gap: 50px; +} + +.section { + display: flex; + flex-direction: column; + gap: 12px; +} + +.section h2 { + font-size: 24px; + font-weight: 600; + color: $gray9; +} diff --git a/src/components/Msg/Input.jsx b/src/components/Msg/Input.jsx new file mode 100644 index 0000000..0f42c52 --- /dev/null +++ b/src/components/Msg/Input.jsx @@ -0,0 +1,18 @@ +// Input.jsx +import classNames from "classnames"; // classnames 라이브러리 +import styles from "./Input.module.scss"; + +function Input({ error, disabled }) { + const inputClass = classNames(styles.input, { + [styles.error]: error, + [styles.disabled]: disabled, + }); + + return ( + <> + + + ); +} + +export default Input; diff --git a/src/components/Msg/Input.module.scss b/src/components/Msg/Input.module.scss new file mode 100644 index 0000000..c25e198 --- /dev/null +++ b/src/components/Msg/Input.module.scss @@ -0,0 +1,38 @@ +@import "../../global.scss"; + +.input { + width: auto; + height: 50px; + background-color: $white; + border: 1px solid $gray3; + border-radius: 8px; + font-size: 16px; + color: $gray5; + padding: 12px 16px; + outline: none; +} + +.input:focus { + // focus on + border: 2px solid $gray5; + color: $gray9; +} + +.input:not(:placeholder-shown) { + // 값이 있는 상태 + border: 1px solid $gray5; + color: $gray9; +} + +.input.disabled { + // 비활성화 + background-color: $gray1; + color: $gray4; + border-color: $gray3; +} + +.input.error { + // 에러 상태 + border-color: $error; + color: $gray9; +} diff --git a/src/pages/Msg/FromMsg/FromMsg.jsx b/src/pages/Msg/FromMsg/FromMsg.jsx deleted file mode 100644 index 21d677d..0000000 --- a/src/pages/Msg/FromMsg/FromMsg.jsx +++ /dev/null @@ -1,7 +0,0 @@ -// FromMsg.jsx - -function FromMsg() { - return <>; -} - -export default FromMsg; diff --git a/src/pages/Msg/FromMsg/FromMsgPage.jsx b/src/pages/Msg/FromMsg/FromMsgPage.jsx new file mode 100644 index 0000000..a6dc538 --- /dev/null +++ b/src/pages/Msg/FromMsg/FromMsgPage.jsx @@ -0,0 +1,15 @@ +// FromMsgPage.jsx + +import Header from "../../../components/Header"; +import FromMsg from "../../../components/Msg/FromMsg/FromMsg"; + +function FromMsgPage() { + return ( + <> +
+ + + ); +} + +export default FromMsgPage;