[ React 블로그 개발 ] 5. Component 꾸미기
2025-09-08
블로그에 적용하는 스타일링
이번 포스트에서 이전 포스트에서 분리한 Top, Left, Right 컴포넌트들을 꾸미는 작업을 하도록 하겠습니다.
포스트 작성하는 시점에는 Left를 없애고, Right Component만 남겨놓았습니다.
기존에 작성중이던 코드는 Left, Right가 있었던 기준이기에 해당 내용으로 진행하려고 합니다.
( 여러분 마음대로 적용하셔서 사용하세요! )
-
우선 어두운 색의 바탕을 별로 안좋아해서 흰색 바탕으로 바꾸겠습니다
- src/index.css에 있는 css를 제거해줍니다.
-
:root { /* color-scheme: light dark; color: rgba(255, 255, 255, 0.87); background-color: #242424; */ }
-
TopComponent에 백그라운드 색상과, 글자를 적용시켜보도록 하겠습니다!
-
export default function TopComponent() { return ( <div className="sidebar-top" style={{ alignItems: "center", justifyContent: "center", flexDirection: "column", display: "flex", backgroundColor: "white", padding: 20, }} > <div style={{ fontSize: 40, color: "black", fontWeight: 600 }}> Hello, World </div> <div style={{ color: "black" }}>여러분도 따라해보세요.</div> </div> ); }
-
-
Mobile 화면의 AppTopComponent도 꾸며줍니다
- menus에 있는 데이터는 추후에 백엔드에서 가져올 예정입니다.
-
import { useState } from "react"; export default function AppTopComponent() { const [isMenuOpen, setIsMenuOpen] = useState(false); const [activeMenu, setActiveMenu] = useState<number | null>(null); // 드롭다운 상태 관리 const toggleDropdown = (menuNo: number) => { setActiveMenu((prev) => (prev === menuNo ? null : menuNo)); // 클릭 시 드롭다운 토글 }; const menus = [ { no: 1, title: "React Menu 1", subMenus: [ { no: 1, title: "React SubMenu 1-1", }, ], }, { no: 2, title: "React Menu 2", subMenus: [ { no: 1, title: "React SubMenu 2-1", }, ], }, ]; return ( <div style={{ flex: 1, paddingRight: 15, display: "flex", justifyContent: "space-between", alignItems: "center", boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)", zIndex: 10, position: "relative", height: 54, }} > <div style={{ height: 54 }}> <div style={{ padding: 15, fontWeight: 700, fontSize: 22 }}> React Smaple Blog </div> </div> <button style={{ display: "flex", flexDirection: "column", justifyContent: "space-between", width: 30, height: 24, background: "transparent", border: "none", cursor: "pointer", padding: 0, zIndex: 20, }} aria-label="Menu" onClick={() => setIsMenuOpen(!isMenuOpen)} > <div style={{ width: "100%", height: 3, backgroundColor: "black", borderRadius: 2, }} /> <div style={{ width: "100%", height: 3, backgroundColor: "black", borderRadius: 2, }} /> <div style={{ width: "100%", height: 3, backgroundColor: "black", borderRadius: 2, }} /> </button> <div style={{ position: "absolute", top: "100%", right: 0, left: 0, // 좌측도 0으로 설정하여 전체 너비를 사용 backgroundColor: "white", zIndex: 15, maxHeight: isMenuOpen ? "300px" : "0", overflow: "hidden", transition: "max-height 0.3s ease-in-out", boxShadow: isMenuOpen ? "0 4px 6px rgba(0, 0, 0, 0.1)" : "none", borderRadius: "4px", width: "100%", // 전체 너비로 변경 }} > <ul style={{ listStyle: "none", margin: 0, padding: 0, fontSize: "24px", textAlign: "center", width: "100%", // 전체 너비 사용 }} > {menus?.map((menu) => ( <div key={menu.no} style={{ width: "100%" }}> <div onClick={() => toggleDropdown(menu.no)} style={{ padding: "10px", cursor: "pointer", textAlign: "center", backgroundColor: activeMenu === menu.no ? "#f9f9f9" : "transparent", // 드롭다운 활성화 시 배경색 변경 color: "black", }} > {menu.title} </div> {activeMenu === menu.no && menu.subMenus?.map((subMenu) => ( <div key={subMenu.no} onClick={() => { setActiveMenu(null); // 서브 메뉴 클릭 시 드롭다운 닫기 setIsMenuOpen(false); // 서브 메뉴 클릭 시 메뉴 닫기 }} style={{ padding: "10px 20px", cursor: "pointer", textAlign: "center", backgroundColor: "white", color: "black", }} > {subMenu.title} </div> ))} </div> ))} </ul> </div> </div> ); }
-
LeftComponent 영역과 RightComponent 영역을 꾸며줍니다
- LeftComponent
-
import { useState } from "react"; export default function SidebarLeft() { const [activeMenu, setActiveMenu] = useState<number | null>(null); // 드롭다운 상태 관리 const menus = [ { no: 1, title: "React Menu 1", subMenus: [ { no: 1, title: "React SubMenu 1-1", }, ], }, { no: 2, title: "React Menu 2", subMenus: [ { no: 1, title: "React SubMenu 2-1", }, ], }, ]; const toggleDropdown = (menuNo: number) => { setActiveMenu((prev) => (prev === menuNo ? null : menuNo)); // 클릭 시 드롭다운 토글 }; return ( <div style={{ alignItems: "center", justifyContent: "center", display: "flex", flexDirection: "column", width: "20%", }} > <div style={{ margin: 10, fontWeight: 900, fontSize: 17 }}>MENU</div> {menus?.map((menu) => ( <div key={menu.no} style={{ width: "100%" }}> <div onClick={() => toggleDropdown(menu.no)} style={{ padding: "10px", cursor: "pointer", textAlign: "center", backgroundColor: activeMenu === menu.no ? "#f0f0f0" : "transparent", // 드롭다운 활성화 시 배경색 변경 }} > {menu.title} </div> {activeMenu === menu.no && menu.subMenus?.map((subMenu) => ( <div key={subMenu.no} onClick={() => { setActiveMenu(null); // 서브 메뉴 클릭 시 드롭다운 닫기 }} style={{ padding: "10px 20px", cursor: "pointer", textAlign: "center", backgroundColor: "#f9f9f9", }} > {subMenu.title} </div> ))} </div> ))} </div> ); }
-
- LeftComponent
-
MainScreen의 영역을 꾸며줍니다.
-
export default function MainScreen() { const posts = [ { no: 1, menu_no: 1, title: "안녕하세요. 리액트 프로젝트", sub_title: "안녕하세요. 리액트 샘플 프로젝트 제작기에 있습니다. 많은 관심 부탁드립니다.", content: "React Content 1", del_yn: "N", createdAt: "2024-06-20 12:00:00", updatedAt: "2024-06-20 12:00:00", }, { no: 1, menu_no: 1, title: "리액트 샘플 프로젝트 테스트 코드입니다.", sub_title: "안녕하세요. 리액트 샘플 프로젝트 제작기에 있습니다. 많은 관심 부탁드립니다.", content: "React Content 1", del_yn: "N", createdAt: "2024-06-21 12:00:00", updatedAt: "2024-06-21 12:00:00", }, ]; return ( <div> <div style={{ gap: "16px", display: "grid", flex: 1, }} > {posts?.map((post) => ( <div className="post-list-item" style={{ flex: 1, alignItems: "center", marginTop: 16, marginBottom: 16, }} > <div style={{ fontWeight: 800, fontSize: 16, marginBottom: 5, textDecoration: "none", transition: "text-decoration 0.2s ease", }} > {post.title} </div> <div style={{ color: "rgba(73,80,87,1)", fontSize: 14, fontWeight: "500", }} > {post.sub_title} </div> <div style={{ color: "rgba(52,58,64,1)", fontSize: 12, fontWeight: "600", marginTop: 12, }} > {post.createdAt} </div> {/* <p>{post.content}</p> */} </div> ))} </div> </div> ); }
-
-
RightComponent는 추후에 검색 기능, 실시간 채팅 기능, 일/월/총 방문자 수 체크 기능을 추가할 예정입니다.
-
다른 페이지로 이동하는 네비게이션 기능을 다루어 볼 예정입니다.
참고: git sample react blog code