새로고침 할 때마다 잠깐동안 <MainNavigation>
컴포넌트의 레이아웃이 변경됐다가 돌아오는 현상이 있었는데, 자세히 보니 이미지가 뒤늦게 불러와지고 있었다. 그래서 이미지 소스를 가져오기 전에도 레이아웃을 유지하기 위해 <img>
태그의 부모 요소로 <div>
태그를 추가해 width 속성을 추가했다. 이를 위해 <Button>
컴포넌트와 <MainNavigation>
컴포넌트를 수정했다.
<Button>
컴포넌트에는 2개의 props가 더 추가됐다.
iconWidth
: img 태그를 감싸는 div 요소에 적용될 widthiconWithText
: 이미지 + 텍스트 조합의 버튼, 하위 태그 클래스(.icon-with-text)로 적용하던 속성을 props로 변경함src/components/ui/Button.js
import styled, { css } from "styled-components";
const colorStyles = css`
${({ theme, background, color }) => {
const selectedBg = theme.palette[background];
const selectedColor = theme.palette[color];
return css`
background: ${selectedBg};
color: ${selectedColor};
`;
}}
`;
const sizes = {
large: {
height: "3rem",
fontSize: "1.25rem"
},
medium: {
height: "2.875rem",
fontSize: "1rem"
},
small: {
height: "1.75rem",
fontSize: "0.875rem"
}
};
const sizeStyles = css`
${({ size }) => css`
height: ${sizes[size].height};
font-size: ${sizes[size].fontSize};
`}
`;
const fullWidthStyle = css`
${({ fullWidth }) =>
fullWidth &&
css`
width: 100%;
justify-content: center;
`}
`;
const StyledButton = styled.button`
display: inline-flex;
align-items: center;
font-weight: ${({ theme }) => theme.fontWeight.semiBold};
outline: none;
border: none;
border-radius: 5px;
${({ radius }) =>
radius === "bottom" &&
css`
border-top-left-radius: 0px;
border-top-right-radius: 0px;
`}
padding-right: 0.875rem;
padding-left: 0.875rem;
${({ marginTop }) =>
marginTop &&
css`
margin-top: ${marginTop};
`}
${colorStyles}
${sizeStyles}
${({ outline }) =>
outline &&
css`
border: 1px solid black;
`}
${({ noPadding }) =>
noPadding &&
css`
padding: 0rem;
`}
${fullWidthStyle}
> div:first-child {
display: flex;
${({ iconWidth }) =>
iconWidth &&
css`
width: ${iconWidth};
`}
${({ iconWithText }) =>
iconWithText &&
css`
margin-right: 6px;
`}
}
`;
function Button({
children,
background,
color,
size = "medium",
outline,
noPadding,
fullWidth,
marginTop,
radius,
iconWidth,
iconWithText
}) {
return (
<StyledButton
background={background}
color={color}
size={size}
outline={outline}
noPadding={noPadding}
fullWidth={fullWidth}
marginTop={marginTop}
radius={radius}
iconWidth={iconWidth}
iconWithText={iconWithText}
>
{children}
</StyledButton>
);
}
export default Button;
어플리케이션 로고 등을 가져오기 위해 사용되는 <img>
태그를 <div>
태그로 감싸고 width를 지정해줬다.
수정 후
import styled, { css } from "styled-components";
import Button from "./UI/Button";
const Header = styled.header`
position: sticky;
top: 0;
width: 100%;
height: 72px;
display: flex;
align-items: center;
padding-right: 1.5rem;
padding-left: 1.5rem;
border-bottom: 1px solid black;
background: white;
> .ddip-logo {
width: 94px;
display: flex;
}
> .search-box {
height: 46px;
flex-grow: 1;
display: flex;
align-items: center;
padding-right: 0.875rem;
padding-left: 0.875rem;
margin-right: 1.5rem;
margin-left: 1.5rem;
border: 1px solid black;
border-radius: 5px;
font-size: 0.875rem;
> .search-icon {
width: 14px;
margin-right: 6px;
}
}
> .right-buttons {
display: flex;
> .auth-buttons {
display: flex;
align-items: center;
margin-left: 16px;
> .user-icon {
width: 46px;
display: flex;
}
> hr {
width: 1px;
height: 12px;
margin: 8px;
}
}
}
${({ logoOnly }) =>
logoOnly &&
css`
justify-content: center;
background: inherit;
`}
${({ noSearchBox }) =>
noSearchBox &&
css`
justify-content: space-between;
`}
`;
function MainNavigation({ logoOnly, noSearchBox, loggedIn }) {
if (logoOnly) {
return (
<Header logoOnly={logoOnly}>
<div className="ddip-logo">
<img className="logo" src="/images/logo.svg" alt="ddip-logo" />
</div>
</Header>
);
}
return (
<Header noSearchBox={noSearchBox}>
<div className="ddip-logo">
<img src="/images/logo.svg" alt="ddip-logo" />
</div>
{!noSearchBox && (
<div className="search-box">
<div className="search-icon">
<img src="/images/search.svg" alt="search" />
</div>
<span>어떤 번개를 찾으시나요?</span>
</div>
)}
<div className="right-buttons">
<Button
background="mainViolet"
color="white"
iconWidth="16px"
iconWithText
>
<div>
<img src="/images/thunder.svg" alt="thunder" />
</div>
<span>번개 만들기</span>
</Button>
<div className="auth-buttons">
{loggedIn ? (
<div className="user-icon">
<img src="/images/user.svg" alt="user" />
</div>
) : (
<>
<Button noPadding>회원가입</Button>
<hr />
<Button noPadding>로그인</Button>
</>
)}
</div>
</div>
</Header>
);
}
export default MainNavigation;