📒 2탄 이전 벨로그

...

🎈사이드바 만들기

▫ src>layout>Sidebar>Sidebar.jsx

햄버거바 눌렀을 때 리덕스 스토어에 있는 state는 변경이 되니까
이거에 따라 Sidebar 만들어주면 됨🆗

🧙‍♀️import styled from 'styled-components';

이부분을 감싸는 부분 하나 만들기

ItemsBox는 이부분 전체를 감싸는 녀석

하나씩 나열할건데 우선 Notes 부터😶

👉 active인지 아닌지를 아는 기능이 있음

Wdwd로 클릭해서 갔다고 하면 약간 색상이 연해진 걸 확인할 수 있음😮

현재 / 이 경로에 있으면 isActivetrue고 없으면 false

<NavLink
  to={'/'}
  className={({isActive}) =>
  	isActive ? 'active-item' : 'inactive-item';
  }
>
</NavLink>

이걸 이용해서 style 다르게 해줄 수 있음
isActivetrue일 땐 'active-item' className을 줘서 다른 스타일로 주고
아닐 땐 'inactive-item' className을 줘서 다른 스타일링을 해주면 됨

Sidebar 에서 필요한 리덕스 스토어 데이터가 있음
👉 isOpen: true

이게 true인지 false인지에 따라 사이드바가 있다 없다 하기 때문❗

useSelector 하고 state 에서 가져와야할 데이터는 state.menu
👉 const { isOpen } = useSelector(state => state.menu);

isOpenfalse일 땐 style 이용해서 이 부분이 안 보이게 해주자

styled-components의 좋은 점 : props를 내려줄 수 있음👍

openMenu 라는 이름의 props로 해줄거임

너비는 250px, 높이는 전체 100%,
min-height: 100vh ( 최소한 전체를 가져간다는 것 )

