Skip to content
Merged
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
90 changes: 90 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,101 @@
# Migration Guide

- [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)

## v1.3.1 → v2.0.0

### Overview

This is a **major release** introducing rich text support across multiple components, significant design version updates, major token updates (v2.4.0 and v2.5.0), and an updated icon library (v1.6). It also brings improvements to the `Tab Bar`, `Toolbar Top`, `Badge`, `Tag`, `Input Tag`, `Text Input`, `Password Input`, `Phone Number Input`, `Filter Chip`, and `Suggestion Chip` components.

### Before You Begin

#### Prerequisites

- Use version 1.3.1 or older

### Breaking Changes

#### 1. Rich text (Markdown) support in multiple components

Several components have been updated to support Markdown formatting in their label/content parameters. The `label` (or equivalent text parameter) still accepts a plain `String`, but now also renders Markdown syntax (bold, italic, links, etc.).

**Affected components**: `OudsAlertMessage`, `OudsSwitch`, `OudsRadioButton`, `OudsCheckbox`, `OudsTextInput`, `OudsPinCodeInput`, `OudsPhoneNumberInput`

**Impact**: Low (additive — existing plain strings continue to work as before)

**Required Action**:
- No action required (backward compatible)
- Optionally use Markdown syntax in labels to add bold, italic, or link formatting

**Reason for Change**: Provide richer content support across input and control components

#### 2. Token breaking changes — v2.4.0 and v2.5.0

Design tokens have been updated to versions 2.4.0 and 2.5.0. These major token updates may rename or restructure token keys.

