기본 HTML 태그만으로 구현하긴 힘들지만 필수적으로 쓰이는 레이아웃 요소는 다음과 같다.
* Bootstrap에선 Navbar라는 명칭이 따로 있다.
Header는 주로 웹페이지 상단에 위치한 컴포넌트로, 주로 브랜드(또는 서비스 이름) GNB(Global Navigation Bar), 메뉴 버튼, 로그인 버튼 등이 있다.
import Container from 'react-bootstrap/Container';
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import NavDropdown from 'react-bootstrap/NavDropdown';
function BasicExample() {
return (
<Navbar expand="lg" className="bg-body-tertiary">
<Container>
<Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Nav.Link href="#home">Home</Nav.Link>
<Nav.Link href="#link">Link</Nav.Link>
<NavDropdown title="Dropdown" id="basic-nav-dropdown">
<NavDropdown.Item href="#action/3.1">Action</NavDropdown.Item>
<NavDropdown.Item href="#action/3.2">
Another action
</NavDropdown.Item>
<NavDropdown.Item href="#action/3.3">Something</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="#action/3.4">
Separated link
</NavDropdown.Item>
</NavDropdown>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
);
}
export default BasicExample;
웹페이지 하단에 위치하며, 회사 정보나 비슷한 혹은 협업 중인 서비스로 이동할 수 있게끔 되어있다. (bootstrap에 있는지는 모르겠다만, Navbar로 비슷하게 구현할 수 있을 것 같다)
웹페이지 내부의 요소나 다른 페이지로 이동할 수 있게 해주는 컴포넌트이다. 구현 방법은 개발자의 성향에 따라 달라지지만 기본적으로 클릭을 통한 상호작용으로 페이지 이동이 일어난다.
import Nav from 'react-bootstrap/Nav';
function BasicExample() {
return (
<Nav
activeKey="/home"
onSelect={(selectedKey) => alert(`selected ${selectedKey}`)}
>
<Nav.Item>
<Nav.Link href="/home">Active</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="link-1">Link</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="link-2">Link</Nav.Link>
</Nav.Item>
<Nav.Item>
<Nav.Link eventKey="disabled" disabled>
Disabled
</Nav.Link>
</Nav.Item>
</Nav>
);
}
export default BasicExample;
팝업(Pop-Up)과 비슷한 결의 컴포넌트이다. 다만 새로운 창에서 작동하는 팝업과 달리, Modal은 현재 페이지 내부에 추가된 요소로 Modal 외의 요소는 상호작용 할 수 없다.
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';
function StaticExample() {
return (
<div
className="modal show"
style={{ display: 'block', position: 'initial' }}
>
<Modal.Dialog>
<Modal.Header closeButton>
<Modal.Title>Modal title</Modal.Title>
</Modal.Header>
<Modal.Body>
<p>Modal body text goes here.</p>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary">Close</Button>
<Button variant="primary">Save changes</Button>
</Modal.Footer>
</Modal.Dialog>
</div>
);
}
export default StaticExample;
Drawer라고 불리기도 하는 컴포넌트다. 대표적인 예시로, 메뉴 아이콘을 누르면 왼쪽이나 오른쪽에서 메뉴창이 등장하는 경우가 Offcanva를 쓰는 경우다.
import { useState } from 'react';
import Button from 'react-bootstrap/Button';
import Offcanvas from 'react-bootstrap/Offcanvas';
function Example() {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<Button variant="primary" onClick={handleShow}>
Launch
</Button>
<Offcanvas show={show} onHide={handleClose}>
<Offcanvas.Header closeButton>
<Offcanvas.Title>Offcanvas</Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body>
Some text as placeholder. In real life you can have the elements you
have chosen. Like, text, images, lists, etc.
</Offcanvas.Body>
</Offcanvas>
</>
);
}
export default Example;
현재 페이지에 임시로 컴포넌트를 보여주는 것이다. 알림 또는 경고 메시지 표시용으로 많이 쓴다.
import { useState, useRef } from 'react';
import Button from 'react-bootstrap/Button';
import Overlay from 'react-bootstrap/Overlay';
function Example() {
const [show, setShow] = useState(false);
const target = useRef(null);
return (
<>
<Button variant="danger" ref={target} onClick={() => setShow(!show)}>
Click me to see
</Button>
<Overlay target={target.current} show={show} placement="right">
{({
placement: _placement,
arrowProps: _arrowProps,
show: _show,
popper: _popper,
hasDoneInitialMeasure: _hasDoneInitialMeasure,
...props
}) => (
<div
{...props}
style={{
position: 'absolute',
backgroundColor: 'rgba(255, 100, 100, 0.85)',
padding: '2px 10px',
color: 'white',
borderRadius: 3,
...props.style,
}}
>
Simple tooltip
</div>
)}
</Overlay>
</>
);
}
export default Example;
대기 중에 보여지는 컴포넌트이다. 주로 바(Progrss-Bar) 형태나 원형(Spinner) 형태가 있다.
import ProgressBar from 'react-bootstrap/ProgressBar';
function BasicExample() {
return <ProgressBar now={60} />;
}
export default BasicExample;
import Spinner from 'react-bootstrap/Spinner';
function BasicExample() {
return (
<Spinner animation="border" role="status">
<span className="visually-hidden">Loading...</span>
</Spinner>
);
}
export default BasicExample;
서버 통신 중 데이터 전달이 완료되지 않은 경우처럼, 아직 데이터를 표시하지 않지만 해당 영역을 표시하고 싶은 경우 쓴다.
import Button from 'react-bootstrap/Button';
import Card from 'react-bootstrap/Card';
import Placeholder from 'react-bootstrap/Placeholder';
function CardExample() {
return (
<div className="d-flex justify-content-around">
<Card style={{ width: '18rem' }}>
<Card.Img variant="top" src="holder.js/100px180" />
<Card.Body>
<Card.Title>Card Title</Card.Title>
<Card.Text>
Some quick example text to build on the card title and make up the
bulk of the card's content.
</Card.Text>
<Button variant="primary">Go somewhere</Button>
</Card.Body>
</Card>
<Card style={{ width: '18rem' }}>
<Card.Img variant="top" src="holder.js/100px180" />
<Card.Body>
<Placeholder as={Card.Title} animation="glow">
<Placeholder xs={6} />
</Placeholder>
<Placeholder as={Card.Text} animation="glow">
<Placeholder xs={7} /> <Placeholder xs={4} /> <Placeholder xs={4} />{' '}
<Placeholder xs={6} /> <Placeholder xs={8} />
</Placeholder>
<Placeholder.Button variant="primary" xs={6} />
</Card.Body>
</Card>
</div>
);
}
export default CardExample;
리스트가 너무 길어 여러 페이지에 걸쳐 보여줘야 하는 상황이 있다. 그런 경우 밑에 페이지를 표시하는 컴포넌트가 Pagination이다.
import Pagination from 'react-bootstrap/Pagination';
function AdvancedExample() {
return (
<Pagination>
<Pagination.First />
<Pagination.Prev />
<Pagination.Item>{1}</Pagination.Item>
<Pagination.Ellipsis />
<Pagination.Item>{10}</Pagination.Item>
<Pagination.Item>{11}</Pagination.Item>
<Pagination.Item active>{12}</Pagination.Item>
<Pagination.Item>{13}</Pagination.Item>
<Pagination.Item disabled>{14}</Pagination.Item>
<Pagination.Ellipsis />
<Pagination.Item>{20}</Pagination.Item>
<Pagination.Next />
<Pagination.Last />
</Pagination>
);
}
export default AdvancedExample;
Overlay와 비슷하지만, 일시적으로 보이고 자동으로 사라지는 컴포넌트를 Toast라 한다.
import React, { useState } from 'react';
import Button from 'react-bootstrap/Button';
import Col from 'react-bootstrap/Col';
import Row from 'react-bootstrap/Row';
import Toast from 'react-bootstrap/Toast';
function DismissibleExample() {
const [showA, setShowA] = useState(true);
const [showB, setShowB] = useState(true);
const toggleShowA = () => setShowA(!showA);
const toggleShowB = () => setShowB(!showB);
return (
<Row>
<Col md={6} className="mb-2">
<Button onClick={toggleShowA} className="mb-2">
Toggle Toast <strong>with</strong> Animation
</Button>
<Toast show={showA} onClose={toggleShowA}>
<Toast.Header>
<img
src="holder.js/20x20?text=%20"
className="rounded me-2"
alt=""
/>
<strong className="me-auto">Bootstrap</strong>
<small>11 mins ago</small>
</Toast.Header>
<Toast.Body>Woohoo, you're reading this text in a Toast!</Toast.Body>
</Toast>
</Col>
<Col md={6} className="mb-2">
<Button onClick={toggleShowB} className="mb-2">
Toggle Toast <strong>without</strong> Animation
</Button>
<Toast onClose={toggleShowB} show={showB} animation={false}>
<Toast.Header>
<img
src="holder.js/20x20?text=%20"
className="rounded me-2"
alt=""
/>
<strong className="me-auto">Bootstrap</strong>
<small>11 mins ago</small>
</Toast.Header>
<Toast.Body>Woohoo, you're reading this text in a Toast!</Toast.Body>
</Toast>
</Col>
</Row>
);
}
export default DismissibleExample;