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
5 changes: 2 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `LocalizedStringKey` and `Bundle` initializers for components using `String` for texts and accessibility labels (Orange-OpenSource/ouds-ios#1366)
- `oudsTintColor` view modifier helper to apply tint color from a `MultipleColorSemanticToken` (Orange-OpenSource/ouds-ios#1370)
- `verbose` flag on `OUDSLogger` to suppress debug and log messages by default (Orange-OpenSource/ouds-ios#1365)

### Changed

- Update illustrations in documentation for `alert message` component (Orange-OpenSource/ouds-ios#1359)
- View modifiers and methods prefixed by `ouds` are replaced by same names without such `ouds` (Orange-OpenSource/ouds-ios#1346)
- Move from Xcode 26.2 to Xcode 26.3 (Orange-OpenSource/ouds-ios#1375)
### Changed

- Update illustrations in documentation for `alert message` component (Orange-OpenSource/ouds-ios#1359)

## [1.3.0](https://github.com/Orange-OpenSource/ouds-ios/compare/1.2.0...1.3.0) - 2026-03-26

Expand Down
91 changes: 90 additions & 1 deletion OUDS/Core/Components/Sources/Actions/Button/OUDSButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ import SwiftUI
///
/// // Text and icon with strong appearance and button taking full width
/// OUDSButton(text: "Validate", icon: Image("ic_heart"), appearance: .strong, isFullWidth: true) { /* the action to process */ }
///
/// // Localizable from bundle can also be used
/// OUDSButton(LocalizedStringKey("validate_button"), bundle: Bundle.module, appearance: .strong) { }
/// ```
///
/// If you need to flip your icon depending to the layout direction or not (e.g. if RTL mode lose semantics / meanings):
Expand Down Expand Up @@ -173,6 +176,41 @@ public struct OUDSButton: View {

// MARK: Initializers

// swiftlint:disable function_default_parameter_at_end
/// Creates a button with a localized text and icon, looking up the key in the given bundle..
/// A raw string can also be given to be displayed.
///
/// ```swift
/// // Use localizable
/// OUDSButton(LocalizedStringKey("validate_button"), bundle: Bundle.module, icon: Image("ic_checkmark"), appearance: .strong) { }
/// ```
///
/// - Parameters:
/// - key: A `LocalizedStringKey` used to look up the text in the given bundle, or a raw `String` to display
/// - tableName: The name of the `.strings` file, or `nil` for the default
/// - bundle: The bundle in which to look up the localized string. Defaults to `Bundle.main`.
/// - icon: An image which shoud contains an icon
/// - flipIcon: Default set to `false`, set to `true` to reverse the image (i.e. flip vertically)
/// - appearance: The button appearance, default set to `.default`
/// - style: The button style, default set to `.default`
/// - isFullWidth: Flag to let button take all the screen width, set to *false* by default.
/// - action: The action to perform when the user triggers the button
public init(_ key: LocalizedStringKey,
tableName: String? = nil,
bundle: Bundle = .main,
icon: Image,
flipIcon: Bool = false,
appearance: Appearance = .default,
style: Style = .default,
isFullWidth: Bool = false,
action: @escaping () -> Void)
{
let resolvedText = key.resolved(tableName: tableName, bundle: bundle)
self.init(text: resolvedText, icon: icon, flipIcon: flipIcon, style: style, isFullWidth: isFullWidth, action: action)
}

// swiftlint:enable function_default_parameter_at_end

/// Creates a button with text and icon.
///
/// - Parameters:
Expand All @@ -196,10 +234,35 @@ public struct OUDSButton: View {
self.style = style
self.isFullWidth = isFullWidth
self.action = action

isHover = false
}

/// Creates a button with an icon only.
///
/// - Parameters:
/// - icon: An image which shoud contains an icon
/// - key: The text to vocalize with *Voice Over* describing the button action, as as `LocalizedStringKey` for the given `Bundle`
/// - tableName: The name of the `.strings` file, or `nil` for the default
/// - bundle: The bundle in which to look up the localized string. Defaults to `Bundle.main`.
/// - flipIcon: Default set to `false`, set to `true` to reverse the image (i.e. flip vertically)
/// - appearance: The button appearance, default set to `.default`
/// - style: The button style, default set to `.default`
/// - isFullWidth: Flag to let button take all the screen width, set to *false* by default.
/// - action: The action to perform when the user triggers the button
public init(icon: Image,
accessibilityLabel key: LocalizedStringKey,
tableName: String? = nil,
bundle: Bundle = .main,
flipIcon: Bool = false,
appearance: Appearance = .default,
style: Style = .default,
isFullWidth: Bool = false,
action: @escaping () -> Void)
{
let resolvedText = key.resolved(tableName: tableName, bundle: bundle)
self.init(icon: icon, accessibilityLabel: resolvedText, flipIcon: flipIcon, appearance: appearance, style: style, isFullWidth: isFullWidth, action: action)
}

/// Creates a button with an icon only.
///
/// - Parameters:
Expand All @@ -226,6 +289,32 @@ public struct OUDSButton: View {
isHover = false
}

/// Creates a button with a localized text only, looking up the key in the given bundle.
///
/// ```swift
/// OUDSButton(LocalizedStringKey("delete_button"), bundle: Bundle.module, appearance: .negative) { }
/// ```
///
/// - Parameters:
/// - key: A `LocalizedStringKey` used to look up the text in the given bundle
/// - tableName: The name of the `.strings` file, or `nil` for the default
/// - bundle: The bundle in which to look up the localized string. Defaults to `Bundle.main`.
/// - appearance: The button appearance, default set to `.default`
/// - style: The button style, default set to `.default`
/// - isFullWidth: Flag to let button take all the screen width, set to *false* by default.
/// - action: The action to perform when the user triggers the button
public init(_ key: LocalizedStringKey,
tableName: String? = nil,
bundle: Bundle = .main,
appearance: Appearance = .default,
style: Style = .default,
isFullWidth: Bool = false,
action: @escaping () -> Void)
{
let resolvedText = key.resolved(tableName: tableName, bundle: bundle)
self.init(text: resolvedText, appearance: appearance, style: style, isFullWidth: isFullWidth, action: action)
}

/// Create a button with a text only.
///
/// - Parameters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,38 @@ public struct OUDSBulletList: View {
self.subListHasBoldText = subListHasBoldText
self.subItems = subItems()
}

/// Creates a bullet list item with a localized text, looking up the key in the given bundle.
///
/// ```swift
/// OUDSBulletList.Item(LocalizedStringKey("item_label"), bundle: Bundle.module)
/// ```
///
/// - Parameters:
/// - key: A `LocalizedStringKey` used to look up the text in the given bundle
/// - tableName: The name of the `.strings` file, or `nil` for the default
/// - bundle: The bundle in which to look up the localized string. Defaults to `Bundle.main`.
/// - subListType: The specific `OUDSBulletList.Type` for the nested sub-list, if any. If `nil`,
/// the type is inherited from the parent list.
/// - subListTextStyle: The specific `OUDSBulletList.TextStyle` for the nested sub-list, if any. If
/// `nil`, the text style is inherited from the parent list.
/// - subListHasBoldText: Whether the text of the nested sub-list should be bold. If `nil`, the bold
/// setting is inherited from the parent list.
/// - subItems: The sub items builder to add to the current item. **Remark** only three levels are allowed.
public init(_ key: LocalizedStringKey,
tableName: String? = nil,
bundle: Bundle = .main,
subListType: OUDSBulletList.`Type`? = nil,
subListTextStyle: OUDSBulletList.TextStyle? = nil,
subListHasBoldText: Bool? = nil,
@OUDSBulletListItemBuilder subItems: () -> [OUDSBulletList.Item] = { [] })
{
text = key.resolved(tableName: tableName, bundle: bundle)
self.subListType = subListType
self.subListTextStyle = subListTextStyle
self.subListHasBoldText = subListHasBoldText
self.subItems = subItems()
}
}

// swiftlint:enable discouraged_optional_boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,28 @@ public struct OUDSCheckbox: View {

// MARK: Initializers

/// Creates a checkbox with only an indicator.
///
/// **The design system does not allow to have both an error or read only situation and a disabled state for the component.**
///
/// - Parameters:
/// - isOn: A binding to a property that determines whether the indicator is ticked (selected) or not (not selected)
/// - key: The text to vocalize with *Voice Over* the component must have, as as `LocalizedStringKey` for the given `Bundle`
/// - tableName: The name of the `.strings` file, or `nil` for the default
/// - bundle: The bundle in which to look up the localized string. Defaults to `Bundle.main`.
/// - isError: True if the look and feel of the component must reflect an error state, default set to `false`
/// - isReadOnly: True if the look and feel of the component must reflect a read only state, default set to `false`
public init(isOn: Binding<Bool>,
accessibilityLabel key: LocalizedStringKey,
tableName: String? = nil,
bundle: Bundle = .main,
isError: Bool = false,
isReadOnly: Bool = false)
{
let resolvedText = key.resolved(tableName: tableName, bundle: bundle)
self.init(isOn: isOn, accessibilityLabel: resolvedText, isError: isError, isReadOnly: isReadOnly)
}

/// Creates a checkbox with only an indicator.
///
/// **The design system does not allow to have both an error or read only situation and a disabled state for the component.**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,28 @@ public struct OUDSCheckboxIndeterminate: View {

// MARK: - Initializers

/// Creates a checkbox with only an indicator.
///
/// **The design system does not allow to have both an error situation and a disabled state for the component.**
///
/// - Parameters:
/// - selection: A binding to a property that determines whether the indicator is ticked, unticked or preticked.
/// - key: The text to vocalize with *Voice Over* the component must have, as as `LocalizedStringKey` for the given `Bundle`
/// - tableName: The name of the `.strings` file, or `nil` for the default
/// - bundle: The bundle in which to look up the localized string. Defaults to `Bundle.main`.
/// - isError: True if the look and feel of the component must reflect an error state, default set to `false`
/// - isReadOnly: True if the look and feel of the component must reflect a read only state, default set to `false`
public init(selection: Binding<OUDSCheckboxIndicatorState>,
accessibilityLabel key: LocalizedStringKey,
tableName: String? = nil,
bundle: Bundle = .main,
isError: Bool = false,
isReadOnly: Bool = false)
{
let resolvedText = key.resolved(tableName: tableName, bundle: bundle)
self.init(selection: selection, accessibilityLabel: resolvedText, isError: isError, isReadOnly: isReadOnly)
}

/// Creates a checkbox with only an indicator.
///
/// **The design system does not allow to have both an error situation and a disabled state for the component.**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ import SwiftUI
/// // The default layout will be used here.
/// OUDSCheckboxItem("Hello world", isOn: $isOn)
///
/// // Localizable from bundle can also be used
/// OUDSCheckboxItem(LocalizedStringKey("agree_terms"), bundle: Bundle.module, isOn: $isOn)
///
/// // A leading checkbox with a label, but in read only mode (user cannot interact yet, but not disabled).
/// // The default layout will be used here.
/// OUDSCheckboxItem("Hello world", isOn: $isOn, isReadOnly: true)
Expand Down Expand Up @@ -294,6 +297,61 @@ public struct OUDSCheckboxItem: View {
self.action = action
}

// swiftlint:disable function_default_parameter_at_end
/// Creates a checkbox with a localized label, looking up the key in the given bundle.
///
/// ```swift
/// OUDSCheckboxItem(LocalizedStringKey("agree_terms"), bundle: Bundle.module, isOn: $isOn)
/// ```
///
/// **The design system does not allow to have both an error situation and a read only mode for the component.**
///
/// - Parameters:
/// - key: A `LocalizedStringKey` used to look up the label in the given bundle
/// - tableName: The name of the `.strings` file, or `nil` for the default
/// - bundle: The bundle in which to look up the localized string. Defaults to `Bundle.main`.
/// - isOn: A binding to a property that determines whether the indicator is ticked (selected) or not (unselected)
/// - description: An additional helper text, a description, which should not be empty, default set to `nil`
/// - icon: An optional icon, default set to `nil`
/// - flipIcon: Default set to `false`, set to `true` to reverse the image (i.e. flip vertically)
/// - isReversed: `true` if the checkbox indicator must be in trailing position, `false` otherwise. Default to `false`
/// - isError: `true` if the look and feel of the component must reflect an error state, default set to `false`
/// - errorText: An optional error message to display at the bottom. This message is ignored if `isError` is `false`.
/// - isReadOnly: True if component is in read only, default set to `false`
/// - hasDivider: If `true` a divider is added at the bottom of the view, by default set to `false`
/// - constrainedMaxWidth: When `true`, the item width is constrained to a maximum value defined by the design system.
/// - action: An additional action to trigger when the checkbox has been pressed
public init(_ key: LocalizedStringKey,
tableName: String? = nil,
bundle: Bundle = .main,
isOn: Binding<Bool>,
description: String? = nil,
icon: Image? = nil,
flipIcon: Bool = false,
isReversed: Bool = false,
isError: Bool = false,
errorText: String? = nil,
isReadOnly: Bool = false,
hasDivider: Bool = false,
constrainedMaxWidth: Bool = false,
action: (() -> Void)? = nil)
{
self.init(key.resolved(tableName: tableName, bundle: bundle),
isOn: isOn,
description: description,
icon: icon,
flipIcon: flipIcon,
isReversed: isReversed,
isError: isError,
errorText: errorText,
isReadOnly: isReadOnly,
hasDivider: hasDivider,
constrainedMaxWidth: constrainedMaxWidth,
action: action)
}

// swiftlint:enable function_default_parameter_at_end

// MARK: Body

public var body: some View {
Expand Down
Loading
Loading