
우리회사는 RN이나 플러터를 사용하지않고 리액트로 앱을 만든다 ㅇ_ㅇ.
앱은 정말 껍데기만 만들고 대부분을 앱 내에서 하고있다.
운영 때 앱 업데이트를 최대한 줄이고 웹 수정 후 바로 반영할 수 있도록 하기위해서.
그래서 항상 앱 만들때 폰트 크기 고정으로 진행했는데,
이번에 진행하는 곳에서 기획에 폰트 크기 조절기능을 넣어달라고 하셔서..
웹에서 폰트크기를 조절해서 설정에서 폰트크기를 조절할 수 있도록 만들었다.
초반부 코드라 조금 더 다듬어져서 지금화면이랑은 다르긴 하지만
기록용으로 남겨두는 포스팅

우헤헹 (한달에 1번 이상은 기술 블로그를 올리고 싶어서..)
// App.jsx
import createCache from '@emotion/cache'
import { CacheProvider } from '@emotion/react'
import { setDefaultOptions } from 'date-fns'
import { ko } from 'date-fns/locale'
import { SnackbarProvider } from 'notistack'
import { useEffect } from 'react'
import Router from './router'
import { useFontSizeStore } from './status'
import { log } from './tools'
/**
* 애플리케이션의 최상위 컴포넌트입니다.
* 전역 상태 및 설정을 모든 하위 컴포넌트에 제공합니다.
*
* @example
* ReactDOM.render(<App />, document.getElementById('root'))
*/
const App = () => {
const cache = createCache({ key: 'css', prepend: true })
const { fontSize, setFontSize } = useFontSizeStore()
useEffect(() => {
setFontSize(fontSize)
document.documentElement.style.setProperty('--base-font-size', `${fontSize}rem`)
}, [fontSize, setFontSize])
setDefaultOptions({ locale: ko })
log.info('App')
return (
<CacheProvider value={cache}>
<SnackbarProvider
anchorOrigin={{ horizontal: 'center', vertical: 'bottom' }}
autoHideDuration={3000}
dense
maxSnack={2}
preventDuplicate
>
<Router />
</SnackbarProvider>
</CacheProvider>
)
}
export default App
// globalStore.js
import { create } from 'zustand'
import { getLocalStorage, hasLocalStorage, setLocalStorage } from '../../tools'
const keyFontSize = 'FontRatio'
const useFontSizeStore = create((set) => ({
fontSize: hasLocalStorage(keyFontSize) ? getLocalStorage(keyFontSize) : 1,
setFontSize: (size) => {
setLocalStorage(keyFontSize, size)
set({ fontSize: size })
// 스토리지 이벤트 트리거
window.dispatchEvent(
new StorageEvent('storage', { key: keyFontSize, newValue: JSON.stringify(size) })
)
},
refreshFontSize: () => {
const storedFontSize = getLocalStorage(keyFontSize)
set({ fontSize: storedFontSize ? storedFontSize : 1 })
},
}))
// 스토리지 이벤트 리스너 추가
if (typeof window !== 'undefined') {
window.addEventListener('storage', (event) => {
if (event.key === keyFontSize) {
useFontSizeStore.getState().refreshFontSize()
}
})
}
export { useFontSizeStore }
//SettingPage.jsx
...
const FontSizeSlider = ({ action }) => {
const { fontSize, setFontSize } = useFontSizeStore()
const handleChange = (event, newValue) => {
setFontSize(newValue)
document.documentElement.style.setProperty('--base-font-size', `${newValue}rem`)
action
}
return (
<Box>
<T>가</T>
<Slider
onChange={handleChange}
aria-label="fontsize"
value={fontSize}
step={0.25}
min={0.75}
max={2}
valueLabelDisplay="off"
/>
<T>가</T>
</Box>
)
}
FontSizeSlider.propTypes = {
action: PropTypes.func.isRequired, // 필수 함수 Prop
}
...
const SettingPage = () => {
const tag = '[Layout RightSideMenu][SettingPage]'
log.debug(`${tag} `)
const propsButtons = {
ok: {
label: '로그아웃',
},
}
return (
<Container className="SettingPage" component="main">
<Box component="section">
<T component="h1">설정</T>
</Box>
<Box component="section">
{Object.entries(settingConfig).map(([key, list]) => (
<SettingsList key={key} title={STR_SETTING[key]} list={list} />
))}
</Box>
<Buttons {...propsButtons} />
</Container>
)
}
// common.scss
...
:root {
--base-font-size: 1rem;
}
@function dp($n) {
@return calc($n / 16 * var(--base-font-size));
}
...
초반부에는 폰트크기뿐 아니라 요소들에 적용하는 여백이나 다른것들도 같이 묶어놨었는데,
폰트 조절되는 다른 앱들을 보니 폰트사이즈 키운다고 다 커지는게 아니라 어떤건 커지고 어떤부분(테이블, 네비 등)은 키워도 적용이 안되는 어플들이 대부분이라서 좀더 다른 앱 UI들 참고하면서 계속 개선 진행중 ~.~
커진다고 무조건 ...으로 말줄임 표시해버리는 어플들도 있구.. 그냥 안늘어나는 것도 있구.. 하지만 지금 구현중인 어플은 내용이 전체가 다 보이는게 중요해서.. 고민 고민 중
6월 오픈이니까 좀더 다른 레퍼런스들 많이많이 써봐야지..
생각보다 글자크기 선택 없는 어플도 많더라!-!
구현하면서 이유를 느끼게 돼..

반응형
'개발 > Javascript' 카테고리의 다른 글
[Javascript] RTKQ(RTK 쿼리) 에서 세션인증 추가하기 (1) | 2024.09.26 |
---|---|
[Vercel] React - vite 를 사용한 프로젝트에 serverless function 추가하기 (6) | 2024.09.11 |
[React] 카카오톡에 공유하기 기능 추가하기 (0) | 2024.08.29 |
[msw] msw 2.x.x 리액트에서 사용하기 (0) | 2024.06.11 |
[Javascript] React에 Zustand와 TanStack Query 함께 사용하기 (3) | 2024.03.24 |