**Impact**: Medium (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
- Rebuild and check for compilation errors related to missing or renamed token properties

**Reason for Change**: Align with latest design system token specification

#### 3. Icon library update — v1.6

The OUDS icon library has been updated to version 1.6. 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 v1.6 if you receive compilation errors or missing asset warnings

### Component Design Version Updates

Several components have been updated to align with new design specification versions. These changes are primarily visual and do not require code changes unless you override component tokens in a custom theme.

**Impact**: Low–Medium (visual changes; verify rendering after upgrading)

**Required Action**:
- Verify the visual appearance and accessibility behaviour of each updated component after upgrading
- If you override component tokens in a custom theme, check that your overrides are still valid

| Component | New Design Version |
|-----------|--------------------|
| `OudsTextInput` | v1.4 |
| `OudsPasswordInput` | v1.3 |
| `OudsFilterChip` / `OudsSuggestionChip` | v1.4 |
| `OudsBadge` (icon variant) | v1.3.0 |
| `OudsPhoneNumberInput` | v1.3 |
| `OudsTag` | v1.5 |
| `OudsInputTag` | v1.2 |

### Component Updates (Non-breaking)

| Component | Change |
|-----------|--------|
| Tab Bar | Updated selected tab indicator animation |
| Toolbar Top | Badge support added in trailing actions |
| Bottom Bar | Fixed inconsistent accessible order and zoom overlap |
| Password Input | Fixed label truncation when zoom is applied |
| Filter Chip | Fixed keyboard/Switch Access focus issue |
| Phone Number Input | Added interaction hint for accessibility |
| Input Tag | Fixed button role for accessibility |

### Compatibility

- **Backward Compatibility**: No (breaking changes in token API, icon API, and component label parameters)
- **v1.3.1 Support**: Ended with this release

---

> **Note**: v1.3.1 is a maintenance release with bug fixes and improvements. No migration is required.

## v1.3.0 → v1.3.1
Expand Down
1 change: 1 addition & 0 deletions app/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased](https://github.com/Orange-OpenSource/ouds-flutter/compare/1.3.1...develop)
### Added
### Changed
- [Library] Remove deprecated code and API ([#820](https://github.com/Orange-OpenSource/ouds-flutter/issues/820))
- [Library] update `Pin code input` component to v1.3 ([#691](https://github.com/Orange-OpenSource/ouds-flutter/issues/691))
- [Library] `tab bar component`, update the animation of the `selected tab indicator` ([#633](https://github.com/Orange-OpenSource/ouds-flutter/issues/633))
- [DemoApp][Library] Update `ToolBar Top`, with Badge in Trailing Actions ([#642](https://github.com/Orange-OpenSource/ouds-flutter/issues/642))
Expand Down
1 change: 1 addition & 0 deletions ouds_core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased](https://github.com/Orange-OpenSource/ouds-flutter/compare/1.3.1...develop)
### Added
### Changed
- [Library] Remove deprecated code and API ([#820](https://github.com/Orange-OpenSource/ouds-flutter/issues/820))
- [Library] update `Pin code input` component to v1.3 ([#691](https://github.com/Orange-OpenSource/ouds-flutter/issues/691))
- [Library] `tab bar component`, update the animation of the `selected tab indicator` ([#633](https://github.com/Orange-OpenSource/ouds-flutter/issues/633))
- [Library] Update `ToolBar Top`, with Badge in Trailing Actions ([#642](https://github.com/Orange-OpenSource/ouds-flutter/issues/642))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,11 @@ class OudsBadgeSizeModifier {
}

double getBadgeIconOffsetsPadding(
OudsBadgeStatus? state,
OudsBadgeSize? size,
OudsIconStatus? status,
) {
final badgeToken = OudsTheme.of(context).componentsTokens(context).badge;
if ((state != null &&
(state != OudsBadgeStatus.neutral &&
state != OudsBadgeStatus.accent)) ||
!OudsIconStatus.functionalStatuses.contains(status.runtimeType)) {
if (!OudsIconStatus.functionalStatuses.contains(status.runtimeType)) {
switch (size) {
case OudsBadgeSize.xsmall:
return badgeToken.spaceInsetXsmall;
Expand Down
175 changes: 40 additions & 135 deletions ouds_core/lib/components/badge/internal/ouds_badge_status_modifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
library;

import 'package:flutter/material.dart';
import 'package:ouds_core/components/badge/ouds_badge.dart';
import 'package:ouds_core/components/common/ouds_icon_status.dart';
import 'package:ouds_core/components/utilities/app_assets.dart';
import 'package:ouds_theme_contract/ouds_theme.dart';
Expand All @@ -27,13 +26,7 @@ class OudsBadgeStatusModifier {
OudsBadgeStatusModifier(this.context);

/// Returns the background color based on the badge status.
//deprecation remove: The param state will be removed after deprecation
Color? getStatusColor(
OudsBadgeStatus? state,
OudsIconStatus? status,
bool isEnabled,
bool iconType,
) {
Color? getStatusColor(OudsIconStatus? status, bool isEnabled, bool iconType) {
final colorTheme = OudsTheme.of(context).colorScheme(context);

if (!isEnabled) {
Expand All @@ -46,127 +39,58 @@ class OudsBadgeStatusModifier {
}

if (iconType &&
((state != null &&
(state != OudsBadgeStatus.neutral &&
state != OudsBadgeStatus.accent)) ||
(status != null &&
(OudsIconStatus.functionalStatuses.contains(
status.runtimeType,
))))) {
(status != null &&
(OudsIconStatus.functionalStatuses.contains(status.runtimeType)))) {
return colorTheme.opacityTransparent;
}
//deprecation remove: will be removed after deprecation
if (state != null) {
switch (state) {
case OudsBadgeStatus.neutral:
return colorTheme.surfaceInverseHigh;
case OudsBadgeStatus.accent:
return colorTheme.surfaceStatusAccentEmphasized;
case OudsBadgeStatus.positive:
return colorTheme.surfaceStatusPositiveEmphasized;
case OudsBadgeStatus.info:
return colorTheme.surfaceStatusInfoEmphasized;
case OudsBadgeStatus.warning:
return colorTheme.surfaceStatusWarningEmphasized;
case OudsBadgeStatus.negative:
return colorTheme.surfaceStatusNegativeEmphasized;
}
} else {
if (status != null) {
final iconTokens = OudsTheme.of(context).componentsTokens(context).icon;

return switch (status) {
Neutral() => colorTheme.surfaceInverseHigh,
Accent() => colorTheme.surfaceStatusAccentEmphasized,
Positive() => colorTheme.surfaceStatusPositiveEmphasized,
Info() => colorTheme.surfaceStatusInfoEmphasized,
Warning() => iconTokens.colorContentStatusWarningExternalShape,
Negative() => colorTheme.surfaceStatusNegativeEmphasized,
};
}

if (status != null) {
final iconTokens = OudsTheme.of(context).componentsTokens(context).icon;

return switch (status) {
Neutral() => colorTheme.surfaceInverseHigh,
Accent() => colorTheme.surfaceStatusAccentEmphasized,
Positive() => colorTheme.surfaceStatusPositiveEmphasized,
Info() => colorTheme.surfaceStatusInfoEmphasized,
Warning() => iconTokens.colorContentStatusWarningExternalShape,
Negative() => colorTheme.surfaceStatusNegativeEmphasized,
};
}
return null;
}

/// Returns the background color based on the badge status.
//deprecation remove: The param state will be removed after deprecation
Color? getTextColor(
OudsBadgeStatus? state,
OudsIconStatus? status,
bool isEnabled,
) {
Color? getTextColor(OudsIconStatus? status, bool isEnabled) {
final colorTheme = OudsTheme.of(context).colorScheme(context);

if (!isEnabled) {
return colorTheme.contentOnActionDisabled;
}
//deprecation remove: will be removed after deprecation
if (state != null) {
switch (state) {
case OudsBadgeStatus.neutral:
return colorTheme.contentInverse;
case OudsBadgeStatus.accent:
return colorTheme.contentOnStatusAccentEmphasized;
case OudsBadgeStatus.positive:
return colorTheme.contentOnStatusPositiveEmphasized;
case OudsBadgeStatus.info:
return colorTheme.contentOnStatusInfoEmphasized;
case OudsBadgeStatus.warning:
return colorTheme.contentOnStatusWarningEmphasized;
case OudsBadgeStatus.negative:
return colorTheme.contentOnStatusNegativeEmphasized;
}
} else {
if (status != null) {
return switch (status) {
Neutral() => colorTheme.contentInverse,
Accent() => colorTheme.contentOnStatusAccentEmphasized,
Positive() => colorTheme.contentOnStatusPositiveEmphasized,
Info() => colorTheme.contentOnStatusInfoEmphasized,
Warning() => colorTheme.contentOnStatusWarningEmphasized,
Negative() => colorTheme.contentOnStatusNegativeEmphasized,
};
}
if (status != null) {
return switch (status) {
Neutral() => colorTheme.contentInverse,
Accent() => colorTheme.contentOnStatusAccentEmphasized,
Positive() => colorTheme.contentOnStatusPositiveEmphasized,
Info() => colorTheme.contentOnStatusInfoEmphasized,
Warning() => colorTheme.contentOnStatusWarningEmphasized,
Negative() => colorTheme.contentOnStatusNegativeEmphasized,
};
}
return null;
}

/// Returns the icon color based on the badge status.
//deprecation remove: The param state will be removed after deprecation
Color getIconColor(
OudsBadgeStatus? state,
OudsIconStatus? status,
bool isEnabled,
) {
Color getIconColor(OudsIconStatus? status, bool isEnabled) {
final colorTheme = OudsTheme.of(context).colorScheme(context);

if (!isEnabled) {
if ((state == OudsBadgeStatus.accent ||
state == OudsBadgeStatus.neutral) ||
(!OudsIconStatus.functionalStatuses.contains(status.runtimeType))) {
if (!OudsIconStatus.functionalStatuses.contains(status.runtimeType)) {
return colorTheme.contentOnActionDisabled;
} else {
return colorTheme.actionDisabled;
}
}

//deprecation remove: will be removed after deprecation
if (state != null) {
switch (state) {
case OudsBadgeStatus.neutral:
return colorTheme.contentInverse;
case OudsBadgeStatus.accent:
return colorTheme.contentOnStatusAccentEmphasized;
case OudsBadgeStatus.positive:
return colorTheme.contentStatusPositive;
case OudsBadgeStatus.info:
return colorTheme.contentStatusInfo;
case OudsBadgeStatus.warning:
return colorTheme.contentOnStatusWarningEmphasized;
case OudsBadgeStatus.negative:
return colorTheme.contentStatusNegative;
}
} else if (status != null) {
if (status != null) {
final iconTokens = OudsTheme.of(context).componentsTokens(context).icon;

return switch (status) {
Expand All @@ -182,37 +106,18 @@ class OudsBadgeStatusModifier {
}

/// Return the icon based on badge status
//deprecation remove: The param state will be removed after deprecation
String? getIcon(OudsBadgeStatus? state, OudsIconStatus? status) {
//deprecation remove: will be removed after deprecation
if (state != null) {
switch (state) {
case OudsBadgeStatus.positive:
return AppAssets.icons.badgeIconTickConfirmationFill;
case OudsBadgeStatus.info:
return AppAssets.icons.badgeIconInfoFill;
case OudsBadgeStatus.warning:
return AppAssets.icons.componentAlertWarningExternalShape;
case OudsBadgeStatus.negative:
return AppAssets.icons.badgeIconErrorFill;
case OudsBadgeStatus.neutral:
case OudsBadgeStatus.accent:
return null;
}
} else {
// Handle the new 'iconStatus' API
if (status != null) {
return switch (status) {
// For those statuses, the icon is fixed and defined here.
Positive() => AppAssets.icons.badgeIconTickConfirmationFill,
Info() => AppAssets.icons.badgeIconInfoFill,
Warning() => null,
Negative() => AppAssets.icons.badgeIconErrorFill,

// For the other Accent and Neutral the icon should be defined by user
_ => null,
};
}
String? getIcon(OudsIconStatus? status) {
if (status != null) {
return switch (status) {
// For those statuses, the icon is fixed and defined here.
Positive() => AppAssets.icons.badgeIconTickConfirmationFill,
Info() => AppAssets.icons.badgeIconInfoFill,
Warning() => null,
Negative() => AppAssets.icons.badgeIconErrorFill,

// For the other Accent and Neutral the icon should be defined by user
_ => null,
};
}
return null;
}
Expand Down
Loading
Loading