RingProgress
RingProgress
원형 다이어그램으로 작업 상태 피드백을 제공하는 컴포넌트예요. 링 모양의 진행률 링을 만들어요.
출처: 문서
본문
사용법 (Usage)
sections prop은 다음 속성을 가진 객체 배열을 받아요.
value– 링을 채울 비율을 나타내는 0~100 사이의 숫자color– theme.colors의 세그먼트 색상 또는 어떤 CSS 색상 값tooltip(선택) – 섹션 위에 마우스를 올렸을 때 표시할 React 노드- 유효한 SVG
<circle>요소 prop (onClick, onMouseEnter, style 등)
참고: 예상대로 동작하려면 섹션 값의 합이 100% 이하여야 해요. 100%를 초과하면 섹션이 겹치게 돼요.
import { RingProgress, Text } from '@mantine/core';
function Demo() {
return (
<RingProgress
label={<Text size="xs">Application data usage</Text>}
sections={[
{ value: 40, color: 'cyan' },
{ value: 15, color: 'orange' },
{ value: 15, color: 'grape' },
]}
/>
);
}
크기, 두께와 둥근 모서리 (Size, thickness & rounded caps)
size, thickness, roundCaps prop으로 RingProgress의 크기와 두께를 설정해요.
import { RingProgress } from '@mantine/core';
function Demo() {
return (
<RingProgress
size={160}
thickness={12}
roundCaps
sections={[
{ value: 40, color: 'cyan' },
{ value: 15, color: 'orange' },
{ value: 15, color: 'grape' },
]}
/>
);
}
섹션 툴팁 (Sections tooltips)
섹션에 tooltip 속성을 추가하면 사용자가 섹션 위에 마우스를 올렸을 때 떠다니는 Tooltip이 표시돼요.
import { RingProgress, Text } from '@mantine/core';
function Demo() {
return (
<RingProgress
label={<Text size="xs">Hover sections to see tooltips</Text>}
sections={[
{ value: 40, color: 'cyan', tooltip: 'Documents – 40 Gb' },
{ value: 25, color: 'orange', tooltip: 'Apps – 25 Gb' },
{ value: 15, color: 'grape', tooltip: 'Other – 15 Gb' },
]}
/>
);
}
섹션 간격 (Section gaps)
sectionGap prop으로 섹션 사이에 시각적 구분을 추가할 수 있어요. 간격은 도(degrees) 단위로 지정해요.
import { RingProgress, Stack, Text } from '@mantine/core';
function Demo() {
const sections = [
{ value: 40, color: 'cyan' },
{ value: 25, color: 'orange' },
{ value: 15, color: 'grape' },
];
return (
<Stack>
<Text>No gap (default)</Text>
<RingProgress sections={sections} sectionGap={0} />
<Text>5° gap</Text>
<RingProgress sections={sections} sectionGap={5} />
<Text>10° gap</Text>
<RingProgress sections={sections} sectionGap={10} />
</Stack>
);
}
시작 각도 (Start angle)
startAngle prop으로 진행률이 시작되는 위치를 제어해요. 각도는 도 단위로 지정하며, 0 = 오른쪽, 90 = 아래, 180 = 왼쪽, 270 = 위(기본값)를 나타내요.
import { Group, RingProgress, Stack, Text } from '@mantine/core';
function Demo() {
const sections = [{ value: 40, color: 'cyan' }];
return (
<Group>
<Stack><Text>0° (right)</Text><RingProgress sections={sections} startAngle={0} /></Stack>
<Stack><Text>90° (bottom)</Text><RingProgress sections={sections} startAngle={90} /></Stack>
<Stack><Text>180° (left)</Text><RingProgress sections={sections} startAngle={180} /></Stack>
<Stack><Text>270° (top)</Text><RingProgress sections={sections} startAngle={270} /></Stack>
</Group>
);
}
배경 색상 (Background color)
rootColor prop으로 링에서 채워지지 않은 부분(배경)의 색상을 커스터마이즈할 수 있어요.
import { RingProgress } from '@mantine/core';
function Demo() {
return (
<RingProgress
sections={[{ value: 40, color: 'cyan' }]}
rootColor="var(--mantine-color-gray-4)"
/>
);
}
섹션 이벤트 (Section events)
각 섹션은 유효한 SVG <circle> 요소 prop을 받을 수 있어요. onClick, onMouseEnter, onMouseLeave 같은 이벤트 핸들러도 포함해요.
import { useState } from 'react';
import { RingProgress, Text } from '@mantine/core';
function Demo() {
const [hovered, setHovered] = useState(-1);
const reset = () => setHovered(-1);
return (
<>
<RingProgress
onMouseLeave={() => setHovered(-1)}
size={140}
sections={[
{ value: 40, color: 'cyan', onMouseEnter: () => setHovered(0), onMouseLeave: reset },
{ value: 20, color: 'blue', onMouseEnter: () => setHovered(1), onMouseLeave: reset },
{ value: 15, color: 'indigo', onMouseEnter: () => setHovered(2), onMouseLeave: reset },
]}
/>
<Text>Hovered section: {hovered === -1 ? 'none' : hovered}</Text>
</>
);
}
라벨 커스터마이즈 (Customize label)
라벨로 어떤 React 노드든 추가할 수 있어요. 예를 들어 커스텀 스타일의 Text 컴포넌트나 ActionIcon을 넣을 수 있어요.
import { ActionIcon, RingProgress, Text, Center } from '@mantine/core';
import { CheckIcon } from '@phosphor-icons/react';
function Demo() {
return (
<>
<RingProgress
label={
<Text c="blue" fw={700} ta="center" size="xl">
40%
</Text>
}
sections={[{ value: 40, color: 'cyan' }]}
/>
<RingProgress
sections={[{ value: 100, color: 'teal' }]}
label={
<Center>
<ActionIcon color="teal" variant="light" radius="xl" size={44}>
<CheckIcon size={22} />
</ActionIcon>
</Center>
}
/>
</>
);
}
채워진 세그먼트 전환 (Filled segment transition)
기본적으로 전환은 비활성화돼 있어요. 활성화하려면 transitionDuration prop을 밀리초 단위 숫자로 설정해요.
import { useState } from 'react';
import { Button, RingProgress, Stack, Text } from '@mantine/core';
function Demo() {
const [value, setValue] = useState(30);
return (
<>
<RingProgress
sections={[{ value, color: 'cyan' }]}
transitionDuration={300}
label={<Text>{value}%</Text>}
/>
<Button onClick={() => setValue(Math.floor(Math.random() * 100))}>Set random value</Button>
</>
);
}