Skip to content

Commit

Permalink
feat: add spacing screen in demo app (#149) (#176)
Browse files Browse the repository at this point in the history
Reviewed-by: Pierre-Yves Lapersonne <[email protected]>
  • Loading branch information
ludovic35 authored Oct 9, 2024
1 parent 1522281 commit b51e51d
Show file tree
Hide file tree
Showing 11 changed files with 290 additions and 6 deletions.
1 change: 1 addition & 0 deletions NOTICE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Any use or displaying shall constitute an infringement under intellectual proper
./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_dimension.imageset/ic_dimension.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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import Foundation
import OUDSTokensRaw
import SwiftUI

/// Kind of semantic tokens which will wrap a combination of `DimensionRawToken` depending to size classes.
/// Kind of composite token with multiple values, but not named "composite" because this word is already used in the design system.
Expand Down Expand Up @@ -41,4 +42,11 @@ public final class MultipleSpacingTokens: NSObject {
guard let other = object as? MultipleSpacingTokens else { return false }
return self.compact == other.compact && self.regular == other.regular
}

/// Returns the right dimension according to the `userInterfaceSizeClass`.
/// - Parameter userInterfaceSizeClass: The user interface size class (Could be the horizontal or the vertical size class)
/// - Returns: The right dimension raw token
public func dimension(for userInterfaceSizeClass: UserInterfaceSizeClass) -> DimensionRawToken {
userInterfaceSizeClass == .compact ? compact : regular
}
}
44 changes: 44 additions & 0 deletions Showcase/Showcase.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
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 */; };
077CCE572CB426090059CC28 /* SpacingTokenElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077CCE512CB426090059CC28 /* SpacingTokenElement.swift */; };
077CCE582CB426090059CC28 /* SpacingTokenPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077CCE522CB426090059CC28 /* SpacingTokenPage.swift */; };
077CCE592CB426090059CC28 /* DimensionTokenElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077CCE542CB426090059CC28 /* DimensionTokenElement.swift */; };
077CCE5C2CB431C50059CC28 /* ShowcaseVariantElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077CCE5B2CB431C50059CC28 /* ShowcaseVariantElement.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 */; };
Expand Down Expand Up @@ -86,13 +90,19 @@
073543172CA172CA001187EA /* TypographyTokenElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypographyTokenElement.swift; sourceTree = "<group>"; };
0735431A2CA18C48001187EA /* TypographyTokenPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypographyTokenPage.swift; sourceTree = "<group>"; };
073543222CA192F9001187EA /* TokenElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TokenElement.swift; sourceTree = "<group>"; };
073EC3212CB3DC9300B2ADB4 /* SpacingTokenElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpacingTokenElement.swift; sourceTree = "<group>"; };
073EC3222CB3DC9300B2ADB4 /* SpacingTokenPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpacingTokenPage.swift; sourceTree = "<group>"; };
074008222C942810006B8729 /* Snapshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Snapshot.swift; sourceTree = "<group>"; };
0740A9872C9833670069D24A /* Appfile */ = {isa = PBXFileReference; lastKnownFileType = text; name = Appfile; path = fastlane/Appfile; sourceTree = "<group>"; };
0740A9882C9833670069D24A /* Fastfile */ = {isa = PBXFileReference; lastKnownFileType = text; name = Fastfile; path = fastlane/Fastfile; sourceTree = "<group>"; };
0740A9892C9833670069D24A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = fastlane/README.md; sourceTree = "<group>"; };
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 = "<group>"; };
074794792CAE882A0033C2D8 /* EmptyState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyState.swift; sourceTree = "<group>"; };
077CCE512CB426090059CC28 /* SpacingTokenElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpacingTokenElement.swift; sourceTree = "<group>"; };
077CCE522CB426090059CC28 /* SpacingTokenPage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpacingTokenPage.swift; sourceTree = "<group>"; };
077CCE542CB426090059CC28 /* DimensionTokenElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DimensionTokenElement.swift; sourceTree = "<group>"; };
077CCE5B2CB431C50059CC28 /* ShowcaseVariantElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowcaseVariantElement.swift; sourceTree = "<group>"; };
07CEDD802C7DB921003E1885 /* generateDoc.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = generateDoc.sh; path = ../generateDoc.sh; sourceTree = "<group>"; };
07CF426A2CA30728000BD03E /* TokensPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokensPage.swift; sourceTree = "<group>"; };
07CF42712CA31AC3000BD03E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
Expand Down Expand Up @@ -183,6 +193,7 @@
51BD760F2C466FCF0033365D /* ShowcaseElementsPage.swift */,
51E3FF0A2CAFD9AE00F1BC59 /* ShowcaseElementPage.swift */,
073543152CA17275001187EA /* ShowcaseElement.swift */,
077CCE5B2CB431C50059CC28 /* ShowcaseVariantElement.swift */,
);
path = Utils;
sourceTree = "<group>";
Expand Down Expand Up @@ -223,6 +234,33 @@
path = ShowcaseTests;
sourceTree = "<group>";
};
077CCE502CB4254B0059CC28 /* Recovered References */ = {
isa = PBXGroup;
children = (
073EC3222CB3DC9300B2ADB4 /* SpacingTokenPage.swift */,
073EC3212CB3DC9300B2ADB4 /* SpacingTokenElement.swift */,
);
name = "Recovered References";
sourceTree = "<group>";
};
077CCE532CB426090059CC28 /* Spacing */ = {
isa = PBXGroup;
children = (
077CCE512CB426090059CC28 /* SpacingTokenElement.swift */,
077CCE522CB426090059CC28 /* SpacingTokenPage.swift */,
);
path = Spacing;
sourceTree = "<group>";
};
077CCE562CB426090059CC28 /* Dimension */ = {
isa = PBXGroup;
children = (
077CCE532CB426090059CC28 /* Spacing */,
077CCE542CB426090059CC28 /* DimensionTokenElement.swift */,
);
path = Dimension;
sourceTree = "<group>";
};
07CF42752CA3F461000BD03E /* Elevation */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -267,6 +305,7 @@
07FDCD922C296A500009AA13 /* Products */,
AFD4931269C94655071502F6 /* Pods */,
6E90D400B72B50FE406E8DFC /* Frameworks */,
077CCE502CB4254B0059CC28 /* Recovered References */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -331,6 +370,7 @@
51BD76102C466FCF0033365D /* Tokens */ = {
isa = PBXGroup;
children = (
077CCE562CB426090059CC28 /* Dimension */,
07CF42832CA45DA9000BD03E /* Border */,
07CF427C2CA412F5000BD03E /* Opacity */,
07CF42752CA3F461000BD03E /* Elevation */,
Expand Down Expand Up @@ -615,6 +655,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
077CCE592CB426090059CC28 /* DimensionTokenElement.swift in Sources */,
07CF42852CA45DA9000BD03E /* BorderTokenPage.swift in Sources */,
07CF42842CA45DA9000BD03E /* BorderTokenElement.swift in Sources */,
07CF42802CA41325000BD03E /* OpacityTokenPage.swift in Sources */,
Expand All @@ -626,11 +667,14 @@
07CF42792CA3F4BE000BD03E /* ElevationTokenPage.swift in Sources */,
0735432A2CA192F9001187EA /* TokenElement.swift in Sources */,
073543182CA172CA001187EA /* TypographyTokenElement.swift in Sources */,
077CCE5C2CB431C50059CC28 /* ShowcaseVariantElement.swift in Sources */,
077CCE582CB426090059CC28 /* SpacingTokenPage.swift in Sources */,
51BD76292C466FCF0033365D /* WebView.swift in Sources */,
51BD76232C466FCF0033365D /* ShowcaseElementsPage.swift in Sources */,
51E3FF0B2CAFD9AE00F1BC59 /* ShowcaseElementPage.swift in Sources */,
073543162CA17275001187EA /* ShowcaseElement.swift in Sources */,
51087A7B2C46DF9F00160CCF /* Bundle+extension.swift in Sources */,
077CCE572CB426090059CC28 /* SpacingTokenElement.swift in Sources */,
0735431B2CA18C48001187EA /* TypographyTokenPage.swift in Sources */,
51BD76222C466FCF0033365D /* ComponentsPage.swift in Sources */,
07CF42892CA55BC8000BD03E /* ThemeSelection.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "a5dafe8eac933fcb82d3621146d26499c98e02cc27a69139d2b8440ccab12b2f",
"originHash" : "81dd24fcf515e36030cf2a7c4f61c707b77ba95118788932a6b66286a8b60877",
"pins" : [
{
"identity" : "swift-docc-plugin",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// 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 DimensionTokenElement: TokenElement {
let name: String
let imageName: String
let description: String
let pageDescription: AnyView

let variants: [TokenElement] = [
SpacingTokenElement()
]

init() {
name = "app_tokens_dimension_label"
imageName = "ic_dimension"
description = "app_tokens_dimension_description_text"
pageDescription = AnyView(ShowcaseVariantElement(elements: variants))
}
}
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
//

import SwiftUI

struct SpacingTokenElement: TokenElement {
let name: String
let imageName: String
let description: String
let pageDescription: AnyView

init() {
name = "app_tokens_dimension_spacing_label"
imageName = "ic_dimension"
description = "app_tokens_dimension_spacing_description_text"
pageDescription = AnyView(SpacingTokenPage())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//
// 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

struct SpacingTokenPage: View {

@Environment(\.theme) private var theme
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
@Environment(\.verticalSizeClass) private var verticalSizeClass
@Environment(\.colorScheme) private var colorScheme

// MARK: Body

var body: some View {
VStack(alignment: .leading, spacing: theme.spaceFixedNone) {
ForEach(NamedSpacing.allCases, id: \.rawValue) { spacingName in
illustration(for: spacingName)
}
}
.frame(maxWidth: .infinity)
.padding(.horizontal, theme.spaceFixedMedium)
}

// MARK: Private helpers

private func illustration(for spacingName: NamedSpacing) -> some View {
illustration(for: spacingName.token(from: theme), named: spacingName.rawValue)
}

private func illustration(for spacingSementicToken: MultipleSpacingTokens, named: String) -> some View {

let horizontalDimensionRawToken = spacingSementicToken.dimension(for: horizontalSizeClass ?? .regular)
let verticalDimensionRawToken = spacingSementicToken.dimension(for: verticalSizeClass ?? .regular)
return HStack(alignment: .center, spacing: theme.spaceFixedMedium) {
ZStack {
Rectangle()
.fill((theme.colorBackgroundEmphasizedPrimary?.color(for: colorScheme))!)
.frame(width: 64, height: 64, alignment: .center)
Rectangle()
// .fill((theme.colorBackgroundStatusAttractiveEmphasized?.color(for: colorScheme))!) // TODO: Update when color is available
.fill(.blue)
.frame(width: horizontalDimensionRawToken, height: 64, alignment: .center)
}
VStack(alignment: .leading) {
Text(named).typeBodyStrongLarge(theme)
Text("horizontal \(horizontalSizeClass == .regular ? "regular" : "compact") \(horizontalDimensionRawToken, specifier: "%.0f") pt")
Text("vertical \(verticalSizeClass == .regular ? "regular" : "compact") \(verticalDimensionRawToken, specifier: "%.0f") pt")
}
.frame(maxWidth: .infinity, alignment: .leading)
.foregroundColor(theme.colorContentDefault?.color(for: colorScheme))
}
.padding(.vertical, theme.spaceFixedShorter)
}
}

// MARK: - Named Spacing

private enum NamedSpacing: String, CaseIterable {
case spaceScaledNone
case spaceScaledSmash
case spaceScaledShortest
case spaceScaledShorter
case spaceScaledShort
case spaceScaledMedium
case spaceScaledTall
case spaceScaledTaller
case spaceScaledTallest
case spaceScaledSpacious

func token(from theme: OUDSTheme) -> MultipleSpacingTokens {
switch self {
case .spaceScaledNone:
return theme.spaceScaledNone
case .spaceScaledSmash:
return theme.spaceScaledSmash
case .spaceScaledShortest:
return theme.spaceScaledShortest
case .spaceScaledShorter:
return theme.spaceScaledShorter
case .spaceScaledShort:
return theme.spaceScaledShort
case .spaceScaledMedium:
return theme.spaceScaledMedium
case .spaceScaledTall:
return theme.spaceScaledTall
case .spaceScaledTaller:
return theme.spaceScaledTaller
case .spaceScaledTallest:
return theme.spaceScaledTallest
case .spaceScaledSpacious:
return theme.spaceScaledSpacious
}
}
}
1 change: 1 addition & 0 deletions Showcase/Showcase/Pages/Tokens/TokensPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct TokensPage: View {

let tokenElements: [TokenElement] = [
BorderTokenElement(),
DimensionTokenElement(),
ElevationTokenElement(),
OpacityTokenElement(),
TypographyTokenElement(),
Expand Down
43 changes: 43 additions & 0 deletions Showcase/Showcase/Pages/Utils/ShowcaseVariantElement.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// 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

struct ShowcaseVariantElement: View {

@Environment(\.theme) private var theme
@Environment(\.colorScheme) private var colorScheme

// MARK: Stored properties

let elements: [ShowcaseElement]

// MARK: Body

var body: some View {
VStack(alignment: .center, spacing: theme.spaceFixedMedium) {
ForEach(elements, id: \.id) { element in
NavigationLink {
ShowcaseElementPage(element: element)
} label: {
Text(LocalizedStringKey(element.name))
.typeHeadingMedium(theme)
.padding(.vertical, theme.spaceFixedShorter)
}
}
}
.padding(.horizontal, theme.spaceFixedMedium)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "ic_dimension.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading

0 comments on commit b51e51d

Please sign in to comment.