Stepper#
사용자가 단계를 클릭하여 이동할 수 있는 인터랙티브 프로세스 컴포넌트입니다.
Live Preview#
class StepperDefaultExample extends StatefulComponent {
const StepperDefaultExample({super.key});
@override
State<StepperDefaultExample> createState() => _StepperDefaultExampleState();
}
class _StepperDefaultExampleState extends State<StepperDefaultExample> {
int _currentStep = 1;
void handleStepChanged(int index) {
setState(() {
_currentStep = index;
});
}
@override
Component build(BuildContext context) {
return CoStepper(
currentStep: _currentStep,
onStepChanged: handleStepChanged,
steps: const [
CoreCoStepItem(label: 'Account', description: 'Create account'),
CoreCoStepItem(label: 'Profile', description: 'Set up profile'),
CoreCoStepItem(label: 'Complete', description: 'All done'),
],
);
}
}
class StepperDefaultExample extends StatefulWidget {
const StepperDefaultExample({super.key});
@override
State<StepperDefaultExample> createState() => _StepperDefaultExampleState();
}
class _StepperDefaultExampleState extends State<StepperDefaultExample> {
int _currentStep = 1;
void handleStepChanged(int index) {
setState(() {
_currentStep = index;
});
}
@override
Widget build(BuildContext context) {
return CoStepper(
currentStep: _currentStep,
onStepChanged: handleStepChanged,
steps: const [
CoreCoStepItem(label: 'Account', description: 'Create account'),
CoreCoStepItem(label: 'Profile', description: 'Set up profile'),
CoreCoStepItem(label: 'Complete', description: 'All done'),
],
);
}
}
class StepperVerticalExample extends StatefulComponent {
const StepperVerticalExample({super.key});
@override
State<StepperVerticalExample> createState() => _StepperVerticalExampleState();
}
class _StepperVerticalExampleState extends State<StepperVerticalExample> {
int _currentStep = 1;
void handleStepChanged(int index) {
setState(() {
_currentStep = index;
});
}
@override
Component build(BuildContext context) {
return CoStepper(
currentStep: _currentStep,
orientation: CoreStepperOrientation.vertical,
onStepChanged: handleStepChanged,
steps: const [
CoreCoStepItem(label: 'Account', description: 'Create account'),
CoreCoStepItem(label: 'Profile', description: 'Set up profile'),
CoreCoStepItem(label: 'Complete', description: 'All done'),
],
);
}
}
class StepperVerticalExample extends StatefulWidget {
const StepperVerticalExample({super.key});
@override
State<StepperVerticalExample> createState() => _StepperVerticalExampleState();
}
class _StepperVerticalExampleState extends State<StepperVerticalExample> {
int _currentStep = 1;
void handleStepChanged(int index) {
setState(() {
_currentStep = index;
});
}
@override
Widget build(BuildContext context) {
return CoStepper(
currentStep: _currentStep,
orientation: CoreStepperOrientation.vertical,
onStepChanged: handleStepChanged,
steps: const [
CoreCoStepItem(label: 'Account', description: 'Create account'),
CoreCoStepItem(label: 'Profile', description: 'Set up profile'),
CoreCoStepItem(label: 'Complete', description: 'All done'),
],
);
}
}
사용 시기 (When to Use)#
이 컴포넌트를 사용하세요:
- 회원가입, 결제, 설정 마법사 등 다단계 폼
- 사용자가 이전 단계로 돌아가거나 특정 단계로 점프할 수 있어야 할 때
대신 다른 컴포넌트를 사용하세요:
Steps: 읽기 전용 진행 상태 표시 (탭 불가)Tabs: 독립적인 콘텐츠 간 전환 (순서/진행 개념 없음)
기본 사용법 (Basic Usage)#
CoStepper(
currentStep: 1,
steps: [
CoreCoStepItem(label: 'Account', description: 'Create account'),
CoreCoStepItem(label: 'Profile', description: 'Set up profile'),
CoreCoStepItem(label: 'Complete', description: 'All done'),
],
onStepChanged: (index) => setState(() => _step = index),
)
Props / Parameters#
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
steps | List<CoreCoStepItem> | 필수 | 단계 목록 |
currentStep |
int |
0 |
현재 활성 단계 인덱스 |
orientation |
CoreStepperOrientation |
.horizontal |
배치 방향 (horizontal/vertical) |
onStepChanged |
void Function(int)? |
null |
단계 클릭 시 호출 |
stepperStyle |
CoreStepperStyle<Color>? / CoreStepperStyle<CoreColor>? |
null |
인스턴스 스타일 (Style 시스템 참조) |
스타일 시스템 (Style System)#
Stepper 의 모든 chrome / dimensional / nested-slot 오버라이드는 CoreStepperStyle<Clr> 단일 슬롯으로 흐릅니다 (Epic #1302 원칙 6/7/8). 시맨틱 enum (orientation) 과 behaviour (steps
/ currentStep / onStepChanged) 는 위젯/컴포넌트 파라미터로 직접 전달합니다.
시맨틱 vs 스타일#
-
시맨틱 enum / behaviour: 위젯/컴포넌트 파라미터로 직접 (
steps,currentStep,orientation,onStepChanged) -
chrome / dimensional / 슬롯 스타일:
CoreStepperStyle한 곳으로 (indicatorActiveColor/indicatorInactiveColor/indicatorBorderColor/indicatorBorderWidth/indicatorSize/connectorActiveColor/connectorInactiveColor/connectorThickness/gap/labelStyle/descriptionStyle/indicatorIconStyle)
Resolve chain#
design system default for stepper
→ CoreStepperTheme.style // 프로젝트 공통
→ parent component slot override
→ widget.stepperStyle // 인스턴스별
각 nested 슬롯 스타일 (labelStyle / descriptionStyle / indicatorIconStyle) 은 자기 컴포넌트의 자체 resolve chain 으로 다시 한 번 머지됩니다.
슬롯 매핑 (CoreStepperStyle 12 필드)#
| 필드 | 타입 (Flutter) | 적용 영역 |
|---|---|---|
indicatorActiveColor | Color? | 활성/완료 단계 인디케이터 fill |
indicatorInactiveColor | Color? | 대기 단계 인디케이터 fill |
indicatorBorderColor | Color? | 인디케이터 보더 색 |
indicatorBorderWidth | double? | 인디케이터 보더 두께 (px) |
indicatorSize | double? | 인디케이터 지름 (px) |
connectorActiveColor | Color? | 완료 연결선 색 |
connectorInactiveColor | Color? | 대기 연결선 색 |
connectorThickness | double? | 연결선 두께 (px) |
gap | double? | 단계 블록 간격 (px) |
labelStyle |
CoreTextStyle<Color>? |
단계 라벨 텍스트 스타일 |
descriptionStyle |
CoreTextStyle<Color>? |
단계 설명 텍스트 스타일 |
indicatorIconStyle |
CoreIconStyle<Color>? |
인디케이터 체크 아이콘 스타일 |
Migration#
기존 CoreStepperTheme 의 평면 chrome (indicatorSize / connectorThickness
/ activeColor / completedColor / inactiveColor / errorColor) 은 호환을 위해 유지되지만, 새 코드는
stepperStyle 슬롯을 사용하세요:
| 기존 (legacy theme 필드) | 새 위치 |
|---|---|
CoreStepperTheme.indicatorSize |
stepperStyle.indicatorSize 또는 CoreStepperTheme.style.indicatorSize |
CoreStepperTheme.connectorThickness |
stepperStyle.connectorThickness |
CoreStepperTheme.activeColor |
stepperStyle.indicatorActiveColor |
CoreStepperTheme.completedColor |
stepperStyle.connectorActiveColor |
CoreStepperTheme.inactiveColor |
stepperStyle.indicatorInactiveColor 또는 connectorInactiveColor |
| 인스턴스 라벨 텍스트 스타일 (불가능) | stepperStyle.labelStyle |
| 인스턴스 설명 텍스트 스타일 (불가능) | stepperStyle.descriptionStyle |
| 인스턴스 아이콘 색/사이즈 (불가능) | stepperStyle.indicatorIconStyle |
사용 예 (Flutter)#
CoStepper(
currentStep: 1,
steps: [
CoreCoStepItem(label: 'Account'),
CoreCoStepItem(label: 'Details'),
CoreCoStepItem(label: 'Confirm'),
],
onStepChanged: (i) => setState(() => _step = i),
stepperStyle: CoreStepperStyle(
indicatorActiveColor: Colors.blue,
indicatorSize: 28,
connectorThickness: 2,
labelStyle: CoreTextStyle(fontSize: 14, fontWeight: 600),
descriptionStyle: CoreTextStyle(fontSize: 12),
),
)
사용 예 (Web)#
CoStepper(
currentStep: 1,
steps: [
CoreCoStepItem(label: 'Account'),
CoreCoStepItem(label: 'Details'),
CoreCoStepItem(label: 'Confirm'),
],
onStepChanged: (i) => setState(() => _step = i),
stepperStyle: CoreStepperStyle<CoreColor>(
indicatorSize: 32,
connectorThickness: 2,
labelStyle: CoreTextStyle(fontSize: 14),
),
)
CoreCoStepItem#
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
label | String | 필수 | 단계 라벨 |
description |
String? |
null |
선택적 부가 설명 |
변형 (Variants)#
가로 배치#
CoStepper(
currentStep: 1,
orientation: CoreStepperOrientation.horizontal,
steps: [
CoreCoStepItem(label: '기본 정보'),
CoreCoStepItem(label: '주소 입력'),
CoreCoStepItem(label: '결제 수단'),
CoreCoStepItem(label: '확인'),
],
onStepChanged: (i) => setState(() => _step = i),
)
세로 배치#
CoStepper(
currentStep: 1,
orientation: CoreStepperOrientation.vertical,
steps: [
CoreCoStepItem(label: '기본 정보', description: '이름과 이메일'),
CoreCoStepItem(label: '주소 입력', description: '배송지 설정'),
CoreCoStepItem(label: '결제 수단', description: '카드 등록'),
],
onStepChanged: (i) => setState(() => _step = i),
)
동작 스펙 (Behavior)#
상태 표시#
currentStep미만: 완료 (primary 원 + 체크 아이콘)currentStep인덱스: 현재 (primary 원 + 번호, 볼드 라벨)currentStep초과: 대기 (surfaceContainer 원 + 번호)
인터랙션#
- 각 단계 인디케이터 클릭 →
onStepChanged(index)호출 - 키보드 네비게이션은 표준
Tab순서 따름
접근성 (Accessibility)#
키보드#
| 키 | 동작 |
|---|---|
Tab | 다음 단계로 포커스 이동 |
Enter / Space | 포커스된 단계로 이동 |
스크린 리더#
- 각 단계는 순서 + 라벨 + 설명 읽음
- 완료/현재/대기 상태 시각 표시 기반
크로스 플랫폼 차이점 (Platform Differences)#
| 항목 | Flutter | Web |
|---|---|---|
| 클래스명 | CoStepper | CoStepper |
| 렌더링 | Column/Row + GestureDetector |
<div> + 인라인 스타일 |
| 아이콘 | CoIcon(CoLucideIcons.check) |
CoIcon(CoLucideIcons.check) |
| 테마 | CoreStepperTheme | CoreStepperTheme |