본문 바로가기

토이프로젝트/programmerGround

programmerGround 다크모드 구현(2021.02.11 ~ 2021.02.12)

반응형

안녕하세요! 새콤하고달콤입니다.

오늘은 다크모드 구현과정을 설명하려고 합니다.

 

1. 다크모드를 위한 뼈대를 마련

 

 

 

검색창 옆에 다크모드를 구현하기 위해서 간단한 UI를 작성해보았습니다.

 

import React from 'react';
import * as StyledComponent from './style';

const Bone = () => {
	return (
		<StyledComponent.BoneContainer>
			<StyledComponent.BoneMoveContainer />
		</StyledComponent.BoneContainer>
	);
};

export default Bone;
/* eslint-disable import/prefer-default-export */
import styled from 'styled-components';

export const BoneContainer = styled.div`
	position: relative;
	width: 50px;
	height: 30px;
	margin-top: 5px;
	margin-bottom: 5px;
	background-color: #d9dfe2;
	border-radius: 50px;
	border: 1px solid #d9dfe2;
`;

 

export const BoneMoveContainer = styled.div`
	width: 28px;
	height: 30px;
	cursor: pointer;
	border-radius: 50px;
	background-color: #fff;
	position: absolute;
`;

 

2. 다크모드 라이트모드에 해당되는 색상을 타입으로 지정해주었습니다.

/* eslint-disable import/prefer-default-export */
interface colorType {
	body: string;
	fontColor: string;
}

export const lightTheme: colorType = {
	body: '#fff',
	fontColor: '#000',
};

export const darkTheme: colorType = {
	body: '#000',
	fontColor: '#fff',
};

 

다크모드를 구현하기 위해서는 localstorage의 도움이 필요했습니다.

localstorage에 저장해야 새로고침 혹은 페이지 이동 시 저장된 상태값에 따라서 렌더링이 가능하기 때문입니다.

 

아직 새로고침할 때, 변화는 적용하지는 않았습니다..(조만간 구현 예정)

 

1. useState를 이용해서 light인지 dark인지 값을 저장하는 상태를 구현하였습니다.

2. darkMode가 light이면 dark로 dark면 light로 바꿔주었습니다.

3. documentElement에 값을 저장하였습니다.

import React, { useState, useEffect } from 'react';
import * as StyledComponent from './style';

const Bone = () => {
	const [darkMode, setDarkMode] = useState('light');

	const modeChange = () => {
		if (darkMode === 'light') {
			setDarkMode('dark');
			localStorage.setItem('color-theme', 'dark');
			document.documentElement.setAttribute('color-theme', 'dark');
		} else if (darkMode === 'dark') {
			setDarkMode('light');
			localStorage.setItem('color-theme', 'light');
			document.documentElement.setAttribute('color-theme', 'light');
		}
	};

	return (
		<StyledComponent.BoneContainer onClick={modeChange}>
			{darkMode === 'light' ? (
				<StyledComponent.BoneMoveContainer
					// eslint-disable-next-line react/jsx-indent-props
					onClick={modeChange}
				/>
			) : (
				<StyledComponent.BoneMoveDarkContainer onClick={modeChange} />
			)}
		</StyledComponent.BoneContainer>
	);
};

export default Bone;

 

- root에 color-theme 속성을 부여함으로서, 버튼을 클릭할 때마다 반영하도록 구현하였습니다.

/* eslint-disable import/prefer-default-export */
import { createGlobalStyle } from 'styled-components';

export const GlobalStyle = createGlobalStyle`
  body{
    margin:0;
    padding:0;
  }
  :root[color-theme='light'] {
    --background: #fff;
    --color: #000;
  }
  
  :root[color-theme='dark'] {
    --background: #000;
    --color: #fff;
  }
  
  html {
    background: var(--background);
    color:var(--color);
  }
  
`;
반응형