브레드크럼
브레드크럼 (Breadcrumbs)
브레드크럼은 페이지가 사이트의 계층 구조에서 어디에 위치하는지 시각화해주는 링크 목록입니다. 상위 조상 중 어느 곳으로든 이동할 수 있게 해줘요. 현재 위치를 보여주는 이 내비게이션 패턴은 사용자가 길을 잃지 않게 도와주는 기본 요소예요.
출처: 문서
본문
브레드크럼 소개
브레드크럼은 페이지가 사이트의 계층 구조에서 어디에 위치하는지 시각화하는 링크 목록입니다. 상위 조상들 중 어느 곳으로든 탐색할 수 있게 해줍니다.
기본 브레드크럼 (Basic breadcrumbs)
import * as React from 'react';
import Typography from '@mui/material/Typography';
import Breadcrumbs from '@mui/material/Breadcrumbs';
import Link from '@mui/material/Link';
function handleClick(event: React.MouseEvent<HTMLDivElement, MouseEvent>) {
event.preventDefault();
console.info('You clicked a breadcrumb.');
}
export default function BasicBreadcrumbs() {
return (
<div role="presentation" onClick={handleClick}>
<Breadcrumbs aria-label="breadcrumb">
<Link underline="hover" color="inherit" href="/">
MUI
</Link>
<Link
underline="hover"
color="inherit"
href="/material-ui/getting-started/installation/"
>
Core
</Link>
<Typography sx={{ color: 'text.primary' }}>Breadcrumbs</Typography>
</Breadcrumbs>
</div>
);
}
마지막 브레드크럼 활성화 (Active last breadcrumb)
마지막 브레드크럼을 상호작용 가능하게 유지합니다.
import * as React from 'react';
import Breadcrumbs from '@mui/material/Breadcrumbs';
import Link from '@mui/material/Link';
function handleClick(event: React.MouseEvent<HTMLDivElement, MouseEvent>) {
event.preventDefault();
console.info('You clicked a breadcrumb.');
}
export default function ActiveLastBreadcrumb() {
return (
<div role="presentation" onClick={handleClick}>
<Breadcrumbs aria-label="breadcrumb">
<Link underline="hover" color="inherit" href="/">
MUI
</Link>
<Link
underline="hover"
color="inherit"
href="/material-ui/getting-started/installation/"
>
Core
</Link>
<Link
underline="hover"
href="/material-ui/react-breadcrumbs/"
aria-current="page"
sx={{
color: 'text.primary',
}}
>
Breadcrumbs
</Link>
</Breadcrumbs>
</div>
);
}
커스텀 구분자 (Custom separator)
아래 예시에서는 문자열 구분자 두 개와 SVG 아이콘을 사용하고 있습니다.
import * as React from 'react';
import Breadcrumbs from '@mui/material/Breadcrumbs';
import Typography from '@mui/material/Typography';
import Link from '@mui/material/Link';
import Stack from '@mui/material/Stack';
import NavigateNextIcon from '@mui/icons-material/NavigateNext';
function handleClick(event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) {
event.preventDefault();
console.info('You clicked a breadcrumb.');
}
export default function CustomSeparator() {
const breadcrumbs = [
<Link underline="hover" key="1" color="inherit" href="/" onClick={handleClick}>
MUI
</Link>,
<Link
underline="hover"
key="2"
color="inherit"
href="/material-ui/getting-started/installation/"
onClick={handleClick}
>
Core
</Link>,
<Typography key="3" sx={{ color: 'text.primary' }}>
Breadcrumb
</Typography>,
];
return (
<Stack spacing={2}>
<Breadcrumbs separator="›" aria-label="breadcrumb">
{breadcrumbs}
</Breadcrumbs>
<Breadcrumbs separator="-" aria-label="breadcrumb">
{breadcrumbs}
</Breadcrumbs>
<Breadcrumbs
separator={<NavigateNextIcon fontSize="small" />}
aria-label="breadcrumb"
>
{breadcrumbs}
</Breadcrumbs>
</Stack>
);
}
아이콘이 있는 브레드크럼 (Breadcrumbs with icons)
import * as React from 'react';
import Typography from '@mui/material/Typography';
import Breadcrumbs from '@mui/material/Breadcrumbs';
import Link from '@mui/material/Link';
import HomeIcon from '@mui/icons-material/Home';
import WhatshotIcon from '@mui/icons-material/Whatshot';
import GrainIcon from '@mui/icons-material/Grain';
function handleClick(event: React.MouseEvent<HTMLDivElement, MouseEvent>) {
event.preventDefault();
console.info('You clicked a breadcrumb.');
}
export default function IconBreadcrumbs() {
return (
<div role="presentation" onClick={handleClick}>
<Breadcrumbs aria-label="breadcrumb">
<Link
underline="hover"
sx={{ display: 'flex', alignItems: 'center' }}
color="inherit"
href="/"
>
<HomeIcon sx={{ mr: 0.5 }} fontSize="inherit" />
MUI
</Link>
<Link
underline="hover"
sx={{ display: 'flex', alignItems: 'center' }}
color="inherit"
href="/material-ui/getting-started/installation/"
>
<WhatshotIcon sx={{ mr: 0.5 }} fontSize="inherit" />
Core
</Link>
<Typography
sx={{ color: 'text.primary', display: 'flex', alignItems: 'center' }}
>
<GrainIcon sx={{ mr: 0.5 }} fontSize="inherit" />
Breadcrumb
</Typography>
</Breadcrumbs>
</div>
);
}
접힌 브레드크럼 (Collapsed breadcrumbs)
import * as React from 'react';
import Breadcrumbs from '@mui/material/Breadcrumbs';
import Typography from '@mui/material/Typography';
import Link from '@mui/material/Link';
function handleClick(event: React.MouseEvent<HTMLDivElement, MouseEvent>) {
event.preventDefault();
console.info('You clicked a breadcrumb.');
}
export default function CollapsedBreadcrumbs() {
return (
<div role="presentation" onClick={handleClick}>
<Breadcrumbs maxItems={2} aria-label="breadcrumb">
<Link underline="hover" color="inherit" href="#">
Home
</Link>
<Link underline="hover" color="inherit" href="#">
Catalog
</Link>
<Link underline="hover" color="inherit" href="#">
Accessories
</Link>
<Link underline="hover" color="inherit" href="#">
New Collection
</Link>
<Typography sx={{ color: 'text.primary' }}>Belts</Typography>
</Breadcrumbs>
</div>
);
}
메뉴로 축소하기 (Condensed with menu)
대안으로, 접힌 링크들을 드롭다운 목록에 표시하는 Menu 컴포넌트를 추가해보는 것도 고려해볼 수 있습니다.
import * as React from 'react';
import Breadcrumbs from '@mui/material/Breadcrumbs';
import Link from '@mui/material/Link';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import IconButton from '@mui/material/IconButton';
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
export default function CondensedWithMenu() {
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent<HTMLButtonElement> | null) => {
if (event) {
setAnchorEl(event.currentTarget);
}
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<React.Fragment>
<Menu
anchorEl={anchorEl}
open={open}
onClose={handleClose}
aria-labelledby="with-menu-demo-breadcrumbs"
>
<MenuItem onClick={handleClose}>Breadcrumb 2</MenuItem>
<MenuItem onClick={handleClose}>Breadcrumb 3</MenuItem>
<MenuItem onClick={handleClose}>Breadcrumb 4</MenuItem>
</Menu>
<Breadcrumbs aria-label="breadcrumbs">
<Link color="primary" href="#condensed-with-menu">
Breadcrumb 1
</Link>
<IconButton color="primary" size="small" onClick={handleClick}>
<MoreHorizIcon />
</IconButton>
<Link color="primary" href="#condensed-with-menu">
Breadcrumb 5
</Link>
<Link color="primary" href="#condensed-with-menu">
Breadcrumb 6
</Link>
</Breadcrumbs>
</React.Fragment>
);
}
커스터마이징 (Customization)
컴포넌트를 커스터마이즈하는 예시입니다. 이에 대해 더 자세히 알아보려면 overrides 문서 페이지를 참고하세요.
import * as React from 'react';
import { emphasize, styled } from '@mui/material/styles';
import Breadcrumbs from '@mui/material/Breadcrumbs';
import Chip from '@mui/material/Chip';
import HomeIcon from '@mui/icons-material/Home';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
const StyledBreadcrumb = styled(Chip)(({ theme }) => {
return {
backgroundColor: theme.palette.grey[100],
height: theme.spacing(3),
color: (theme.vars || theme).palette.text.primary,
fontWeight: theme.typography.fontWeightRegular,
'&:hover, &:focus': {
backgroundColor: emphasize(theme.palette.grey[100], 0.06),
...theme.applyStyles('dark', {
backgroundColor: emphasize(theme.palette.grey[800], 0.06),
}),
},
'&:active': {
boxShadow: theme.shadows[1],
backgroundColor: emphasize(theme.palette.grey[100], 0.12),
...theme.applyStyles('dark', {
backgroundColor: emphasize(theme.palette.grey[800], 0.12),
}),
},
...theme.applyStyles('dark', {
backgroundColor: theme.palette.grey[800],
}),
};
}) as typeof Chip; // TypeScript only: need a type cast here because https://github.com/Microsoft/TypeScript/issues/26591
function handleClick(event: React.MouseEvent<Element, MouseEvent>) {
event.preventDefault();
console.info('You clicked a breadcrumb.');
}
export default function CustomizedBreadcrumbs() {
return (
<div role="presentation" onClick={handleClick}>
<Breadcrumbs aria-label="breadcrumb">
<StyledBreadcrumb
component="a"
href="#"
label="Home"
icon={<HomeIcon fontSize="small" />}
/>
<StyledBreadcrumb component="a" href="#" label="Catalog" />
<StyledBreadcrumb
label="Accessories"
deleteIcon={<ExpandMoreIcon />}
onDelete={handleClick}
/>
</Breadcrumbs>
</div>
);
}
react-router와 통합 (Integration with react-router)
import * as React from 'react';
import Box from '@mui/material/Box';
import List from '@mui/material/List';
import Link, { LinkProps } from '@mui/material/Link';
import { ListItemProps } from '@mui/material/ListItem';
import ListItemButton from '@mui/material/ListItemButton';
import Collapse from '@mui/material/Collapse';
import ListItemText from '@mui/material/ListItemText';
import Typography from '@mui/material/Typography';
import ExpandLess from '@mui/icons-material/ExpandLess';
import ExpandMore from '@mui/icons-material/ExpandMore';
import Breadcrumbs from '@mui/material/Breadcrumbs';
import {
Link as RouterLink,
Route,
Routes,
MemoryRouter,
useLocation,
} from 'react-router';
interface ListItemLinkProps extends ListItemProps {
to: string;
open?: boolean;
}
const breadcrumbNameMap: { [key: string]: string } = {
'/inbox': 'Inbox',
'/inbox/important': 'Important',
'/trash': 'Trash',
'/spam': 'Spam',
'/drafts': 'Drafts',
};
function ListItemLink(props: ListItemLinkProps) {
const { to, open, ...other } = props;
const primary = breadcrumbNameMap[to];
let icon = null;
if (open != null) {
icon = open ? <ExpandLess /> : <ExpandMore />;
}
return (
<li>
<ListItemButton component={RouterLink as any} to={to} {...other}>
<ListItemText primary={primary} />
{icon}
</ListItemButton>
</li>
);
}
interface LinkRouterProps extends LinkProps {
to: string;
replace?: boolean;
}
function LinkRouter(props: LinkRouterProps) {
return <Link {...props} component={RouterLink as any} />;
}
function Page() {
const location = useLocation();
const pathnames = location.pathname.split('/').filter((x) => x);
return (
<Breadcrumbs aria-label="breadcrumb">
<LinkRouter underline="hover" color="inherit" to="/">
Home
</LinkRouter>
{pathnames.map((value, index) => {
const last = index === pathnames.length - 1;
const to = `/${pathnames.slice(0, index + 1).join('/')}`;
return last ? (
<Typography key={to} sx={{ color: 'text.primary' }}>
{breadcrumbNameMap[to]}
</Typography>
) : (
<LinkRouter underline="hover" color="inherit" to={to} key={to}>
{breadcrumbNameMap[to]}
</LinkRouter>
);
})}
</Breadcrumbs>
);
}
export default function RouterBreadcrumbs() {
const [open, setOpen] = React.useState(true);
const handleClick = () => {
setOpen((prevOpen) => !prevOpen);
};
return (
<MemoryRouter initialEntries={['/inbox']} initialIndex={0}>
<Box sx={{ display: 'flex', flexDirection: 'column', width: 360 }}>
<Routes>
<Route path="*" element={<Page />} />
</Routes>
<Box
sx={{ bgcolor: 'background.paper', mt: 1 }}
component="nav"
aria-label="mailbox folders"
>
<List>
<ListItemLink to="/inbox" open={open} onClick={handleClick} />
<Collapse component="li" in={open} timeout="auto" unmountOnExit>
<List disablePadding>
<ListItemLink sx={{ pl: 4 }} to="/inbox/important" />
</List>
</Collapse>
<ListItemLink to="/trash" />
<ListItemLink to="/spam" />
</List>
</Box>
</Box>
</MemoryRouter>
);
}
접근성 (Accessibility)
(WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/)
Breadcrumbs 컴포넌트에 aria-label 설명을 추가하는 것을 잊지 마세요.
이 컴포넌트의 접근성은 다음에 의존합니다.
- 링크 집합이 순서 있는 목록(
<ol>요소)으로 구성됩니다. - 스크린 리더가 링크 사이의 시각적 구분자를 읽지 않도록
aria-hidden으로 숨깁니다. aria-label로 라벨이 지정된 nav 요소가 구조를 브레드크럼 트레일로 식별하고, 탐색 landmark가 되어 쉽게 찾을 수 있게 합니다.
Breadcrumbs API
데모 (Demos)
이 React 컴포넌트 사용에 대한 예시와 세부 사항은 컴포넌트 데모 페이지를 참고하세요.
Import
import Breadcrumbs from '@mui/material/Breadcrumbs';
// or
import { Breadcrumbs } from '@mui/material';
Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
| children | node |
- | No | |
| classes | object |
- | No | 컴포넌트에 적용되는 스타일을 오버라이드하거나 확장합니다. |
| component | elementType |
- | No | |
| expandText | string |
'Show path' |
No | |
| itemsAfterCollapse | integer |
1 |
No | |
| itemsBeforeCollapse | integer |
1 |
No | |
| maxItems | integer |
8 |
No | |
| separator | node |
'/' |
No | |
| slotProps | { collapsedIcon?: func | object } |
{} |
No | |
| slots | { CollapsedIcon?: elementType } |
{} |
No | |
| sx | Array<func | object | bool> | func | object |
- | No | 시스템 오버라이드와 추가 CSS 스타일을 정의할 수 있게 해주는 system prop입니다. |
참고:
ref는 루트 요소(HTMLElement)로 전달됩니다.
다른 추가 props는 루트 요소(Typography)로 제공됩니다.
상속 (Inheritance)
위에 명시적으로 문서화되지는 않았지만, Typography 컴포넌트의 props도 Breadcrumbs에서 사용할 수 있습니다.
테마 기본 props (Theme default props)
MuiBreadcrumbs를 사용해 테마로 이 컴포넌트의 기본 props를 변경할 수 있습니다.
CSS
규칙 이름 (Rule name)
| Global class | Rule name | Description |
|---|---|---|
| - | li | li 요소에 적용되는 스타일입니다. |
| - | ol | ol 요소에 적용되는 스타일입니다. |
| - | root | 루트 요소에 적용되는 스타일입니다. |
| - | separator | 구분자 요소에 적용되는 스타일입니다. |
소스 코드 (Source code)
이 페이지에서 원하는 정보를 찾지 못했다면, 더 자세한 내용을 위해 컴포넌트 구현을 살펴보세요.
Link API
데모 (Demos)
이 React 컴포넌트 사용에 대한 예시와 세부 사항은 컴포넌트 데모 페이지를 참고하세요.
Import
import Link from '@mui/material/Link';
// or
import { Link } from '@mui/material';
Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
| children | node |
- | No | |
| classes | object |
- | No | 컴포넌트에 적용되는 스타일을 오버라이드하거나 확장합니다. |
| color | 'primary' | 'secondary' | 'success' | 'error' | 'info' | 'warning' | 'textPrimary' | 'textSecondary' | 'textDisabled' | string |
'primary' |
No | |
| component | element type |
- | No | |
| sx | Array<func | object | bool> | func | object |
- | No | 시스템 오버라이드와 추가 CSS 스타일을 정의할 수 있게 해주는 system prop입니다. |
| TypographyClasses | object |
- | No | |
| underline | 'always' | 'hover' | 'none' |
'always' |
No | |
| variant | 'body1' | 'body2' | 'button' | 'caption' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'inherit' | 'overline' | 'subtitle1' | 'subtitle2' | string |
'inherit' |
No |
참고:
ref는 루트 요소(HTMLAnchorElement)로 전달됩니다.
다른 추가 props는 루트 요소(Typography)로 제공됩니다.
상속 (Inheritance)
위에 명시적으로 문서화되지는 않았지만, Typography 컴포넌트의 props도 Link에서 사용할 수 있습니다.
테마 기본 props (Theme default props)
MuiLink를 사용해 테마로 이 컴포넌트의 기본 props를 변경할 수 있습니다.
CSS
규칙 이름 (Rule name)
| Global class | Rule name | Description |
|---|---|---|
| - | button | component="button"일 때 루트 요소에 적용되는 스타일입니다. |
.Mui-focusVisible |
- | 링크가 키보드 포커스 상태일 때 루트 요소에 적용되는 상태 클래스입니다. |
| - | root | 루트 요소에 적용되는 스타일입니다. |
| - | underlineAlways | underline="always"일 때 루트 요소에 적용되는 스타일입니다. |
| - | underlineHover | underline="hover"일 때 루트 요소에 적용되는 스타일입니다. |
| - | underlineNone | underline="none"일 때 루트 요소에 적용되는 스타일입니다. |
소스 코드 (Source code)
이 페이지에서 원하는 정보를 찾지 못했다면, 더 자세한 내용을 위해 컴포넌트 구현을 살펴보세요.
Typography API
데모 (Demos)
이 React 컴포넌트 사용에 대한 예시와 세부 사항은 컴포넌트 데모 페이지를 참고하세요.
Import
import Typography from '@mui/material/Typography';
// or
import { Typography } from '@mui/material';
Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
| align | 'center' | 'inherit' | 'justify' | 'left' | 'right' |
'inherit' |
No | |
| children | node |
- | No | |
| classes | object |
- | No | 컴포넌트에 적용되는 스타일을 오버라이드하거나 확장합니다. |
| color | 'primary' | 'secondary' | 'success' | 'error' | 'info' | 'warning' | 'textPrimary' | 'textSecondary' | 'textDisabled' | string |
- | No | |
| component | elementType |
- | No | |
| gutterBottom | bool |
false |
No | |
| noWrap | bool |
false |
No | |
| sx | Array<func | object | bool> | func | object |
- | No | 시스템 오버라이드와 추가 CSS 스타일을 정의할 수 있게 해주는 system prop입니다. |
| variant | 'body1' | 'body2' | 'button' | 'caption' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'inherit' | 'overline' | 'subtitle1' | 'subtitle2' | string |
'body1' |
No | |
| variantMapping | object |
`{ | ||
| h1: 'h1', | ||||
| h2: 'h2', | ||||
| h3: 'h3', | ||||
| h4: 'h4', | ||||
| h5: 'h5', | ||||
| h6: 'h6', | ||||
| subtitle1: 'h6', | ||||
| subtitle2: 'h6', | ||||
| body1: 'p', | ||||
| body2: 'p', | ||||
| inherit: 'p', | ||||
| }` | No |
참고:
ref는 루트 요소(HTMLParagraphElement)로 전달됩니다.
다른 추가 props는 루트 요소(네이티브 요소)로 제공됩니다.
테마 기본 props (Theme default props)
MuiTypography를 사용해 테마로 이 컴포넌트의 기본 props를 변경할 수 있습니다.
CSS
규칙 이름 (Rule name)
| Global class | Rule name | Description |
|---|---|---|
| - | alignCenter | align="center"일 때 루트 요소에 적용되는 스타일입니다. |
| - | alignJustify | align="justify"일 때 루트 요소에 적용되는 스타일입니다. |
| - | alignLeft | align="left"일 때 루트 요소에 적용되는 스타일입니다. |
| - | alignRight | align="right"일 때 루트 요소에 적용되는 스타일입니다. |
| - | body1 | variant="body1"일 때 루트 요소에 적용되는 스타일입니다. |
| - | body2 | variant="body2"일 때 루트 요소에 적용되는 스타일입니다. |
| - | button | variant="button"일 때 루트 요소에 적용되는 스타일입니다. |
| - | caption | variant="caption"일 때 루트 요소에 적용되는 스타일입니다. |
| - | gutterBottom | gutterBottom={true}일 때 루트 요소에 적용되는 스타일입니다. |
| - | h1 | variant="h1"일 때 루트 요소에 적용되는 스타일입니다. |
| - | h2 | variant="h2"일 때 루트 요소에 적용되는 스타일입니다. |
| - | h3 | variant="h3"일 때 루트 요소에 적용되는 스타일입니다. |
| - | h4 | variant="h4"일 때 루트 요소에 적용되는 스타일입니다. |
| - | h5 | variant="h5"일 때 루트 요소에 적용되는 스타일입니다. |
| - | h6 | variant="h6"일 때 루트 요소에 적용되는 스타일입니다. |
| - | inherit | variant="inherit"일 때 루트 요소에 적용되는 스타일입니다. |
| - | noWrap | nowrap={true}일 때 루트 요소에 적용되는 스타일입니다. |
| - | overline | variant="overline"일 때 루트 요소에 적용되는 스타일입니다. |
| - | root | 루트 요소에 적용되는 스타일입니다. |
| - | subtitle1 | variant="subtitle1"일 때 루트 요소에 적용되는 스타일입니다. |
| - | subtitle2 | variant="subtitle2"일 때 루트 요소에 적용되는 스타일입니다. |
소스 코드 (Source code)
이 페이지에서 원하는 정보를 찾지 못했다면, 더 자세한 내용을 위해 컴포넌트 구현을 살펴보세요.
더 알아보기 (Learn more)
- Material UI 내비게이션 컴포넌트 둘러보기