Skip to content

Commit

Permalink
refactor: wrapping for semantic tokens of opacities (#79)
Browse files Browse the repository at this point in the history
Signed-off-by: Pierre-Yves Lapersonne <[email protected]>
  • Loading branch information
pylapp committed Dec 13, 2024
1 parent 3223f10 commit e560187
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Foundation
import OUDSTokensRaw
import OUDSTokensSemantic

extension OUDSTheme: OpacitySemanticTokens {
extension OUDSOpacitySemanticTokensWrapper: OpacitySemanticTokens {
@objc open var opacityInvisible: OpacitySemanticToken { OpacityRawTokens.opacity0 }
@objc open var opacityMedium: OpacitySemanticToken { OpacityRawTokens.opacity320 }
@objc open var opacityOpaque: OpacitySemanticToken { OpacityRawTokens.opacity1000 }
Expand Down
15 changes: 12 additions & 3 deletions OUDS/Core/OUDS/Sources/OUDSTheme/OUDSTheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ open class OUDSTheme: @unchecked Sendable {

// MARK: - Properties

/// All semantic tokens of border exposed in one object
/// All border semantic tokens exposed in one object
public let borders: BorderSemanticTokens

/// All opacity semantic tokens exposed in one object
public let opacities: OpacitySemanticTokens

/// A theme can have a custom font which is not the system font
public let customFontFamily: FontFamilySemanticToken?

Expand All @@ -41,19 +44,25 @@ open class OUDSTheme: @unchecked Sendable {
/// No custom font family will be used.
/// - Parameters:
/// - borders: An object providing all the border semantic tokens, by default `OUDSBorderSemanticTokensWrapper`
public init(borders: BorderSemanticTokens = OUDSBorderSemanticTokensWrapper()) {
/// - opacities: An object providing all the opacity semantic tokens, by default `OUDSOpacitySemanticTokensWrapper`
public init(borders: BorderSemanticTokens = OUDSBorderSemanticTokensWrapper(),
opacities: OpacitySemanticTokens = OUDSOpacitySemanticTokensWrapper()) {
self.borders = borders
self.opacities = opacities
customFontFamily = nil
}

/// Defines a basic kind of abstract theme to subclass then.
/// - Parameters:
/// - borders: An object providing all the border semantic tokens, as `BorderSemanticTokens` implementation
/// - opacities: An object providing all the opacity semantic tokens, as `OpacitySemanticTokens` implementation
/// - customFontFamily: Set `nil` if system font to use, otherwise use the `FontFamilySemanticToken` you want to apply
public init(borders: BorderSemanticTokens,
opacities: OpacitySemanticTokens,
customFontFamily: FontFamilySemanticToken?) {
self.customFontFamily = customFontFamily
self.borders = borders
self.opacities = opacities
self.customFontFamily = customFontFamily
}

deinit { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import OUDSTokensSemantic

// swiftlint:disable required_deinit

/// Overrides **all** the border semantic tokens (from its super class, i.e. `OUDSBorderSemanticTokensWrapper` so as to test overriding of them (unit tests)
/// Overrides **all** the border semantic tokens (from its super class, i.e. `OUDSBorderSemanticTokensWrapper`) so as to test overriding of them (unit tests)
/// and to act like smoke tests with crashing tests if some tokens disappeared.
final class MockThemeBorderSemanticTokensWrapper: OUDSBorderSemanticTokensWrapper {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// SPDX-License-Identifier: MIT
//
// This software is distributed under the MIT license,
// the text of which is available at https://opensource.org/license/MIT/
// the text of which is available at https://publicsource.org/license/MIT/
// or see the "LICENSE" file for more details.
//
// Authors: See CONTRIBUTORS.txt
Expand All @@ -15,16 +15,20 @@ import Foundation
import OUDSTokensRaw
import OUDSTokensSemantic

/// Overrides **all** the opacity semantic tokens (from its super class, i.e. `OUDSTheme` so as to test overriding of them (unit tests)
// swiftlint:disable required_deinit

/// Overrides **all** the opacity semantic tokens (from its super class, i.e. `OUDSOpacitySemanticTokensWrapper`) so as to test overriding of them (unit tests)
/// and to act like smoke tests with crashing tests if some tokens disappeared.
extension MockTheme {
final class MockThemeOpacitySemanticTokensWrapper: OUDSOpacitySemanticTokensWrapper {

static let mockThemeOpacityRawToken: OpacityRawToken = 713

override open var opacityInvisible: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
override open var opacityWeaker: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
override open var opacityWeak: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
override open var opacityMedium: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
override open var opacityStrong: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
override open var opacityOpaque: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
override public var opacityInvisible: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
override public var opacityWeaker: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
override public var opacityWeak: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
override public var opacityMedium: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
override public var opacityStrong: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
override public var opacityOpaque: OpacitySemanticToken { Self.mockThemeOpacityRawToken }
}

// swiftlint:enable required_deinit
2 changes: 2 additions & 0 deletions OUDS/Core/OUDS/Tests/OUDSTheme/MockThemes/MockTheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import OUDSTokensSemantic
///
/// Uses its own tokens wrappers for tests:
/// - ``MockThemeBorderSemanticTokensWrapper`` for borders
/// - ``MockThemeOpacitySemanticTokensWrapper`` for opacities
open class MockTheme: OUDSTheme, @unchecked Sendable {

convenience init() {
Expand All @@ -28,6 +29,7 @@ open class MockTheme: OUDSTheme, @unchecked Sendable {

init(customFont: String?) {
super.init(borders: MockThemeBorderSemanticTokensWrapper(),
opacities: MockThemeOpacitySemanticTokensWrapper(),
customFontFamily: customFont)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,33 +34,33 @@ final class TestThemeOverrideOfOpacitySemanticTokens: XCTestCase {
}

func testInheritedThemeCanOverrideSemanticTokenOpacityInvisible() throws {
XCTAssertNotEqual(inheritedTheme.opacityInvisible, abstractTheme.opacityInvisible)
XCTAssertTrue(inheritedTheme.opacityInvisible == MockTheme.mockThemeOpacityRawToken)
XCTAssertNotEqual(inheritedTheme.opacities.opacityInvisible, abstractTheme.opacities.opacityInvisible)
XCTAssertTrue(inheritedTheme.opacities.opacityInvisible == MockThemeOpacitySemanticTokensWrapper.mockThemeOpacityRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenOpacityWeaker() throws {
XCTAssertNotEqual(inheritedTheme.opacityWeaker, abstractTheme.opacityWeaker)
XCTAssertTrue(inheritedTheme.opacityWeaker == MockTheme.mockThemeOpacityRawToken)
XCTAssertNotEqual(inheritedTheme.opacities.opacityWeaker, abstractTheme.opacities.opacityWeaker)
XCTAssertTrue(inheritedTheme.opacities.opacityWeaker == MockThemeOpacitySemanticTokensWrapper.mockThemeOpacityRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenOpacityWeak() throws {
XCTAssertNotEqual(inheritedTheme.opacityWeak, abstractTheme.opacityWeak)
XCTAssertTrue(inheritedTheme.opacityWeak == MockTheme.mockThemeOpacityRawToken)
XCTAssertNotEqual(inheritedTheme.opacities.opacityWeak, abstractTheme.opacities.opacityWeak)
XCTAssertTrue(inheritedTheme.opacities.opacityWeak == MockThemeOpacitySemanticTokensWrapper.mockThemeOpacityRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenOpacityMedium() throws {
XCTAssertNotEqual(inheritedTheme.opacityMedium, abstractTheme.opacityMedium)
XCTAssertTrue(inheritedTheme.opacityMedium == MockTheme.mockThemeOpacityRawToken)
XCTAssertNotEqual(inheritedTheme.opacities.opacityMedium, abstractTheme.opacities.opacityMedium)
XCTAssertTrue(inheritedTheme.opacities.opacityMedium == MockThemeOpacitySemanticTokensWrapper.mockThemeOpacityRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenOpacityEmphasized() throws {
XCTAssertNotEqual(inheritedTheme.opacityStrong, abstractTheme.opacityStrong)
XCTAssertTrue(inheritedTheme.opacityStrong == MockTheme.mockThemeOpacityRawToken)
XCTAssertNotEqual(inheritedTheme.opacities.opacityStrong, abstractTheme.opacities.opacityStrong)
XCTAssertTrue(inheritedTheme.opacities.opacityStrong == MockThemeOpacitySemanticTokensWrapper.mockThemeOpacityRawToken)
}

func testInheritedThemeCanOverrideSemanticTokenOpacityOpaque() throws {
XCTAssertNotEqual(inheritedTheme.opacityOpaque, abstractTheme.opacityOpaque)
XCTAssertTrue(inheritedTheme.opacityOpaque == MockTheme.mockThemeOpacityRawToken)
XCTAssertNotEqual(inheritedTheme.opacities.opacityOpaque, abstractTheme.opacities.opacityOpaque)
XCTAssertTrue(inheritedTheme.opacities.opacityOpaque == MockThemeOpacitySemanticTokensWrapper.mockThemeOpacityRawToken)
}
}

Expand Down
4 changes: 3 additions & 1 deletion OUDS/Core/Themes/Orange/Sources/OrangeTheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ open class OrangeTheme: OUDSTheme, @unchecked Sendable {
/// Initializes the `OrangeTheme` and lets children classes to user their own tokens implementations
/// - Parameters:
/// - borders: An object providing all the border semantic tokens, as `BorderSemanticTokens` implementation
override public init(borders: BorderSemanticTokens) {
/// - opacities: An object providing all the opacity semantic tokens, as `OpacitySemanticTokens` implementation
override public init(borders: BorderSemanticTokens,
opacities: OpacitySemanticTokens) {
super.init(borders: borders)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

/// This is a group of semantic tokens for **opacity.**
/// It defines all ``OpacitySemanticToken`` a theme must have.
/// Any opacity semantic token must be declared there.
/// Any opacity semantic token must be declared there as wrappers like ``OUDSOpacitySemanticTokensWrapper`` will then expose them through `OUDSTheme`.
public protocol OpacitySemanticTokens {

// MARK: Semantic token - Opacity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// Software description: A SwiftUI components library with code examples for Orange Unified Design System
//

/// A class which wraps all ``BorderSemanticTokens`` and expose them.
/// A class which wraps all **border semantic tokens** and expose them.
/// This wrapper should be integrated as a ``BorderSemanticTokens`` implementation inside `OUDSTheme` so as to provide
/// all tokens to the users.
open class OUDSBorderSemanticTokensWrapper {
Expand All @@ -24,5 +24,5 @@ open class OUDSBorderSemanticTokensWrapper {
// ଘ( ・ω・)_/゚・:*:・。☆
// Note: So as to help the integration of generated code produced by the tokenator
// the implemention of BorderSemanticTokens is not here but in OUDS/OUDSTheme/OUDSTheme+SemanticTokens/OUDSTheme+BorderSemanticTokens.swift
// This declaration of BorderSemanticTokensWrapper is here to allow to write documentation.
// This declaration of OUDSBorderSemanticTokensWrapper is here to allow to write documentation.
}
Original file line number Diff line number Diff line change
@@ -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
//

/// A class which wraps all **opacity semantic tokens** and expose them.
/// This wrapper should be integrated as a ``OpacitySemanticTokens`` implementation inside `OUDSTheme` so as to provide
/// all tokens to the users.
open class OUDSOpacitySemanticTokensWrapper {

/// Intializes the wrapper
public init() { }

deinit{ }

// ଘ( ・ω・)_/゚・:*:・。☆
// Note: So as to help the integration of generated code produced by the tokenator
// the implemention of BorderSemanticTokens is not here but in OUDS/OUDSTheme/OUDSTheme+SemanticTokens/OUDSTheme+OpacitySemanticTokens.swift
// This declaration of OUDSOpacitySemanticTokens is here to allow to write documentation.
}
14 changes: 7 additions & 7 deletions Showcase/Showcase/Pages/Tokens/Opacity/OpacityTokenPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct OpacityTokenPage: View {
var body: some View {
VStack(alignment: .leading, spacing: theme.spaceFixedNone) {
Section {
ShowcaseCode(code: "theme.opacityInvisible")
ShowcaseCode(code: "theme.opacities.opacityInvisible")
}

Spacer() .frame(height: theme.spaceFixedMedium)
Expand Down Expand Up @@ -88,17 +88,17 @@ enum NamedOpacity: String, CaseIterable {
func token(from theme: OUDSTheme) -> OpacitySemanticToken {
switch self {
case .opacityInvisible:
return theme.opacityInvisible
return theme.opacities.opacityInvisible
case .opacityWeaker:
return theme.opacityWeaker
return theme.opacities.opacityWeaker
case .opacityWeak:
return theme.opacityWeak
return theme.opacities.opacityWeak
case .opacityMedium:
return theme.opacityMedium
return theme.opacities.opacityMedium
case .opacityStrong:
return theme.opacityStrong
return theme.opacities.opacityStrong
case .opacityOpaque:
return theme.opacityOpaque
return theme.opacities.opacityOpaque
}
}
}
2 changes: 1 addition & 1 deletion Showcase/Showcase/Pages/Utils/ShowcaseCode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ struct ShowcaseCode: View {
.accessibilityHint("app_tokens_code_copy_button_a11y")
.overlay(
Rectangle()
.opacity(theme.opacityInvisible)
.opacity(theme.opacities.opacityInvisible)
.frame(minWidth: 40, maxWidth: .infinity, alignment: .leading)
.oudsBorder(style: theme.borders.borderStyleDefault,
width: theme.borders.borderWidthThin,
Expand Down

0 comments on commit e560187

Please sign in to comment.