-
Notifications
You must be signed in to change notification settings - Fork 4
[Mission003] 자바스크립트로 Form 과 Modal 에 대한 UI 만들기 #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| { | ||
| "env": { | ||
| "browser": true, | ||
| "es6": true, | ||
| "node": true | ||
| }, | ||
| "extends": ["airbnb-base", "prettier"], | ||
| "globals": { | ||
| "SharedArrayBuffer": "readonly" | ||
| }, | ||
| "parserOptions": { | ||
| "sourceType": "module" | ||
| }, | ||
| "rules": { | ||
| "no-console": false, | ||
| "ordered-imports": false, | ||
| "no-shadowed-variable": false, | ||
| "no-angle-bracket-type-assertion": false | ||
| }, | ||
| "linterOptions": { | ||
| "exclude": ["configs/**/*.js", "node_modules/**/*.js"] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,239 @@ | ||
| /* reset */ | ||
| * { | ||
| margin: 0; | ||
| padding: 0; | ||
| -webkit-tap-highlight-color: rgba(255, 255, 255, 0); | ||
| -webkit-tap-highlight-color: transparent; | ||
| color: #212124; | ||
| -webkit-box-sizing: border-box; | ||
| box-sizing: border-box; | ||
| border: 0; | ||
| font-size: 100%; | ||
| font-family: "Noto Sans KR", system-ui, "AppleSDGothicNeo", sans-serif; | ||
| font-style: normal; | ||
| word-wrap: break-word; | ||
| word-break: keep-all; | ||
| /* Non standard for webkit */ | ||
| -webkit-hyphens: auto; | ||
| -ms-hyphens: auto; | ||
| hyphens: auto; | ||
| } | ||
| *:focus { | ||
| outline: none; | ||
| } | ||
|
|
||
| html, | ||
| body { | ||
| width: 100%; | ||
| height: 100%; | ||
| -ms-user-select: none; | ||
| -moz-user-select: -moz-none; | ||
| -webkit-user-select: none; | ||
| user-select: none; | ||
| } | ||
|
|
||
| body { | ||
| line-height: 1; | ||
| overflow-x: hidden; | ||
| background-color: #f4efd3; | ||
| height: 100%; | ||
| } | ||
|
|
||
| body.scroll-lock { | ||
| overflow: hidden; | ||
| position: fixed; | ||
| } | ||
|
|
||
| body.overflow-hidden { | ||
| overflow: hidden; | ||
| } | ||
|
|
||
| ol, | ||
| ul { | ||
| list-style: none; | ||
| } | ||
|
|
||
| blockquote, | ||
| q { | ||
| quotes: none; | ||
| } | ||
|
|
||
| blockquote:before, | ||
| blockquote:after, | ||
| q:before, | ||
| q:after { | ||
| content: ""; | ||
| content: none; | ||
| } | ||
|
|
||
| table { | ||
| border-collapse: collapse; | ||
| border-spacing: 0; | ||
| } | ||
|
|
||
| button { | ||
| display: inline-block; | ||
| background: none; | ||
| border: none; | ||
| outline: none; | ||
| cursor: pointer; | ||
| vertical-align: middle; | ||
| } | ||
|
|
||
| button:disabled, | ||
| button[disabled] { | ||
| cursor: initial; | ||
| } | ||
|
|
||
| select { | ||
| border: none; | ||
| background-color: transparent; | ||
| } | ||
|
|
||
| a { | ||
| text-decoration: none; | ||
| color: inherit; | ||
| } | ||
|
|
||
| /* Typography */ | ||
| h2 { | ||
| font-size: 24px; | ||
| } | ||
|
|
||
| /* main */ | ||
| .main { | ||
| padding: 20px; | ||
| } | ||
|
|
||
| /* components */ | ||
| .modal { | ||
| -webkit-box-shadow: 0px 0px 12px -4px rgba(0, 0, 0, 0.25); | ||
| box-shadow: 0px 0px 12px -4px rgba(0, 0, 0, 0.25); | ||
| position: absolute; | ||
| width: 340px; | ||
| height: 480px; | ||
| top: calc(50% - 270px); | ||
| left: calc(50% - 170px); | ||
| background-color: rgba(255, 255, 255, 0.35); | ||
| border-radius: 12px; | ||
| } | ||
|
|
||
| .modal-cont { | ||
| width: 100%; | ||
| position: absolute; | ||
| padding: 12px 28px 0; | ||
| top: 50%; | ||
| left: 50%; | ||
| -webkit-transform: translateX(-50%) translateY(-50%); | ||
| transform: translateX(-50%) translateY(-50%); | ||
| } | ||
|
|
||
| .modal h2 { | ||
| margin-bottom: 36px; | ||
| } | ||
|
|
||
| .btn { | ||
| width: 100%; | ||
| height: 60px; | ||
| background-color: #9656a1; | ||
| color: #f4efd3; | ||
| font-size: 17px; | ||
| font-weight: bold; | ||
| } | ||
|
|
||
| .btn.fixed { | ||
| position: fixed; | ||
| bottom: 0; | ||
| right: 0; | ||
| left: 0; | ||
| } | ||
|
|
||
| .btn-add { | ||
| position: absolute; | ||
| width: 316px; | ||
| height: 48px; | ||
| font-size: 15px; | ||
| background-color: #9656a1; | ||
| color: #fff; | ||
| border-radius: 8px; | ||
| bottom: 12px; | ||
| left: 12px; | ||
| } | ||
|
|
||
| .btn:disabled { | ||
| background-color: #cccccc; | ||
| } | ||
|
|
||
| form { | ||
| width: 100%; | ||
| position: relative; | ||
| } | ||
|
|
||
| #familyForm { | ||
| padding-bottom: 44px; | ||
| } | ||
|
|
||
| label { | ||
| margin-bottom: 26px; | ||
| display: block; | ||
| position: relative; | ||
| font-size: 12px; | ||
| } | ||
|
|
||
| label.finish { | ||
| margin-bottom: 12px; | ||
| display: -webkit-box; | ||
| display: -ms-flexbox; | ||
| display: flex; | ||
| -webkit-box-pack: justify; | ||
| -ms-flex-pack: justify; | ||
| justify-content: space-between; | ||
| -webkit-box-align: center; | ||
| -ms-flex-align: center; | ||
| align-items: center; | ||
| } | ||
|
|
||
| label.finish.family { | ||
| -webkit-box-align: start; | ||
| -ms-flex-align: start; | ||
| align-items: flex-start; | ||
| } | ||
|
|
||
| input { | ||
| width: 100%; | ||
| height: 40px; | ||
| font-size: 18px; | ||
| font-weight: bold; | ||
| background-color: transparent; | ||
| border-bottom: 2px solid #cccccc; | ||
| -webkit-transition: all 0.2s ease-in-out; | ||
| transition: all 0.2s ease-in-out; | ||
| } | ||
|
|
||
| input:focus, | ||
| .has-value { | ||
| border-bottom: 2px solid #9656a1; | ||
| } | ||
|
|
||
| label.finish > input { | ||
| display: inline-block; | ||
| width: calc(100% - 100px); | ||
| font-size: 16px; | ||
| height: auto; | ||
| border: none; | ||
| text-align: right; | ||
| } | ||
|
|
||
| input.checkbox { | ||
| position: absolute; | ||
| width: 24px; | ||
| height: 15px; | ||
| right: 0; | ||
| } | ||
|
|
||
| .hide { | ||
| opacity: 0; | ||
| display: none; | ||
| -webkit-transform: translateY(-100px); | ||
| transform: translateY(-100px); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="utf-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
| <title>Mission 3</title> | ||
| <link rel="stylesheet" href="css/style.css" /> | ||
| </head> | ||
| <body> | ||
| <div class="main"> | ||
| <div class="modal" id="modal"></div> | ||
| </div> | ||
| <!-- <button class="btn fixed" id="btnNext">NEXT ></button> --> | ||
| <script src="js/app.js" type="module"></script> | ||
| </body> | ||
| </html> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| import Modal from "./components/Modal.js"; | ||
| import NextButton from "./components/NextButton.js"; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. react.js 컴포넌트를 만들면서 알게 된 팁인데 |
||
| import { getData } from "./store/store.js"; | ||
|
|
||
| const modal = new Modal(getData()); | ||
| modal.setState(getData()); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import NextButton from "./NextButton.js"; | ||
| import { familyTemplate, familyNodeTemplate } from "../utils/template.js"; | ||
| import { onCheckNull } from "../utils/utils.js"; | ||
| import { getFamilyNum, setFamilyNum } from "../store/store.js"; | ||
|
|
||
| const modal = document.getElementById("modal"); | ||
|
|
||
| export default function FamilyModal(data) { | ||
| this.setState = nextData => { | ||
| data = nextData; | ||
| render(data); | ||
| }; | ||
| } | ||
|
|
||
| const render = data => { | ||
| modal.innerHTML = familyTemplate(data); | ||
|
|
||
| const inputs = document.querySelectorAll("input"); | ||
| Array.from(inputs).map(elem => { | ||
| elem.addEventListener("change", onCheckNull); | ||
|
|
||
| const btnAdd = document.getElementById("btnAdd"); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 변수명이 현재 |
||
| btnAdd.addEventListener("click", () => { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넘길 파라미터가 없다면 아래와 같이 작성하실 수 있을 것 같아요 :) |
||
| addFamily(); | ||
| }); | ||
|
|
||
| const nextButton = new NextButton(data); | ||
| nextButton.setState(data); | ||
| }; | ||
|
|
||
| const addFamily = () => { | ||
| const form = document.getElementById("familyForm"); | ||
| const familyNum = getFamilyNum(); | ||
|
|
||
| if (familyNum >= 5) { | ||
| alert("구성원을 더 이상 추가할 수 없습니다"); | ||
| return; | ||
| } | ||
|
|
||
| form.insertAdjacentHTML("beforeend", familyNodeTemplate("", familyNum)); | ||
| setFamilyNum(familyNum + 1); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import SubmitButton from "./SubmitButton.js"; | ||
| import { finishTemplate } from "../utils/template.js"; | ||
|
|
||
| const modal = document.getElementById("modal"); | ||
|
|
||
| export default function FinishModal(data) { | ||
| this.setState = nextData => { | ||
| data = nextData; | ||
| render(data); | ||
| console.log(data); | ||
| }; | ||
| } | ||
|
|
||
| const render = data => { | ||
| modal.innerHTML = finishTemplate(data); | ||
|
|
||
| const submitButton = new SubmitButton(data); | ||
| submitButton.setState(data); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import MyInfoModal from "./MyInfoModal.js"; | ||
| import FamilyModal from "./FamilyModal.js"; | ||
| import FinishModal from "./FinishModal.js"; | ||
| import { getPage, getData } from "../store/store.js"; | ||
| import { exceptionTemplate } from "../utils/template.js"; | ||
| import { pageName } from "../utils/constants.js"; | ||
|
|
||
| const modal = document.getElementById("modal"); | ||
|
|
||
| let page; | ||
| let data; | ||
|
|
||
| export default function Modal(data) { | ||
| this.setState = nextData => { | ||
| detactChange(); | ||
| data = nextData; | ||
| render(data); | ||
| }; | ||
| } | ||
|
|
||
| const render = data => { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 혹시 여기에 받는 파라미터인 data는 나중에 어디에 쓰일 예정인지 알수 있을까요??ㅎㅎ |
||
| switch (page) { | ||
| case pageName.MYINFO: | ||
| const myInfoModal = new MyInfoModal(getData()); | ||
| myInfoModal.setState(getData()); | ||
| break; | ||
| case pageName.FAMILY: | ||
| const familyModal = new FamilyModal(getData()); | ||
| familyModal.setState(getData()); | ||
| break; | ||
| case pageName.FINISH: | ||
| const finishModal = new FinishModal(getData()); | ||
| finishModal.setState(getData()); | ||
| break; | ||
| default: | ||
| modal.innerHTML = exceptionTemplate; | ||
| break; | ||
| } | ||
| }; | ||
|
|
||
| const detactChange = () => { | ||
| page = getPage(); | ||
| data = getData(); | ||
| }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사용하지 않을 거라면 주석을 제거해주시면 더 좋을 것 같아.요 다른 팀원이 해당 코드를 본다면 어떤 용도와 의미로 주석처리 해둔건지 고민하게 될 수 있을 것 같아요 :)