Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,134 @@
# Migration Guide

- [v2.1.0 → v3.0.0](#v210--v300)
- [v2.0.0 → v2.1.0](#v200--v210)
- [v1.3.1 → v2.0.0](#v131--v200)
- [v1.3.0 → v1.3.1](#v130--v131)
- [v1.2.0 → v1.3.0](#v120--v130)
- [v1.1.x → v1.2.0](#v11x--v120)
- [v1.0.0 → v1.1.1](#v100--v111)
- [Support](#support)

## v2.1.0 → v3.0.0

### Overview

This release adds the `List item` component and a typography tokens component, updates the icon library to v2.3.0, updates the `Button` component to v3.3.0 with tinted/untinted icon support, updates the `Link` component to v2.4.0, adds a `size` parameter to `OudsCircularProgressIndicator` for button integration, and fixes a crash in `OudsTabBar`. It also introduces a typed prefix/suffix icon configuration with tinting support for `OudsTextInput` and `OudsPhoneNumberInput`.

### Before You Begin

#### Prerequisites

- Use version 2.1.0 or older

### Breaking Changes

#### 1. `OudsTextInput` / `OudsPhoneNumberInput` — Typed prefix/suffix icon configuration with tinting support

`OudsFormInputDecoration.prefixIcon` and `suffixIcon` are no longer plain `String`/asset paths. They now take `OudsTextInputPrefixIcon` and `OudsTextInputSuffixIconButton` objects, which let you control whether the icon is tinted with the theme color or displayed with its original (multi-color) asset colors via a new `tinted` parameter (defaults to `true`). The `onSuffixPressed` parameter on the decoration has been removed; the press callback now lives on `OudsTextInputSuffixIconButton.onPressed`.

**Impact**: Medium (breaking — any code setting `prefixIcon`, `suffixIcon`, or `onSuffixPressed` on `OudsInputDecoration`/`OudsFormInputDecoration` must be updated)

**Before**:
```dart
OudsInputDecoration(
prefixIcon: 'assets/ic_heart.svg',
suffixIcon: 'assets/ic_heart.svg',
onSuffixPressed: () {},
)
```

**After**:
```dart
OudsInputDecoration(
prefixIcon: OudsTextInputPrefixIcon(
icon: 'assets/ic_heart.svg',
tinted: true, // optional, defaults to true
),
suffixIcon: OudsTextInputSuffixIconButton(
icon: 'assets/ic_heart.svg',
tinted: true, // optional, defaults to true
onPressed: () {},
),
)
```

**Required Action**:
- Wrap existing `prefixIcon` asset paths in `OudsTextInputPrefixIcon(icon: ...)`
- Wrap existing `suffixIcon` asset paths in `OudsTextInputSuffixIconButton(icon: ..., onPressed: ...)`, moving the `onSuffixPressed` callback into `onPressed`
- Set `tinted: false` if the icon asset is multi-color and should keep its original colors instead of being tinted with the theme color

**Reason for Change**: Support untinted (multi-color) leading and trailing icons in text and phone number inputs, consistent with the `tinted` behavior available in `OudsButton` and `OudsLink`

### Icon Library Update — v2.3.0

The OUDS icon library has been updated to version 2.3.0. Some icon names or asset paths may have changed.

**Impact**: Medium (if using icon constants from the library)

**Required Action**:
- Review any icon constants or asset paths you reference directly
- Update to the new icon names from v2.3.0 if you receive compilation errors or missing asset warnings

### New Components Added

| Component | Description |
|-----------|-------------|
| `OudsListItem` | Standard list item component with leading/trailing content support |

### Component Updates (Non-breaking)

| Component | Change |
|-----------|--------|
| Button | Updated to v3.3.0 — added `tinted` parameter (defaults to `true`) to control whether the icon follows the theme color or keeps its original (multi-color) asset colors |
| Link | Updated to v2.4.0 |
| Progress Indicator | Added `size` parameter to `OudsCircularProgressIndicator` for button integration |
| Tab Bar | Fixed `Invalid value: Not in inclusive range 0..2: 3` crash |
| Typography | Added typography tokens component |

### Compatibility

- **Backward Compatibility**: No (breaking change in form input decoration API)
- **v2.1.0 Support**: Ended with this release

## v2.0.0 → v2.1.0

### Overview

This release adds the `Navigation Button`, `Circular Progress Indicator`, and `Linear Progress Indicator` components, and updates design tokens to v2.6.0.

### Before You Begin

#### Prerequisites

- Use version 2.0.0 or older

### Breaking Changes

None.

### New Components Added

| Component | Description |
|-----------|-------------|
| `OudsNavigationButton` | Navigation button component |
| `OudsCircularProgressIndicator` | Circular (indeterminate/determinate) progress indicator |
| `OudsLinearProgressIndicator` | Linear (indeterminate/determinate) progress indicator |

### Token Updates — v2.6.0

Design tokens have been updated to version 2.6.0.

**Impact**: Low (only if overriding tokens directly in a custom theme)

**Required Action**:
- If you override tokens in a custom theme, audit your overrides against the new token names

### Compatibility

- **Backward Compatibility**: Yes
- **v2.0.0 Support**: Ended with this release

## v1.3.1 → v2.0.0

### Overview
Expand Down
4 changes: 4 additions & 0 deletions app/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- [DemoApp][Library] Create component - `List item` ([#54](https://github.com/Orange-OpenSource/ouds-flutter/issues/54))
### Changed
- [DemoApp][Library] For `Button` component, add with `tinted parameter ([#912](https://github.com/Orange-OpenSource/ouds-flutter/issues/912))
- [DemoApp][Library] For `passwordInput` component, update to v1.3.1 ([#785](https://github.com/Orange-OpenSource/ouds-flutter/issues/785))
- [DemoApp][Library] For `textInput` component, update to v1.4.1 ([#784](https://github.com/Orange-OpenSource/ouds-flutter/issues/784))
- [DemoApp][Library] For `phoneNumberInput` component, update to v1.3.1 ([#839](https://github.com/Orange-OpenSource/ouds-flutter/issues/839))
- [Library] Add typography Tokens component ([#905](https://github.com/Orange-OpenSource/ouds-flutter/issues/905))
- [DemoApp][Library] update icons to use the icons pack 2.3.0 ([#863](https://github.com/Orange-OpenSource/ouds-flutter/issues/863))
- [DemoApp][Library] In library, update `link` component to v2.4.0 ([#861](https://github.com/Orange-OpenSource/ouds-flutter/issues/861))
Expand Down
8 changes: 7 additions & 1 deletion app/lib/l10n/gen/ouds_flutter_app_localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -634,9 +634,15 @@ abstract class AppLocalizations {
/// No description provided for @app_components_common_tinted_tech.
///
/// In en, this message translates to:
/// **'Tinted icon'**
/// **'Tinted'**
String get app_components_common_tinted_tech;

/// No description provided for @app_components_common_untinted_tech.
///
/// In en, this message translates to:
/// **'Untinted'**
String get app_components_common_untinted_tech;

/// No description provided for @app_components_alert_tech.
///
/// In en, this message translates to:
Expand Down
5 changes: 4 additions & 1 deletion app/lib/l10n/gen/ouds_flutter_app_localizations_ar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,10 @@ class AppLocalizationsAr extends AppLocalizations {
String get app_components_common_type_tech => 'Type';

@override
String get app_components_common_tinted_tech => 'Tinted icon';
String get app_components_common_tinted_tech => 'Tinted';

@override
String get app_components_common_untinted_tech => 'Untinted';

@override
String get app_components_alert_tech => 'Alert';
Expand Down
5 changes: 4 additions & 1 deletion app/lib/l10n/gen/ouds_flutter_app_localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,10 @@ class AppLocalizationsEn extends AppLocalizations {
String get app_components_common_type_tech => 'Type';

@override
String get app_components_common_tinted_tech => 'Tinted icon';
String get app_components_common_tinted_tech => 'Tinted';

@override
String get app_components_common_untinted_tech => 'Untinted';

@override
String get app_components_alert_tech => 'Alert';
Expand Down
5 changes: 4 additions & 1 deletion app/lib/l10n/gen/ouds_flutter_app_localizations_fr.dart
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,10 @@ class AppLocalizationsFr extends AppLocalizations {
String get app_components_common_type_tech => 'Type';

@override
String get app_components_common_tinted_tech => 'Tinted icon';
String get app_components_common_tinted_tech => 'Tinted';

@override
String get app_components_common_untinted_tech => 'Untinted';

@override
String get app_components_alert_tech => 'Alert';
Expand Down
3 changes: 2 additions & 1 deletion app/lib/l10n/ouds_flutter_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@
"app_components_common_description_tech": "Description",
"app_components_common_edgeToEdge_tech": "Edge to edge",
"app_components_common_type_tech" : "Type",
"app_components_common_tinted_tech": "Tinted icon",
"app_components_common_tinted_tech": "Tinted",
"app_components_common_untinted_tech": "Untinted",

"@_components_alert": {},
"app_components_alert_tech": "Alert",
Expand Down
17 changes: 15 additions & 2 deletions app/lib/ui/components/button/button_code_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ class ButtonCodeGenerator {

case OudsButtonLayout.iconOnly:
code =
"""${coloredSurfaceCodeModifier(context)}$buttonSizeConstructor(\nicon: 'assets/ic_heart.svg',\nappearance: ${appearance.toString()},${fullWidthCodeModifier(context)}${loaderCodeModifier(context)}\n${disableCode(context)}""";
"""${coloredSurfaceCodeModifier(context)}$buttonSizeConstructor(\nicon: 'assets/ic_heart.svg',\nappearance: ${appearance.toString()},${fullWidthCodeModifier(context)}${tintedCodeModifier(context)}${loaderCodeModifier(context)}\n${disableCode(context)}""";
break;

case OudsButtonLayout.iconAndText:
code =
"""${coloredSurfaceCodeModifier(context)}$buttonSizeConstructor(\nicon: 'assets/ic_heart.svg',\nlabel: "$label",\nappearance: ${appearance.toString()},${fullWidthCodeModifier(context)}${loaderCodeModifier(context)}\n${disableCode(context)}""";
"""${coloredSurfaceCodeModifier(context)}$buttonSizeConstructor(\nicon: 'assets/ic_heart.svg',\nlabel: "$label",\nappearance: ${appearance.toString()},${fullWidthCodeModifier(context)}${tintedCodeModifier(context)}${loaderCodeModifier(context)}\n${disableCode(context)}""";
break;
}

Expand Down Expand Up @@ -101,6 +101,19 @@ class ButtonCodeGenerator {
}
}

// Method to generate the tinted code modifier for icon-bearing buttons.
// Only emitted when untinted is selected, since tinted is the default.
static String tintedCodeModifier(BuildContext context) {
final ButtonCustomizationState? customizationState = ButtonCustomization.of(
context,
);
if (customizationState?.isTinted == false) {
return "\ntinted: false,";
} else {
return "";
}
}

// Method to generate the constructor name based on the selected size:
// `OudsButton.small` when small size is selected, `OudsButton` otherwise
static String buttonVariant(BuildContext context) {
Expand Down
32 changes: 32 additions & 0 deletions app/lib/ui/components/button/button_customization.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:ouds_flutter_demo/ui/components/button/button_enum.dart';
import 'package:ouds_flutter_demo/ui/utilities/customizable/customizable_widget_state.dart';
import 'package:ouds_flutter_demo/ui/utilities/customizable/tinted_enum.dart';

/// Section for InheritedWidget to pass data down the widget tree
class _ButtonCustomization extends InheritedWidget {
Expand Down Expand Up @@ -37,6 +38,7 @@ class ButtonCustomizationState
late final ChevronState chevronState;
late final NavigationAppearanceState navigationAppearanceState;
late final SizeState sizeState;
late final TintedState tintedState;

@override
void initState() {
Expand All @@ -51,6 +53,7 @@ class ButtonCustomizationState
onColoredBoxState,
);
sizeState = SizeState(setState);
tintedState = TintedState(setState);
}

// Getter to determine if the 'OnColoredBox' should be disabled
Expand Down Expand Up @@ -92,6 +95,16 @@ class ButtonCustomizationState
ButtonEnumSize get selectedSize => sizeState.selected;
set selectedSize(ButtonEnumSize value) => sizeState.selected = value;

bool get isTinted => tintedState.selected == TintedEnum.tinted;

TintedEnum get selectedTinted => tintedState.selected;
set selectedTinted(TintedEnum value) => tintedState.selected = value;

// Getter to determine if the icon should be shown in the demo (used to gate the tinted chip)
bool get hasIcon =>
selectedLayout == ButtonEnumLayout.iconAndText ||
selectedLayout == ButtonEnumLayout.iconOnly;

@override
Widget build(BuildContext context) {
return _ButtonCustomization(data: this, child: widget.child);
Expand Down Expand Up @@ -187,6 +200,25 @@ class FullWidthState {
}
}

/// Tinted icon state management (relevant when the button displays an icon)
class TintedState {
TintedState(this._setState);

final void Function(void Function()) _setState;

final List<TintedEnum> _tintedList = [TintedEnum.tinted, TintedEnum.untinted];
TintedEnum _selectedTinted = TintedEnum.tinted;

List<TintedEnum> get list => _tintedList;

TintedEnum get selected => _selectedTinted;
set selected(TintedEnum newValue) {
_setState(() {
_selectedTinted = newValue;
});
}
}

/// Error handling for specific button behavior
class ButtonErrorCases {
// OnColoredBox behavior: Disable if appearance is 'Negative'
Expand Down
10 changes: 7 additions & 3 deletions app/lib/ui/components/button/button_customization_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,19 @@ class ButtonCustomizationUtils {
}

/// Determines the icon to display based on the selected layout.
///
/// Uses a single-color, theme-tintable asset when [ButtonCustomizationState.isTinted]
/// is true, or a multi-color asset kept as-is (untinted) otherwise. This mirrors
/// the behavior used in the Link component demo.
static String? getIcon(
ButtonCustomizationState? customizationState,
ThemeController themeController,
) {
if (customizationState?.selectedLayout == ButtonEnumLayout.iconOnly ||
customizationState?.selectedLayout == ButtonEnumLayout.iconAndText) {
return AppAssets.icons.functionalSocialAndEngagementHeartRecommend(
themeController,
);
return customizationState?.isTinted == true
? AppAssets.icons.assistanceTipsAndTricks(themeController)
: AppAssets.icons.icUntintedSquare;
}
return null;
}
Expand Down
15 changes: 15 additions & 0 deletions app/lib/ui/components/button/button_demo_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import 'package:ouds_flutter_demo/ui/utilities/customizable/customizable_chips.d
import 'package:ouds_flutter_demo/ui/utilities/customizable/customizable_section.dart';
import 'package:ouds_flutter_demo/ui/utilities/customizable/customizable_switch.dart';
import 'package:ouds_flutter_demo/ui/utilities/customizable/customizable_textfield.dart';
import 'package:ouds_flutter_demo/ui/utilities/customizable/tinted_enum.dart';
import 'package:ouds_flutter_demo/ui/utilities/detail_screen_header.dart';
import 'package:ouds_flutter_demo/ui/utilities/dismiss_keyboard.dart';
import 'package:ouds_flutter_demo/ui/utilities/light_dark_box.dart';
Expand Down Expand Up @@ -154,6 +155,7 @@ class _ButtonDemoState extends State<_ButtonDemo> {
isLoading: loader,
onPressed: onPressed,
isFullWidth: isFullWidth,
tinted: customizationState?.isTinted ?? true,
)
: OudsButton(
label: label,
Expand All @@ -162,6 +164,7 @@ class _ButtonDemoState extends State<_ButtonDemo> {
isLoading: loader,
onPressed: onPressed,
isFullWidth: isFullWidth,
tinted: customizationState?.isTinted ?? true,
);
}

Expand Down Expand Up @@ -288,6 +291,18 @@ class _CustomizationContentState extends State<_CustomizationContent> {
});
},
),
if (customizationState.hasIcon)
CustomizableChips<TintedEnum>(
title: TintedEnum.enumName(context),
options: customizationState.tintedState.list,
selectedOption: customizationState.selectedTinted,
getText: (option) => option.stringValue(context),
onSelected: (selectedOption) {
setState(() {
customizationState.selectedTinted = selectedOption;
});
},
),
CustomizableTextField(
title: context.l10n.app_components_common_label_label,
text: customizationState.textValue,
Expand Down
Loading
Loading