73 lines
2.0 KiB
Dart
73 lines
2.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import '../theme/app_colors.dart';
|
|
|
|
/// ドット・ステッパー型のステップインジケーター
|
|
///
|
|
/// Kintone の申込フローで実績のあるデザインパターンを採用
|
|
/// 数字表記なしで、ドットと線だけで進捗を直感的に表現
|
|
class StepIndicator extends StatelessWidget {
|
|
final int currentStep; // 1, 2, 3
|
|
final int totalSteps; // 通常は 3
|
|
|
|
const StepIndicator({
|
|
super.key,
|
|
required this.currentStep,
|
|
this.totalSteps = 3,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final appColors = Theme.of(context).extension<AppColors>()!;
|
|
|
|
return Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: List.generate(totalSteps * 2 - 1, (index) {
|
|
// 偶数インデックス: ドット
|
|
// 奇数インデックス: 連結線
|
|
if (index.isEven) {
|
|
final stepNumber = index ~/ 2 + 1;
|
|
final isActive = stepNumber <= currentStep;
|
|
return _buildDot(context, isActive, appColors);
|
|
} else {
|
|
return _buildLine(appColors);
|
|
}
|
|
}),
|
|
);
|
|
}
|
|
|
|
/// ドット (円) を生成
|
|
///
|
|
/// - 完了済み: brandPrimary で塗りつぶし
|
|
/// - 未完了: グレーの枠線のみ
|
|
Widget _buildDot(BuildContext context, bool isActive, AppColors appColors) {
|
|
return Container(
|
|
width: 12,
|
|
height: 12,
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
color: isActive
|
|
? appColors.brandPrimary
|
|
: Colors.transparent,
|
|
border: Border.all(
|
|
color: isActive
|
|
? appColors.brandPrimary
|
|
: appColors.divider,
|
|
width: 2,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
/// 連結線を生成
|
|
///
|
|
/// ドット同士を繋ぐ細い線
|
|
Widget _buildLine(AppColors appColors) {
|
|
return Container(
|
|
width: 20,
|
|
height: 2,
|
|
color: appColors.divider,
|
|
margin: const EdgeInsets.symmetric(horizontal: 4),
|
|
);
|
|
}
|
|
}
|