From 70e992dee751260e4661fe7806b699aebfc1d005 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Lapersonne Date: Fri, 4 Oct 2024 11:19:32 +0200 Subject: [PATCH] feat: add tokens section (border, elevation, opacity, typography) in demo app (#120) (#137) Co-authored-by: Ludovic PINEL Co-authored-by: Pierre-Yves Lapersonne Signed-off-by: Pierre-Yves Lapersonne --- .swiftlint.yml | 2 + CHANGELOG.md | 1 + NOTICE.txt | 8 +- .../Sources/Buttons/OUDSButton.swift | 10 +- .../Sources/Extensions/View+Font.swift | 1 - .../Sources/Extensions/View+Shadows.swift | 16 +- .../Sources/Extensions/View+Typography.swift | 5 +- .../Forms/TextInput/OUDSFormsTextInput.swift | 80 -------- .../AccessibleModifiers.swift | 86 ++++++++ .../AccessibleModifiers/View+extensions.swift | 57 ++++++ .../BorderModifier.swift} | 59 +++--- .../BorderModifiers/View+Border.swift | 34 ++++ .../CustomFontModifier.swift | 1 - .../FontModifier.swift | 1 - .../TypographyModifier.swift | 16 +- .../_OUDSComponents.docc/_OUDSComponents.md | 4 +- ...DSTheme+FormsTextInputComponentToken.swift | 2 +- .../OUDSTheme+ColorSemanticTokens.swift | 1 - .../OUDS/Sources/_OUDS.docc/Components.md | 9 - .../MockTheme+BorderSemanticTokens.swift | 2 +- .../MockTheme+DimensionSemanticTokens.swift | 1 - .../MockTheme+SizingSemanticTokens.swift | 1 - .../MockTheme+SpacingSemanticTokens.swift | 1 - .../MockTheme+TypographySemanticTokens.swift | 1 - .../Themes/Inverse/Sources/InverseTheme.swift | 1 - .../OrangeBrandColorRawTokens.swift | 4 - .../OrangeTheme+SemanticColorTokens.swift | 1 - .../Themes/Orange/Sources/OrangeTheme.swift | 1 - .../OrangeBrandColorRawTokens+Values.swift | 2 - OUDS/Core/Themes/Sosh/Sources/SoshTheme.swift | 1 - .../Values/ButtonsComponentTokens.swift | 1 - .../FormsTextInputComponentTokens.swift | 1 - .../Values/TypographyRawTokens+Values.swift | 36 ++-- .../Multiples/MultipleColorTokens.swift | 9 +- .../Multiples/MultipleElevationTokens.swift | 11 +- .../Sources/Extensions/Color+extensions.swift | 1 - Showcase/Showcase.xcodeproj/project.pbxproj | 172 +++++++++++++--- Showcase/Showcase/MainView.swift | 11 +- Showcase/Showcase/OrangeCustomTheme.swift | 3 +- .../Pages/Components/ComponentsPage.swift | 7 +- .../Elevations/ElevationsList.swift | 95 --------- .../Pages/Components/EmptyState.swift | 39 ++++ .../Pages/Guidelines/GuidelinesPage.swift | 57 ------ .../Pages/ThemeSelection/ThemeSelection.swift | 124 ++++++++++++ .../Tokens/Border/BorderTokenElement.swift | 28 +++ .../Pages/Tokens/Border/BorderTokenPage.swift | 159 +++++++++++++++ .../Elevation/ElevationTokenElement.swift | 28 +++ .../Tokens/Elevation/ElevationTokenPage.swift | 106 ++++++++++ .../Tokens/Opacity/OpacityTokenElement.swift | 28 +++ .../Tokens/Opacity/OpacityTokenPage.swift | 93 +++++++++ .../Showcase/Pages/Tokens/TokenElement.swift | 16 ++ .../Showcase/Pages/Tokens/TokensPage.swift | 28 +++ .../Typography/TypographyTokenElement.swift | 28 +++ .../Typography/TypographyTokenPage.swift | 188 ++++++++++++++++++ .../Showcase/Pages/Utils/Cards/Card.swift | 53 +++++ .../Pages/Utils/Cards/CardIllustration.swift | 42 ++++ .../Pages/Utils/ShowcaseElement.swift | 25 +++ .../Pages/Utils/ShowcaseElementPage.swift | 62 ++++++ .../Pages/Utils/ShowcaseElementsPage.swift | 54 +++++ .../Illustrations/Contents.json | 6 + .../il_empty_screen.imageset/Contents.json | 12 ++ .../il_empty_screen.svg | 79 ++++++++ .../Assets.xcassets/Tokens/Contents.json | 6 + .../Tokens/ic_border.imageset/Contents.json | 12 ++ .../Tokens/ic_border.imageset/ic_border.svg | 10 + .../ic_filter_effects.imageset/Contents.json | 12 ++ .../ic_filter_effects.svg | 5 + .../Tokens/ic_layers.imageset/Contents.json | 12 ++ .../Tokens/ic_layers.imageset/ic_layers.svg | 5 + .../ic_typography.imageset/Contents.json | 12 ++ .../ic_typography.imageset/ic_typography.svg | 5 + .../Tokens/ic_union.imageset/Contents.json | 12 ++ .../Tokens/ic_union.imageset/ic_union.svg | 3 + .../ic_guideline_dna.svg | 10 - .../Contents.json | 2 +- .../ic_token.imageset/ic_token.svg | 3 + .../Resources/Colors.xcassets/Contents.json | 6 + .../cardBackground.colorset/Contents.json | 38 ++++ .../Resources/en.lproj/Localizable.strings | 21 +- Showcase/Showcase/Showcase.swift | 7 +- .../ElevationsEffectsUITests.swift | 39 ---- .../OUDSFormsTextInputUITests.swift | 49 ----- 82 files changed, 1792 insertions(+), 488 deletions(-) delete mode 100644 OUDS/Core/Components/Sources/Forms/TextInput/OUDSFormsTextInput.swift create mode 100644 OUDS/Core/Components/Sources/ViewModifiers/AccessibleModifiers/AccessibleModifiers.swift create mode 100644 OUDS/Core/Components/Sources/ViewModifiers/AccessibleModifiers/View+extensions.swift rename OUDS/Core/Components/Sources/ViewModifiers/{BorderStyleModifier.swift => BorderModifiers/BorderModifier.swift} (59%) create mode 100644 OUDS/Core/Components/Sources/ViewModifiers/BorderModifiers/View+Border.swift rename OUDS/Core/Components/Sources/ViewModifiers/{ => TypographyModifiers}/CustomFontModifier.swift (99%) rename OUDS/Core/Components/Sources/ViewModifiers/{ => TypographyModifiers}/FontModifier.swift (98%) rename OUDS/Core/Components/Sources/ViewModifiers/{ => TypographyModifiers}/TypographyModifier.swift (84%) delete mode 100644 Showcase/Showcase/Pages/Components/Elevations/ElevationsList.swift create mode 100644 Showcase/Showcase/Pages/Components/EmptyState.swift delete mode 100644 Showcase/Showcase/Pages/Guidelines/GuidelinesPage.swift create mode 100644 Showcase/Showcase/Pages/ThemeSelection/ThemeSelection.swift create mode 100644 Showcase/Showcase/Pages/Tokens/Border/BorderTokenElement.swift create mode 100644 Showcase/Showcase/Pages/Tokens/Border/BorderTokenPage.swift create mode 100644 Showcase/Showcase/Pages/Tokens/Elevation/ElevationTokenElement.swift create mode 100644 Showcase/Showcase/Pages/Tokens/Elevation/ElevationTokenPage.swift create mode 100644 Showcase/Showcase/Pages/Tokens/Opacity/OpacityTokenElement.swift create mode 100644 Showcase/Showcase/Pages/Tokens/Opacity/OpacityTokenPage.swift create mode 100644 Showcase/Showcase/Pages/Tokens/TokenElement.swift create mode 100644 Showcase/Showcase/Pages/Tokens/TokensPage.swift create mode 100644 Showcase/Showcase/Pages/Tokens/Typography/TypographyTokenElement.swift create mode 100644 Showcase/Showcase/Pages/Tokens/Typography/TypographyTokenPage.swift create mode 100644 Showcase/Showcase/Pages/Utils/Cards/Card.swift create mode 100644 Showcase/Showcase/Pages/Utils/Cards/CardIllustration.swift create mode 100644 Showcase/Showcase/Pages/Utils/ShowcaseElement.swift create mode 100644 Showcase/Showcase/Pages/Utils/ShowcaseElementPage.swift create mode 100644 Showcase/Showcase/Pages/Utils/ShowcaseElementsPage.swift create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Illustrations/Contents.json create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Illustrations/il_empty_screen.imageset/Contents.json create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Illustrations/il_empty_screen.imageset/il_empty_screen.svg create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Tokens/Contents.json create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_border.imageset/Contents.json create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_border.imageset/ic_border.svg create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_filter_effects.imageset/Contents.json create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_filter_effects.imageset/ic_filter_effects.svg create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_layers.imageset/Contents.json create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_layers.imageset/ic_layers.svg create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_typography.imageset/Contents.json create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_typography.imageset/ic_typography.svg create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_union.imageset/Contents.json create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_union.imageset/ic_union.svg delete mode 100644 Showcase/Showcase/Resources/Assets.xcassets/ic_guideline_dna.imageset/ic_guideline_dna.svg rename Showcase/Showcase/Resources/Assets.xcassets/{ic_guideline_dna.imageset => ic_token.imageset}/Contents.json (81%) create mode 100644 Showcase/Showcase/Resources/Assets.xcassets/ic_token.imageset/ic_token.svg create mode 100644 Showcase/Showcase/Resources/Colors.xcassets/Contents.json create mode 100644 Showcase/Showcase/Resources/Colors.xcassets/cardBackground.colorset/Contents.json delete mode 100644 Showcase/ShowcaseTests/ElevationsEffectsUITests.swift delete mode 100644 Showcase/ShowcaseTests/OUDSFormsTextInputUITests.swift diff --git a/.swiftlint.yml b/.swiftlint.yml index 193cd1cb8..1ba81d288 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -31,6 +31,8 @@ excluded: - Showcase/Pods - Showcase/DerivedData +strict: true + # ============== # Disabled rules # ============== diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bbb4805f..8c4d72bd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [Library] Add color semantic tokens `colorBackgroundStatusNeutral`, some `OnBackgroundEmphasized`, `colorBackgroundAction`, `colorBackgroundAlways`, `colorContent` variants - [Library] Add typography semantic tokens for font letter spacing +- [DemoApp] Create token section (Border, Typography, Elevation, Opacity) ([#120](https://github.com/Orange-OpenSource/ouds-ios/issues/120)) - [Library] Unit tests for multiple tokens - [Library] Add color semantic composite tokens embeding light and dark modes values - [Library] Add spacing semantic tokens "huge" and "jumbo" diff --git a/NOTICE.txt b/NOTICE.txt index 544133c41..c81bab22e 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -66,8 +66,14 @@ Any use or displaying shall constitute an infringement under intellectual proper ./Showcase/Showcase/Resources/Assets.xcassets/AppIconQualif.appiconset/iPad-Notification-20@2x.png ./Showcase/Showcase/Resources/Assets.xcassets/AppIconQualif.appiconset/iPad-Settings-29@1x.png -./Showcase/Showcase/Resources/Assets.xcassets/ic_guideline_dna.imageset/ic_guideline_dna.svg +./Showcase/Showcase/Resources/Assets.xcassets/ic_token.imageset/ic_token.svg ./Showcase/Showcase/Resources/Assets.xcassets/ic_component_atom.imageset/ic_component_atom.svg ./Showcase/Showcase/Resources/Assets.xcassets/ic_info.imageset/ic_info.svg +./Showcase/Showcase/Resources/Assets.xcassets/Illustrations/il_empty_screen.imageset/il_empty_screen.svg +./Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_border.imageset/ic_border.svg +./Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_filter_effects.imageset/ic_filter_effects.svg +./Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_layers.imageset/ic_layers.svg +./Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_typography.imageset/ic_typography.svg +./Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_union.imageset/ic_union.svg End of the parts list under Orange SA Copyright diff --git a/OUDS/Core/Components/Sources/Buttons/OUDSButton.swift b/OUDS/Core/Components/Sources/Buttons/OUDSButton.swift index edc0864f7..9a7663065 100644 --- a/OUDS/Core/Components/Sources/Buttons/OUDSButton.swift +++ b/OUDS/Core/Components/Sources/Buttons/OUDSButton.swift @@ -11,7 +11,7 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation +import OUDS import OUDSFoundations import OUDSTokensSemantic import SwiftUI @@ -63,10 +63,10 @@ public struct OUDSButton: View { .foregroundColor(colorScheme == .light ? theme.buttonForegroundColor.light.color : theme.buttonForegroundColor.dark.color) - .modifier(BorderStyleModifier(theme.buttonBorderStyle, - theme.buttonBorderWidth, - theme.buttonBorderRadius, - theme.buttonBorderColor)) + .oudsBorder(style: theme.buttonBorderStyle, + width: theme.buttonBorderWidth, + radius: theme.buttonBorderRadius, + color: theme.buttonBorderColor) }.frame(width: theme.buttonWidth, height: theme.buttonHeight) } } diff --git a/OUDS/Core/Components/Sources/Extensions/View+Font.swift b/OUDS/Core/Components/Sources/Extensions/View+Font.swift index 4e0b2a7db..443b2f8c6 100644 --- a/OUDS/Core/Components/Sources/Extensions/View+Font.swift +++ b/OUDS/Core/Components/Sources/Extensions/View+Font.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSTokensSemantic import SwiftUI diff --git a/OUDS/Core/Components/Sources/Extensions/View+Shadows.swift b/OUDS/Core/Components/Sources/Extensions/View+Shadows.swift index d00e5fd3a..0357bb784 100644 --- a/OUDS/Core/Components/Sources/Extensions/View+Shadows.swift +++ b/OUDS/Core/Components/Sources/Extensions/View+Shadows.swift @@ -11,22 +11,20 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation -import OUDSTokensSemantic +import OUDSTokensRaw import SwiftUI extension View { /// Wraps the *SwiftUI* `shadow(color:radius:x:y)` method so as to use as `radius` value - /// the computed `radius` value of the given `ElevationCompositeSemanticToken`. + /// the computed `radius` value of the given `ElevationCompositeRawToken`. /// - Parameter elevation: The token to give for the shadow / elevation effect /// - Returns `View`: The current `View` with the shadow / elevation effect - public func shadow(elevation: ElevationCompositeSemanticToken) -> some View { - // TODO: Manage light and dark color scheme + public func shadow(elevation: ElevationCompositeRawToken) -> some View { return self - .shadow(color: elevation.light.color.color, - radius: elevation.light.radius, - x: CGFloat(elevation.light.x), - y: CGFloat(elevation.light.y)) + .shadow(color: elevation.color.color, + radius: elevation.radius, + x: CGFloat(elevation.x), + y: CGFloat(elevation.y)) } } diff --git a/OUDS/Core/Components/Sources/Extensions/View+Typography.swift b/OUDS/Core/Components/Sources/Extensions/View+Typography.swift index d45982290..5d35d08d9 100644 --- a/OUDS/Core/Components/Sources/Extensions/View+Typography.swift +++ b/OUDS/Core/Components/Sources/Extensions/View+Typography.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDS import SwiftUI @@ -191,7 +190,7 @@ extension View { /// The current `OUDSTheme` must be given in parameter because `@Environment` property cannot be accessed through an extension or inside a method. /// - Parameter theme: The current `OUDSTheme` to use to load the current font family and the suitable typography semantic token. /// - Returns some View: The current `View` but with new typography applied - public func typeLabelCodeMedium(_ theme: OUDSTheme) -> some View { + public func typeCodeMedium(_ theme: OUDSTheme) -> some View { self.modifier(TypographyModifier(customFontFamily: theme.customFontFamily, typography: theme.typeCodeMedium)) } @@ -199,7 +198,7 @@ extension View { /// The current `OUDSTheme` must be given in parameter because `@Environment` property cannot be accessed through an extension or inside a method. /// - Parameter theme: The current `OUDSTheme` to use to load the current font family and the suitable typography semantic token. /// - Returns some View: The current `View` but with new typography applied - public func typeLabelCodeSmall(_ theme: OUDSTheme) -> some View { + public func typeCodeSmall(_ theme: OUDSTheme) -> some View { self.modifier(TypographyModifier(customFontFamily: theme.customFontFamily, typography: theme.typeCodeSmall)) } } diff --git a/OUDS/Core/Components/Sources/Forms/TextInput/OUDSFormsTextInput.swift b/OUDS/Core/Components/Sources/Forms/TextInput/OUDSFormsTextInput.swift deleted file mode 100644 index 88cebbee8..000000000 --- a/OUDS/Core/Components/Sources/Forms/TextInput/OUDSFormsTextInput.swift +++ /dev/null @@ -1,80 +0,0 @@ -// -// Software Name: OUDS iOS -// SPDX-FileCopyrightText: Copyright (c) Orange SA -// SPDX-License-Identifier: MIT -// -// This software is distributed under the MIT license, -// the text of which is available at https://opensource.org/license/MIT/ -// or see the "LICENSE" file for more details. -// -// Authors: See CONTRIBUTORS.txt -// Software description: A SwiftUI components library with code examples for Orange Unified Design System -// - -import OUDS -import SwiftUI - -/// An OUDS component for text input in formulars. -/// __Warning: This is a draft component__. -/// -/// This component is created to illustrate the mecanism of theme and tokens. -public struct OUDSFormsTextInput: View { - - // MARK: - Properties - - private let label: String - private let hint: String - private let placeholder: String - private let isEnabled: Bool - - @Binding var value: String - - @Environment(\.colorScheme) var colorScheme - @Environment(\.theme) var theme - - // MARK: - Initializer - - /// Use this initializer to create a text field that binds to a bound optional - /// value and propose a placeholder. - /// - /// - Parameters: - /// - label: The text to display in the top of the component - /// - hint: The text to display in above the input field - /// - placeholder: Text in placeholder - /// - value: Binding of the value - /// - isEnabled: Flag to indicate if input is enabled (_true_ by default) - public init(label: String, hint: String, placeholder: String, value: Binding, isEnabled: Bool = true) { - self.label = label - self.hint = hint - self.placeholder = placeholder - self._value = value - self.isEnabled = isEnabled - } - - // MARK: - Body - - public var body: some View { - VStack(spacing: theme.spacePaddingBlockTall) { - - Label( - title: { - Text(label) - .fontWeight(theme.ftiTitleFontWeight.fontWeight) - .font(.system(size: theme.ftiTitleFontSize)) - .foregroundColor(theme.ftiTitleColor.light.color) - }, - icon: { /*@START_MENU_TOKEN@*/Image(systemName: "42.circle")/*@END_MENU_TOKEN@*/ } - ) - - Text(hint) - .fontWeight(theme.ftiSubtitleFontWeight.fontWeight) - .font(.system(size: theme.ftiSubtitleFontSize)) - .foregroundColor(theme.ftiSubtitleColor.light.color) - - TextField(placeholder, text: $value) - } - .padding(theme.spacePaddingBlockTall) - .background(colorScheme == .light ? theme.ftiBackgroundColor.light.color : theme.ftiBackgroundColor.dark.color) - .border(theme.ftiBorderColor.light.color, width: theme.ftiBorderWidth) - } -} diff --git a/OUDS/Core/Components/Sources/ViewModifiers/AccessibleModifiers/AccessibleModifiers.swift b/OUDS/Core/Components/Sources/ViewModifiers/AccessibleModifiers/AccessibleModifiers.swift new file mode 100644 index 000000000..6d042f301 --- /dev/null +++ b/OUDS/Core/Components/Sources/ViewModifiers/AccessibleModifiers/AccessibleModifiers.swift @@ -0,0 +1,86 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI + +// MARK: - Accessible Navigation Title Modifier + +/// `ViewModifier` which defines a navigation title for the calling `View` and also uses `UIAccessibility` to notify for screen changed. +struct AccessibleNavigationTitleModifier: ViewModifier { + + /// The title used as a `LocalizedStringKey` to add as navigation title + let title: String + + /// Elapsed time to wait before sending an accessibility notification of a screen change with the `title` in argument + let deadline: DispatchTime + + func body(content: Content) -> some View { + content + .navigationTitle(LocalizedStringKey(title)) + .onAppear { + DispatchQueue.main.asyncAfter(deadline: deadline) { + UIAccessibility.post(notification: .screenChanged, argument: title) + } + } + } +} + +// MARK: - Request Accessible Focus Modifier + +/// `ViewModifier` to apply on a a `View` so as to request the focus after a given time. +struct RequestAccessibleFocusModifier: ViewModifier { + + /// Flag to listen saying wether or not the `View` got the focus + @AccessibilityFocusState var requestFocus: Bool + + /// Elapsed time to wait before requesting the focus + let deadline: DispatchTime + + func body(content: Content) -> some View { + content.onAppear { + DispatchQueue.main.asyncAfter(deadline: deadline) { + requestFocus = true + } + } + } +} + +// MARK: - Accessibility Focusable + +public enum AccessibilityFocusable: Hashable { + case none + case some(id: String) +} + +// MARK: - Restricted Request Accessible Focus Modifier + +/// `ViewModifier` to apply on a `View` to request the focus on that `View` after a given time +struct RestrictedRequestAccessibleFocusModifier: ViewModifier { + + /// Flag to listen saying wether or not the `View` got the focus + @AccessibilityFocusState var requestFocus: AccessibilityFocusable? + + /// The target to give the focus after the deadLine` delay + let target: AccessibilityFocusable + + /// Elapsed time to wait before requesting the focus + let deadline: DispatchTime + + func body(content: Content) -> some View { + content.onAppear { + DispatchQueue.main.asyncAfter(deadline: deadline) { + requestFocus = target + } + } + } +} diff --git a/OUDS/Core/Components/Sources/ViewModifiers/AccessibleModifiers/View+extensions.swift b/OUDS/Core/Components/Sources/ViewModifiers/AccessibleModifiers/View+extensions.swift new file mode 100644 index 000000000..5d08bf9aa --- /dev/null +++ b/OUDS/Core/Components/Sources/ViewModifiers/AccessibleModifiers/View+extensions.swift @@ -0,0 +1,57 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI + +// MARK: - Accessibility Delay + +/// Contains some delays to apply to view modifiers' deadlines for vocalizations or accessibility notifications +private enum AccessibilityDelay: Double { + // Must be lower than accesibleFocusRequestDelay to start before + case accessibleTitleNotificationDelay = 0.0 + // Must be greater than accessibleTitleNotificationDelay to start after + case accessibleFocusRequestDelay = 1.0 +} + +// MARK: - View extension + +extension View { + + /// Adds a modifier to the current `View` so as to define a navigation title using the current `title` + /// and also send a notification for accessibility layers for a change of screen when appeared. + /// - Parameter title: The navigation title + /// - Returns View: The view with a new modifier + public func oudsNavigationTitle(_ title: String) -> some View { + self.modifier(AccessibleNavigationTitleModifier(title: title, + deadline: .now() + AccessibilityDelay.accessibleTitleNotificationDelay.rawValue)) + } + + /// Adds a modifier to the current `View` so as to defer a focus request after the view is displayed + /// - Parameter requestFocus: The boolean binding (e.g. the `AccessibilityFocusState`) + /// - Returns View: The view with a new modifier + public func oudsRequestAccessibleFocus(_ requestFocus: AccessibilityFocusState) -> some View { + self.modifier(RequestAccessibleFocusModifier(requestFocus: requestFocus, + deadline: .now() + AccessibilityDelay.accessibleFocusRequestDelay.rawValue)) + } + + /// Adds a modifier to the current `View` so as to defer a focus request after the view is displayed for the given element + /// - Parameters: + /// - requestFocus: The boolean binding (e.g. the `AccessibilityFocusState`) + /// - target: The item which will get the focus + /// - Returns View: The view with a new modifier + public func oudsRequestAccessibleFocus(_ requestFocus: AccessibilityFocusState, for target: AccessibilityFocusable) -> some View { + self.modifier(RestrictedRequestAccessibleFocusModifier(requestFocus: requestFocus, + target: target, + deadline: .now() + AccessibilityDelay.accessibleFocusRequestDelay.rawValue)) + } +} diff --git a/OUDS/Core/Components/Sources/ViewModifiers/BorderStyleModifier.swift b/OUDS/Core/Components/Sources/ViewModifiers/BorderModifiers/BorderModifier.swift similarity index 59% rename from OUDS/Core/Components/Sources/ViewModifiers/BorderStyleModifier.swift rename to OUDS/Core/Components/Sources/ViewModifiers/BorderModifiers/BorderModifier.swift index 73d46d25a..470825d2c 100644 --- a/OUDS/Core/Components/Sources/ViewModifiers/BorderStyleModifier.swift +++ b/OUDS/Core/Components/Sources/ViewModifiers/BorderModifiers/BorderModifier.swift @@ -11,18 +11,17 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation -import OUDSTokensSemantic import OUDSFoundations +import OUDSTokensSemantic import SwiftUI -/// A `ViewModifier` which will apply a specific border style to a `View` using several semantic tokens. -struct BorderStyleModifier: ViewModifier { +/// A `ViewModifier` which will apply a specific border to a `View` using several semantic tokens. +struct BorderModifier: ViewModifier { // MARK: - Properties /// The style to apply on the component - private let token: BorderStyleSemanticToken + private let style: BorderStyleSemanticToken /// The width of the border private let width: BorderWidthSemanticToken @@ -35,7 +34,7 @@ struct BorderStyleModifier: ViewModifier { /// Color to apply depending to the `colorScheme` private var colorToApply: Color { - colorScheme == .light ? color.light.color : color.dark.color + (colorScheme == .light ? color.light.color : color.dark.color) } /// To know if the device is in light mode or in dark mode @@ -43,16 +42,16 @@ struct BorderStyleModifier: ViewModifier { // MARK: - Initializer - init(_ token: BorderStyleSemanticToken, + init(_ style: BorderStyleSemanticToken, _ width: BorderWidthSemanticToken, _ radius: BorderRadiusSemanticToken, _ color: ColorSemanticToken) { - self.token = token + self.style = style self.width = width self.radius = radius self.color = color - if token != "solid" && token != "dashed" && token != "dotted" { - OUDSLogger.error("Unmanaged token: '\(token)'!") + if style != "solid" && style != "dashed" && style != "dotted" { + OUDSLogger.error("Unmanaged style: '\(style)'!") } } @@ -60,11 +59,11 @@ struct BorderStyleModifier: ViewModifier { @ViewBuilder func body(content: Content) -> some View { - if token == "solid" { + if style == "solid" { solid(content) - } else if token == "dashed" { + } else if style == "dashed" { dashed(content) - } else if token == "dotted" { + } else if style == "dotted" { dotted(content) } else { // if token == "none" and unmanaged cases none(content) @@ -76,34 +75,26 @@ struct BorderStyleModifier: ViewModifier { } private func solid(_ content: Content) -> some View { - content.background( - RoundedRectangle( - cornerRadius: radius, - style: .circular - ) - .border(colorToApply, width: width) - ) + content + .clipShape(RoundedRectangle(cornerRadius: radius)) + .overlay(RoundedRectangle(cornerRadius: radius).stroke(colorToApply, lineWidth: width)) } private func dashed(_ content: Content) -> some View { - content.background( - RoundedRectangle( - cornerRadius: radius, - style: .circular + content + .clipShape(RoundedRectangle(cornerRadius: radius)) + .overlay(RoundedRectangle(cornerRadius: radius) + .stroke(style: StrokeStyle(lineWidth: width, dash: [10, 5])) + .foregroundColor(colorToApply) ) - .stroke(style: StrokeStyle(lineWidth: width, dash: [10, 5])) - .foregroundColor(colorToApply) - ) } private func dotted(_ content: Content) -> some View { - content.background( - RoundedRectangle( - cornerRadius: radius, - style: .circular + content + .clipShape(RoundedRectangle(cornerRadius: radius)) + .overlay(RoundedRectangle(cornerRadius: radius) + .stroke(style: StrokeStyle(lineWidth: width, dash: [1, 5])) + .foregroundColor(colorToApply) ) - .stroke(style: StrokeStyle(lineWidth: width, dash: [1, 5])) - .foregroundColor(colorToApply) - ) } } diff --git a/OUDS/Core/Components/Sources/ViewModifiers/BorderModifiers/View+Border.swift b/OUDS/Core/Components/Sources/ViewModifiers/BorderModifiers/View+Border.swift new file mode 100644 index 000000000..7d5cb27ef --- /dev/null +++ b/OUDS/Core/Components/Sources/ViewModifiers/BorderModifiers/View+Border.swift @@ -0,0 +1,34 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import OUDSTokensSemantic +import SwiftUI + +extension View { + + /// Modifies the current `View` to apply a border. + /// + /// - Parameters + /// - style: The style to apply on the component + /// - width: The width of the border + /// - radius: The radius of the border to apply + /// - color: The colors of the border (depending to the `colorScheme`) + /// - Returns some View: The current `View` but with a border. + public func oudsBorder( + style: BorderStyleSemanticToken, + width: BorderWidthSemanticToken, + radius: BorderRadiusSemanticToken, + color: ColorSemanticToken) -> some View { + self.modifier(BorderModifier(style, width, radius, color)) + } +} diff --git a/OUDS/Core/Components/Sources/ViewModifiers/CustomFontModifier.swift b/OUDS/Core/Components/Sources/ViewModifiers/TypographyModifiers/CustomFontModifier.swift similarity index 99% rename from OUDS/Core/Components/Sources/ViewModifiers/CustomFontModifier.swift rename to OUDS/Core/Components/Sources/ViewModifiers/TypographyModifiers/CustomFontModifier.swift index 40bcb9e32..9ae27aac1 100644 --- a/OUDS/Core/Components/Sources/ViewModifiers/CustomFontModifier.swift +++ b/OUDS/Core/Components/Sources/ViewModifiers/TypographyModifiers/CustomFontModifier.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSTokensSemantic import SwiftUI diff --git a/OUDS/Core/Components/Sources/ViewModifiers/FontModifier.swift b/OUDS/Core/Components/Sources/ViewModifiers/TypographyModifiers/FontModifier.swift similarity index 98% rename from OUDS/Core/Components/Sources/ViewModifiers/FontModifier.swift rename to OUDS/Core/Components/Sources/ViewModifiers/TypographyModifiers/FontModifier.swift index eb8efce5f..28f86e5a4 100644 --- a/OUDS/Core/Components/Sources/ViewModifiers/FontModifier.swift +++ b/OUDS/Core/Components/Sources/ViewModifiers/TypographyModifiers/FontModifier.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSTokensSemantic import SwiftUI diff --git a/OUDS/Core/Components/Sources/ViewModifiers/TypographyModifier.swift b/OUDS/Core/Components/Sources/ViewModifiers/TypographyModifiers/TypographyModifier.swift similarity index 84% rename from OUDS/Core/Components/Sources/ViewModifiers/TypographyModifier.swift rename to OUDS/Core/Components/Sources/ViewModifiers/TypographyModifiers/TypographyModifier.swift index 03e9772ec..9032c668e 100644 --- a/OUDS/Core/Components/Sources/ViewModifiers/TypographyModifier.swift +++ b/OUDS/Core/Components/Sources/ViewModifiers/TypographyModifiers/TypographyModifier.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDS import OUDSFoundations import OUDSTokensRaw @@ -62,19 +61,20 @@ struct TypographyModifier: ViewModifier { } } - /// Applies to the `Content` the *adaptive font* (i.e. *font family*, *font weight*, *font size* and the *line height* - /// depending to the current `MultipleTypographyTokens` + // TODO: #51 - Call lineSpacing() and tracking() functions when values usable in TypographyRawTokens + /// Applies to the `Content` the *adaptive font* (i.e. *font family*, *font weight* and *font size* + /// depending to the current `MultipleTypographyTokens`. + /// **Does not apply _letter spacing_ nor _line height_ because raw tokens values are not usable!** func body(content: Content) -> some View { if #available(iOS 16.0, *) { content .font(adaptiveFont()) - .lineSpacing(adaptiveTypography.lineHeight) - .tracking(adaptiveTypography.letterSpacing) - } else { +// .lineSpacing(adaptiveTypography.lineHeight) +// .tracking(adaptiveTypography.letterSpacing) + } else { // tracking() and kerning() only available for iOS 16+ content .font(adaptiveFont()) - .lineSpacing(adaptiveTypography.lineHeight) - // tracking() and kerning() only available for iOS 16+ +// .lineSpacing(adaptiveTypography.lineHeight) } } } diff --git a/OUDS/Core/Components/Sources/_OUDSComponents.docc/_OUDSComponents.md b/OUDS/Core/Components/Sources/_OUDSComponents.docc/_OUDSComponents.md index cf8c010c1..2a3106795 100644 --- a/OUDS/Core/Components/Sources/_OUDSComponents.docc/_OUDSComponents.md +++ b/OUDS/Core/Components/Sources/_OUDSComponents.docc/_OUDSComponents.md @@ -1,6 +1,6 @@ # ``OUDSComponents`` -The catalog of all components provided by OUDS. +The catalog of all components provided by OUDS. It contains also `View` extensions and `ViewModifiers` to apply tokens and styles on components and higher-level views. @Metadata { @TechnologyRoot @@ -66,6 +66,6 @@ myView.typeLabelStrongXLarge(theme) // Etc. ``` + ### Group -- ``OUDSFormsTextInput`` diff --git a/OUDS/Core/OUDS/Sources/OUDSTheme/OUDSTheme+ComponentTokens/OUDSTheme+FormsTextInputComponentToken.swift b/OUDS/Core/OUDS/Sources/OUDSTheme/OUDSTheme+ComponentTokens/OUDSTheme+FormsTextInputComponentToken.swift index 27aa6491c..7cf33ad1c 100644 --- a/OUDS/Core/OUDS/Sources/OUDSTheme/OUDSTheme+ComponentTokens/OUDSTheme+FormsTextInputComponentToken.swift +++ b/OUDS/Core/OUDS/Sources/OUDSTheme/OUDSTheme+ComponentTokens/OUDSTheme+FormsTextInputComponentToken.swift @@ -12,9 +12,9 @@ // import Foundation +import OUDSTokensComponent import OUDSTokensRaw import OUDSTokensSemantic -import OUDSTokensComponent /// Defines for `FormsTextInputComponentTokens` the basic configuration which can be overriden in subthemes / subclasses of this theme. /// **Warning: These are random and dumb values** diff --git a/OUDS/Core/OUDS/Sources/OUDSTheme/OUDSTheme+SemanticTokens/OUDSTheme+ColorSemanticTokens.swift b/OUDS/Core/OUDS/Sources/OUDSTheme/OUDSTheme+SemanticTokens/OUDSTheme+ColorSemanticTokens.swift index a075e6bff..0954957b5 100644 --- a/OUDS/Core/OUDS/Sources/OUDSTheme/OUDSTheme+SemanticTokens/OUDSTheme+ColorSemanticTokens.swift +++ b/OUDS/Core/OUDS/Sources/OUDSTheme/OUDSTheme+SemanticTokens/OUDSTheme+ColorSemanticTokens.swift @@ -12,7 +12,6 @@ // import Foundation -import OUDSFoundations import OUDSTokensRaw import OUDSTokensSemantic diff --git a/OUDS/Core/OUDS/Sources/_OUDS.docc/Components.md b/OUDS/Core/OUDS/Sources/_OUDS.docc/Components.md index 4110613e8..3e21e9042 100644 --- a/OUDS/Core/OUDS/Sources/_OUDS.docc/Components.md +++ b/OUDS/Core/OUDS/Sources/_OUDS.docc/Components.md @@ -10,15 +10,6 @@ Import the target of components, and use the component you want: ```swift import OUDSComponents // To get the components - -struct YourView: View { - - @State private var writtenText: String = "" - - var body: some View { - OUDSFormsTextInput(placeholder: "Some placeholder to display", value: $writtenText) - } -} ``` Of course you must use in your root view the with the suitable theme: diff --git a/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+BorderSemanticTokens.swift b/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+BorderSemanticTokens.swift index 12bc89111..514ebf6f9 100644 --- a/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+BorderSemanticTokens.swift +++ b/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+BorderSemanticTokens.swift @@ -12,8 +12,8 @@ // import Foundation -import OUDSTokensSemantic import OUDSTokensRaw +import OUDSTokensSemantic extension MockTheme { diff --git a/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+DimensionSemanticTokens.swift b/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+DimensionSemanticTokens.swift index 5de4df69c..fd92e762e 100644 --- a/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+DimensionSemanticTokens.swift +++ b/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+DimensionSemanticTokens.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSTokensSemantic /// Defines basic values common to all themes for `DimensionSemanticTokens`. diff --git a/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+SizingSemanticTokens.swift b/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+SizingSemanticTokens.swift index ac4c698d8..3795a9de9 100644 --- a/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+SizingSemanticTokens.swift +++ b/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+SizingSemanticTokens.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSTokensRaw import OUDSTokensSemantic diff --git a/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+SpacingSemanticTokens.swift b/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+SpacingSemanticTokens.swift index 2e45b9bfc..6fa47cd13 100644 --- a/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+SpacingSemanticTokens.swift +++ b/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+SpacingSemanticTokens.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSTokensRaw import OUDSTokensSemantic diff --git a/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+TypographySemanticTokens.swift b/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+TypographySemanticTokens.swift index 5f80bc9a9..a9d3bf2dd 100644 --- a/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+TypographySemanticTokens.swift +++ b/OUDS/Core/OUDS/Tests/OUDSTheme/MockTheme/MockTheme+TypographySemanticTokens.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSTokensRaw import OUDSTokensSemantic diff --git a/OUDS/Core/Themes/Inverse/Sources/InverseTheme.swift b/OUDS/Core/Themes/Inverse/Sources/InverseTheme.swift index 5482486da..bb02464d6 100644 --- a/OUDS/Core/Themes/Inverse/Sources/InverseTheme.swift +++ b/OUDS/Core/Themes/Inverse/Sources/InverseTheme.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSThemesOrange /// This is an override of the default basic `OrangeTheme` with some inverted colors. diff --git a/OUDS/Core/Themes/Orange/Sources/Declarations/OrangeBrandColorRawTokens.swift b/OUDS/Core/Themes/Orange/Sources/Declarations/OrangeBrandColorRawTokens.swift index 479eefaff..e244caf0e 100644 --- a/OUDS/Core/Themes/Orange/Sources/Declarations/OrangeBrandColorRawTokens.swift +++ b/OUDS/Core/Themes/Orange/Sources/Declarations/OrangeBrandColorRawTokens.swift @@ -11,10 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation -import SwiftUI -import OUDSTokensRaw - /// This enum helps to add new raw tokens for this theme. /// Such tokens are packed in a _Swift enum_ so as to gather them in one object with the suitable namespace and avoid to have just constants in nothing else /// (i.e. publicly accessible from everywhere). More optimized than _struct_. diff --git a/OUDS/Core/Themes/Orange/Sources/OrangeTheme+SemanticColorTokens.swift b/OUDS/Core/Themes/Orange/Sources/OrangeTheme+SemanticColorTokens.swift index ad9a58c30..07863ade9 100644 --- a/OUDS/Core/Themes/Orange/Sources/OrangeTheme+SemanticColorTokens.swift +++ b/OUDS/Core/Themes/Orange/Sources/OrangeTheme+SemanticColorTokens.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSTokensRaw import OUDSTokensSemantic diff --git a/OUDS/Core/Themes/Orange/Sources/OrangeTheme.swift b/OUDS/Core/Themes/Orange/Sources/OrangeTheme.swift index 912120c02..ab15e574a 100644 --- a/OUDS/Core/Themes/Orange/Sources/OrangeTheme.swift +++ b/OUDS/Core/Themes/Orange/Sources/OrangeTheme.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDS /// This is an override of the default basic `OUDSTheme` and should be seen as the default theme for the OUDS library. diff --git a/OUDS/Core/Themes/Orange/Sources/Values/OrangeBrandColorRawTokens+Values.swift b/OUDS/Core/Themes/Orange/Sources/Values/OrangeBrandColorRawTokens+Values.swift index 5cdc46d76..ca3f75582 100644 --- a/OUDS/Core/Themes/Orange/Sources/Values/OrangeBrandColorRawTokens+Values.swift +++ b/OUDS/Core/Themes/Orange/Sources/Values/OrangeBrandColorRawTokens+Values.swift @@ -11,8 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation -import SwiftUI import OUDSTokensRaw // ଘ( ・ω・)_/゚・:*:・。☆ diff --git a/OUDS/Core/Themes/Sosh/Sources/SoshTheme.swift b/OUDS/Core/Themes/Sosh/Sources/SoshTheme.swift index 9180ecc4c..027265d4a 100644 --- a/OUDS/Core/Themes/Sosh/Sources/SoshTheme.swift +++ b/OUDS/Core/Themes/Sosh/Sources/SoshTheme.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDS /// Overrides some colors using values defined in extension of `ColorRawTokens` in this current module. diff --git a/OUDS/Core/Tokens/ComponentTokens/Sources/Values/ButtonsComponentTokens.swift b/OUDS/Core/Tokens/ComponentTokens/Sources/Values/ButtonsComponentTokens.swift index d4b80226f..22800bb86 100644 --- a/OUDS/Core/Tokens/ComponentTokens/Sources/Values/ButtonsComponentTokens.swift +++ b/OUDS/Core/Tokens/ComponentTokens/Sources/Values/ButtonsComponentTokens.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSTokensSemantic /// This is a component tokens list for buttons like `OUDSButton`. diff --git a/OUDS/Core/Tokens/ComponentTokens/Sources/Values/FormsTextInputComponentTokens.swift b/OUDS/Core/Tokens/ComponentTokens/Sources/Values/FormsTextInputComponentTokens.swift index 2902b5dcd..9eb5896d2 100644 --- a/OUDS/Core/Tokens/ComponentTokens/Sources/Values/FormsTextInputComponentTokens.swift +++ b/OUDS/Core/Tokens/ComponentTokens/Sources/Values/FormsTextInputComponentTokens.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSTokensSemantic /// This is a component token for a text input in formulars. diff --git a/OUDS/Core/Tokens/RawTokens/Sources/Values/TypographyRawTokens+Values.swift b/OUDS/Core/Tokens/RawTokens/Sources/Values/TypographyRawTokens+Values.swift index 4f3c119eb..02de48d9e 100644 --- a/OUDS/Core/Tokens/RawTokens/Sources/Values/TypographyRawTokens+Values.swift +++ b/OUDS/Core/Tokens/RawTokens/Sources/Values/TypographyRawTokens+Values.swift @@ -11,6 +11,8 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // +import UIKit + // ଘ( ・ω・)_/゚・:*:・。☆ // [File to generate with the tokenator] @@ -64,23 +66,23 @@ extension TypographyRawTokens { // WARNING: values in pixels and not in points, do not use as is! - public static let fontLetterSpacing150: TypographyFontLetterSpacingRawToken = 150 - public static let fontLetterSpacing175: TypographyFontLetterSpacingRawToken = 175 - public static let fontLetterSpacing200: TypographyFontLetterSpacingRawToken = 200 - public static let fontLetterSpacing250: TypographyFontLetterSpacingRawToken = 250 - public static let fontLetterSpacing300: TypographyFontLetterSpacingRawToken = 300 - public static let fontLetterSpacing350: TypographyFontLetterSpacingRawToken = 350 - public static let fontLetterSpacing450: TypographyFontLetterSpacingRawToken = 450 - public static let fontLetterSpacing550: TypographyFontLetterSpacingRawToken = 550 - public static let fontLetterSpacing650: TypographyFontLetterSpacingRawToken = 650 - public static let fontLetterSpacing750: TypographyFontLetterSpacingRawToken = 750 - public static let fontLetterSpacing850: TypographyFontLetterSpacingRawToken = 850 - public static let fontLetterSpacing950: TypographyFontLetterSpacingRawToken = 950 - public static let fontLetterSpacing1050: TypographyFontLetterSpacingRawToken = 1050 - public static let fontLetterSpacing1150: TypographyFontLetterSpacingRawToken = 1150 - public static let fontLetterSpacing1250: TypographyFontLetterSpacingRawToken = 1250 - public static let fontLetterSpacing1450: TypographyFontLetterSpacingRawToken = 1450 - public static let fontLetterSpacing1850: TypographyFontLetterSpacingRawToken = 1850 + public static let fontLetterSpacing150: TypographyFontLetterSpacingRawToken = 150 / UIScreen.main.scale + public static let fontLetterSpacing175: TypographyFontLetterSpacingRawToken = 175 / UIScreen.main.scale + public static let fontLetterSpacing200: TypographyFontLetterSpacingRawToken = 200 / UIScreen.main.scale + public static let fontLetterSpacing250: TypographyFontLetterSpacingRawToken = 250 / UIScreen.main.scale + public static let fontLetterSpacing300: TypographyFontLetterSpacingRawToken = 300 / UIScreen.main.scale + public static let fontLetterSpacing350: TypographyFontLetterSpacingRawToken = 350 / UIScreen.main.scale + public static let fontLetterSpacing450: TypographyFontLetterSpacingRawToken = 450 / UIScreen.main.scale + public static let fontLetterSpacing550: TypographyFontLetterSpacingRawToken = 550 / UIScreen.main.scale + public static let fontLetterSpacing650: TypographyFontLetterSpacingRawToken = 650 / UIScreen.main.scale + public static let fontLetterSpacing750: TypographyFontLetterSpacingRawToken = 750 / UIScreen.main.scale + public static let fontLetterSpacing850: TypographyFontLetterSpacingRawToken = 850 / UIScreen.main.scale + public static let fontLetterSpacing950: TypographyFontLetterSpacingRawToken = 950 / UIScreen.main.scale + public static let fontLetterSpacing1050: TypographyFontLetterSpacingRawToken = 1050 / UIScreen.main.scale + public static let fontLetterSpacing1150: TypographyFontLetterSpacingRawToken = 1150 / UIScreen.main.scale + public static let fontLetterSpacing1250: TypographyFontLetterSpacingRawToken = 1250 / UIScreen.main.scale + public static let fontLetterSpacing1450: TypographyFontLetterSpacingRawToken = 1450 / UIScreen.main.scale + public static let fontLetterSpacing1850: TypographyFontLetterSpacingRawToken = 1850 / UIScreen.main.scale // MARK: Primitive token - Typography - Font family diff --git a/OUDS/Core/Tokens/SemanticTokens/Sources/Multiples/MultipleColorTokens.swift b/OUDS/Core/Tokens/SemanticTokens/Sources/Multiples/MultipleColorTokens.swift index 5f049bf46..285940c2b 100644 --- a/OUDS/Core/Tokens/SemanticTokens/Sources/Multiples/MultipleColorTokens.swift +++ b/OUDS/Core/Tokens/SemanticTokens/Sources/Multiples/MultipleColorTokens.swift @@ -11,9 +11,9 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import OUDSTokensRaw import OUDSFoundations +import SwiftUI /// Kind of semantic tokens which will wrap a combination of `ColorRawToken` depending to color scheme. /// Kind of composite token with multiple values, but not named "composite" because this word is already used in the design system. @@ -72,4 +72,11 @@ public final class MultipleColorTokens: NSObject { guard let other = object as? MultipleColorTokens else { return false } return self.light == other.light && self.dark == other.dark } + + /// Returns the right color according to the `colorScheme`. + /// - Parameter colorScheme: The color scheme + /// - Returns: The right color raw token + public func color(for colorSheme: ColorScheme) -> Color { + (colorSheme == .light ? light : dark).color + } } diff --git a/OUDS/Core/Tokens/SemanticTokens/Sources/Multiples/MultipleElevationTokens.swift b/OUDS/Core/Tokens/SemanticTokens/Sources/Multiples/MultipleElevationTokens.swift index 4a4d88f6f..ca7968e35 100644 --- a/OUDS/Core/Tokens/SemanticTokens/Sources/Multiples/MultipleElevationTokens.swift +++ b/OUDS/Core/Tokens/SemanticTokens/Sources/Multiples/MultipleElevationTokens.swift @@ -11,9 +11,9 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation -import OUDSTokensRaw import OUDSFoundations +import OUDSTokensRaw +import SwiftUI /// Semantic tokens which will wrap a combination of `ElevationCompositeRawToken` depending to color scheme. /// Kind of composite token with multiple values, but not named "composite" because this word is already used in the design system. @@ -49,4 +49,11 @@ public final class MultipleElevationTokens: NSObject { guard let other = object as? MultipleElevationTokens else { return false } return self.light == other.light && self.dark == other.dark } + + /// Returns the right elevation according to the `colorScheme`. + /// - Parameter colorScheme: The color scheme + /// - Returns: The right elevation raw token + public func elevation(for colorSheme: ColorScheme) -> ElevationCompositeRawToken { + (colorSheme == .light ? light : dark) + } } diff --git a/OUDS/Foundations/Sources/Extensions/Color+extensions.swift b/OUDS/Foundations/Sources/Extensions/Color+extensions.swift index a445fabf8..4d805dd8b 100644 --- a/OUDS/Foundations/Sources/Extensions/Color+extensions.swift +++ b/OUDS/Foundations/Sources/Extensions/Color+extensions.swift @@ -11,7 +11,6 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import SwiftUI extension Color { diff --git a/Showcase/Showcase.xcodeproj/project.pbxproj b/Showcase/Showcase.xcodeproj/project.pbxproj index 09b48e66d..1a92f7531 100644 --- a/Showcase/Showcase.xcodeproj/project.pbxproj +++ b/Showcase/Showcase.xcodeproj/project.pbxproj @@ -25,30 +25,44 @@ 070C35642C773A0D0029C6A8 /* OUDSThemesInverse in Frameworks */ = {isa = PBXBuildFile; productRef = 070C35632C773A0D0029C6A8 /* OUDSThemesInverse */; }; 070C35662C7762B90029C6A8 /* OUDSModules in Frameworks */ = {isa = PBXBuildFile; productRef = 070C35652C7762B90029C6A8 /* OUDSModules */; }; 070C35682C7762B90029C6A8 /* OUDSThemesSosh in Frameworks */ = {isa = PBXBuildFile; productRef = 070C35672C7762B90029C6A8 /* OUDSThemesSosh */; }; - 0740A9982C9874160069D24A /* OUDSFormsTextInputUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074008182C942753006B8729 /* OUDSFormsTextInputUITests.swift */; }; + 073543112CA154DE001187EA /* Card.swift in Sources */ = {isa = PBXBuildFile; fileRef = 073543102CA154DE001187EA /* Card.swift */; }; + 073543132CA1676C001187EA /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 073543122CA1676C001187EA /* Colors.xcassets */; }; + 073543162CA17275001187EA /* ShowcaseElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 073543152CA17275001187EA /* ShowcaseElement.swift */; }; + 073543182CA172CA001187EA /* TypographyTokenElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 073543172CA172CA001187EA /* TypographyTokenElement.swift */; }; + 0735431B2CA18C48001187EA /* TypographyTokenPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0735431A2CA18C48001187EA /* TypographyTokenPage.swift */; }; + 0735432A2CA192F9001187EA /* TokenElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 073543222CA192F9001187EA /* TokenElement.swift */; }; 0740A99A2C9874670069D24A /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 0740A9992C9874670069D24A /* SnapshotTesting */; }; 0740A99B2C9874E70069D24A /* Snapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074008222C942810006B8729 /* Snapshot.swift */; }; + 0747947A2CAE882A0033C2D8 /* EmptyState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 074794792CAE882A0033C2D8 /* EmptyState.swift */; }; + 07CF426B2CA30728000BD03E /* TokensPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07CF426A2CA30728000BD03E /* TokensPage.swift */; }; + 07CF42722CA31AC3000BD03E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 07CF42712CA31AC3000BD03E /* Assets.xcassets */; }; + 07CF42742CA3EC58000BD03E /* CardIllustration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07CF42732CA3EC58000BD03E /* CardIllustration.swift */; }; + 07CF42782CA3F4BE000BD03E /* ElevationTokenElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07CF42762CA3F4BE000BD03E /* ElevationTokenElement.swift */; }; + 07CF42792CA3F4BE000BD03E /* ElevationTokenPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07CF42772CA3F4BE000BD03E /* ElevationTokenPage.swift */; }; + 07CF427F2CA41325000BD03E /* OpacityTokenElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07CF427D2CA41325000BD03E /* OpacityTokenElement.swift */; }; + 07CF42802CA41325000BD03E /* OpacityTokenPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07CF427E2CA41325000BD03E /* OpacityTokenPage.swift */; }; + 07CF42842CA45DA9000BD03E /* BorderTokenElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07CF42812CA45DA9000BD03E /* BorderTokenElement.swift */; }; + 07CF42852CA45DA9000BD03E /* BorderTokenPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07CF42822CA45DA9000BD03E /* BorderTokenPage.swift */; }; + 07CF42892CA55BC8000BD03E /* ThemeSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 07CF42882CA55BC8000BD03E /* ThemeSelection.swift */; }; 51087A7B2C46DF9F00160CCF /* Bundle+extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51087A7A2C46DF9F00160CCF /* Bundle+extension.swift */; }; 510A9CD02C5679A300430620 /* OUDSComponents in Frameworks */ = {isa = PBXBuildFile; productRef = 510A9CCF2C5679A300430620 /* OUDSComponents */; }; - 511B8EC12C99861600E7C2F1 /* ElevationsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 511B8EC02C99861600E7C2F1 /* ElevationsList.swift */; }; 512364792C3D7B2D00572FD5 /* Podfile.lock in Resources */ = {isa = PBXBuildFile; fileRef = 512364782C3D7B2D00572FD5 /* Podfile.lock */; }; 5123647B2C3D7B3500572FD5 /* Gemfile.lock in Resources */ = {isa = PBXBuildFile; fileRef = 5123647A2C3D7B3500572FD5 /* Gemfile.lock */; }; 513AD9402C5AAADE0003253B /* OUDSTokensComponent in Frameworks */ = {isa = PBXBuildFile; productRef = 513AD93F2C5AAADE0003253B /* OUDSTokensComponent */; }; - 513D58C22C9B28E100614929 /* ElevationsEffectsUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 513D58C12C9B28E100614929 /* ElevationsEffectsUITests.swift */; }; 5149BADB2C3D6F4F000FA4BF /* Podfile in Resources */ = {isa = PBXBuildFile; fileRef = 5149BADA2C3D6F4F000FA4BF /* Podfile */; }; 51B4F7F42C5BEAB700312019 /* OrangeCustomTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51B4F7F32C5BEAB700312019 /* OrangeCustomTheme.swift */; }; 51BC9DE72C6513F200EB2A11 /* OUDSFoundations in Frameworks */ = {isa = PBXBuildFile; productRef = 51BC9DE62C6513F200EB2A11 /* OUDSFoundations */; }; 51BD76212C466FCF0033365D /* AboutPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BD760B2C466FCF0033365D /* AboutPage.swift */; }; 51BD76222C466FCF0033365D /* ComponentsPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BD760D2C466FCF0033365D /* ComponentsPage.swift */; }; - 51BD76232C466FCF0033365D /* GuidelinesPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BD760F2C466FCF0033365D /* GuidelinesPage.swift */; }; + 51BD76232C466FCF0033365D /* ShowcaseElementsPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BD760F2C466FCF0033365D /* ShowcaseElementsPage.swift */; }; 51BD76242C466FCF0033365D /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 51BD76122C466FCF0033365D /* Preview Assets.xcassets */; }; 51BD76252C466FCF0033365D /* about_legal_information.html in Resources */ = {isa = PBXBuildFile; fileRef = 51BD76152C466FCF0033365D /* about_legal_information.html */; }; 51BD76262C466FCF0033365D /* about_privacy_policy.html in Resources */ = {isa = PBXBuildFile; fileRef = 51BD76172C466FCF0033365D /* about_privacy_policy.html */; }; - 51BD76272C466FCF0033365D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 51BD76182C466FCF0033365D /* Assets.xcassets */; }; 51BD76282C466FCF0033365D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 51BD761A2C466FCF0033365D /* Localizable.strings */; }; 51BD76292C466FCF0033365D /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BD761C2C466FCF0033365D /* WebView.swift */; }; 51BD762A2C466FCF0033365D /* Showcase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BD761E2C466FCF0033365D /* Showcase.swift */; }; 51BD762B2C466FCF0033365D /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51BD761F2C466FCF0033365D /* MainView.swift */; }; + 51E3FF0B2CAFD9AE00F1BC59 /* ShowcaseElementPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51E3FF0A2CAFD9AE00F1BC59 /* ShowcaseElementPage.swift */; }; 51EE2C682C5BF5DE00F634EC /* OUDSThemesOrange in Frameworks */ = {isa = PBXBuildFile; productRef = 51EE2C672C5BF5DE00F634EC /* OUDSThemesOrange */; }; E537B9B66A6466473179DEE8 /* Pods_Showcase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E0D3017314DBC1733F8D0C79 /* Pods_Showcase.framework */; }; /* End PBXBuildFile section */ @@ -66,14 +80,31 @@ /* Begin PBXFileReference section */ 0707B6402C2C3C0400A911E7 /* .github */ = {isa = PBXFileReference; lastKnownFileType = folder; name = .github; path = ../.github; sourceTree = ""; }; 0707B6432C2C569500A911E7 /* Gemfile */ = {isa = PBXFileReference; lastKnownFileType = text; name = Gemfile; path = ../Gemfile; sourceTree = ""; }; - 074008182C942753006B8729 /* OUDSFormsTextInputUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OUDSFormsTextInputUITests.swift; sourceTree = ""; }; + 073543102CA154DE001187EA /* Card.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Card.swift; sourceTree = ""; }; + 073543122CA1676C001187EA /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = ""; }; + 073543152CA17275001187EA /* ShowcaseElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowcaseElement.swift; sourceTree = ""; }; + 073543172CA172CA001187EA /* TypographyTokenElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypographyTokenElement.swift; sourceTree = ""; }; + 0735431A2CA18C48001187EA /* TypographyTokenPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypographyTokenPage.swift; sourceTree = ""; }; + 073543222CA192F9001187EA /* TokenElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenElement.swift; sourceTree = ""; }; + 073543232CA192F9001187EA /* ShacaseElementPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShacaseElementPage.swift; sourceTree = ""; }; 074008222C942810006B8729 /* Snapshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Snapshot.swift; sourceTree = ""; }; 0740A9872C9833670069D24A /* Appfile */ = {isa = PBXFileReference; lastKnownFileType = text; name = Appfile; path = fastlane/Appfile; sourceTree = ""; }; 0740A9882C9833670069D24A /* Fastfile */ = {isa = PBXFileReference; lastKnownFileType = text; name = Fastfile; path = fastlane/Fastfile; sourceTree = ""; }; 0740A9892C9833670069D24A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = fastlane/README.md; sourceTree = ""; }; 0740A98F2C9873500069D24A /* ShowcaseTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShowcaseTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 0740A99C2C9888CF0069D24A /* ShowcaseUITestPlan.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = ShowcaseUITestPlan.xctestplan; path = ../ShowcaseUITestPlan.xctestplan; sourceTree = ""; }; + 074794792CAE882A0033C2D8 /* EmptyState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyState.swift; sourceTree = ""; }; 07CEDD802C7DB921003E1885 /* generateDoc.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = generateDoc.sh; path = ../generateDoc.sh; sourceTree = ""; }; + 07CF426A2CA30728000BD03E /* TokensPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokensPage.swift; sourceTree = ""; }; + 07CF42712CA31AC3000BD03E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 07CF42732CA3EC58000BD03E /* CardIllustration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardIllustration.swift; sourceTree = ""; }; + 07CF42762CA3F4BE000BD03E /* ElevationTokenElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElevationTokenElement.swift; sourceTree = ""; }; + 07CF42772CA3F4BE000BD03E /* ElevationTokenPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElevationTokenPage.swift; sourceTree = ""; }; + 07CF427D2CA41325000BD03E /* OpacityTokenElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpacityTokenElement.swift; sourceTree = ""; }; + 07CF427E2CA41325000BD03E /* OpacityTokenPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpacityTokenPage.swift; sourceTree = ""; }; + 07CF42812CA45DA9000BD03E /* BorderTokenElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BorderTokenElement.swift; sourceTree = ""; }; + 07CF42822CA45DA9000BD03E /* BorderTokenPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BorderTokenPage.swift; sourceTree = ""; }; + 07CF42882CA55BC8000BD03E /* ThemeSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeSelection.swift; sourceTree = ""; }; 07FDCD912C296A500009AA13 /* OUDS Showcase.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "OUDS Showcase.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 07FDCDA52C296B4B0009AA13 /* .gitattributes */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = .gitattributes; path = ../.gitattributes; sourceTree = ""; }; 07FDCDA72C296B7A0009AA13 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; @@ -86,24 +117,22 @@ 07FDCDB72C296C370009AA13 /* .swiftformat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = .swiftformat; path = ../.swiftformat; sourceTree = ""; }; 07FDCDB82C296C370009AA13 /* .gitignore */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = .gitignore; path = ../.gitignore; sourceTree = ""; }; 51087A7A2C46DF9F00160CCF /* Bundle+extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+extension.swift"; sourceTree = ""; }; - 511B8EC02C99861600E7C2F1 /* ElevationsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElevationsList.swift; sourceTree = ""; }; 512364782C3D7B2D00572FD5 /* Podfile.lock */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Podfile.lock; sourceTree = ""; }; 5123647A2C3D7B3500572FD5 /* Gemfile.lock */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Gemfile.lock; path = ../Gemfile.lock; sourceTree = ""; }; - 513D58C12C9B28E100614929 /* ElevationsEffectsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElevationsEffectsUITests.swift; sourceTree = ""; }; 5149BADA2C3D6F4F000FA4BF /* Podfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Podfile; sourceTree = ""; }; 51A7A9DA2C46E17F00EF7A77 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 51B4F7F32C5BEAB700312019 /* OrangeCustomTheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrangeCustomTheme.swift; sourceTree = ""; }; 51BD760B2C466FCF0033365D /* AboutPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutPage.swift; sourceTree = ""; }; 51BD760D2C466FCF0033365D /* ComponentsPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComponentsPage.swift; sourceTree = ""; }; - 51BD760F2C466FCF0033365D /* GuidelinesPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GuidelinesPage.swift; sourceTree = ""; }; + 51BD760F2C466FCF0033365D /* ShowcaseElementsPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShowcaseElementsPage.swift; sourceTree = ""; }; 51BD76122C466FCF0033365D /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 51BD76142C466FCF0033365D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = en; path = en.lproj/about_legal_information.html; sourceTree = ""; }; 51BD76162C466FCF0033365D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.html; name = en; path = en.lproj/about_privacy_policy.html; sourceTree = ""; }; - 51BD76182C466FCF0033365D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 51BD76192C466FCF0033365D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 51BD761C2C466FCF0033365D /* WebView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = ""; }; 51BD761E2C466FCF0033365D /* Showcase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Showcase.swift; sourceTree = ""; }; 51BD761F2C466FCF0033365D /* MainView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; }; + 51E3FF0A2CAFD9AE00F1BC59 /* ShowcaseElementPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ShowcaseElementPage.swift; path = Showcase/Pages/Utils/ShowcaseElementPage.swift; sourceTree = ""; }; 974E2EAB64D9123627CD7D29 /* Pods-DemoApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DemoApp.release.xcconfig"; path = "Target Support Files/Pods-DemoApp/Pods-DemoApp.release.xcconfig"; sourceTree = ""; }; BF4130905502F287757622E2 /* Pods-DemoApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DemoApp.debug.xcconfig"; path = "Target Support Files/Pods-DemoApp/Pods-DemoApp.debug.xcconfig"; sourceTree = ""; }; E0D3017314DBC1733F8D0C79 /* Pods_Showcase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Showcase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -139,6 +168,35 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0735430F2CA15440001187EA /* Cards */ = { + isa = PBXGroup; + children = ( + 073543102CA154DE001187EA /* Card.swift */, + 07CF42732CA3EC58000BD03E /* CardIllustration.swift */, + ); + path = Cards; + sourceTree = ""; + }; + 073543142CA17244001187EA /* Utils */ = { + isa = PBXGroup; + children = ( + 0735430F2CA15440001187EA /* Cards */, + 51BD760F2C466FCF0033365D /* ShowcaseElementsPage.swift */, + 073543152CA17275001187EA /* ShowcaseElement.swift */, + 073543232CA192F9001187EA /* ShacaseElementPage.swift */, + ); + path = Utils; + sourceTree = ""; + }; + 073543192CA17388001187EA /* Typography */ = { + isa = PBXGroup; + children = ( + 073543172CA172CA001187EA /* TypographyTokenElement.swift */, + 0735431A2CA18C48001187EA /* TypographyTokenPage.swift */, + ); + path = Typography; + sourceTree = ""; + }; 074008212C9427F8006B8729 /* Snapshots */ = { isa = PBXGroup; children = ( @@ -161,16 +219,50 @@ isa = PBXGroup; children = ( 074008212C9427F8006B8729 /* Snapshots */, - 074008182C942753006B8729 /* OUDSFormsTextInputUITests.swift */, - 513D58C12C9B28E100614929 /* ElevationsEffectsUITests.swift */, 0740A99C2C9888CF0069D24A /* ShowcaseUITestPlan.xctestplan */, ); path = ShowcaseTests; sourceTree = ""; }; + 07CF42752CA3F461000BD03E /* Elevation */ = { + isa = PBXGroup; + children = ( + 07CF42762CA3F4BE000BD03E /* ElevationTokenElement.swift */, + 07CF42772CA3F4BE000BD03E /* ElevationTokenPage.swift */, + ); + path = Elevation; + sourceTree = ""; + }; + 07CF427C2CA412F5000BD03E /* Opacity */ = { + isa = PBXGroup; + children = ( + 07CF427D2CA41325000BD03E /* OpacityTokenElement.swift */, + 07CF427E2CA41325000BD03E /* OpacityTokenPage.swift */, + ); + path = Opacity; + sourceTree = ""; + }; + 07CF42832CA45DA9000BD03E /* Border */ = { + isa = PBXGroup; + children = ( + 07CF42812CA45DA9000BD03E /* BorderTokenElement.swift */, + 07CF42822CA45DA9000BD03E /* BorderTokenPage.swift */, + ); + path = Border; + sourceTree = ""; + }; + 07CF42872CA55BB4000BD03E /* ThemeSelection */ = { + isa = PBXGroup; + children = ( + 07CF42882CA55BC8000BD03E /* ThemeSelection.swift */, + ); + path = ThemeSelection; + sourceTree = ""; + }; 07FDCD882C296A500009AA13 = { isa = PBXGroup; children = ( + 51E3FF0A2CAFD9AE00F1BC59 /* ShowcaseElementPage.swift */, 07FDCDA32C296B170009AA13 /* 🛠 */, 51BD76202C466FCF0033365D /* Showcase */, 0740A9902C9873500069D24A /* ShowcaseTests */, @@ -221,14 +313,6 @@ name = Configuration; sourceTree = ""; }; - 511B8EBF2C9985C700E7C2F1 /* Elevations */ = { - isa = PBXGroup; - children = ( - 511B8EC02C99861600E7C2F1 /* ElevationsList.swift */, - ); - path = Elevations; - sourceTree = ""; - }; 51BD760C2C466FCF0033365D /* About */ = { isa = PBXGroup; children = ( @@ -240,26 +324,33 @@ 51BD760E2C466FCF0033365D /* Components */ = { isa = PBXGroup; children = ( - 511B8EBF2C9985C700E7C2F1 /* Elevations */, 51BD760D2C466FCF0033365D /* ComponentsPage.swift */, + 074794792CAE882A0033C2D8 /* EmptyState.swift */, ); path = Components; sourceTree = ""; }; - 51BD76102C466FCF0033365D /* Guidelines */ = { + 51BD76102C466FCF0033365D /* Tokens */ = { isa = PBXGroup; children = ( - 51BD760F2C466FCF0033365D /* GuidelinesPage.swift */, + 07CF42832CA45DA9000BD03E /* Border */, + 07CF427C2CA412F5000BD03E /* Opacity */, + 07CF42752CA3F461000BD03E /* Elevation */, + 073543192CA17388001187EA /* Typography */, + 073543222CA192F9001187EA /* TokenElement.swift */, + 07CF426A2CA30728000BD03E /* TokensPage.swift */, ); - path = Guidelines; + path = Tokens; sourceTree = ""; }; 51BD76112C466FCF0033365D /* Pages */ = { isa = PBXGroup; children = ( + 07CF42872CA55BB4000BD03E /* ThemeSelection */, + 073543142CA17244001187EA /* Utils */, 51BD760C2C466FCF0033365D /* About */, 51BD760E2C466FCF0033365D /* Components */, - 51BD76102C466FCF0033365D /* Guidelines */, + 51BD76102C466FCF0033365D /* Tokens */, ); path = Pages; sourceTree = ""; @@ -275,9 +366,10 @@ 51BD761B2C466FCF0033365D /* Resources */ = { isa = PBXGroup; children = ( + 07CF42712CA31AC3000BD03E /* Assets.xcassets */, + 073543122CA1676C001187EA /* Colors.xcassets */, 51BD76152C466FCF0033365D /* about_legal_information.html */, 51BD76172C466FCF0033365D /* about_privacy_policy.html */, - 51BD76182C466FCF0033365D /* Assets.xcassets */, 51BD761A2C466FCF0033365D /* Localizable.strings */, ); path = Resources; @@ -355,10 +447,10 @@ buildConfigurationList = 07FDCD9F2C296A540009AA13 /* Build configuration list for PBXNativeTarget "Showcase" */; buildPhases = ( 2A5B2E6765E57E6A6B13CBA1 /* [CP] Check Pods Manifest.lock */, + 0707B6412C2C414200A911E7 /* Run Swiftlint */, 07FDCD8D2C296A500009AA13 /* Sources */, 07FDCD8E2C296A500009AA13 /* Frameworks */, 07FDCD8F2C296A500009AA13 /* Resources */, - 0707B6412C2C414200A911E7 /* Run Swiftlint */, ); buildRules = ( ); @@ -436,13 +528,14 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 073543132CA1676C001187EA /* Colors.xcassets in Resources */, 5149BADB2C3D6F4F000FA4BF /* Podfile in Resources */, 51BD76242C466FCF0033365D /* Preview Assets.xcassets in Resources */, 51BD76252C466FCF0033365D /* about_legal_information.html in Resources */, 5123647B2C3D7B3500572FD5 /* Gemfile.lock in Resources */, 51BD76262C466FCF0033365D /* about_privacy_policy.html in Resources */, 51BD76282C466FCF0033365D /* Localizable.strings in Resources */, - 51BD76272C466FCF0033365D /* Assets.xcassets in Resources */, + 07CF42722CA31AC3000BD03E /* Assets.xcassets in Resources */, 512364792C3D7B2D00572FD5 /* Podfile.lock in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -467,7 +560,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if which \"swiftlint\" >/dev/null; then\n swiftlint --config ../.swiftlint.yml OUDS/*\n swiftlint --config ../.swiftlint.yml Showcase/*\nelse\n echo \"warning: SwiftLint not installed, download from CocoaPods (see https://github.com/realm/SwiftLint)\"\nfi\n"; + shellScript = "if which \"swiftlint\" >/dev/null; then\n swiftlint --config ../.swiftlint.yml Showcase/*\n swiftlint --config ../.swiftlint.yml OUDS/*\nelse\n echo \"warning: SwiftLint not installed, download from CocoaPods (see https://github.com/realm/SwiftLint)\"\nfi\n"; }; 2A5B2E6765E57E6A6B13CBA1 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; @@ -516,9 +609,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0740A9982C9874160069D24A /* OUDSFormsTextInputUITests.swift in Sources */, 0740A99B2C9874E70069D24A /* Snapshot.swift in Sources */, - 513D58C22C9B28E100614929 /* ElevationsEffectsUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -526,13 +617,28 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 07CF42852CA45DA9000BD03E /* BorderTokenPage.swift in Sources */, + 07CF42842CA45DA9000BD03E /* BorderTokenElement.swift in Sources */, + 07CF42802CA41325000BD03E /* OpacityTokenPage.swift in Sources */, + 0747947A2CAE882A0033C2D8 /* EmptyState.swift in Sources */, 51BD762B2C466FCF0033365D /* MainView.swift in Sources */, 51B4F7F42C5BEAB700312019 /* OrangeCustomTheme.swift in Sources */, + 07CF42742CA3EC58000BD03E /* CardIllustration.swift in Sources */, + 07CF42782CA3F4BE000BD03E /* ElevationTokenElement.swift in Sources */, + 07CF42792CA3F4BE000BD03E /* ElevationTokenPage.swift in Sources */, + 0735432A2CA192F9001187EA /* TokenElement.swift in Sources */, + 073543182CA172CA001187EA /* TypographyTokenElement.swift in Sources */, 51BD76292C466FCF0033365D /* WebView.swift in Sources */, - 51BD76232C466FCF0033365D /* GuidelinesPage.swift in Sources */, - 511B8EC12C99861600E7C2F1 /* ElevationsList.swift in Sources */, + 51BD76232C466FCF0033365D /* ShowcaseElementsPage.swift in Sources */, + 51E3FF0B2CAFD9AE00F1BC59 /* ShowcaseElementPage.swift in Sources */, + 073543162CA17275001187EA /* ShowcaseElement.swift in Sources */, 51087A7B2C46DF9F00160CCF /* Bundle+extension.swift in Sources */, + 0735431B2CA18C48001187EA /* TypographyTokenPage.swift in Sources */, 51BD76222C466FCF0033365D /* ComponentsPage.swift in Sources */, + 07CF42892CA55BC8000BD03E /* ThemeSelection.swift in Sources */, + 07CF427F2CA41325000BD03E /* OpacityTokenElement.swift in Sources */, + 07CF426B2CA30728000BD03E /* TokensPage.swift in Sources */, + 073543112CA154DE001187EA /* Card.swift in Sources */, 51BD76212C466FCF0033365D /* AboutPage.swift in Sources */, 51BD762A2C466FCF0033365D /* Showcase.swift in Sources */, ); diff --git a/Showcase/Showcase/MainView.swift b/Showcase/Showcase/MainView.swift index c9471fe47..023646e0e 100644 --- a/Showcase/Showcase/MainView.swift +++ b/Showcase/Showcase/MainView.swift @@ -11,14 +11,19 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // +import OUDS +import OUDSThemesOrange import SwiftUI struct MainView: View { + + @Environment(\.theme) private var theme + var body: some View { TabView { - GuidelinesPage() + TokensPage() .tabItem { - Label("app_bottomBar_guidelines", image: "ic_guideline_dna") + Label("app_bottomBar_tokens", image: "ic_token") } ComponentsPage() .tabItem { @@ -28,8 +33,8 @@ struct MainView: View { .tabItem { Label("app_bottomBar_about", image: "ic_info") } - } + .accentColor(theme.sysColorBrandPrimaryDefault?.color) } } diff --git a/Showcase/Showcase/OrangeCustomTheme.swift b/Showcase/Showcase/OrangeCustomTheme.swift index 968016c60..271ddac6d 100644 --- a/Showcase/Showcase/OrangeCustomTheme.swift +++ b/Showcase/Showcase/OrangeCustomTheme.swift @@ -11,11 +11,10 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // -import Foundation import SwiftUI +import OUDSTokensComponent import OUDSTokensRaw import OUDSTokensSemantic -import OUDSTokensComponent import OUDSThemesOrange // swiftlint:disable line_length diff --git a/Showcase/Showcase/Pages/Components/ComponentsPage.swift b/Showcase/Showcase/Pages/Components/ComponentsPage.swift index 7b5154160..d688ca15b 100644 --- a/Showcase/Showcase/Pages/Components/ComponentsPage.swift +++ b/Showcase/Showcase/Pages/Components/ComponentsPage.swift @@ -12,8 +12,9 @@ // import SwiftUI -import OUDSTokensSemantic -import OUDSTokensRaw +import OUDS +import OUDSThemesOrange +import OUDSComponents // MARK: - View for display @@ -21,7 +22,7 @@ struct ComponentsPage: View { var body: some View { NavigationView { - ElevationsList().navigationTitle("app_bottomBar_components") + EmptyState() } } } diff --git a/Showcase/Showcase/Pages/Components/Elevations/ElevationsList.swift b/Showcase/Showcase/Pages/Components/Elevations/ElevationsList.swift deleted file mode 100644 index 239352715..000000000 --- a/Showcase/Showcase/Pages/Components/Elevations/ElevationsList.swift +++ /dev/null @@ -1,95 +0,0 @@ -// -// Software Name: OUDS iOS -// SPDX-FileCopyrightText: Copyright (c) Orange SA -// SPDX-License-Identifier: MIT -// -// This software is distributed under the MIT license, -// the text of which is available at https://opensource.org/license/MIT/ -// or see the "LICENSE" file for more details. -// -// Authors: See CONTRIBUTORS.txt -// Software description: A SwiftUI components library with code examples for Orange Unified Design System -// - -import Foundation -import OUDSTokensSemantic -import OUDSTokensRaw -import SwiftUI - -// MARK: - Raw tokens - -let raised = ElevationCompositeRawToken(x: 0, y: 1, blur: 2, color: ColorRawTokens.colorTransparentBlack500) -let overlayDefault = ElevationCompositeRawToken(x: 0, y: 2, blur: 3, color: ColorRawTokens.colorTransparentBlack400) -let allSticky = ElevationCompositeRawToken(x: 0, y: 4, blur: 4, color: ColorRawTokens.colorTransparentBlack300) -let drag = ElevationCompositeRawToken(x: 0, y: 4, blur: 4, color: ColorRawTokens.colorTransparentBlack500) -let overlayEmphasized = ElevationCompositeRawToken(x: 0, y: 12, blur: 12, color: ColorRawTokens.colorTransparentBlack300) - -// MARK: - Rectangle for elevation tests - -/// Simple rectangle -struct ElevationRectangle: View { - - @Environment(\.colorScheme) private var colorScheme - - var foregroundColor: Color { - switch colorScheme { - case .light: - .white - case .dark: - "#333333".color - @unknown default: - fatalError() - } - } - - let elevation: ElevationCompositeSemanticToken - var body: some View { - Rectangle() - .frame(width: 300, height: 80) - .foregroundColor(foregroundColor) - .shadow(elevation: elevation) - } -} - -// MARK: - List of rectangles for rendering tests - -/// Just a debug `View` to list the elevations effects and render them. -/// Set as public for UI tests purposes. -public struct ElevationsList: View { - - public init() {} - - @Environment(\.colorScheme) private var colorScheme - - var backgroundColor: Color { - switch colorScheme { - case .light: - "#f4f4f4".color - case .dark: - "#272727".color - @unknown default: - fatalError() - } - } - - public var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 40) { - ElevationRectangle(elevation: ElevationCompositeSemanticToken(raised)) - ElevationRectangle(elevation: ElevationCompositeSemanticToken(overlayDefault)) - ElevationRectangle(elevation: ElevationCompositeSemanticToken(allSticky)) - ElevationRectangle(elevation: ElevationCompositeSemanticToken(drag)) - ElevationRectangle(elevation: ElevationCompositeSemanticToken(overlayEmphasized)) - } - .frame(maxWidth: .infinity) - } - .background(backgroundColor) - } -} - -#Preview { - ElevationsList().preferredColorScheme(.dark) -} -#Preview { - ElevationsList().preferredColorScheme(.light) -} diff --git a/Showcase/Showcase/Pages/Components/EmptyState.swift b/Showcase/Showcase/Pages/Components/EmptyState.swift new file mode 100644 index 000000000..e68d4b9da --- /dev/null +++ b/Showcase/Showcase/Pages/Components/EmptyState.swift @@ -0,0 +1,39 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI +import OUDSTokensSemantic + +struct EmptyState: View { + + @Environment(\.theme) private var theme + + var body: some View { + ScrollView { + VStack(alignment: .center, spacing: theme.spaceFixedMedium) { + Image("il_empty_screen") + .frame(width: 160, height: 160, alignment: .center) + + VStack(alignment: .center, spacing: theme.spaceFixedShorter) { + Text("app_component_empty_content_text") + .typeHeadingMedium(theme) + Text("app_component_empty_content_description_text") + .typeBodyDefaultSmall(theme) + } + .padding(.vertical, theme.spaceFixedMedium) + } + .padding(.top, theme.spaceFixedJumbo) + .padding(.horizontal, theme.spaceFixedMedium) + } + } +} diff --git a/Showcase/Showcase/Pages/Guidelines/GuidelinesPage.swift b/Showcase/Showcase/Pages/Guidelines/GuidelinesPage.swift deleted file mode 100644 index 404bdf92e..000000000 --- a/Showcase/Showcase/Pages/Guidelines/GuidelinesPage.swift +++ /dev/null @@ -1,57 +0,0 @@ -// -// Software Name: OUDS iOS -// SPDX-FileCopyrightText: Copyright (c) Orange SA -// SPDX-License-Identifier: MIT -// -// This software is distributed under the MIT license, -// the text of which is available at https://opensource.org/license/MIT/ -// or see the "LICENSE" file for more details. -// -// Authors: See CONTRIBUTORS.txt -// Software description: A SwiftUI components library with code examples for Orange Unified Design System -// - -import SwiftUI -import OUDS -import OUDSComponents -import OUDSThemesOrange - -struct GuidelinesPage: View { - - @State private var writtenText: String = "" - @State private var selectedTheme: OUDSTheme - - init() { - writtenText = "" - selectedTheme = OrangeTheme() - } - - var body: some View { - OUDSThemeableView(theme: selectedTheme) { - NavigationView { - VStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/, spacing: 30) { - - OUDSFormsTextInput(label: "Awesome form", - hint: "Type something", - placeholder: "Display large", - value: $writtenText) - - OUDSButton(text: "Some button") {} - - Button("Try OUDS Orange Theme") { - selectedTheme = OrangeTheme() - print("Showcase app - Selected OUDS Orange theme") - } - - Button("Try custom \"local\" theme") { - selectedTheme = OrangeCustomTheme() - print("Showcase app - Selected app custom theme") - } - - } - .padding(.horizontal, 20) - .navigationTitle("app_bottomBar_guidelines") - } - } - } -} diff --git a/Showcase/Showcase/Pages/ThemeSelection/ThemeSelection.swift b/Showcase/Showcase/Pages/ThemeSelection/ThemeSelection.swift new file mode 100644 index 000000000..87aa96adb --- /dev/null +++ b/Showcase/Showcase/Pages/ThemeSelection/ThemeSelection.swift @@ -0,0 +1,124 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import OUDS +import OUDSThemesInverse +import OUDSThemesOrange +import OUDSThemesSosh +import SwiftUI + +// MARK: - Extension of OUDSTheme + +/// Extension of the `OUDSTheme` to add both `Identifiable` and `Hashable`. +/// An `OUDSTheme` must be `Identifiable` to be enumerated like in `ForEach`(e.g. used to build the list of elements in picker). +/// It must be `Hashable` because it is used in a picker than need `Hashable` element. +extension OUDSTheme: Identifiable, Hashable { + + var name: String { + if self is InverseTheme { // Is also an OrangeTheme, should be checked before + return "Inverse" + } + + if self is OrangeTheme { + return "Orange" + } + + if self is SoshTheme { + return "Sosh" + } + + return String(describing: Self.self) + } + + // MARK: Identifiable + + public var id: String { + name + } + + // MARK: Hashable + + public static func == (lhs: OUDSTheme, rhs: OUDSTheme) -> Bool { + lhs.name == rhs.name + } + + public func hash(into hasher: inout Hasher) { + hasher.combine(name) + } +} + +// MARK: - Theme Provider + +/// Theme provider that proposes all supported themes for the demo application. +/// It also stores the current theme, selected by user. +final class ThemeProvider: ObservableObject { + + let themes: [OUDSTheme] + + @Published + var currentTheme: OUDSTheme { + didSet { + UserDefaults.standard.set(currentTheme.name, forKey: "themeName") + } + } + + init() { + let orangeTheme = OrangeTheme() + let soshTheme = SoshTheme() + let inverseTheme = InverseTheme() + let defaultTheme = orangeTheme + themes = [orangeTheme, soshTheme, inverseTheme] + + if let themeName = UserDefaults.standard.value(forKey: "themeName") as? String, + let theme = themes.first(where: { $0.name == themeName }) { + currentTheme = theme + } else { + currentTheme = defaultTheme + } + } +} + +// MARK: - Theme Selection Button + +extension View { + + /// To add a `ThemeSelectionButton` in the toolbar + func navigationbarMenuForThemeSelection() -> some View { + toolbar { + ToolbarItemGroup(placement: .navigationBarTrailing) { + ThemeSelectionButton() + } + } + } +} + +/// Button to make the user change the current theme. +struct ThemeSelectionButton: View { + + @EnvironmentObject private var themeProvider: ThemeProvider + @Environment(\.colorScheme) private var colorScheme + + var body: some View { + Menu { + Picker(selection: $themeProvider.currentTheme, label: EmptyView()) { + ForEach(themeProvider.themes, id: \.id) { theme in + Text(theme.name).tag(theme) + } + } + .pickerStyle(.automatic) + } label: { + Image(systemName: "paintpalette") + } + .foregroundColor(themeProvider.currentTheme.colorContentBrandPrimary?.color(for: colorScheme)) + } +} diff --git a/Showcase/Showcase/Pages/Tokens/Border/BorderTokenElement.swift b/Showcase/Showcase/Pages/Tokens/Border/BorderTokenElement.swift new file mode 100644 index 000000000..2c52750b4 --- /dev/null +++ b/Showcase/Showcase/Pages/Tokens/Border/BorderTokenElement.swift @@ -0,0 +1,28 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI + +struct BorderTokenElement: TokenElement { + let name: String + let imageName: String + let description: String + let pageDescription: AnyView + + init() { + name = "app_tokens_border_label" + imageName = "ic_border" + description = "app_tokens_border_description_text" + pageDescription = AnyView(BorderTokenPage()) + } +} diff --git a/Showcase/Showcase/Pages/Tokens/Border/BorderTokenPage.swift b/Showcase/Showcase/Pages/Tokens/Border/BorderTokenPage.swift new file mode 100644 index 000000000..5062dcbd5 --- /dev/null +++ b/Showcase/Showcase/Pages/Tokens/Border/BorderTokenPage.swift @@ -0,0 +1,159 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI +import OUDS +import OUDSTokensSemantic +import OUDSComponents // for BorderStyleModifier + +// Remark: do we need to keep BorderStyleModifier in OUDSComponent or move it to OUDS or OUDSSementicToken ? + +struct BorderTokenPage: View { + + @Environment(\.theme) private var theme + @Environment(\.colorScheme) private var colorScheme + + // MARK: Body + + var body: some View { + VStack(alignment: .center, spacing: theme.spaceFixedMedium) { + groupOfIllustrations(name: "Width") { + ForEach(Width.allCases, id: \.rawValue) { width in + let token = width.token(from: theme) + + illustration(width: token, + radius: theme.borderRadiusNone, + style: theme.borderStyleDefault, + name: width.rawValue, + value: token) + } + } + + groupOfIllustrations(name: "Radius") { + ForEach(Radius.allCases, id: \.rawValue) { radius in + let token = radius.token(from: theme) + illustration(width: theme.borderWidthDefault, + radius: token, + style: theme.borderStyleDefault, + name: radius.rawValue, + value: token) + } + } + + groupOfIllustrations(name: "Style") { + illustration(width: theme.borderWidthMedium, + radius: theme.borderRadiusNone, + style: theme.borderStyleDefault, + name: "borderStyleDefault") + illustration(width: theme.borderWidthMedium, + radius: theme.borderRadiusNone, + style: theme.borderStyleDrag, + name: "borderStyleDrag") + } + } + .padding(.horizontal, theme.spaceFixedMedium) + } + + // MARK: Private helpers + + @ViewBuilder + private func groupOfIllustrations (name: String, @ViewBuilder illustrations: () -> Illustration) -> some View where Illustration: View { + VStack(alignment: .leading, spacing: theme.spaceFixedShorter) { + Text(name).typeHeadingLarge(theme) + + VStack(alignment: .leading, spacing: theme.spaceFixedNone) { + illustrations() + } + } + } + + private func illustration( + width: BorderWidthSemanticToken, + radius: BorderRadiusSemanticToken, + style: BorderStyleSemanticToken, + name: String, + value: Double? = nil) -> some View { + HStack(alignment: .center, spacing: theme.spaceFixedMedium) { + + Rectangle() + .fill(theme.colorBackgroundDefaultSecondary?.color(for: colorScheme) ?? Color(UIColor.systemGroupedBackground)) + .frame(width: 64, height: 64) + .oudsBorder(style: style, + width: width, + radius: radius, + color: theme.colorBorderDefault!) + + VStack(alignment: .leading, spacing: theme.spaceFixedNone) { + Text(name).bold() + if let value { + Text("\(value, specifier: "%.1f")") + } + } + .frame(maxWidth: .infinity, alignment: .leading) + } + .padding(.vertical, theme.spaceFixedShorter) + } +} + +private enum Radius: String, CaseIterable { + case borderRadiusNone + case borderRadiusDefault + case borderRadiusShort + case borderRadiusMedium + case borderRadiusTall + + func token(from theme: OUDSTheme) -> BorderRadiusSemanticToken { + switch self { + case .borderRadiusNone: + return theme.borderRadiusNone + case .borderRadiusDefault: + return theme.borderRadiusDefault + case .borderRadiusShort: + return theme.borderRadiusShort + case .borderRadiusMedium: + return theme.borderRadiusMedium + case .borderRadiusTall: + return theme.borderRadiusTall + } + } +} + +private enum Width: String, CaseIterable { + + case borderWidthNone + case borderWidthDefault + case borderWidthThin + case borderWidthMedium + case borderWidthThick + case borderWidthThicker + case borderWidthOutsideFocus + + func token(from theme: OUDSTheme) -> BorderWidthSemanticToken { + switch self { + case .borderWidthNone: + return theme.borderWidthNone + case .borderWidthDefault: + return theme.borderWidthDefault + case .borderWidthThin: + return theme.borderWidthThin + case .borderWidthMedium: + return theme.borderWidthMedium + case .borderWidthThick: + return theme.borderWidthThick + case .borderWidthThicker: + return theme.borderWidthThicker + case .borderWidthOutsideFocus: + return theme.borderWidthOutsideFocus + } + } +} diff --git a/Showcase/Showcase/Pages/Tokens/Elevation/ElevationTokenElement.swift b/Showcase/Showcase/Pages/Tokens/Elevation/ElevationTokenElement.swift new file mode 100644 index 000000000..46b85f8b9 --- /dev/null +++ b/Showcase/Showcase/Pages/Tokens/Elevation/ElevationTokenElement.swift @@ -0,0 +1,28 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI + +struct ElevationTokenElement: TokenElement { + let name: String + let imageName: String + let description: String + let pageDescription: AnyView + + init() { + name = "app_tokens_elevation_label" + imageName = "ic_layers" + description = "app_tokens_elevation_description_text" + pageDescription = AnyView(ElevationTokenPage()) + } +} diff --git a/Showcase/Showcase/Pages/Tokens/Elevation/ElevationTokenPage.swift b/Showcase/Showcase/Pages/Tokens/Elevation/ElevationTokenPage.swift new file mode 100644 index 000000000..91b35a399 --- /dev/null +++ b/Showcase/Showcase/Pages/Tokens/Elevation/ElevationTokenPage.swift @@ -0,0 +1,106 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI +import OUDS +import OUDSTokensRaw +import OUDSTokensSemantic + +// MARK: - Elevation Token Page + +struct ElevationTokenPage: View { + + @Environment(\.theme) private var theme + @Environment(\.colorScheme) private var colorScheme + + // MARK: Body + + var body: some View { + VStack(alignment: .leading, spacing: theme.spaceFixedNone) { + ForEach(NamedElevation.allCases, id: \.rawValue) { elevationName in + illustration(for: elevationName) + } + } + .frame(maxWidth: .infinity) + .padding(.horizontal, theme.spaceFixedMedium) + } + + // MARK: Helpers + + private func illustration(for elevation: NamedElevation) -> some View { + illustration(for: elevation.token(from: theme), named: elevation.rawValue) + } + + private func illustration(for elevationSementicToken: ElevationCompositeSemanticToken, named: String) -> some View { + + let elevationRawToken = elevationSementicToken.elevation(for: colorScheme) + return HStack(alignment: .center, spacing: theme.spaceFixedMedium) { + elevationRectangle(elevationRawToken: elevationRawToken) + + VStack(alignment: .leading) { + Text(named).bold() + Text("x: \(elevationRawToken.x, specifier: "%.2f"), ") + + Text("y: \(elevationRawToken.y, specifier: "%.2f"), ") + + Text("radius: \(elevationRawToken.radius, specifier: "%.2f")") + + Text("Color: \(elevationRawToken.color)") + } + .frame(maxWidth: .infinity, alignment: .leading) + } + .padding(.vertical, theme.spaceFixedShorter) + } + + private func elevationRectangle(elevationRawToken: ElevationCompositeRawToken) -> some View { + Rectangle() + .frame(width: theme.sizeIconDecorativeTallest, height: theme.sizeIconDecorativeTallest) + .foregroundColor(theme.colorBackgroundDefaultSecondary?.color(for: colorScheme)) + .shadow(elevation: elevationRawToken) + } +} + +// MARK: - Named Elevation + +private enum NamedElevation: String, CaseIterable { + case elevationNone + case elevationFocus + case elevationRaised + case elevationStickyNavigationScrolled + case elevationOverlayDefault + case elevationStickyDefault + case elevationStickyEmphasized + case elevationDrag + case elevationOverlayEmphasized + + func token(from theme: OUDSTheme) -> ElevationCompositeSemanticToken { + switch self { + case .elevationNone: + return theme.elevationNone + case .elevationFocus: + return theme.elevationFocus + case .elevationRaised: + return theme.elevationRaised + case .elevationStickyNavigationScrolled: + return theme.elevationStickyNavigationScrolled + case .elevationOverlayDefault: + return theme.elevationOverlayDefault + case .elevationStickyDefault: + return theme.elevationStickyDefault + case .elevationStickyEmphasized: + return theme.elevationStickyEmphasized + case .elevationDrag: + return theme.elevationDrag + case .elevationOverlayEmphasized: + return theme.elevationOverlayEmphasized + } + } +} diff --git a/Showcase/Showcase/Pages/Tokens/Opacity/OpacityTokenElement.swift b/Showcase/Showcase/Pages/Tokens/Opacity/OpacityTokenElement.swift new file mode 100644 index 000000000..be24735f9 --- /dev/null +++ b/Showcase/Showcase/Pages/Tokens/Opacity/OpacityTokenElement.swift @@ -0,0 +1,28 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI + +struct OpacityTokenElement: TokenElement { + let name: String + let imageName: String + let description: String + let pageDescription: AnyView + + init() { + name = "app_tokens_opacity_label" + imageName = "ic_filter_effects" + description = "app_tokens_opacity_description_text" + pageDescription = AnyView(OpacityTokenPage()) + } +} diff --git a/Showcase/Showcase/Pages/Tokens/Opacity/OpacityTokenPage.swift b/Showcase/Showcase/Pages/Tokens/Opacity/OpacityTokenPage.swift new file mode 100644 index 000000000..b556e32f5 --- /dev/null +++ b/Showcase/Showcase/Pages/Tokens/Opacity/OpacityTokenPage.swift @@ -0,0 +1,93 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import OUDS +import OUDSTokensSemantic +import SwiftUI + +// MARK: - Opacity Token Page + +struct OpacityTokenPage: View { + + @Environment(\.theme) private var theme + @Environment(\.colorScheme) private var colorScheme + + // MARK: Body + + var body: some View { + VStack(alignment: .leading, spacing: theme.spaceFixedNone) { + ForEach(NamedOpacity.allCases, id: \.rawValue) { opmacityName in + illustration(for: opmacityName) + } + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.horizontal, theme.spaceFixedMedium) + } + + // MARK: Helpers + + private func illustration(for opacityName: NamedOpacity) -> some View { + illustration(for: opacityName.token(from: theme), named: opacityName.rawValue) + } + + private func illustration(for opacityToken: OpacitySemanticToken, named name: String) -> some View { + HStack(alignment: .center, spacing: theme.spaceFixedMedium) { + ZStack { + Image("ic_union") + .resizable() + .frame(width: 44, height: 44) + + Rectangle().fill(colorScheme == .dark ? .white : .black) + .opacity(opacityToken) + .frame(width: 44, height: 44) + .transformEffect(CGAffineTransform(translationX: 10, y: 10)) + } + .frame(width: 54, height: 54, alignment: .leading) + + VStack(alignment: .leading, spacing: theme.spaceFixedNone) { + Text(name).bold() + Text("\(opacityToken, specifier: "%.2f")") + } + .frame(maxWidth: .infinity, alignment: .leading) + } + .padding(.vertical, theme.spaceFixedShorter) + } +} + +// MARK: - Named Opacity + +private enum NamedOpacity: String, CaseIterable { + case opacityTransparent + case opacityWeaker + case opacityWeak + case opacityMedium + case opacityStrong + case opacityOpaque + + func token(from theme: OUDSTheme) -> OpacitySemanticToken { + switch self { + case .opacityTransparent: + return theme.opacityTransparent + case .opacityWeaker: + return theme.opacityWeaker + case .opacityWeak: + return theme.opacityWeak + case .opacityMedium: + return theme.opacityMedium + case .opacityStrong: + return theme.opacityStrong + case .opacityOpaque: + return theme.opacityOpaque + } + } +} diff --git a/Showcase/Showcase/Pages/Tokens/TokenElement.swift b/Showcase/Showcase/Pages/Tokens/TokenElement.swift new file mode 100644 index 000000000..5f6190bc7 --- /dev/null +++ b/Showcase/Showcase/Pages/Tokens/TokenElement.swift @@ -0,0 +1,16 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI + +typealias TokenElement = ShowcaseElement diff --git a/Showcase/Showcase/Pages/Tokens/TokensPage.swift b/Showcase/Showcase/Pages/Tokens/TokensPage.swift new file mode 100644 index 000000000..72e3a0d75 --- /dev/null +++ b/Showcase/Showcase/Pages/Tokens/TokensPage.swift @@ -0,0 +1,28 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI + +struct TokensPage: View { + + let tokenElements: [TokenElement] = [ + BorderTokenElement(), + ElevationTokenElement(), + OpacityTokenElement(), + TypographyTokenElement(), + ] + + var body: some View { + ShowcaseElementsPage(elements: tokenElements) + } +} diff --git a/Showcase/Showcase/Pages/Tokens/Typography/TypographyTokenElement.swift b/Showcase/Showcase/Pages/Tokens/Typography/TypographyTokenElement.swift new file mode 100644 index 000000000..b5611fed2 --- /dev/null +++ b/Showcase/Showcase/Pages/Tokens/Typography/TypographyTokenElement.swift @@ -0,0 +1,28 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI + +struct TypographyTokenElement: TokenElement { + let name: String + let imageName: String + let description: String + let pageDescription: AnyView + + init() { + name = "app_tokens_typography_label" + imageName = "ic_typography" + description = "app_tokens_typography_description_text" + pageDescription = AnyView(TypographyTokenPage()) + } +} diff --git a/Showcase/Showcase/Pages/Tokens/Typography/TypographyTokenPage.swift b/Showcase/Showcase/Pages/Tokens/Typography/TypographyTokenPage.swift new file mode 100644 index 000000000..bfc82fa3d --- /dev/null +++ b/Showcase/Showcase/Pages/Tokens/Typography/TypographyTokenPage.swift @@ -0,0 +1,188 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import OUDS +import OUDSTokensSemantic +import SwiftUI + +// MARK: - Typography Token Page +struct TypographyTokenPage: View { + + @Environment(\.theme) private var theme + + // MARK: Body + + var body: some View { + VStack(alignment: .leading, spacing: theme.spaceFixedNone) { + ForEach(NamedTypography.allCases, id: \.rawValue) { typographyName in + illustration(from: typographyName) + } + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.horizontal, theme.spaceFixedShort) + .navigationTitle(LocalizedStringKey("app_tokens_typography_label")) + } + + // MARK: Helpers + + @ViewBuilder + private func illustration(from namedTypography: NamedTypography) -> some View { + let token = namedTypography.token(from: theme).compact + + VStack(alignment: .leading, spacing: theme.spaceFixedNone) { + typgraphyName(from: namedTypography) + Group { + Text("family (\(theme.customFontFamily ?? "system")), ") + + Text("weight (\(token.weight)), ") + + Text("size (\(token.size, specifier: "%.2f")), ") + + Text("lineHeight (\(token.lineHeight, specifier: "%.2f")), ") + + Text("letterSpacing \(token.letterSpacing, specifier: "%.2f"))") + } + .typeBodyDefaultSmall(theme) + .fixedSize(horizontal: false, vertical: true) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.vertical, theme.spaceFixedShorter) + } + + @ViewBuilder + private func typgraphyName(from namedTypography: NamedTypography) -> some View { + switch namedTypography { + case .displayLarge: + Text(namedTypography.rawValue).typeDisplayLarge(theme) + case .displayMedium: + Text(namedTypography.rawValue).typeDisplayMedium(theme) + case .displaySmall: + Text(namedTypography.rawValue).typeDisplaySmall(theme) + case .headingXLarge: + Text(namedTypography.rawValue).typeHeadingXLarge(theme) + case .headingLarge: + Text(namedTypography.rawValue).typeHeadingLarge(theme) + case .headingMedium: + Text(namedTypography.rawValue).typeHeadingMedium(theme) + case .headingSmall: + Text(namedTypography.rawValue).typeHeadingSmall(theme) + case .bodyDefaultLarge: + Text(namedTypography.rawValue).typeBodyDefaultLarge(theme) + case .bodyDefaultMedium: + Text(namedTypography.rawValue).typeBodyDefaultMedium(theme) + case .bodyDefaultSmall: + Text(namedTypography.rawValue).typeBodyDefaultSmall(theme) + case .bodyStrongLarge: + Text(namedTypography.rawValue).typeBodyStrongLarge(theme) + case .bodyStrongMedium: + Text(namedTypography.rawValue).typeBodyStrongMedium(theme) + case .bodyStrongSmall: + Text(namedTypography.rawValue).typeBodyStrongSmall(theme) + case .labelDefaultXLarge: + Text(namedTypography.rawValue).typeLabelDefaultXLarge(theme) + case .labelDefaultLarge: + Text(namedTypography.rawValue).typeLabelDefaultLarge(theme) + case .labelDefaultMedium: + Text(namedTypography.rawValue).typeLabelDefaultMedium(theme) + case .labelDefaultSmall: + Text(namedTypography.rawValue).typeLabelDefaultSmall(theme) + case .labelStrongXLarge: + Text(namedTypography.rawValue).typeLabelStrongXLarge(theme) + case .labelStrongLarge: + Text(namedTypography.rawValue).typeLabelStrongLarge(theme) + case .labelStrongMedium: + Text(namedTypography.rawValue).typeLabelStrongMedium(theme) + case .labelStrongSmall: + Text(namedTypography.rawValue).typeLabelStrongSmall(theme) + case .codeSmall: + Text(namedTypography.rawValue).typeCodeMedium(theme) + case .codeMedium: + Text(namedTypography.rawValue).typeCodeMedium(theme) + } + } +} + +// MARK: - Named Typography + +private enum NamedTypography: String, CaseIterable { + case displayLarge + case displayMedium + case displaySmall + case headingXLarge + case headingLarge + case headingMedium + case headingSmall + case bodyDefaultLarge + case bodyDefaultMedium + case bodyDefaultSmall + case bodyStrongLarge + case bodyStrongMedium + case bodyStrongSmall + case labelDefaultXLarge + case labelDefaultLarge + case labelDefaultMedium + case labelDefaultSmall + case labelStrongXLarge + case labelStrongLarge + case labelStrongMedium + case labelStrongSmall + case codeMedium + case codeSmall + + func token(from theme: OUDSTheme) -> MultipleTypographyTokens { + switch self { + case .displayLarge: + return theme.typeDisplayLarge + case .displayMedium: + return theme.typeDisplayMedium + case .displaySmall: + return theme.typeDisplaySmall + case .headingXLarge: + return theme.typeHeadingXLarge + case .headingLarge: + return theme.typeHeadingLarge + case .headingMedium: + return theme.typeHeadingMedium + case .headingSmall: + return theme.typeHeadingSmall + case .bodyDefaultLarge: + return theme.typeBodyDefaultLarge + case .bodyDefaultMedium: + return theme.typeBodyDefaultMedium + case .bodyDefaultSmall: + return theme.typeBodyDefaultSmall + case .bodyStrongLarge: + return theme.typeBodyStrongLarge + case .bodyStrongMedium: + return theme.typeBodyStrongMedium + case .bodyStrongSmall: + return theme.typeBodyStrongSmall + case .labelDefaultXLarge: + return theme.typeLabelDefaultXLarge + case .labelDefaultLarge: + return theme.typeLabelDefaultLarge + case .labelDefaultMedium: + return theme.typeLabelDefaultMedium + case .labelDefaultSmall: + return theme.typeLabelDefaultSmall + case .labelStrongXLarge: + return theme.typeLabelStrongXLarge + case .labelStrongLarge: + return theme.typeLabelStrongLarge + case .labelStrongMedium: + return theme.typeLabelStrongMedium + case .labelStrongSmall: + return theme.typeLabelStrongSmall + case .codeSmall: + return theme.typeCodeSmall + case .codeMedium: + return theme.typeCodeMedium + } + } +} diff --git a/Showcase/Showcase/Pages/Utils/Cards/Card.swift b/Showcase/Showcase/Pages/Utils/Cards/Card.swift new file mode 100644 index 000000000..5e7cddcea --- /dev/null +++ b/Showcase/Showcase/Pages/Utils/Cards/Card.swift @@ -0,0 +1,53 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI + +// MARK: - Card + +struct Card: View { + + let title: Text + let icon: Image + + @Environment(\.theme) private var theme + + var body: some View { + VStack(alignment: .leading, spacing: 0) { + CardIllustration(icon: icon) + title + .typeBodyDefaultMedium(theme) + .multilineTextAlignment(.leading) + .padding(.horizontal, 16) + .padding(.vertical, 16) + .frame(maxWidth: .infinity, alignment: .leading) + } + .foregroundColor(.primary) + .background(Color.cardBackground) + .cornerRadius(10) + .shadow(radius: 4) + .padding(.all, 4) + } +} + +// MARK: - Previews + +#Preview { + ScrollView { + VStack { + Card(title: Text("Border"), icon: Image("ic_border", bundle: .main)) + Card(title: Text("Typography"), icon: Image("ic_typography", bundle: .main)) + } + .padding(.horizontal, 16) + } +} diff --git a/Showcase/Showcase/Pages/Utils/Cards/CardIllustration.swift b/Showcase/Showcase/Pages/Utils/Cards/CardIllustration.swift new file mode 100644 index 000000000..6be7ff3eb --- /dev/null +++ b/Showcase/Showcase/Pages/Utils/Cards/CardIllustration.swift @@ -0,0 +1,42 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI + +struct CardIllustration: View { + + let icon: Image + + var body: some View { + HStack { + Spacer() + icon + .resizable() + .renderingMode(.template) + .foregroundColor(.white) + .aspectRatio(contentMode: .fit) + .frame(width: 88, height: 88, alignment: .center) + .clipped() + Spacer() + } + .padding(.vertical, 53) + .background(.black) + .accessibilityElement(children: .combine) + .accessibilityRemoveTraits(.isImage) + .accessibilityHidden(true) + } +} + +#Preview { + CardIllustration(icon: Image("ic_border", bundle: .main)) +} diff --git a/Showcase/Showcase/Pages/Utils/ShowcaseElement.swift b/Showcase/Showcase/Pages/Utils/ShowcaseElement.swift new file mode 100644 index 000000000..805126688 --- /dev/null +++ b/Showcase/Showcase/Pages/Utils/ShowcaseElement.swift @@ -0,0 +1,25 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI + +protocol ShowcaseElement { + var name: String { get } + var imageName: String { get } + var description: String { get } + var pageDescription: AnyView { get } +} + +extension ShowcaseElement { + var id: String { name } +} diff --git a/Showcase/Showcase/Pages/Utils/ShowcaseElementPage.swift b/Showcase/Showcase/Pages/Utils/ShowcaseElementPage.swift new file mode 100644 index 000000000..c99aaf4e3 --- /dev/null +++ b/Showcase/Showcase/Pages/Utils/ShowcaseElementPage.swift @@ -0,0 +1,62 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import SwiftUI +import OUDS +import OUDSTokensSemantic + +struct ShowcaseElementPage: View { + + @AccessibilityFocusState private var requestFocus: Bool + @Environment(\.theme) private var theme + @Environment(\.colorScheme) private var colorScheme + + // MARK: Stored Properties + + let element: ShowcaseElement + + // MARK: Body + + var body: some View { + List { + VStack(alignment: .leading, spacing: theme.spaceFixedMedium) { + CardIllustration(icon: Image(element.imageName)) + .accessibilityHidden(true) + + Text(LocalizedStringKey(element.description)) + .typeBodyDefaultMedium(theme) + .accessibilityFocused($requestFocus) + .padding(.horizontal, theme.spaceFixedMedium) + + } + .listRowInsets(EdgeInsets()) + .listRowSeparator(Visibility.hidden) + .padding(.horizontal, theme.spaceFixedNone) + .padding(.bottom, theme.spaceFixedMedium) + .background(theme.colorBackgroundDefaultPrimary?.color(for: colorScheme)) + + element.pageDescription + .listRowInsets(EdgeInsets()) + .listRowSeparator(Visibility.hidden) + .padding(.bottom, theme.spaceFixedMedium) + .background(theme.colorBackgroundDefaultPrimary?.color(for: colorScheme)) + } + .listStyle(.plain) + .padding(.top, theme.spaceFixedNone) + .padding(.horizontal, theme.spaceFixedNone) + .background(theme.colorBackgroundDefaultPrimary?.color(for: colorScheme)) + .navigationTitle(LocalizedStringKey(element.name)) + .navigationbarMenuForThemeSelection() + .oudsRequestAccessibleFocus(_requestFocus) + } +} diff --git a/Showcase/Showcase/Pages/Utils/ShowcaseElementsPage.swift b/Showcase/Showcase/Pages/Utils/ShowcaseElementsPage.swift new file mode 100644 index 000000000..ab87637fa --- /dev/null +++ b/Showcase/Showcase/Pages/Utils/ShowcaseElementsPage.swift @@ -0,0 +1,54 @@ +// +// Software Name: OUDS iOS +// SPDX-FileCopyrightText: Copyright (c) Orange SA +// SPDX-License-Identifier: MIT +// +// This software is distributed under the MIT license, +// the text of which is available at https://opensource.org/license/MIT/ +// or see the "LICENSE" file for more details. +// +// Authors: See CONTRIBUTORS.txt +// Software description: A SwiftUI components library with code examples for Orange Unified Design System +// + +import OUDS +import OUDSComponents +import SwiftUI + +struct ShowcaseElementsPage: View { + + @AccessibilityFocusState private var requestFocus: AccessibilityFocusable? + @Environment(\.theme) private var theme + @Environment(\.colorScheme) private var colorScheme + + // MARK: Stored properties + + let elements: [ShowcaseElement] + + // MARK: Body + + var body: some View { + NavigationView { + ScrollView { + LazyVGrid(columns: [GridItem(.flexible(), alignment: .topLeading)], spacing: theme.spaceFixedShortest) { + ForEach(elements, id: \.id) { element in + NavigationLink { + ShowcaseElementPage(element: element) + } label: { + Card( + title: Text(LocalizedStringKey(element.name)), + icon: Image(element.imageName)) + .accessibilityFocused($requestFocus, equals: .some(id: element.id)) + .oudsRequestAccessibleFocus(_requestFocus, for: .some(id: elements[0].id)) + } + } + } + .padding(.all, theme.spaceFixedMedium) + .navigationbarMenuForThemeSelection() + .oudsNavigationTitle("app_bottomBar_tokens") + } + .background(theme.colorBackgroundDefaultPrimary?.color(for: colorScheme)) + } + .navigationViewStyle(.stack) + } +} diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Illustrations/Contents.json b/Showcase/Showcase/Resources/Assets.xcassets/Illustrations/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Illustrations/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Illustrations/il_empty_screen.imageset/Contents.json b/Showcase/Showcase/Resources/Assets.xcassets/Illustrations/il_empty_screen.imageset/Contents.json new file mode 100644 index 000000000..6a35cee84 --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Illustrations/il_empty_screen.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "il_empty_screen.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Illustrations/il_empty_screen.imageset/il_empty_screen.svg b/Showcase/Showcase/Resources/Assets.xcassets/Illustrations/il_empty_screen.imageset/il_empty_screen.svg new file mode 100644 index 000000000..212c7d033 --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Illustrations/il_empty_screen.imageset/il_empty_screen.svg @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Tokens/Contents.json b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_border.imageset/Contents.json b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_border.imageset/Contents.json new file mode 100644 index 000000000..ac9cc8a2e --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_border.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "ic_border.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_border.imageset/ic_border.svg b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_border.imageset/ic_border.svg new file mode 100644 index 000000000..4bcbe859d --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_border.imageset/ic_border.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_filter_effects.imageset/Contents.json b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_filter_effects.imageset/Contents.json new file mode 100644 index 000000000..3cfa38033 --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_filter_effects.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "ic_filter_effects.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_filter_effects.imageset/ic_filter_effects.svg b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_filter_effects.imageset/ic_filter_effects.svg new file mode 100644 index 000000000..f72b7fd23 --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_filter_effects.imageset/ic_filter_effects.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_layers.imageset/Contents.json b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_layers.imageset/Contents.json new file mode 100644 index 000000000..2f394be7c --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_layers.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "ic_layers.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_layers.imageset/ic_layers.svg b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_layers.imageset/ic_layers.svg new file mode 100644 index 000000000..a4f32eb15 --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_layers.imageset/ic_layers.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_typography.imageset/Contents.json b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_typography.imageset/Contents.json new file mode 100644 index 000000000..b580a0754 --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_typography.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "ic_typography.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_typography.imageset/ic_typography.svg b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_typography.imageset/ic_typography.svg new file mode 100644 index 000000000..1bf42c7f0 --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_typography.imageset/ic_typography.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_union.imageset/Contents.json b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_union.imageset/Contents.json new file mode 100644 index 000000000..ff0c4fa40 --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_union.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "ic_union.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_union.imageset/ic_union.svg b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_union.imageset/ic_union.svg new file mode 100644 index 000000000..8ae136591 --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/Tokens/ic_union.imageset/ic_union.svg @@ -0,0 +1,3 @@ + + + diff --git a/Showcase/Showcase/Resources/Assets.xcassets/ic_guideline_dna.imageset/ic_guideline_dna.svg b/Showcase/Showcase/Resources/Assets.xcassets/ic_guideline_dna.imageset/ic_guideline_dna.svg deleted file mode 100644 index 3af4f83e5..000000000 --- a/Showcase/Showcase/Resources/Assets.xcassets/ic_guideline_dna.imageset/ic_guideline_dna.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/Showcase/Showcase/Resources/Assets.xcassets/ic_guideline_dna.imageset/Contents.json b/Showcase/Showcase/Resources/Assets.xcassets/ic_token.imageset/Contents.json similarity index 81% rename from Showcase/Showcase/Resources/Assets.xcassets/ic_guideline_dna.imageset/Contents.json rename to Showcase/Showcase/Resources/Assets.xcassets/ic_token.imageset/Contents.json index 239af817d..c1c919126 100644 --- a/Showcase/Showcase/Resources/Assets.xcassets/ic_guideline_dna.imageset/Contents.json +++ b/Showcase/Showcase/Resources/Assets.xcassets/ic_token.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "ic_guideline_dna.svg", + "filename" : "ic_token.svg", "idiom" : "universal" } ], diff --git a/Showcase/Showcase/Resources/Assets.xcassets/ic_token.imageset/ic_token.svg b/Showcase/Showcase/Resources/Assets.xcassets/ic_token.imageset/ic_token.svg new file mode 100644 index 000000000..530f528b1 --- /dev/null +++ b/Showcase/Showcase/Resources/Assets.xcassets/ic_token.imageset/ic_token.svg @@ -0,0 +1,3 @@ + + + diff --git a/Showcase/Showcase/Resources/Colors.xcassets/Contents.json b/Showcase/Showcase/Resources/Colors.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/Showcase/Showcase/Resources/Colors.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Showcase/Showcase/Resources/Colors.xcassets/cardBackground.colorset/Contents.json b/Showcase/Showcase/Resources/Colors.xcassets/cardBackground.colorset/Contents.json new file mode 100644 index 000000000..c84ed18f5 --- /dev/null +++ b/Showcase/Showcase/Resources/Colors.xcassets/cardBackground.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x1A", + "green" : "0x1C", + "red" : "0x1C" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Showcase/Showcase/Resources/en.lproj/Localizable.strings b/Showcase/Showcase/Resources/en.lproj/Localizable.strings index eb5734d16..e9ca13aef 100644 --- a/Showcase/Showcase/Resources/en.lproj/Localizable.strings +++ b/Showcase/Showcase/Resources/en.lproj/Localizable.strings @@ -14,10 +14,29 @@ // MARK: - bottomBar "app_bottomBar_components" = "Components"; -"app_bottomBar_guidelines" = "Guidelines"; +"app_bottomBar_tokens" = "Tokens"; "app_bottomBar_about" = "About"; // MARK: - About Screen "app_about_label_legalInformation" = "Legal information"; "app_about_label_privacyPolicy" = "Privacy policy"; + +// MARK: - Tokens Screen + +"app_tokens_border_label" = "Border"; +"app_tokens_border_description_text" = "Borders are used for the stroke colours on components and also for the colours of divider lines for components like tables"; + +"app_tokens_elevation_label" = "Elevation"; +"app_tokens_elevation_description_text" = "Shadows are used to give the impression of distance or elevation between surfaces, which adds depth to our designs"; + +"app_tokens_typography_label" = "Typogaphy"; +"app_tokens_typography_description_text" = "Typography is our system of fonts and text styles. They enhance communication and reinforce the brand style"; + +"app_tokens_opacity_label" = "Opacity"; +"app_tokens_opacity_description_text" = "Opacity can help distinguish foreground elements from background elements, making content easier to read and important actions more noticeable"; + + +// MARK: - Component Screen +"app_component_empty_content_text" = "No content"; +"app_component_empty_content_description_text" = "This content is under construction and will be available very soon"; diff --git a/Showcase/Showcase/Showcase.swift b/Showcase/Showcase/Showcase.swift index 80ac6f145..e3cd5ba8a 100644 --- a/Showcase/Showcase/Showcase.swift +++ b/Showcase/Showcase/Showcase.swift @@ -11,13 +11,18 @@ // Software description: A SwiftUI components library with code examples for Orange Unified Design System // +import OUDS import SwiftUI @main struct Showcase: App { + @StateObject var themeProvider = ThemeProvider() + var body: some Scene { WindowGroup { - MainView() + OUDSThemeableView(theme: themeProvider.currentTheme) { + MainView().environmentObject(themeProvider) + } } } } diff --git a/Showcase/ShowcaseTests/ElevationsEffectsUITests.swift b/Showcase/ShowcaseTests/ElevationsEffectsUITests.swift deleted file mode 100644 index 98b4c73fb..000000000 --- a/Showcase/ShowcaseTests/ElevationsEffectsUITests.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// Software Name: OUDS iOS -// SPDX-FileCopyrightText: Copyright (c) Orange SA -// SPDX-License-Identifier: MIT -// -// This software is distributed under the MIT license, -// the text of which is available at https://opensource.org/license/MIT/ -// or see the "LICENSE" file for more details. -// -// Authors: See CONTRIBUTORS.txt -// Software description: A SwiftUI components library with code examples for Orange Unified Design System -// - -import OUDS_Showcase -import OUDSComponents -import OUDSThemesOrange -import OUDSThemesSosh -import OUDSThemesInverse -import SwiftUI -import XCTest - -/// Class to make UI tests on elevations effects using the -/// [swift-snapshot-testing](https://github.com/pointfreeco/swift-snapshot-testing) library. -final class ElevationsEffectsUITests: XCTestCase { - - // MARK: - Tests - - func testElevationsEffects_OrangeTheme() { - Snapshot.assert(ElevationsList().environment(\.theme, OrangeTheme()), testName: "\(#function)OrangeTheme") - } - - func testElevationsEffects_SoshTheme() { - Snapshot.assert(ElevationsList().environment(\.theme, SoshTheme()), testName: "\(#function)SoshTheme") - } - - func testElevationsEffects_InverseTheme() { - Snapshot.assert(ElevationsList().environment(\.theme, InverseTheme()), testName: "\(#function)InverseTheme") - } -} diff --git a/Showcase/ShowcaseTests/OUDSFormsTextInputUITests.swift b/Showcase/ShowcaseTests/OUDSFormsTextInputUITests.swift deleted file mode 100644 index 4dade640f..000000000 --- a/Showcase/ShowcaseTests/OUDSFormsTextInputUITests.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// Software Name: OUDS iOS -// SPDX-FileCopyrightText: Copyright (c) Orange SA -// SPDX-License-Identifier: MIT -// -// This software is distributed under the MIT license, -// the text of which is available at https://opensource.org/license/MIT/ -// or see the "LICENSE" file for more details. -// -// Authors: See CONTRIBUTORS.txt -// Software description: A SwiftUI components library with code examples for Orange Unified Design System -// - -import OUDS_Showcase -import OUDSComponents -import OUDSThemesOrange -import OUDSThemesSosh -import OUDSThemesInverse -import SwiftUI -import XCTest - -/// Class to make UI tests on the fake component `OUDSFormsTextInput` using the -/// [swift-snapshot-testing](https://github.com/pointfreeco/swift-snapshot-testing) library. -final class OUDSFormsTextInputUITests: XCTestCase { - - // MARK: - Wrapper - - private struct TestFormsTextInput: View { - @State private var value: String = "" - - var body: some View { - OUDSFormsTextInput(label: "Some label", hint: "Some hint", placeholder: "Add text here", value: $value) - } - } - - // MARK: - Tests - - func testOUDSFormsTextInput_OrangeTheme() { - Snapshot.assert(TestFormsTextInput().environment(\.theme, OrangeTheme()), testName: "\(#function)OrangeTheme") - } - - func testOUDSFormsTextInput_SoshTheme() { - Snapshot.assert(TestFormsTextInput().environment(\.theme, SoshTheme()), testName: "\(#function)SoshTheme") - } - - func testOUDSFormsTextInput_InverseTheme() { - Snapshot.assert(TestFormsTextInput().environment(\.theme, InverseTheme()), testName: "\(#function)InverseTheme") - } -}