Progress#
작업 진행률을 시각적으로 표시하는 컴포넌트입니다. 직선형(Progress)과 원형(RadialProgress)을 지원합니다.
Live Preview#
class ProgressDefaultExample extends StatefulComponent {
const ProgressDefaultExample({super.key});
@override
State<ProgressDefaultExample> createState() => _ProgressDefaultExampleState();
}
class _ProgressDefaultExampleState extends State<ProgressDefaultExample> {
@override
Component build(BuildContext context) {
return Progress(value: 0.65);
}
}
class ProgressDefaultExample extends StatefulWidget {
const ProgressDefaultExample({super.key});
@override
State<ProgressDefaultExample> createState() => _ProgressDefaultExampleState();
}
class _ProgressDefaultExampleState extends State<ProgressDefaultExample> {
@override
Widget build(BuildContext context) {
return const SizedBox(
width: double.infinity,
child: Progress(value: 0.65),
);
}
}
class ProgressIndeterminateExample extends StatelessComponent {
const ProgressIndeterminateExample({super.key});
@override
Component build(BuildContext context) {
return const Progress();
}
}
class ProgressIndeterminateExample extends StatelessWidget {
const ProgressIndeterminateExample({super.key});
@override
Widget build(BuildContext context) {
return const SizedBox(
width: double.infinity,
child: Progress(),
);
}
}
class ProgressRadialExample extends StatefulComponent {
const ProgressRadialExample({super.key});
@override
State<ProgressRadialExample> createState() => _ProgressRadialExampleState();
}
class _ProgressRadialExampleState extends State<ProgressRadialExample> {
@override
Component build(BuildContext context) {
return RadialProgress(
value: 75,
showValueText: true,
);
}
}
class ProgressRadialExample extends StatefulWidget {
const ProgressRadialExample({super.key});
@override
State<ProgressRadialExample> createState() => _ProgressRadialExampleState();
}
class _ProgressRadialExampleState extends State<ProgressRadialExample> {
@override
Widget build(BuildContext context) {
return const RadialProgress(
value: 75,
showValueText: true,
);
}
}
class ProgressChainExample extends StatefulComponent {
const ProgressChainExample({super.key});
@override
State<ProgressChainExample> createState() => _ProgressChainExampleState();
}
class _ProgressChainExampleState extends State<ProgressChainExample> {
@override
Component build(BuildContext context) {
return div(
[
// 토큰-정확 getter combo — 이름이 곧 값 (getter 이름 = Core 토큰 상수 1:1).
Progress(value: 0.65).radius16.primary,
const Gap.space12(),
// withStyle full-control — getter 가 없는 필드(minHeight)까지 한 번에.
Progress(value: 0.65).withStyle(
const CoreProgressStyle(
color: CoreColor.token(CoreColors.tertiary),
borderRadius: CoreBorderRadius.all(CoreRadius.radius24),
minHeight: CoreSpace.space16,
),
),
],
classes: 'flex flex-col items-start',
);
}
}
class ProgressChainExample extends StatefulWidget {
const ProgressChainExample({super.key});
@override
State<ProgressChainExample> createState() => _ProgressChainExampleState();
}
class _ProgressChainExampleState extends State<ProgressChainExample> {
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 토큰-정확 getter combo — 이름이 곧 값 (getter 이름 = Core 토큰 상수 1:1).
SizedBox(
width: double.infinity,
child: const Progress(value: 0.65).radius16.primary,
),
const Gap.space12(),
// withStyle full-control — getter 가 없는 필드(minHeight)까지 한 번에.
SizedBox(
width: double.infinity,
child: const Progress(value: 0.65).withStyle(
const CoreProgressStyle(
color: CoreColor.token(CoreColors.tertiary),
borderRadius: CoreBorderRadius.all(CoreRadius.radius24),
minHeight: CoreSpace.space16,
),
),
),
],
);
}
}
사용 시기 (When to Use)#
이 컴포넌트를 사용하세요:
- 파일 업로드, 다운로드 등 작업 진행률을 표시할 때
- 목표 달성률, 스토리지 사용량 등 비율을 시각화할 때
대신 다른 컴포넌트를 사용하세요:
Loading: 단순 로딩 스피너가 필요할 때Skeleton: 콘텐츠 로딩 플레이스홀더가 필요할 때Slider: 사용자가 값을 조절해야 할 때
기본 사용법 (Basic Usage)#
// 기본 진행률 바 (0.0 ~ 1.0 범위)
Progress(value: 0.65)
// 커스텀 min/max 범위 지정
Progress(value: 75, min: 0, max: 100)
// 색상/두께 커스터마이징은 progressStyle 슬롯으로
Progress(
value: 0.5,
progressStyle: CoreProgressStyle(
color: CoreColor.token(CoreColors.tertiary),
minHeight: 12,
),
)
// 원형 진행률
RadialProgress(
value: 75,
showValueText: true,
)
// 원형 크기/두께 커스터마이징
RadialProgress(
value: 50,
radialProgressStyle: CoreRadialProgressStyle(size: 120, strokeWidth: 12),
)
// 기본 진행률 바 (0.0 ~ 1.0 범위)
Progress(value: 0.65)
// 커스텀 min/max 범위 지정
Progress(value: 75, min: 0, max: 100)
// 색상/두께 커스터마이징은 progressStyle 슬롯으로
Progress(
value: 0.5,
progressStyle: CoreProgressStyle(
color: CoreColor.token(CoreColors.tertiary),
minHeight: 12,
),
)
// 원형 진행률
RadialProgress(
value: 75,
showValueText: true,
)
// 원형 크기/두께 커스터마이징
RadialProgress(
value: 50,
radialProgressStyle: CoreRadialProgressStyle(size: 120, strokeWidth: 12),
)
빠른 오버라이드 (Chain)#
이미 만든 Progress 인스턴스에 스타일을 빠르게 덧붙이고 싶다면 withStyle 체인을 쓸 수 있습니다. 생성자의 style 슬롯 인자와 동일하게 동작하지만, 이미 구성된 위젯 위에서 바로 이어 쓸 수 있습니다.
.radius9999처럼 Core 토큰 상수 이름과 똑같은 이름의 getter도 있습니다 — withStyle을 한 번 더 줄인 sugar로, 이름이 곧 값이라(radius9999 ==
CoreRadius.radius9999) 어느 컴포넌트에서 써도 뜻이 갈리지 않습니다.
class ProgressChainExample extends StatefulWidget {
const ProgressChainExample({super.key});
@override
State<ProgressChainExample> createState() => _ProgressChainExampleState();
}
class _ProgressChainExampleState extends State<ProgressChainExample> {
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 토큰-정확 getter combo — 이름이 곧 값 (getter 이름 = Core 토큰 상수 1:1).
SizedBox(
width: double.infinity,
child: const Progress(value: 0.65).radius16.primary,
),
const Gap.space12(),
// withStyle full-control — getter 가 없는 필드(minHeight)까지 한 번에.
SizedBox(
width: double.infinity,
child: const Progress(value: 0.65).withStyle(
const CoreProgressStyle(
color: CoreColor.token(CoreColors.tertiary),
borderRadius: CoreBorderRadius.all(CoreRadius.radius24),
minHeight: CoreSpace.space16,
),
),
),
],
);
}
}
class ProgressChainExample extends StatefulComponent {
const ProgressChainExample({super.key});
@override
State<ProgressChainExample> createState() => _ProgressChainExampleState();
}
class _ProgressChainExampleState extends State<ProgressChainExample> {
@override
Component build(BuildContext context) {
return div(
[
// 토큰-정확 getter combo — 이름이 곧 값 (getter 이름 = Core 토큰 상수 1:1).
Progress(value: 0.65).radius16.primary,
const Gap.space12(),
// withStyle full-control — getter 가 없는 필드(minHeight)까지 한 번에.
Progress(value: 0.65).withStyle(
const CoreProgressStyle(
color: CoreColor.token(CoreColors.tertiary),
borderRadius: CoreBorderRadius.all(CoreRadius.radius24),
minHeight: CoreSpace.space16,
),
),
],
classes: 'flex flex-col items-start',
);
}
}
Props / Parameters#
모든 chrome / dimensional override는 단일 Style 슬롯
(progressStyle / radialProgressStyle) 한 곳으로 모입니다. 위젯 평면 파라미터는
behaviour (value / min / max / disableAnimation / showValueText / child) 만 남습니다.
Progress (직선형)#
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
value |
double? |
null |
진행률 (0.0~1.0) — null → 무한 슬라이드 |
min | double | 0.0 | 최소값 |
max | double | 1.0 | 최대값 |
disableAnimation |
bool |
false |
결정형(determinate) 트랜지션 비활성화 |
progressStyle |
CoreProgressStyle? |
null |
chrome 슬롯 (아래 표) |
CoreProgressStyle 필드#
| 필드 | 타입 | 설명 |
|---|---|---|
color | CoreColor? | Progress fill colour override. |
backgroundColor |
CoreColor? |
Track background colour override.
null
(default) → renderer fades [color] by [backgroundAlpha] (or [defaultBackgroundAlpha]).
Deliberately has no default* — absence is the design.
Absence is what makes the track DERIVE from the arc: Flutter
arcColor.scaleAlpha(backgroundAlpha)
, Web
arcToken.withOpacity(backgroundAlpha)
. A fixed default stops the track following a recoloured arc and makes the sibling backgroundAlpha — whose contract is literally 'applied when backgroundColor is not set' — unreachable.
|
backgroundAlpha |
double? |
Track background alpha override applied when [backgroundColor] is not set.
null
(default) → renderer uses [defaultBackgroundAlpha].
|
borderRadius |
CoreBorderRadius? |
Border radius override. Applies to both track and indicator so rounded shapes remain visually consistent. |
minHeight |
double? |
Minimum height (thickness) override (logical px).
null
defers to [defaultsBySize] for the active
CoreProgressSize
.
|
duration |
Duration? |
Determinate width transition duration override. |
indeterminateDuration |
Duration? |
Indeterminate slide cycle duration override. |
RadialProgress (원형)#
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
value | double | 필수 | 진행률 (0~100) |
showValueText |
bool |
false |
퍼센트 텍스트 표시 |
child |
Widget? / Component? |
null |
중앙 커스텀 콘텐츠 |
radialProgressStyle |
CoreRadialProgressStyle? |
null |
chrome 슬롯 (아래 표) |
CoreRadialProgressStyle 필드 (chrome)
| 필드 | 타입 | 기본값 | 설명 |
|---|---|---|---|
color |
CoreColor? |
CoreColors.primary |
아크 색상 |
backgroundColor |
CoreColor? |
null → 아크 색을 backgroundAlpha로 페이드 |
트랙 링 색상 |
backgroundAlpha |
double? |
0.2 |
backgroundColor가 없을 때 트랙 링에 적용되는 알파 |
size |
double? |
CoreSize.size80 (80px) |
원 지름 |
strokeWidth |
double? |
CoreSpace.space8 (8px) |
링 두께 |
valueTextStyle |
CoreTextStyle? |
bodyLarge + onSurface + semi-bold |
중앙 퍼센트 텍스트 타이포그래피 (색 포함) |
동작 스펙 (Behavior)#
직선형#
value변경 시 부드러운 width 애니메이션 (300ms ease-in-out)- 인디케이터에 borderRadius 적용 — 양쪽 둥근 모양
- 트랙 배경 기본값: primary 색상의 20% 투명도
원형#
- 12시 방향(-π/2)에서 시작하는 원형 아크
strokeCap: round— 양쪽 끝 둥근 형태showValueText: true시 중앙에 "75%" 형태 표시
사용 가이드라인 (Usage Guidelines)#
Do#
원형 진행률은 대시보드 통계에 적합합니다.
RadialProgress(
value: 75,
showValueText: true,
)
공간이 제한된 카드에서 목표 달성률을 효과적으로 표시합니다.
Don't#
진행률이 멈춘 상태에서 아무 피드백 없이 두지 마세요.
진행이 느리면 "대용량 파일 처리 중..." 같은 텍스트를 추가하세요.
접근성 (Accessibility)#
ARIA 속성#
-
Web:
role="progressbar",aria-valuenow,aria-valuemin,aria-valuemax자동 적용 - Flutter: Semantics 노드에 진행률 값 전달
크로스 플랫폼 차이점 (Platform Differences)#
| 항목 | Flutter | Web |
|---|---|---|
| 클래스명 | Progress / RadialProgress |
Progress / RadialProgress |
| 값 범위 | 0.0~1.0 (기본) | 0.0~1.0 (기본) |
| 직선형 렌더링 | Container + AnimatedContainer |
div + inline style |
| 원형 렌더링 | CustomPaint (_RadialProgressPainter) |
inline
<svg>
+
<circle>
2개 (트랙 +
stroke-dasharray
/
stroke-dashoffset
아크)
|
| 애니메이션 | AnimatedContainer 300ms | CSS transition 300ms |