Closed rkdcodus closed 2 months ago
styles ์ ๋ ๊ฒฝ๋ก์ s๊ฐ ๋น ์ ธ์๋ ์คํ๊ฐ ์์ด ์์ ํ์ต๋๋ค.
ํผ๊ทธ๋ง์ sementic background ํ๋๊ฐ bg๋ก ๋์ด์์ด background -> bg ๋ก ์์ ํ์ต๋๋ค.
background -> bg
svg ์ฌ์ฉ์ด ๋ง์ ๊ฒ์ผ๋ก ์์๋ฉ๋๋ค. svgํ์ผ๊ณผ png ํ์ผ์ ๋ถ๋ฆฌํ๊ธฐ ์ํด assets์ svg, image ํด๋๋ฅผ ์์ฑํด๋์๊ณ @svg, @image ์ ๋ ๊ฒฝ๋ก๋ฅผ ์ง์ ํด์ฃผ์์ต๋๋ค.
@svg, @image
svg๋ ์๋์ฒ๋ผ importํ๋ฉด ์ปดํฌ๋ํธ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
import { ReactComponent as LogoSVG } from '@svg/logo.svg'; ... <LogoSVG />
์ด๋ ๊ฒ ์ปดํฌ๋ํธ๋ก ์ฌ์ฉํ๊ฒ ๋๋ฉด svg์ ์ต๋ ์ฅ์ ์ธ ์์, ํฌ๊ธฐ ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํฉ๋๋ค. ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ์ ์ฐธ๊ณ ๋ธ๋ก๊ทธ ๋งํฌ ๋ฌ์๋๊ฒ ์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก img ํ๊ทธ์ src ๊ฒฝ๋ก๋ก ์ง์ ๋ ๊ฐ๋ฅํฉ๋๋ค. ์ด ๋ฐฉ๋ฒ์ svg ์ด๋ฏธ์ง์ ์์ ๋ณ๊ฒฝ์ด ๋ถ๊ฐํฉ๋๋ค.
import avatarBg from '@svg/avatarBg.svg'; ... <img src={avatarBg}></img>
ํ์ ์คํฌ๋ฆฝํธ์์ svg ์ด๋ฏธ์ง๋ฅผ ReactComponent๋ก ์ฌ์ฉํ๊ธฐ ์ํด costom.d.ts ํ์ผ์ ๋ง๋ ๋ค tsconfig.json์ includes์ ์ถ๊ฐํด์ฃผ์์ต๋๋ค. ๋ํ, svg๋ฅผ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ก ๋ณํ์์ผ์ฃผ๋ svgr๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค. CRA๋ก ๋ฆฌ์กํธ์ฑ์ ์์ฑํ๋ค๋ฉด ์๋ ์ค์ ๋์ด์์ง๋ง, ์๋์ผ๊ธฐ ์ฒ๋ผ Vite๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ, ์ง์ ์ค์ ํด์ฃผ์ด์ผํฉ๋๋ค. ๋๋ฌธ์ @svgr/rollup๋ฅผ ์ค์นํด์ฃผ์์ต๋๋ค.
svgr
CRA
Vite
@svgr/rollup
ํผ๊ทธ๋ง ๋์์ธ์ interaction๋ถ๋ถ(hover, focus ๋ฑ)์ ๋ ์ด์ด์ฒ๋ผ ์์์ผ ํ๋ ๊ตฌ์กฐ๋ก ๋์ด์์ต๋๋ค. ์ด๋ฅผ ๊ตฌํํ๊ธฐ ์ํด ButtonWrapper์ Interaction ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ์ต๋๋ค. Interaction์ ํผ๊ทธ๋ง์ ๋ง๋ค์ด์ง ๊ฒ๊ณผ ๊ฐ์ด Interaction1, Interaction2, Interaction3, Interaction4๋ก ๊ตฌ์ฑ๋์ด์์ต๋๋ค.
Interaction1, Interaction2, Interaction3, Interaction4
onClick
topRadius
bottomRadius
<ButtonWrapper> // Interaction์ ์ํ๋ ์์๋ฅผ ๊ฐ์ธ๋ ๊ฒ์ด ์๋ ๊ทธ๋ฅ ์์ ์์น. <Interaction1 onClick={ํจ์} topRadius={8} bottomRadius={8} /> <LoginBtn>๋ก๊ทธ์ธ</LoginBtn> </ButtonWrapper>
Interaction์ ์ฌ์ฉํ๊ณ ์ ํ ๋๋ ButtonWrapper๋ก ๊ฐ์ธ์ค ํ ์ธํฐ๋์ ์ด ํ์ํ ์ปดํฌ๋ํธ ์์ ๊ฑธ์ด์ฃผ์๋ฉด ๋ฉ๋๋ค.
ButtonWrapper
ํค๋์ ๋ฉ๋ด๋ฐ ์ธ์๋ ์ฌ๋ฌ ์ค์ ๋ฐ์ ๊ฐ์ด ์ฐ๊ธฐ ์ํด Menu ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ์ต๋๋ค. ๋ฉ๋ด๋ฐ์ ๋ค์ด๊ฐ๋ ํ๋์ ๋ฉ๋ด ์ปดํฌ๋ํธ ์ ๋๋ค.
link
text
svg
line
link, onClick, line, topRadius, bottomRadius์ ์๋ต ๊ฐ๋ฅํฉ๋๋ค.
Menus๋ Menu๋ฅผ ๊ฐ์ธ๋ Container ์ญํ ์ ํ๋ ์ปดํฌ๋ํธ์ ๋๋ค.
toggle
<Menus toggle={toggle}> <Menu link={'/mypage'} text={'๋ง์ดํ์ด์ง'} svg={person} line={4} topRadius={16}/> <Menu link={'/setting'} text={'์ค์ '} svg={setting} /> <Menu onClick={handleLogout} text={'๋ก๊ทธ์์'} svg={logout} /> <Menu onClick={deleteAccount} text={'ํํด'} svg={person_remove} bottomRadius={16}/> </Menus>
$
// toggle์ด๋ผ๋ ์ปค์คํ ์์ฑ์ ์ฌ์ฉํ Menus ์ปดํฌ๋ํธ const Menus = ({ children, toggle }: MenusProps) => { return <MenusContainer $toggle={toggle}>{children}</MenusContainer>; }; const MenusContainer = styled.div<{ $toggle: boolean }>` height: ${props => (props.$toggle ? 'auto' : '0px')}; ... `;
styled component ๋ฅผ ์ฌ์ฉํ ๋ topRadius, bottomRadius, toggle์ ๊ฐ์ ์ปค์คํ ์์ฑ์ HTML DOM์์ ์ธ์ํ์ง ๋ชปํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก styled-component๋ ๋ชจ๋ ์ปค์คํ ์์ฑ์ HTML ์์ฑ์ผ๋ก ์ ๋ฌํ๋ค๊ณ ํฉ๋๋ค. ํ์ง๋ง React props ๋ก ์ ๋ฌ ๋๊ฑฐ๋, DOM ์์๋ก ๋ ๋๋ง ๋์ง ์๋๋ก ๊ธฐํธ($)๋ฅผ prefix๋ก ๋ถ์ด๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ณ ์์ด ์ด๋ฅผ ์ด์ฉํด ๊ฒฝ๊ณ ๋ฌธ์ ํด๊ฒฐํ ์ ์์ต๋๋ค.
[React] SVG ํ์ฉ๋ฒ React์์ svgํ์ผ ์ฌ์ฉํ๋ ๋ฒ (create-react-app)
vite ํ๊ฒฝ์์ svg๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ํ๊ฒฝ ์ค์ ํ์ ์คํฌ๋ฆฝํธ ์์์ svg ํ์ผ์ ์ปดํฌ๋ํธ๋ก์ importํ ๋ ๋ฌธ์ ]
Warning: Received "true" for a non-boolean attribute ํด๊ฒฐํ๊ธฐ
๋ณ๊ฒฝ ์ฌํญ์ ๋ํ ์คํฌ๋ฆฐ์ท์ด ์๋ค๋ฉด ์ฒจ๋ถํด์ฃผ์ธ์.
์ด์ ๋ฒํธ: Close #165
โ ์ฒดํฌ๋ฆฌ์คํธ
๐ ์์ ์์ธ ๋ด์ฉ
1๏ธโฃ ์คํ์ผ ์ ๋ ๊ฒฝ๋ก ๋ฐ sementic ํ๋กํผํฐ ์ด๋ฆ ๋ณ๊ฒฝ
styles ์ ๋ ๊ฒฝ๋ก์ s๊ฐ ๋น ์ ธ์๋ ์คํ๊ฐ ์์ด ์์ ํ์ต๋๋ค.
ํผ๊ทธ๋ง์ sementic background ํ๋๊ฐ bg๋ก ๋์ด์์ด
background -> bg
๋ก ์์ ํ์ต๋๋ค.2๏ธโฃ @svgr/rollup ์ค์น ๋ฐ svg, image ์ ๋ ๊ฒฝ๋ก ์ค์
svg ์ฌ์ฉ์ด ๋ง์ ๊ฒ์ผ๋ก ์์๋ฉ๋๋ค. svgํ์ผ๊ณผ png ํ์ผ์ ๋ถ๋ฆฌํ๊ธฐ ์ํด assets์ svg, image ํด๋๋ฅผ ์์ฑํด๋์๊ณ
@svg, @image
์ ๋ ๊ฒฝ๋ก๋ฅผ ์ง์ ํด์ฃผ์์ต๋๋ค.svg ์ด๋ฏธ์ง ์ฌ์ฉ๋ฒ
svg๋ ์๋์ฒ๋ผ importํ๋ฉด ์ปดํฌ๋ํธ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ์ปดํฌ๋ํธ๋ก ์ฌ์ฉํ๊ฒ ๋๋ฉด svg์ ์ต๋ ์ฅ์ ์ธ ์์, ํฌ๊ธฐ ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํฉ๋๋ค. ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ์ ์ฐธ๊ณ ๋ธ๋ก๊ทธ ๋งํฌ ๋ฌ์๋๊ฒ ์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก img ํ๊ทธ์ src ๊ฒฝ๋ก๋ก ์ง์ ๋ ๊ฐ๋ฅํฉ๋๋ค. ์ด ๋ฐฉ๋ฒ์ svg ์ด๋ฏธ์ง์ ์์ ๋ณ๊ฒฝ์ด ๋ถ๊ฐํฉ๋๋ค.
svg๋ฅผ ์ปดํฌ๋ํธ๋ก ์ด์ฉํ๊ธฐ ์ํด์
ํ์ ์คํฌ๋ฆฝํธ์์ svg ์ด๋ฏธ์ง๋ฅผ ReactComponent๋ก ์ฌ์ฉํ๊ธฐ ์ํด costom.d.ts ํ์ผ์ ๋ง๋ ๋ค tsconfig.json์ includes์ ์ถ๊ฐํด์ฃผ์์ต๋๋ค. ๋ํ, svg๋ฅผ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ก ๋ณํ์์ผ์ฃผ๋
svgr
๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค.CRA
๋ก ๋ฆฌ์กํธ์ฑ์ ์์ฑํ๋ค๋ฉด ์๋ ์ค์ ๋์ด์์ง๋ง, ์๋์ผ๊ธฐ ์ฒ๋ผVite
๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ, ์ง์ ์ค์ ํด์ฃผ์ด์ผํฉ๋๋ค. ๋๋ฌธ์@svgr/rollup
๋ฅผ ์ค์นํด์ฃผ์์ต๋๋ค.3๏ธโฃ ButtonWrapper/Interaction ๊ณต์ฉ ์ปดํฌ๋ํธ ์์ฑ
ํผ๊ทธ๋ง ๋์์ธ์ interaction๋ถ๋ถ(hover, focus ๋ฑ)์ ๋ ์ด์ด์ฒ๋ผ ์์์ผ ํ๋ ๊ตฌ์กฐ๋ก ๋์ด์์ต๋๋ค. ์ด๋ฅผ ๊ตฌํํ๊ธฐ ์ํด ButtonWrapper์ Interaction ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ์ต๋๋ค. Interaction์ ํผ๊ทธ๋ง์ ๋ง๋ค์ด์ง ๊ฒ๊ณผ ๊ฐ์ด
Interaction1, Interaction2, Interaction3, Interaction4
๋ก ๊ตฌ์ฑ๋์ด์์ต๋๋ค.props
onClick
?: ์์์ onClick ํจ์ ๋๊ฒจ์ค. ์๋ต ๊ฐ๋ฅtopRadius
?: ์์์ border-top-right/left-radius ์ค์ ๊ฐ๋ฅ. ๊ธฐ๋ณธ๊ฐ์ 0px. ์๋ต ๊ฐ๋ฅbottomRadius
?: ์์์ border-bottom-right/left-radius ์ค์ ๊ฐ๋ฅ.๊ธฐ๋ณธ๊ฐ์ 0px. ์๋ต ๊ฐ๋ฅ.์ฌ์ฉ ์์
Interaction์ ์ฌ์ฉํ๊ณ ์ ํ ๋๋
ButtonWrapper
๋ก ๊ฐ์ธ์ค ํ ์ธํฐ๋์ ์ด ํ์ํ ์ปดํฌ๋ํธ ์์ ๊ฑธ์ด์ฃผ์๋ฉด ๋ฉ๋๋ค.4๏ธโฃ Menu/Menus ์ปดํฌ๋ํธ ์์ฑ
Menu ์ปดํฌ๋ํธ
ํค๋์ ๋ฉ๋ด๋ฐ ์ธ์๋ ์ฌ๋ฌ ์ค์ ๋ฐ์ ๊ฐ์ด ์ฐ๊ธฐ ์ํด Menu ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ์ต๋๋ค. ๋ฉ๋ด๋ฐ์ ๋ค์ด๊ฐ๋ ํ๋์ ๋ฉ๋ด ์ปดํฌ๋ํธ ์ ๋๋ค.
props
link
?: ๋ฉ๋ด ์์ ํด๋ฆญ ์, ์ด๋ํ๊ธฐ ์ํจ.onClick
?: ๋ฉ๋ด ์์ ํด๋ฆญ์, ์ด๋ฒคํธ ๋ฐ์์ํค๊ธฐ ์ํจ.text
: ๋ฉ๋ด ์ด๋ฆsvg
: ๋ฉ๋ด ์์ด์ฝline
?: ๋ฉ๋ด ๋ฐ ๋ผ์ธ(divider) ๊ตต๊ธฐ ์ค์ topRadius
?: top border radius ์ค์ ( ์ ์ผ ์ฒ์ ๋ฉ๋ด ์์๋ topRadius ์ค์ )bottomRadius
?: bottom border radius ์ค์ ( ์ ์ผ ๋ง์ง๋ง ๋ฉ๋ด ์์๋ bottomRadius ์ค์ )link
,onClick
,line
,topRadius
,bottomRadius
์ ์๋ต ๊ฐ๋ฅํฉ๋๋ค.Menus ์ปดํฌ๋ํธ
Menus๋ Menu๋ฅผ ๊ฐ์ธ๋ Container ์ญํ ์ ํ๋ ์ปดํฌ๋ํธ์ ๋๋ค.
props
toggle
: ์ธ์ ๋ฉ๋ด๋ฐ๋ฅผ ์ด๊ณ ๋ซ์์ง boolean๊ฐ์ ๋ฐ๋ผ ๋ฉ๋ด๋ฐ๊ฐ ์ด๊ณ ๋ซํ.์ฌ์ฉ์์
๐ก (์ถ๊ฐ)
styled props ์์
$
prefix ๋ฌ๊ธฐstyled component ๋ฅผ ์ฌ์ฉํ ๋
topRadius
,bottomRadius
,toggle
์ ๊ฐ์ ์ปค์คํ ์์ฑ์ HTML DOM์์ ์ธ์ํ์ง ๋ชปํฉ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก styled-component๋ ๋ชจ๋ ์ปค์คํ ์์ฑ์ HTML ์์ฑ์ผ๋ก ์ ๋ฌํ๋ค๊ณ ํฉ๋๋ค. ํ์ง๋ง React props ๋ก ์ ๋ฌ ๋๊ฑฐ๋, DOM ์์๋ก ๋ ๋๋ง ๋์ง ์๋๋ก ๊ธฐํธ($)๋ฅผ prefix๋ก ๋ถ์ด๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ณ ์์ด ์ด๋ฅผ ์ด์ฉํด ๊ฒฝ๊ณ ๋ฌธ์ ํด๊ฒฐํ ์ ์์ต๋๋ค.๐จ ๋ฒ๊ทธ ๋ฐ์ ์ด์ (์ ํ ์ฌํญ)
๐ ํ์ ์์ (์ ํ ์ฌํญ)
๐ค ์ง๋ฌธ ์ฌํญ (์ ํ ์ฌํญ)
๐ ์ฐธ๊ณ ์๋ฃ (์ ํ ์ฌํญ)
[React] SVG ํ์ฉ๋ฒ React์์ svgํ์ผ ์ฌ์ฉํ๋ ๋ฒ (create-react-app)
vite ํ๊ฒฝ์์ svg๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ํ๊ฒฝ ์ค์ ํ์ ์คํฌ๋ฆฝํธ ์์์ svg ํ์ผ์ ์ปดํฌ๋ํธ๋ก์ importํ ๋ ๋ฌธ์ ]
Warning: Received "true" for a non-boolean attribute ํด๊ฒฐํ๊ธฐ
๐ธ ์คํฌ๋ฆฐ์ท (์ ํ ์ฌํญ)
๋ณ๊ฒฝ ์ฌํญ์ ๋ํ ์คํฌ๋ฆฐ์ท์ด ์๋ค๋ฉด ์ฒจ๋ถํด์ฃผ์ธ์.
โ ์ ํ ์ฒดํฌ๋ฆฌ์คํธ
์ด์ ๋ฒํธ: Close #165