Chip
Chip
Chip(칩)은 입력, 속성 또는 동작을 나타내는 컴팩트한 요소예요.
Chip을 사용하면 사용자가 정보를 입력하거나, 선택을 하거나, 콘텐츠를 필터링하거나, 동작을 트리거할 수 있어요.
여기서는 독립형 컴포넌트로 포함되어 있지만, 가장 흔한 용도는 어떤 형태의 입력(input)이에요. 그래서 여기서 보여주는 동작 중 일부는 그 맥락에서 표시되지 않아요.
출처: 문서
본문
기본 칩 (Basic chip)
Chip 컴포넌트는 outlined(윤곽선)과 filled(채움) 스타일링을 지원해요.
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
export default function BasicChips() {
return (
<Stack direction="row" spacing={1}>
<Chip label="Chip Filled" />
<Chip label="Chip Outlined" variant="outlined" />
</Stack>
);
}
칩 동작 (Chip actions)
다음 동작들을 사용할 수 있어요.
onClickprop이 정의된 Chip은 포커스, 호버, 클릭 시 모양이 바뀌어요.onDeleteprop이 정의된 Chip은 호버 시 모양이 바뀌는 삭제 아이콘을 표시해요.
클릭 가능 (Clickable)
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
export default function ClickableChips() {
const handleClick = () => {
console.info('You clicked the Chip.');
};
return (
<Stack direction="row" spacing={1}>
<Chip label="Clickable" onClick={handleClick} />
<Chip label="Clickable" variant="outlined" onClick={handleClick} />
</Stack>
);
}
삭제 가능 (Deletable)
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
export default function DeletableChips() {
const handleDelete = () => {
console.info('You clicked the delete icon.');
};
return (
<Stack direction="row" spacing={1}>
<Chip label="Deletable" onDelete={handleDelete} />
<Chip label="Deletable" variant="outlined" onDelete={handleDelete} />
</Stack>
);
}
클릭 및 삭제 가능 (Clickable and deletable)
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
export default function ClickableAndDeletableChips() {
const handleClick = () => {
console.info('You clicked the Chip.');
};
const handleDelete = () => {
console.info('You clicked the delete icon.');
};
return (
<Stack direction="row" spacing={1}>
<Chip
label="Clickable Deletable"
onClick={handleClick}
onDelete={handleDelete}
/>
<Chip
label="Clickable Deletable"
variant="outlined"
onClick={handleClick}
onDelete={handleDelete}
/>
</Stack>
);
}
클릭 가능 링크 (Clickable link)
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
export default function ClickableLinkChips() {
return (
<Stack direction="row" spacing={1}>
<Chip label="Clickable Link" component="a" href="#basic-chip" clickable />
<Chip
label="Clickable Link"
component="a"
href="#basic-chip"
variant="outlined"
clickable
/>
</Stack>
);
}
커스텀 삭제 아이콘 (Custom delete icon)
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
import DoneIcon from '@mui/icons-material/Done';
import DeleteIcon from '@mui/icons-material/Delete';
export default function CustomDeleteIconChips() {
const handleClick = () => {
console.info('You clicked the Chip.');
};
const handleDelete = () => {
console.info('You clicked the delete icon.');
};
return (
<Stack direction="row" spacing={1}>
<Chip
label="Custom delete icon"
onClick={handleClick}
onDelete={handleDelete}
deleteIcon={<DoneIcon />}
/>
<Chip
label="Custom delete icon"
onClick={handleClick}
onDelete={handleDelete}
deleteIcon={<DeleteIcon />}
variant="outlined"
/>
</Stack>
);
}
칩 장식 (Chip adornments)
컴포넌트의 시작 부분에 장식을 추가할 수 있어요.
avatar prop을 사용해 아바타를 추가하거나 icon prop을 사용해 아이콘을 추가해요.
아바타 칩 (Avatar chip)
import Avatar from '@mui/material/Avatar';
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
export default function AvatarChips() {
return (
<Stack direction="row" spacing={1}>
<Chip avatar={<Avatar>M</Avatar>} label="Avatar" />
<Chip
avatar={<Avatar alt="Natacha" src="/static/images/avatar/1.jpg" />}
label="Avatar"
variant="outlined"
/>
</Stack>
);
}
아이콘 칩 (Icon chip)
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
import FaceIcon from '@mui/icons-material/Face';
export default function IconChips() {
return (
<Stack direction="row" spacing={1}>
<Chip icon={<FaceIcon />} label="With Icon" />
<Chip icon={<FaceIcon />} label="With Icon" variant="outlined" />
</Stack>
);
}
색상 칩 (Color chip)
color prop을 사용해 테마 팔레트에서 색상을 정의할 수 있어요.
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
export default function ColorChips() {
return (
<Stack spacing={1} sx={{ alignItems: 'center' }}>
<Stack direction="row" spacing={1}>
<Chip label="primary" color="primary" />
<Chip label="success" color="success" />
</Stack>
<Stack direction="row" spacing={1}>
<Chip label="primary" color="primary" variant="outlined" />
<Chip label="success" color="success" variant="outlined" />
</Stack>
</Stack>
);
}
크기 칩 (Sizes chip)
size prop을 사용해 작은 Chip을 정의할 수 있어요.
import Chip from '@mui/material/Chip';
import Stack from '@mui/material/Stack';
export default function SizesChips() {
return (
<Stack direction="row" spacing={1}>
<Chip label="Small" size="small" />
<Chip label="Small" size="small" variant="outlined" />
</Stack>
);
}
여러 줄 칩 (Multiline chip)
기본적으로 Chip은 라벨을 한 줄에만 표시해요.
여러 줄 콘텐츠를 지원하게 하려면 sx prop을 사용해 Chip 컴포넌트에 height:auto를 추가하고, label 스타일에 whiteSpace: normal을 추가하세요.
import Chip from '@mui/material/Chip';
import Box from '@mui/material/Box';
export default function MultilineChips() {
return (
<Box sx={{ width: 100 }}>
<Chip
sx={{
height: 'auto',
'& .MuiChip-label': {
display: 'block',
whiteSpace: 'normal',
},
}}
label="This is a chip that has multiple lines."
/>
</Box>
);
}
칩 배열 (Chip array)
값 배열에서 여러 칩을 렌더링하는 예시예요.
칩을 삭제하면 배열에서 제거돼요. onClick prop이 정의되어 있지 않으므로, Chip은 포커스될 수 있지만 클릭하거나 터치할 때 깊이(depth)를 얻지는 않는다는 점에 주의하세요.
import * as React from 'react';
import { styled } from '@mui/material/styles';
import Chip from '@mui/material/Chip';
import Paper from '@mui/material/Paper';
import TagFacesIcon from '@mui/icons-material/TagFaces';
interface ChipData {
key: number;
label: string;
}
const ListItem = styled('li')(({ theme }) => ({
margin: theme.spacing(0.5),
}));
export default function ChipsArray() {
const [chipData, setChipData] = React.useState<readonly ChipData[]>([
{ key: 0, label: 'Angular' },
{ key: 1, label: 'jQuery' },
{ key: 2, label: 'Polymer' },
{ key: 3, label: 'React' },
{ key: 4, label: 'Vue.js' },
]);
const handleDelete = (chipToDelete: ChipData) => () => {
setChipData((chips) => chips.filter((chip) => chip.key !== chipToDelete.key));
};
return (
<Paper
sx={{
display: 'flex',
justifyContent: 'center',
flexWrap: 'wrap',
listStyle: 'none',
p: 0.5,
m: 0,
}}
component="ul"
>
{chipData.map((data) => {
let icon;
if (data.label === 'React') {
icon = <TagFacesIcon />;
}
return (
<ListItem key={data.key}>
<Chip
icon={icon}
label={data.label}
onDelete={data.label === 'React' ? undefined : handleDelete(data)}
/>
</ListItem>
);
})}
</Paper>
);
}
칩 플레이그라운드 (Chip playground)
import * as React from 'react';
import Grid from '@mui/material/Grid';
import FormControl from '@mui/material/FormControl';
import FormLabel from '@mui/material/FormLabel';
import FormControlLabel from '@mui/material/FormControlLabel';
import RadioGroup from '@mui/material/RadioGroup';
import Radio from '@mui/material/Radio';
import Avatar from '@mui/material/Avatar';
import Chip from '@mui/material/Chip';
import FaceIcon from '@mui/icons-material/Face';
import DoneIcon from '@mui/icons-material/Done';
import { HighlightedCode } from '@mui/internal-core-docs/HighlightedCode';
function ChipsPlayground() {
const [state, setState] = React.useState({
color: 'default',
onDelete: 'none',
avatar: 'none',
icon: 'none',
variant: 'filled',
size: 'medium',
});
const { color, onDelete, avatar, icon, variant, size } = state;
const handleChange = (event) => {
setState({
...state,
[event.target.name]: event.target.value,
});
};
const handleDeleteExample = () => {
console.info('You clicked the delete icon.');
};
const colorToCode = color !== 'default' ? `color="${color}" ` : '';
const sizeToCode = size === 'small' ? `size="small" ` : '';
const variantToCode = variant !== 'filled' ? `variant="${variant}" ` : '';
let onDeleteToCode;
switch (onDelete) {
case 'none':
onDeleteToCode = '';
break;
case 'custom':
onDeleteToCode = 'deleteIcon={<DoneIcon />} onDelete={handleDelete} ';
break;
default:
onDeleteToCode = 'onDelete={handleDelete} ';
break;
}
let iconToCode;
let iconToPlayground;
switch (icon) {
case 'none':
iconToCode = '';
break;
default:
iconToCode = 'icon={<FaceIcon />} ';
iconToPlayground = <FaceIcon />;
break;
}
let avatarToCode;
let avatarToPlayground;
switch (avatar) {
case 'none':
avatarToCode = '';
break;
case 'img':
avatarToCode = 'avatar={<Avatar src="/static/images/avatar/1.jpg" />} ';
avatarToPlayground = <Avatar src="/static/images/avatar/1.jpg" />;
break;
case 'letter':
avatarToCode = 'avatar={<Avatar>F</Avatar>} ';
avatarToPlayground = <Avatar>F</Avatar>;
break;
default:
break;
}
if (avatar !== 'none') {
iconToCode = '';
iconToPlayground = null;
}
const jsx = `
<Chip ${variantToCode}${colorToCode}${sizeToCode}${onDeleteToCode}${avatarToCode}${iconToCode}/>
`;
return (
<Grid container sx={{ flexGrow: 1 }}>
<Grid size={12}>
<Grid container sx={{ justifyContent: 'center', alignItems: 'center' }}>
<Grid sx={(theme) => ({ height: theme.spacing(10) })}>
<Chip
label="Chip Component"
color={color}
deleteIcon={onDelete === 'custom' ? <DoneIcon /> : undefined}
onDelete={onDelete !== 'none' ? handleDeleteExample : undefined}
avatar={avatarToPlayground}
icon={iconToPlayground}
variant={variant}
size={size}
/>
</Grid>
</Grid>
</Grid>
<Grid size={12}>
<Grid container spacing={3}>
<Grid
size={{
xs: 12,
md: 6,
}}
>
<FormControl component="fieldset">
<FormLabel>variant</FormLabel>
<RadioGroup
row
name="variant"
aria-label="variant"
value={variant}
onChange={handleChange}
>
<FormControlLabel
value="filled"
control={<Radio />}
label="filled"
/>
<FormControlLabel
value="outlined"
control={<Radio />}
label="outlined"
/>
</RadioGroup>
</FormControl>
</Grid>
<Grid
size={{
xs: 12,
md: 6,
}}
>
<FormControl component="fieldset">
<FormLabel>color</FormLabel>
<RadioGroup
row
name="color"
aria-label="color"
value={color}
onChange={handleChange}
>
<FormControlLabel
value="default"
control={<Radio />}
label="default"
/>
<FormControlLabel
value="primary"
control={<Radio />}
label="primary"
/>
<FormControlLabel
value="secondary"
control={<Radio />}
label="secondary"
/>
<FormControlLabel value="error" control={<Radio />} label="error" />
<FormControlLabel value="info" control={<Radio />} label="info" />
<FormControlLabel
value="success"
control={<Radio />}
label="success"
/>
<FormControlLabel
value="warning"
control={<Radio />}
label="warning"
/>
</RadioGroup>
</FormControl>
</Grid>
<Grid
size={{
xs: 12,
md: 6,
}}
>
<FormControl component="fieldset">
<FormLabel>size</FormLabel>
<RadioGroup
row
name="size"
aria-label="size"
value={size}
onChange={handleChange}
>
<FormControlLabel
value="medium"
control={<Radio />}
label="medium"
/>
<FormControlLabel value="small" control={<Radio />} label="small" />
</RadioGroup>
</FormControl>
</Grid>
<Grid
size={{
xs: 12,
md: 6,
}}
>
<FormControl component="fieldset">
<FormLabel>icon</FormLabel>
<RadioGroup
row
name="icon"
aria-label="icon"
value={icon}
onChange={handleChange}
>
<FormControlLabel value="none" control={<Radio />} label="none" />
<FormControlLabel value="icon" control={<Radio />} label="icon" />
</RadioGroup>
</FormControl>
</Grid>
<Grid
size={{
xs: 12,
md: 6,
}}
>
<FormControl component="fieldset">
<FormLabel>avatar</FormLabel>
<RadioGroup
row
name="avatar"
aria-label="avatar"
value={avatar}
onChange={handleChange}
>
<FormControlLabel value="none" control={<Radio />} label="none" />
<FormControlLabel
value="letter"
control={<Radio />}
label="letter"
/>
<FormControlLabel value="img" control={<Radio />} label="img" />
</RadioGroup>
</FormControl>
</Grid>
<Grid
size={{
xs: 12,
md: 6,
}}
>
<FormControl component="fieldset">
<FormLabel>onDelete</FormLabel>
<RadioGroup
row
name="onDelete"
aria-label="on delete"
value={onDelete}
onChange={handleChange}
>
<FormControlLabel value="none" control={<Radio />} label="none" />
<FormControlLabel
value="default"
control={<Radio />}
label="default"
/>
<FormControlLabel
value="custom"
control={<Radio />}
label="custom"
/>
</RadioGroup>
</FormControl>
</Grid>
</Grid>
</Grid>
<Grid size={12}>
<HighlightedCode code={jsx} language="jsx" />
</Grid>
</Grid>
);
}
export default ChipsPlayground;
접근성 (Accessibility)
Chip이 삭제 가능하거나 클릭 가능하면 탭 순서상 버튼이에요. Chip이 포커스될 때(예: 탭 이동) Backspace 또는 Delete를 놓으면(keyup 이벤트) onDelete 핸들러가 호출되고, Escape를 놓으면 Chip이 블러(blur)돼요.
Chip API
데모 (Demos)
이 React 컴포넌트의 사용에 관한 예제와 자세한 내용은 컴포넌트 데모 페이지를 방문하세요:
Import
import Chip from '@mui/material/Chip';
// or
import { Chip } from '@mui/material';
Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
| avatar | element |
- | No | |
| children | unsupportedProp |
- | No | |
| classes | object |
- | No | 컴포넌트에 적용되는 스타일을 오버라이드하거나 확장해요. |
| clickable | bool |
- | No | |
| color | 'default' | 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning' | string |
'default' |
No | |
| component | elementType |
- | No | |
| deleteIcon | element |
- | No | |
| disabled | bool |
false |
No | |
| icon | element |
- | No | |
| label | node |
- | No | |
| nativeButton | bool |
- | No | |
| onDelete | func |
- | No | |
| size | 'medium' | 'small' | string |
'medium' |
No | |
| skipFocusWhenDisabled | bool |
false |
No | |
| slotProps | { label?: func | object, root?: func | object } |
{} |
No | |
| slots | { label?: elementType, root?: elementType } |
{} |
No | |
| sx | Array<func | object | bool> | func | object |
- | No | 시스템 오버라이드 및 추가 CSS 스타일을 정의할 수 있게 해주는 시스템 prop이에요. |
| variant | 'filled' | 'outlined' | string |
'filled' |
No |
Note:
ref는 루트 요소(HTMLDivElement)로 전달돼요.
제공된 다른 모든 props는 루트 요소(네이티브 요소)로 전달돼요.
테마 기본 props (Theme default props)
MuiChip을 사용해 테마로 이 컴포넌트의 기본 props를 변경할 수 있어요.
Slots
| Name | Default | Class | Description |
|---|---|---|---|
| root | div |
.MuiChip-root |
루트를 렌더링하는 컴포넌트예요. |
| label | span |
.MuiChip-label |
라벨을 렌더링하는 컴포넌트예요. |
CSS
규칙 이름 (Rule name)
| Global class | Rule name | Description |
|---|---|---|
| - | avatar | 아바타 요소에 적용되는 스타일이에요. |
| - | clickable | onClick이 정의되거나 clickable={true}일 때 루트 요소에 적용되는 스타일이에요. |
| - | colorDefault | color="default"일 때 루트 요소에 적용되는 스타일이에요. |
| - | colorError | color="error"일 때 루트 요소에 적용되는 스타일이에요. |
| - | colorInfo | color="info"일 때 루트 요소에 적용되는 스타일이에요. |
| - | colorPrimary | color="primary"일 때 루트 요소에 적용되는 스타일이에요. |
| - | colorSecondary | color="secondary"일 때 루트 요소에 적용되는 스타일이에요. |
| - | colorSuccess | color="success"일 때 루트 요소에 적용되는 스타일이에요. |
| - | colorWarning | color="warning"일 때 루트 요소에 적용되는 스타일이에요. |
| - | deletable | onDelete가 정의될 때 루트 요소에 적용되는 스타일이에요. |
| - | deleteIcon | deleteIcon 요소에 적용되는 스타일이에요. |
.Mui-disabled |
- | disabled={true}일 때 루트 요소에 적용되는 상태 클래스예요. |
| - | filled | variant="filled"일 때 루트 요소에 적용되는 스타일이에요. |
.Mui-focusVisible |
- | 키보드로 포커스될 때 루트 요소에 적용되는 상태 클래스예요. |
| - | icon | 아이콘 요소에 적용되는 스타일이에요. |
| - | outlined | variant="outlined"일 때 루트 요소에 적용되는 스타일이에요. |
| - | sizeMedium | size="medium"일 때 루트 요소에 적용되는 스타일이에요. |
| - | sizeSmall | size="small"일 때 루트 요소에 적용되는 스타일이에요. |
소스 코드 (Source code)
이 페이지에서 정보를 찾지 못했다면, 더 자세한 내용을 위해 컴포넌트 구현을 살펴보세요.