기본적인 셋팅은 얼추 끝났으니 이제 레이아웃을 만들어주려고 한다.
페이지 윗부분에는 헤더 Navbar, 그리고 페이지 아래에는 고정된 아이콘 바를 만들어주고 싶다.
보통 헤더 Navbar를 보면 왼쪽은 로고, 오른쪽은 메뉴가 위치한다.
flex
에 justify-between
을 사용해서 좌, 우 간격을 벌렸다.
헤더 주변에는 임시로 border를 넣어서 사이즈를 파악하기 쉽게 만들었다.
// components/Header/Header.tsx
import HeaderButton from './HeaderButton';
const Header = () => {
return (
<div className="flex justify-between border-2 border-dashed border-gray-400 px-16 py-8">
<div>LOGO</div>
<div>
<HeaderButton text="menu 1" />
<HeaderButton text="menu 2" />
<HeaderButton text="menu 3" />
</div>
</div>
);
};
export default Header;
// components/Header/HeaderButton.tsx
interface Props {
text: string;
}
const HeaderButton = ({ text }: Props) => {
return <button className="px-4">{text}</button>;
};
export default HeaderButton;
수직 형태의 작은 아이콘 바를 양 옆에 배치해서 왼쪽에는 라이트/다크 모드 전환과 언어 전환 버튼, 오른쪽에는 깃허브, 블로그 등 링크 버튼을 놓고 싶었다.
// components/IconBar/IconBar.tsx
import IconButton from './IconButton';
import VerticalLine from './VerticalLine';
type Direction = 'left' | 'right';
interface Props {
direction: Direction;
icons: string[];
}
const IconBar = ({ direction, icons }: Props) => {
const placement = direction === 'left' ? 'left-16 right-auto' : 'left-auto right-16';
return (
<div className={`w-40px fixed bottom-0 ${placement}`}>
<div className="m-0 flex list-none flex-col items-center p-0">
{icons.map((icon, i) => (
<IconButton key={i} name={icon} />
))}
<VerticalLine />
</div>
</div>
);
};
export default IconBar;
아이콘들은 Icon
폴더에 잘 모아놨다. svg를 사용했기 때문에 컴포넌트를 하나하나 만들어줬는데, 그냥 그림 파일로 만들어서 파라미터로 경로를 넣어주면 코드가 더 간결해질 것 같긴 하다.
// components/IconBar/IconButton.tsx
import GitHubIcon from '../Icons/github';
import LightDarkIcon from '../Icons/light-dark';
import VelogIcon from '../Icons/velog';
interface Props {
name: string;
}
function getIcon(name: string) {
switch (name) {
case 'light-dark':
return <LightDarkIcon />;
case 'github':
return <GitHubIcon />;
case 'velog':
return <VelogIcon />;
}
}
const IconButton = ({ name }: Props) => {
const icon = getIcon(name);
return <button className="mb-2 px-4">{icon}</button>;
};
export default IconButton;
// components/IconBar/VerticalLine.tsx
const VerticalLine = () => {
return <div className="my-0 mx-auto h-[90px] w-[1px] bg-gray-600"></div>;
};
export default VerticalLine;
내일은 메인 콘텐츠 레이아웃을 잡아줘야겠다.