@media (max-width: 950px) {
  transition: 350ms transform ease-in-out;

position: absolute 주니까 저랬다가 이렇게 됨

사이드바 메뉴 클릭했을 땐 움직이면서 사라지고 햄버거바 눌렀을 때도
움직이면서 사이드바가 생김 이걸 위해 transform 해주는 것

transform: ${({openMenu})
  => openMenu === "open" ? "translateX(0%)" : "translateX(-100%)"}

👉 openMenu"open"( isOpen: true면 )이면
사이드바 열려있는 거니까 0% 아니면 -100%

// 0.2초동안 변화 천천히 시작하고 끝남
// 0.25초동안 변화 천천히 시작하고 끝남
transition: 200ms visibility ease-in-out, 
  250ms background-color ease-in-out; 

// 사이드바 열려있으면 normal로 아니면 hidden(숨김)
visibility: ${({openMenu}) 
  => openMenu === "open" ? "normal" : "hidden"};

background-color: ${({openMenu}) 
  => openMenu === "open" ? "rgba(0, 0, 0, 0.8)" : "rgba(0, 0, 0, 0)"};

cursor: pointer;

이부분 이렇게 변경해주기

햄버거바 클릭하면

이렇게 사이드바가 잘 나오는 걸 확인할 수 있음👀

👩‍🎨스타일링 해주기

box-shadow: 0px 2px 4px 0px rgba(255, 255, 255, 0.3);

a 태그 링크로 감싸져있어서

이렇게 해주고

👉 .active-item➡background-color: rgba(255, 255, 255, 0.18);

active 하지 않은 애들
👉 transition: 250ms background color ease-in-out;
👉 background-color: rgba(255, 255, 255, 0.15);


🙋‍♀️이제 이 부분 하나씩 만들어줄 것❗

🔖사이드바 태그들

tags는 여기에 있음
✅ 여기 있는 걸 가져와서 하나씩 나열해야함

왜냐, 태그는 Edit Notes 모달 이용해서 새롭게 생성할 수 있음🎆
그럼 tagsList가 총 4개가 돼서 여긴 하드코딩이 아닌
있는 개수를 가져와서 보여주는 부분인 것🤓

💁‍♀️useSelector 이용해서 가져오기✨

useSelector state 하고 tags 에서 tagsList 가져오면 되니까
state.tags 한 담에 바로 구조분해할당 해서 { tagsList } 해주면 됨
그럼 tagsList에 0~3 인덱스 총 4개가 들어있을거임😎

👉 import { useSelector } from 'react-redex';
👉 const { tagsList } = useSelector(state => state.tags);

🗺 tagsList가 있으면 당연히 나열하는거니까 map 사용
그 담에 ( 하나하나의 객체가 들어올거 )

객체 안엔 어떤 게 있냐면 tag엔 태그의 이름이랑 태그의 유니크한 id가 있음✔
( 원랜 객체가 올텐데 ) 얘네를 바로 구조분해할당 해서 가져고 올 것

객체 안에 tag, id 하고 li 태그 사용해서 keyid 넣어주기

사이드바에서 Coding 클릭하면 /tag/coding으로 이동하고
Exercise 클릭하면 /tag/exercise로 이동함

👉 /tag/${tag(태그의 이름인 tag 넣어주기)}

그담에 state 어떠한 데이터를 넣어줄거냐면
{ tag( exercise면 exercise, coding이면 coding ) }

stateto의 경로로 갔을 때 해당 컴포넌트에서 tag 데이터를 가져올 수 있음😲

가져올 때 어떻게 가져오냐면 useLocation 한 담에 const location 객체를 리턴함🔁
location.state{ tag } 이 데이터가 있어서 전달해주는거임

className 해서 isActive 이면 'active-item' 이고 아니면 'inactive-item'

span 태그 해서 태그의 아이콘 FaTag 하고

span 또 해서 이번엔 태그의 이름들 { tag } 넣어주면 됨👌

이렇게 잘 된 걸 확인 할 수 있음👀

🚨근데 문제가 Notes는 대문자로 시작하는데 나머지는 소문자로 되어있음
나머지도 Notes와 똑같이 대문자로 시작하게 해줄 것❗


🔖태그 이름들 대문자로 시작하게 해주기

▫ src>utils>getStandardName.js

여기에 함수를 만든 담에 이렇게 첫 글자만 대문자로 바꿔줘야할 때
여러군데에서 이 함수를 사용하면 됨 ♻

📢이 함수 호출할 때 스펠링 name을 받아올거임 ( string 값 )

return 한 담에 name의 첫 글자만 대문자로 바꿔줘야함

만약, name 있으면 slice 사용해서 첨에 시작을 0 으로 하고 끝은 1 로 주고
toUpperCase 이용해서 첫 글자를 대문자로 바꿔주면 됨➡( ex - "e"->"E" )😎

그담에 ➕ 첨은 1 인덱스 주고 끝까지 가져오려면 name.length 해주면 됨
그리고 첫글자 빼고 나머지는 소문자여야 하니까 toLowerCase 이용하기
( ex - "xercise" 1 인덱스부터 끝까지 가져오기 )

다른 곳에서 사용할거니까 export로 내보내주기🥏

다시 Sidebar.jsx로 와서 { getStandardName(tag) } 해주면 됨

첫글자는 대문자, 나머지는 소문자로 잘 나오는 것을 확인할 수 있음👀

태그들까지 한거고 이제 Edit~Trash 까지 해주면 됨 🆗


✍사이드바에 있는 Edit Notes 화면에 보여주기

하드 코딩

현재는 이렇게 나옴

👩‍🎨ItemsBox 안에 sidebar__edit-item 스타일링 해주기

호버했을 때 이렇게 색상이 약간 다르게 되는 걸 볼 수 있음

이제 Edit Notes를 클릭하면

이 모달이 나오는데

modalviewEditTagsModal

모달을 위해서 이미 만들어놓은 게 이부분

viewEditTagsModalview의 값으로 넣어주는 부분

toggleTagsModal을 호출해야함📢

다시 src>layout>Sidebar>Sidebar.jsx로 와서

onClick 한 담에 어떤 걸 호출해야하는데 dispatch
근데 지금 dispatch가 없으니까

useDispatch 이용해서 dispatch 만들기

dispatch 하고 modalSlice 에서 만들어놓았던 toggleTagsModal 함수 가져오기

여기 payload엔 뭘 넣어줘야할까❓

여기에 action.payload 에서 받아오는 게 { type, view } 얘네를 넣어줘야함

객체로 type & view를 넣어주기

type'add' | 'edit' 이 있었는데 여기선 'edit' 이니까 써주고
viewtrue | false니까 지금은 보여주는 부분이니 true로 써주기

Edit Notes 클릭하면 이젠 true가 뜸👀

Archive & Trash 이부분을 해주기 위해

두 개니까 items 한 담에 { }, { } 해주고 iconArchive 왼쪽에 있는 아이콘을 위해 써줌

🔹아이콘은 FaArchive, 타이틀은 'Archive',
#️⃣아이디는 uuid 이용해서 유니크하게 주기 위해 v4( )

Trash도 똑같이 작성해주면 됨🙆‍♀️

items 이용해서 만들어주면 됨
items.map 이용해서 (( 여기서 객체 icon, title, id ) 받아오고

사이드바에 Archive 누르면 /archive로 가고
Trash 클릭하면 /trash로 가게 해야함

state={ title } 해주고 classNameisActive로 넣어서
isActive"active-item" 아니면 "inactive-item"

이렇게 다 잘 만들어진 것을 확인할 수 있음👀

클릭했을 때 해당 경로로 잘 가고 Edit Notes 클릭하면 true로 잘 반영은 되지만
🖱눌렀을 때 사이드바가 없어져야하는데 그럴려면 어떻게 해줘야할까❓

🖱클릭했을 때 isOpen: false로 해서 사이드바 사라지게 하기

그러기 위해 menuSlice 에서 이걸 이용하면 됨✔

이젠 사이드 바에서 원하는 거 클릭하면 사이드바가 없어지는 걸 확인 할 수 있음👀

🖱Edit Notes 클릭하면 isOpen: true 되고 모달창 열게하기

🤷‍♀️모달 보여주는 건 어떻게 하는걸까❓

우선 이걸 보여주기 위해서

▫ src>App.jsx

App.jsx로 가서 TagsModal를 여기다 넣어주고 실행화면 보면 저렇게 되어있을 것

근데 TagsModal은 언제만 보여줘야하냐면 viewEditTagsModaltrue일 때만 보여줘야함

useSelector 이용해서 가져오자➡state 하고 state.modal 🔥
const { 구조분해할당 } 해서 viewEditTagsModal을 가져옴

viewEditTasModaltrue일 때 TagsModal을 렌더링 하게 해줌

첨엔 없는데

햄버거바 클릭하면 사이드바가 나오고 Edit Notes 클릭하면

TagsModal이 나오는 걸 볼 수 있음👀

그리고 이 TagsModal 같은 경우엔

여기에서도 사용되고

여기서도 사용되고 있음

ADD TagsEdit Tags는 조금 달랐음
둘 다 TagsModal 이라는 컴포넌트를 사용할 것✔

이거의 typeedit 이라고 넣어주면 됨

edit을 이용해서 조금 다른 UI랑 로직을 처리하면 되기 때문😎

그런 담에 TagsModal로 이동하기🌫🐱‍🏍

▫ src>components>Modal>TagsModal>TagsModal.jsx

FixedContainerTagsModal을 감싸주고

▫ src>components>Modal>Modal.styles.js

모달의 공통적인 스타일은 Modal.styles.js 에서 만들어줄거임

원랜 TagsModal 에서 만들어주려고 했는데
여기다 넣어주고 외부에서 사용할거니까 export로 내보내주기🥏

햄버거바 클릭 Edit Notes 클릭하면 나오는 모달창을 위한 스타일링👩‍🎨

이거처럼 만들어보자❗

하얀색 둘러싸는 부분 만들어야함
모달마다 DeleteBox( ✖ ) 이부분은 같지만
하얀색 부분은 모달마다 다르기 때문에

이건 TagsModal로 돌아와서 여기에서 만들어줄것🙆‍♀️

▫ src>components>Modal>TagsModal>TagsModal.jsx

이렇게 하고 Box를 이용해서 저렇게 감싸줄거임

여기 보면 Edit | ADD Tags가 될 것✔

App.jsx 에서 type을 넣어줬었는데

TagsModaltype을 받아와서 type'add' 이면 "Add" 아니면 "Edit"

Edit Tags 라고 잘 나오는 걸 볼 수 있음👀

💁‍♀️Edit Tags ✖ 누르면 모달창 없어지게 하기

이제 Edit Tags 옆에 있는 ✖ 이부분 해줄것

이렇게 아이콘 ✖ 이 잘 뜸

🖱onClick : ✖ 누르면 해당 모달이 없어지게 해줄거임🗑

useDispatch 이용해서 dispatch 하고 ( 여기서 뭐를 해줘야할까❓ )

modalSlice.js 에서 만들어놓은 toggleTagsModal
view 에다가 false를 넣어줘야함👌

onClick={() => dispatch(toggleTagsModal({ type, view: false }))}

✖ 누르면 모달창 닫아짐 ❗

Edit Tags input 창 만들기

🎈Edit Tags 나열해주는 부분 만들기

이부분은 form 태그 아래 에다가 만들어주면됨

스타일 컴포넌트 만들어주기

TagsBox 하고 나열하려면 어떤 데이터가 필요할까❓

👉 tagsList 다 가져와야함❗

useSelector 해서 state.tags 하고
tags 안에 있는 tagsList를 가져올거니까➡{ tagsList }

🗺 tagsList.map을 이용해서 나열하기

tagid만 직접 가져오고 li 태그 사용해서 key={id} 해주기

<div className='editTags__tag'>
  {getStandardName(tag)}
</div>

태그의 이름을 대문자로 시작할 수 있게 하려면
👉 getStandarName 함수에다가 tag를 넣어주면 됨✨

태그 이름의 옆엔 ✖버튼을 넣어주면 됨 ( FaTimes 아이콘 )

이런식으로 되어있어서 스타일링 하러 가자❗

👩‍🎨Edit Tags 모달 스타일링 해주기

Box

const Box = styled.div`
	// 최소 250px, 최대 280px 사이에서 60% 값을 적용
	width: clamp(250px 60%, 280px);
	// 화면 높이의 85%까지 최대 높이 제한
	max-height: 85vh;
	// 내용이 넘칠 때만 세로 스크롤이 생김
	overflow-y: auto;
	background-color: white;
	color: black;
	border-radius: 5px;
	padding: 15px 20px;
	
	.editTags__header {
		display: flex;
		justify-content: space-between;
		align-items: center;
		
		.editTags__title {
			font-weight: 500;
			font-size: 1.3rem;
		}
		
		.editTags__close {
			svg {
				font-size: 1.6rem;
			}
		}
	}
	
	form {
		width: 100%;
		display: flex;
		align-items: center;
		justify-content: space-between;
		height: 30px;
		margin: 30px 0;
	}
`

StyledInput

const StyledInput = styled.input`
	height: 100%;
	width: 100%;
	border: none;
	border-bottom: 1px solid black;
	// border 변화가 150ms 동안 천천히 시작되며 변경
	transition: 150ms border ease-in;
	font-size: 1rem;
	font-weight: 500;
	
	$:focus {
		border-bottom: 2px solid black;
	}

	&::placeholder {
		color: rgba(0, 0, 0, 0.3);
	}
`

TagsBox

const TagsBox = styled.div`
	li {
		display: flex;
		align-items: center;
		justify-content: space-between;
		font-size: 1.2rem;
		height: 30px;
		margin-bottom: 10px;
	}
`

DeleteBox는 모든 모달에 있는거라서 Modal.styled.js 에다가 만들어놨음🆗

▫ src>components>Modal>Modal.styles.js

svg {
  font-size: 1.2rem;
  color: rgba(0, 0, 0, 0.5);
  // transform 변화는 0.25초 동안 부드럽게 (ease-in-out) 진행
  // color 변화는 0.2초 동안 부드럽게 (ease-in-out) 진행
  transition: 250ms transform ease-in-out, 200ms color ease-in-out;
  
  &:hover {
    transform: scale(1.15);
    color: rgba(0, 0, 0, 0.8);
  }
}
`;

hover➡ransform: scale(1.15) 해줘서 호버 시 이렇게 됨 ( 15% 크게 )

스타일링 완성👍

🙋‍♀️Edit Tags input 입력한 값 넣어주기

input 창에 타이핑한 걸 넣어줘야함
그리고 엔터누르면 추가가 되게 해줘야 함⚡

StyledInput 여기다가 어떤 걸 타이핑 한 담에
엔터누르면 tagsList 에다가 추가되면 됨😎

🤷‍♀️이 기능을 어떻게 만들면 될까❓
⌨우선 타이핑한 걸 컴포넌트에서 기억하고 있어야됨🧠

▫ src>components>Modal>TagsModal>TagsModal.jsx

이건 이 컴포넌트에서만 기억하고 있으면 되니까
useState 이용해서 state 만들어주기

바로 valueinputText 넣어주면 됨✔

⌨ 타이핑할 때마다 변경해야하니까➡onChange 🔄

이렇게 타이핑하고 엔터누르면

이렇게 됨 🥴 ...

onSubmit 으로 폼 안에서 처리해야함❗

e.preventDefault( ) 해줘야 페이지 새로고침 해도 초기화 안 됨🔥

엔터눌러도 페이지 리플레쉬 안 되는 걸 볼 수 있음👀

아무것도 타이핑 안 한 상태에서 엔터 눌렀다고 해서
tagsList 안에 추가 되면 안되기 때문에 조건 넣어준 것🤓
⌨ 타이핑 했을 때만 진행 될 수 있게 해주는거임 ✔

그리고 마지막엔 setInputText를 초기화 해주기

✍여기서 해줘야할게 타이핑한 걸 여기에 추가해주는 로직 작성할거임

▫ src>store>tags>tagsSlice.js

tagsSlice.js 여기서 처리해줘야함⭕

여기다 하나를 추가해주는 것

이름을 addTags 라고 해줄거임
먼저 가져오는게 state, 그리고 action 가져오는데 바로 { payload } 가져올것🙃

만약, work 라는 tag가 이미 있는데
input에 또 work 라고 작성하면 안 되기 때문에 조건 처리 해주자💪

✅이 로직을 먼저 한 담에 작성한 게 없는 애면 그때 새로운 tag를 넣어주면 됨

🔍find ( 주로 뭐를 찾을 땐 find 메소드 사용, 배열을 위한 메소드니까 순회할 것 )

하나하나 순회할 때마다 여기서 가져다주는 건 뭘까❓
👉 당연히 tagsList 안에 들어있는 객체 🧩

🎭 tag 객체 안에 2개의 프로퍼티 - { tag, id }
🔖 tag : 태그의 이름, #️⃣ id : 유니크한 값

🔖여기에서 실제 필요한 건 id는 필요없고 tag( 태그의 이름 )만 필요🙆‍♀️

id는 빼고 tag랑 새롭게 넣으려고 하는
태그의 이름( payload 안에 있는 tag의 이름 )과 같으면 여기엔 안 된다고 하면 됨🙅‍♀️

Coding 이라고 이미 있는데 coding 이라고 input 창에 치면
"이미 존재하는 태그입니다." 이렇게 나오게 할 것 ❗

state.tagsList.push( payload( 태그의 객체 ) )
여기선 불변성 안 지켜줘도 돼서 push 사용해도 됨✔

addTags 만든김에 ✖눌러서 지우는 것도 구현해보자

state.tagsList 에서 지우는거니까 filter 메소드 사용해서
🧩 객체 안에 있는 태그의 id만 가져옴➡{ id }

addTags & deleteTags 내보내주기🥏

다시 TagsModal로 돌아가기

▫ src>components>Modal>TagsModal>TagsModal.jsx

🗣타이핑하고 엔터눌렀을 때 호출돼야하는 부분📢

추가해줘야하니까 dispatch 하고 tagsSlice 에서 만들어준
addTags 한 담에 payload로 넣어줘야하는게 태그 객체👌

태그 객체엔 어떤게 필요하냐면 { 태그의 이름과 아이디가 필요⭕ }

idv4( ), tag의 이름은 타이핑한 값인데

타이핑한 값은 inputText니까➡inputText
근데 이거 소문자로 바꿔서 넣어줄 것
타이핑할 때 E 대문자로 넣었으면 e 소문자로 해주게 하기

타이핑 대문자 넣어도

첫글자 빼고 나머지 소문자로 되고 리스트에 추가 된 것을 확인할 수 있음👀

...

📒 4탄 다음 벨로그

profile
안녕하세요! 퍼블리싱 & 프론트엔드 개발 공부 블로그 입니다!

0개의 댓글