Skip to content

Commit c722e69

Browse files
committed
feat(progress-indicator): review code
1 parent 40574ba commit c722e69

13 files changed

Lines changed: 122 additions & 76 deletions

File tree

app/lib/ui/components/progress_indicator/progress_indicator_customization_utils.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,14 @@ class ProgressIndicatorCustomizationUtils {
6464

6565
/// Parses the progress value from a string.
6666
static double getProgressValue(String progress) {
67-
return progress.isNotEmpty ? double.parse(progress) : 0.0;
67+
if (progress.isEmpty) return 0.0;
68+
try {
69+
final value = double.parse(progress);
70+
return value.clamp(0.0, 1.0); // Also clamp to valid range
71+
} catch (e) {
72+
debugPrint('Invalid progress value: $progress');
73+
return 0.0;
74+
}
6875
}
6976

7077
/// Returns the gap size used by the progress indicator.

ouds_core/lib/components/progress_indicator/internal/ouds_progress_indicator_utils.dart

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,13 @@ class OudsProgressIndicatorUtils {
6161
/// If [percentage] is `false`, the provided [helperText] is returned.
6262
///
6363
/// Returns an empty string when no helper text should be displayed.
64-
static String buildHelperText(
64+
static String? buildHelperText(
6565
bool percentage,
6666
bool spaceBeforePercentage,
6767
double? progress, // ou double/int selon ton type réel
6868
String? helperText,
6969
) {
70-
final progressValue = progress != null ? progress * 100 : 0;
70+
final progressValue = progress != null ? (progress * 100).round() : 0;
7171
if (percentage) {
7272
return spaceBeforePercentage ? '$progressValue %' : '$progressValue%';
7373
}
@@ -76,9 +76,13 @@ class OudsProgressIndicatorUtils {
7676
return helperText;
7777
}
7878

79-
return '';
79+
return null;
8080
}
8181

82+
/// Builds the accessibility status text associated with an [OudsIconStatus].
83+
///
84+
/// This helper returns a localized semantic label intended for assistive
85+
/// technologies, such as screen readers.
8286
static String? buildStatusSemanticsLabel(
8387
OudsLocalizations? localizations,
8488
OudsIconStatus status,
@@ -91,4 +95,31 @@ class OudsProgressIndicatorUtils {
9195
? localizations?.core_common_info_a11y
9296
: null;
9397
}
98+
99+
/// Returns `true` when the progress indicator should animate its value.
100+
///
101+
/// Animation is only enabled for determinate indicators when [animated]
102+
/// is set to `true`.
103+
static bool shouldAnimate(
104+
OudsProgressIndicatorType? progressType,
105+
bool animated,
106+
) {
107+
return progressType == OudsProgressIndicatorType.determinate && animated;
108+
}
109+
110+
/// Returns the normalized progress value used by the indicator.
111+
///
112+
/// This helper delegates to [OudsProgressIndicatorUtils.getProgressValue]
113+
/// and ensures the resulting value is clamped between `0.0` and `1.0`.
114+
///
115+
/// Returns `null` for indeterminate indicators.
116+
static double? clampedProgressValue(
117+
OudsProgressIndicatorType? progressType,
118+
double? progress,
119+
) {
120+
return OudsProgressIndicatorUtils.getProgressValue(
121+
progressType,
122+
progress,
123+
)?.clamp(0.0, 1.0);
124+
}
94125
}

ouds_core/lib/components/progress_indicator/ouds_circular_progress_indicator.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
library;
1414

1515
import 'package:flutter/material.dart';
16+
import 'package:ouds_core/components/progress_indicator/ouds_progress_indicator.dart';
1617
import 'package:ouds_theme_contract/ouds_theme.dart';
1718

1819
/// A temporary circular progress indicator component
1920
/// used internally by several public components like text input.
21+
/// It will be replaced with [OudsProgressIndicator] in the future.
2022
class OudsCircularProgressIndicator extends StatelessWidget {
2123
const OudsCircularProgressIndicator({
2224
super.key,

ouds_core/lib/components/progress_indicator/ouds_progress_indicator.dart

Lines changed: 51 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,13 @@ abstract class OudsProgressIndicator extends StatefulWidget {
108108
///
109109
/// ```dart
110110
/// OudsCircularProgressIndicator(
111-
/// progressType: OudsProgressIndicatorType.determinate,
112-
/// status: Positive(),
113-
/// progress: 80,
114-
/// track: false,
115-
/// animated: true,
116-
/// gapSize: OudsCircularIndicatorGapSize.small
117-
/// );
111+
/// progressType: OudsProgressIndicatorType.determinate,
112+
/// status: Positive(),
113+
/// progress: 0.8,
114+
/// track: false,
115+
/// animated: true,
116+
/// gapSize: OudsProgressIndicatorGapSize.small,
117+
/// )
118118
/// ```
119119
///
120120
class OudsCircularProgressIndicator extends OudsProgressIndicator {
@@ -143,7 +143,7 @@ class _OudsCircularProgressIndicatorState
143143
final textScaler = MediaQuery.textScalerOf(context);
144144

145145
final defaultSize = textScaler.scale(_oudsCircularProgressIndicatorSize);
146-
final progressValue = _clampedProgressValue(
146+
final progressValue = OudsProgressIndicatorUtils.clampedProgressValue(
147147
widget.progressType,
148148
widget.progress,
149149
);
@@ -153,7 +153,10 @@ class _OudsCircularProgressIndicatorState
153153
final strokeWidth = styleModifier.computeStrokeWidth(defaultSize);
154154
final strokeCap = styleModifier.getStrokeCap(widget.gapSize);
155155

156-
if (_shouldAnimate(widget.progressType, widget.animated)) {
156+
if (OudsProgressIndicatorUtils.shouldAnimate(
157+
widget.progressType,
158+
widget.animated,
159+
)) {
157160
return TweenAnimationBuilder<double>(
158161
tween: Tween<double>(begin: 0, end: progressValue ?? 0.0),
159162
duration: _animationDuration,
@@ -198,8 +201,13 @@ class _OudsCircularProgressIndicatorState
198201
required StrokeCap strokeCap,
199202
}) {
200203
final localizations = OudsLocalizations.of(context);
201-
final semanticsLabel =
202-
'${widget.semanticLabel} , ${OudsProgressIndicatorUtils.buildStatusSemanticsLabel(localizations, widget.status) ?? ''}, ';
204+
final statusLabel = OudsProgressIndicatorUtils.buildStatusSemanticsLabel(
205+
localizations,
206+
widget.status,
207+
);
208+
final semanticsLabel = statusLabel != null
209+
? '${widget.semanticLabel}, $statusLabel'
210+
: widget.semanticLabel ?? '';
203211

204212
return CircularProgressIndicator(
205213
semanticsLabel: semanticsLabel,
@@ -269,7 +277,8 @@ class _OudsCircularProgressIndicatorState
269277
/// percentage: false,
270278
/// spaceBeforePercentage: false,
271279
/// )
272-
/// `
280+
/// ```
281+
///
273282
class OudsLinearProgressIndicator extends OudsProgressIndicator {
274283
final bool stopIndicator;
275284
final String? helperText;
@@ -324,20 +333,25 @@ class _OudsLinearProgressIndicatorState
324333
);
325334
}
326335

327-
Widget _buildHelperTextWidget() {
328-
return Text(
329-
OudsProgressIndicatorUtils.buildHelperText(
330-
widget.percentage,
331-
widget.spaceBeforePercentage,
332-
widget.progress,
333-
widget.helperText,
334-
),
335-
style: OudsTheme.of(context).typographyTokens
336-
.typeLabelDefaultMedium(context)
337-
.copyWith(
338-
color: OudsTheme.of(context).colorScheme(context).contentDefault,
339-
),
336+
Widget? _buildHelperTextWidget() {
337+
final helperTextLabel = OudsProgressIndicatorUtils.buildHelperText(
338+
widget.percentage,
339+
widget.spaceBeforePercentage,
340+
widget.progress,
341+
widget.helperText,
340342
);
343+
return helperTextLabel != null && helperTextLabel.isNotEmpty
344+
? Text(
345+
helperTextLabel,
346+
style: OudsTheme.of(context).typographyTokens
347+
.typeLabelDefaultMedium(context)
348+
.copyWith(
349+
color: OudsTheme.of(
350+
context,
351+
).colorScheme(context).contentDefault,
352+
),
353+
)
354+
: null;
341355
}
342356

343357
/// Builds the visual [LinearProgressIndicator].
@@ -373,14 +387,17 @@ class _OudsLinearProgressIndicatorState
373387
widget.track,
374388
);
375389

376-
final progressValue = _clampedProgressValue(
390+
final progressValue = OudsProgressIndicatorUtils.clampedProgressValue(
377391
widget.progressType,
378392
widget.progress,
379393
);
380394

381395
final borderRadius = progressIndicatorStyleModifier.getBorderRadius();
382396

383-
if (_shouldAnimate(widget.progressType, widget.animated)) {
397+
if (OudsProgressIndicatorUtils.shouldAnimate(
398+
widget.progressType,
399+
widget.animated,
400+
)) {
384401
return TweenAnimationBuilder<double>(
385402
tween: Tween<double>(begin: 0, end: progressValue ?? 0.0),
386403
duration: _animationDuration,
@@ -422,9 +439,13 @@ class _OudsLinearProgressIndicatorState
422439
required BorderRadiusGeometry borderRadius,
423440
}) {
424441
final localizations = OudsLocalizations.of(context);
425-
426-
final semanticsLabel =
427-
'${widget.semanticLabel} , ${OudsProgressIndicatorUtils.buildStatusSemanticsLabel(localizations, widget.status) ?? ''}, ';
442+
final statusLabel = OudsProgressIndicatorUtils.buildStatusSemanticsLabel(
443+
localizations,
444+
widget.status,
445+
);
446+
final semanticsLabel = statusLabel != null
447+
? '${widget.semanticLabel}, $statusLabel'
448+
: widget.semanticLabel ?? '';
428449

429450
return LinearProgressIndicator(
430451
minHeight: minHeight,
@@ -440,27 +461,3 @@ class _OudsLinearProgressIndicatorState
440461
);
441462
}
442463
}
443-
444-
/// Returns `true` when the progress indicator should animate its value.
445-
///
446-
/// Animation is only enabled for determinate indicators when [animated]
447-
/// is set to `true`.
448-
bool _shouldAnimate(OudsProgressIndicatorType? progressType, bool animated) {
449-
return progressType == OudsProgressIndicatorType.determinate && animated;
450-
}
451-
452-
/// Returns the normalized progress value used by the indicator.
453-
///
454-
/// This helper delegates to [OudsProgressIndicatorUtils.getProgressValue]
455-
/// and ensures the resulting value is clamped between `0.0` and `1.0`.
456-
///
457-
/// Returns `null` for indeterminate indicators.
458-
double? _clampedProgressValue(
459-
OudsProgressIndicatorType? progressType,
460-
double? progress,
461-
) {
462-
return OudsProgressIndicatorUtils.getProgressValue(
463-
progressType,
464-
progress,
465-
)?.clamp(0.0, 1.0);
466-
}

ouds_theme_contract/lib/theme/tokens/components/ouds_progressIndicatorMono_tokens.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// Software description: Flutter library of reusable graphical components
1111
//
1212

13-
// Orange brand tokens version 2.5.0
13+
// Orange brand tokens version 2.6.0
1414
// Generated by Tokenator
1515

1616
import 'package:flutter/material.dart';

ouds_theme_contract/lib/theme/tokens/components/ouds_progressIndicator_tokens.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// Software description: Flutter library of reusable graphical components
1111
//
1212

13-
// Orange brand tokens version 2.5.0
13+
// Orange brand tokens version 2.6.0
1414
// Generated by Tokenator
1515

1616
import 'package:flutter/material.dart';

ouds_theme_orange/lib/components/orange_progressIndicator_tokens.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// Software description: Flutter library of reusable graphical components
1111
//
1212

13-
// Orange brand tokens version 2.5.0
13+
// Orange brand tokens version 2.6.0
1414
// Generated by Tokenator
1515

1616
import 'package:flutter/material.dart';
@@ -31,9 +31,11 @@ class OrangeProgressIndicatorTokens extends OudsProgressIndicatorTokens {
3131
@override
3232
Color get colorContentTrackDark => ColorRawTokens.colorFunctionalGrayDark480;
3333
@override
34-
Color get colorContentTrackLight => ColorRawTokens.colorFunctionalGrayLight400;
34+
Color get colorContentTrackLight =>
35+
ColorRawTokens.colorFunctionalGrayLight400;
3536
@override
3637
double get sizeLinearIndicatorHeight => DimensionRawTokens.dimension50;
3738
@override
38-
double get spacePaddingBlock => providersTokens.spaceTokens.paddingBlockXsmall;
39+
double get spacePaddingBlock =>
40+
providersTokens.spaceTokens.paddingBlockXsmall;
3941
}

ouds_theme_orange_compact/lib/components/orangeCompact_progressIndicatorMono_tokens.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// Software description: Flutter library of reusable graphical components
1111
//
1212

13-
// Orange Compact brand tokens version 2.5.0
13+
// Orange Compact brand tokens version 2.6.0
1414
// Generated by Tokenator
1515

1616
import 'package:flutter/material.dart';

ouds_theme_orange_compact/lib/components/orangeCompact_progressIndicator_tokens.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// Software description: Flutter library of reusable graphical components
1111
//
1212

13-
// Orange Compact brand tokens version 2.5.0
13+
// Orange Compact brand tokens version 2.6.0
1414
// Generated by Tokenator
1515

1616
import 'package:flutter/material.dart';
@@ -31,9 +31,11 @@ class OrangeCompactProgressIndicatorTokens extends OudsProgressIndicatorTokens {
3131
@override
3232
Color get colorContentTrackDark => ColorRawTokens.colorFunctionalGrayDark480;
3333
@override
34-
Color get colorContentTrackLight => ColorRawTokens.colorFunctionalGrayLight400;
34+
Color get colorContentTrackLight =>
35+
ColorRawTokens.colorFunctionalGrayLight400;
3536
@override
3637
double get sizeLinearIndicatorHeight => DimensionRawTokens.dimension50;
3738
@override
38-
double get spacePaddingBlock => providersTokens.spaceTokens.paddingBlockXsmall;
39+
double get spacePaddingBlock =>
40+
providersTokens.spaceTokens.paddingBlockXsmall;
3941
}

ouds_theme_sosh/lib/components/sosh_progressIndicatorMono_tokens.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// Software description: Flutter library of reusable graphical components
1111
//
1212

13-
// Sosh brand tokens version 2.5.0
13+
// Sosh brand tokens version 2.6.0
1414
// Generated by Tokenator
1515

1616
import 'package:flutter/material.dart';

0 commit comments

Comments
 (0)