mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Adopt Compound Colours (#1086)
* Delete deprecated font tokens. * Migrate from primaryContent to textPrimary/iconPrimary. * Migrate from links to textLinkExternal. * Migrate from secondaryContent to textSecondary/iconSecondary. * Migrate from accent to textActionPrimary. - Some uses changed to textPrimary or iconPrimary as necessary. - Some manual tints removed now that that Sentry is fixed. * Migrate alert to textCriticalPrimary/iconCriticalPrimary. * Migrate from brand to textActionAccent/iconAccentTertiary. * Migrate from background to bgCanvasDefault or text/iconOnSolidPrimary * Migrate system to bgSubtleSecondary. * Remove ElementUIColors and obsolete migrated colours. * Migrate tertiaryContent/quaternaryContent/quinaryContent to Compound. * Migrate bubblesYou/bubblesNotYou to use Compound. * Update Compound.
This commit is contained in:
@@ -12,7 +12,7 @@ let package = Package(
|
||||
.library(name: "DesignKit", targets: ["DesignKit"])
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/vector-im/compound-ios.git", revision: "aaa43409ca09130cb9e9a0fe02c803c65aa42aed"),
|
||||
.package(url: "https://github.com/vector-im/compound-ios.git", revision: "d59c317362beba940baa43d6aacdd357e208048d"),
|
||||
.package(url: "https://github.com/vector-im/element-design-tokens.git", exact: "0.0.3"),
|
||||
.package(url: "https://github.com/siteline/SwiftUI-Introspect.git", from: "0.1.4")
|
||||
],
|
||||
|
||||
@@ -23,7 +23,7 @@ public extension ButtonStyle where Self == ElementActionButtonStyle {
|
||||
/// - Parameter size: The control size to use. Defaults to regular.
|
||||
/// - Parameter color: The color of the button's background. Defaults to the accent color.
|
||||
static func elementAction(_ size: ElementControlSize = .regular,
|
||||
color: Color = .element.accent) -> ElementActionButtonStyle {
|
||||
color: Color = .compound.textActionPrimary) -> ElementActionButtonStyle {
|
||||
ElementActionButtonStyle(size: size, color: color)
|
||||
}
|
||||
}
|
||||
@@ -40,12 +40,11 @@ public struct ElementActionButtonStyle: ButtonStyle {
|
||||
private var maxWidth: CGFloat? { size == .xLarge ? .infinity : nil }
|
||||
|
||||
private var fontColor: Color {
|
||||
// Always white unless disabled with a dark theme.
|
||||
Color.element.systemPrimaryBackground
|
||||
Color.compound.textOnSolidPrimary
|
||||
.opacity(colorScheme == .dark && !isEnabled ? 0.3 : 1.0)
|
||||
}
|
||||
|
||||
public init(size: ElementControlSize = .regular, color: Color = .element.accent) {
|
||||
public init(size: ElementControlSize = .regular, color: Color = .compound.textActionPrimary) {
|
||||
self.size = size
|
||||
self.color = color
|
||||
}
|
||||
@@ -80,12 +79,12 @@ public struct ElementActionButtonStyle_Previews: PreviewProvider {
|
||||
|
||||
Button { /* preview */ } label: {
|
||||
Text("Clear BG")
|
||||
.foregroundColor(.element.alert)
|
||||
.foregroundColor(.compound.textCriticalPrimary)
|
||||
}
|
||||
.buttonStyle(ElementActionButtonStyle(color: .clear))
|
||||
|
||||
Button("Red BG") { /* preview */ }
|
||||
.buttonStyle(ElementActionButtonStyle(color: .element.alert))
|
||||
.buttonStyle(ElementActionButtonStyle(color: .compound.textCriticalPrimary))
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
|
||||
@@ -47,15 +47,15 @@ public struct ElementCapsuleButtonStyle: ButtonStyle {
|
||||
var background: some View {
|
||||
if isProminent {
|
||||
Capsule()
|
||||
.foregroundColor(Color.element.accent)
|
||||
.foregroundColor(Color.compound.textActionPrimary)
|
||||
} else {
|
||||
Capsule()
|
||||
.stroke(Color.element.accent)
|
||||
.stroke(Color.compound.textActionPrimary)
|
||||
}
|
||||
}
|
||||
|
||||
var fontColor: Color {
|
||||
isProminent ? .element.systemPrimaryBackground : .element.systemPrimaryLabel
|
||||
isProminent ? .compound.textOnSolidPrimary : .compound.textPrimary
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Compound
|
||||
import DesignTokens
|
||||
import SwiftUI
|
||||
|
||||
@@ -22,7 +23,7 @@ public extension ButtonStyle where Self == ElementGhostButtonStyle {
|
||||
/// - Parameter size: The control size to use. Defaults to `regular`.
|
||||
/// - Parameter color: The color of the label and border. Defaults to the accent color.
|
||||
static func elementGhost(_ size: ElementControlSize = .regular,
|
||||
color: Color = .element.primaryContent) -> ElementGhostButtonStyle {
|
||||
color: Color = .compound.textActionAccent) -> ElementGhostButtonStyle {
|
||||
ElementGhostButtonStyle(size: size, color: color)
|
||||
}
|
||||
}
|
||||
@@ -36,7 +37,7 @@ public struct ElementGhostButtonStyle: ButtonStyle {
|
||||
private var verticalPadding: CGFloat { size == .xLarge ? 12 : 4 }
|
||||
private var maxWidth: CGFloat? { size == .xLarge ? .infinity : nil }
|
||||
|
||||
public init(size: ElementControlSize = .regular, color: Color = .element.primaryContent) {
|
||||
public init(size: ElementControlSize = .regular, color: Color = .compound.textActionAccent) {
|
||||
self.size = size
|
||||
self.color = color
|
||||
}
|
||||
@@ -75,13 +76,13 @@ public struct ElementGhostButtonStyle_Previews: PreviewProvider {
|
||||
.disabled(true)
|
||||
|
||||
Button("Red BG") { /* preview */ }
|
||||
.buttonStyle(ElementGhostButtonStyle(color: .element.alert))
|
||||
.buttonStyle(ElementGhostButtonStyle(color: .compound.textCriticalPrimary))
|
||||
|
||||
Button { /* preview */ } label: {
|
||||
Text("Custom")
|
||||
.foregroundColor(.element.primaryContent)
|
||||
.foregroundColor(.compound.iconInfoPrimary)
|
||||
}
|
||||
.buttonStyle(ElementGhostButtonStyle(color: .element.quaternaryContent))
|
||||
.buttonStyle(ElementGhostButtonStyle(color: .compound.borderInfoSubtle))
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
|
||||
@@ -27,22 +27,32 @@ public extension Color {
|
||||
public struct ElementColors {
|
||||
// MARK: - Legacy Compound
|
||||
|
||||
private let compound = DesignTokens.CompoundColors()
|
||||
private let colors = DesignTokens.CompoundColors()
|
||||
|
||||
public var accent: Color { systemPrimaryLabel }
|
||||
public var alert: Color { compound.alert }
|
||||
public var links: Color { compound.links }
|
||||
public var primaryContent: Color { compound.primaryContent }
|
||||
public var secondaryContent: Color { compound.secondaryContent }
|
||||
public var tertiaryContent: Color { compound.tertiaryContent }
|
||||
public var quaternaryContent: Color { compound.quaternaryContent }
|
||||
public var quinaryContent: Color { compound.quinaryContent }
|
||||
public var system: Color { compound.system }
|
||||
public var background: Color { compound.background }
|
||||
// Should be the accent color
|
||||
public var brand: Color { compound.accent }
|
||||
@available(swift, obsoleted: 5.0, message: "Use textActionPrimary from Compound.")
|
||||
public var accent: Color { colors.primaryContent }
|
||||
@available(swift, obsoleted: 5.0, message: "Use textCriticalPrimary/iconCriticalPrimary from Compound.")
|
||||
public var alert: Color { colors.alert }
|
||||
@available(swift, obsoleted: 5.0, message: "Use textLinkExternal from Compound.")
|
||||
public var links: Color { colors.links }
|
||||
@available(swift, obsoleted: 5.0, message: "Use textPrimary/iconPrimary from Compound.")
|
||||
public var primaryContent: Color { colors.primaryContent }
|
||||
@available(swift, obsoleted: 5.0, message: "Use textSecondary/iconSecondary from Compound.")
|
||||
public var secondaryContent: Color { colors.secondaryContent }
|
||||
@available(swift, obsoleted: 5.0, message: "Use iconTertiary form Compound for icons. For text use textSecondary. For borders and backgrounds check with Design.")
|
||||
public var tertiaryContent: Color { colors.tertiaryContent }
|
||||
@available(swift, obsoleted: 5.0, message: "Use iconQuaternary from Compound for icons. For text, borders and backgrounds check with Design.")
|
||||
public var quaternaryContent: Color { colors.quaternaryContent }
|
||||
@available(swift, obsoleted: 5.0, message: "Check with Design for the tokens to use from Compound.")
|
||||
public var quinaryContent: Color { colors.quinaryContent }
|
||||
@available(swift, obsoleted: 5.0, message: "Use bgSubtleSecondary from Compound.")
|
||||
public var system: Color { colors.system }
|
||||
@available(swift, obsoleted: 5.0, message: "Use bgCanvasDefault from Compound for backgrounds. For text or icons use textOnSolidPrimary/iconOnSolidPrimary.")
|
||||
public var background: Color { colors.background }
|
||||
@available(swift, obsoleted: 5.0, message: "Use textActionAccent/iconAccentTertiary from Compound.")
|
||||
public var brand: Color { colors.accent }
|
||||
|
||||
public var contentAndAvatars: [Color] { compound.contentAndAvatars }
|
||||
public var contentAndAvatars: [Color] { colors.contentAndAvatars }
|
||||
|
||||
public func avatarBackground(for contentId: String) -> Color {
|
||||
let colorIndex = Int(contentId.hashCode % Int32(contentAndAvatars.count))
|
||||
@@ -51,31 +61,12 @@ public struct ElementColors {
|
||||
|
||||
// MARK: - Temp
|
||||
|
||||
public var systemPrimaryLabel: Color { .primary }
|
||||
public var systemPrimaryBackground: Color { Color(.systemBackground) }
|
||||
public var systemGray4: Color { Color(.systemGray4) }
|
||||
public var systemGray6: Color { Color(.systemGray6) }
|
||||
|
||||
public var bubblesYou: Color {
|
||||
Color(UIColor { collection in
|
||||
// Note: Light colour doesn't currently match Figma.
|
||||
collection.userInterfaceStyle == .light ? .systemGray5 : UIColor(red: 0.16, green: 0.18, blue: 0.21, alpha: 1)
|
||||
})
|
||||
}
|
||||
|
||||
public var bubblesNotYou: Color {
|
||||
Color(UIColor { collection in
|
||||
// Note: Light colour doesn't currently match Figma.
|
||||
collection.userInterfaceStyle == .light ? .systemGray6 : .element.system
|
||||
})
|
||||
}
|
||||
|
||||
/// The colour to use on the background of a Form or grouped List.
|
||||
///
|
||||
/// This colour is a special case as it uses `system` in light mode and `background` in dark mode.
|
||||
public var formBackground: Color {
|
||||
Color(UIColor { collection in
|
||||
collection.userInterfaceStyle == .light ? .element.system : .element.background
|
||||
collection.userInterfaceStyle == .light ? UIColor(.compound.bgSubtleSecondary) : UIColor(.compound.bgCanvasDefault)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -84,42 +75,11 @@ public struct ElementColors {
|
||||
/// This colour is a special case as it uses `background` in light mode and `system` in dark mode.
|
||||
public var formRowBackground: Color {
|
||||
Color(UIColor { collection in
|
||||
collection.userInterfaceStyle == .light ? .element.background : .element.system
|
||||
collection.userInterfaceStyle == .light ? UIColor(.compound.bgCanvasDefault) : UIColor(.compound.bgSubtleSecondary)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: UIKit
|
||||
|
||||
public extension UIColor {
|
||||
/// The colors from Compound, as dynamic colors that automatically update for light and dark mode.
|
||||
static let element = ElementUIColors()
|
||||
}
|
||||
|
||||
@objcMembers public class ElementUIColors: NSObject {
|
||||
// MARK: - Compound
|
||||
|
||||
private let compound = DesignTokens.CompoundUIColors()
|
||||
|
||||
public var accent: UIColor { .label }
|
||||
public var alert: UIColor { compound.alert }
|
||||
public var links: UIColor { compound.links }
|
||||
public var primaryContent: UIColor { compound.primaryContent }
|
||||
public var secondaryContent: UIColor { compound.secondaryContent }
|
||||
public var tertiaryContent: UIColor { compound.tertiaryContent }
|
||||
public var quaternaryContent: UIColor { compound.quaternaryContent }
|
||||
public var quinaryContent: UIColor { compound.quinaryContent }
|
||||
public var system: UIColor { compound.system }
|
||||
public var background: UIColor { compound.background }
|
||||
|
||||
public var contentAndAvatars: [UIColor] { compound.contentAndAvatars }
|
||||
|
||||
public func avatarBackground(for contentId: String) -> UIColor {
|
||||
let colorIndex = Int(contentId.hashCode % Int32(contentAndAvatars.count))
|
||||
return contentAndAvatars[colorIndex % contentAndAvatars.count]
|
||||
}
|
||||
}
|
||||
|
||||
private extension String {
|
||||
/// Calculates a numeric hash same as Element Web
|
||||
/// See original function here https://github.com/matrix-org/matrix-react-sdk/blob/321dd49db4fbe360fc2ff109ac117305c955b061/src/utils/FormattingUtils.js#L47
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
/// Fonts at https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound?node-id=1362%3A0
|
||||
@objcMembers
|
||||
public class ElementBaseFonts {
|
||||
// MARK: - Types
|
||||
|
||||
/// A wrapper to provide both a `UIFont` and a SwiftUI `Font` in the same type.
|
||||
/// The need for this comes from `Font` not adapting for dynamic type until the app
|
||||
/// is restarted (or working at all in Xcode Previews) when initialised from a `UIFont`
|
||||
/// (even if that font was created with the appropriate metrics).
|
||||
public struct SharedFont {
|
||||
public let uiFont: UIFont
|
||||
public let font: Font
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
/// Returns an instance of the font associated with the text style and scaled appropriately for the content size category defined in the trait collection.
|
||||
/// Keep this method private method at the moment and create a DesignKit.Fonts.TextStyle if needed.
|
||||
private func font(forTextStyle textStyle: UIFont.TextStyle, compatibleWith traitCollection: UITraitCollection? = nil) -> UIFont {
|
||||
UIFont.preferredFont(forTextStyle: textStyle, compatibleWith: traitCollection)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Fonts protocol
|
||||
|
||||
public extension ElementBaseFonts {
|
||||
var largeTitle: SharedFont {
|
||||
let uiFont = font(forTextStyle: .largeTitle)
|
||||
return SharedFont(uiFont: uiFont, font: .largeTitle)
|
||||
}
|
||||
|
||||
var title1: SharedFont {
|
||||
let uiFont = font(forTextStyle: .title1)
|
||||
return SharedFont(uiFont: uiFont, font: .title)
|
||||
}
|
||||
|
||||
var title2: SharedFont {
|
||||
let uiFont = font(forTextStyle: .title2)
|
||||
return SharedFont(uiFont: uiFont, font: .title2)
|
||||
}
|
||||
|
||||
var title3: SharedFont {
|
||||
let uiFont = font(forTextStyle: .title3)
|
||||
return SharedFont(uiFont: uiFont, font: .title3)
|
||||
}
|
||||
|
||||
var headline: SharedFont {
|
||||
let uiFont = font(forTextStyle: .headline)
|
||||
return SharedFont(uiFont: uiFont, font: .headline)
|
||||
}
|
||||
|
||||
var body: SharedFont {
|
||||
let uiFont = font(forTextStyle: .body)
|
||||
return SharedFont(uiFont: uiFont, font: .body)
|
||||
}
|
||||
|
||||
var callout: SharedFont {
|
||||
let uiFont = font(forTextStyle: .callout)
|
||||
return SharedFont(uiFont: uiFont, font: .callout)
|
||||
}
|
||||
|
||||
var subheadline: SharedFont {
|
||||
let uiFont = font(forTextStyle: .subheadline)
|
||||
return SharedFont(uiFont: uiFont, font: .subheadline)
|
||||
}
|
||||
|
||||
var footnote: SharedFont {
|
||||
let uiFont = font(forTextStyle: .footnote)
|
||||
return SharedFont(uiFont: uiFont, font: .footnote)
|
||||
}
|
||||
|
||||
var caption1: SharedFont {
|
||||
let uiFont = font(forTextStyle: .caption1)
|
||||
return SharedFont(uiFont: uiFont, font: .caption)
|
||||
}
|
||||
|
||||
var caption2: SharedFont {
|
||||
let uiFont = font(forTextStyle: .caption2)
|
||||
return SharedFont(uiFont: uiFont, font: .caption2)
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
public extension Font {
|
||||
/// The fonts used by Element as defined in https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound?node-id=1362%3A0
|
||||
@available(*, deprecated, renamed: "compound")
|
||||
static let element = ElementFonts(values: ElementBaseFonts())
|
||||
}
|
||||
|
||||
/// Struct for holding fonts for use in SwiftUI.
|
||||
public struct ElementFonts: Fonts {
|
||||
public let largeTitle: Font
|
||||
public let largeTitleBold: Font
|
||||
public let title1: Font
|
||||
public let title1Bold: Font
|
||||
public let title2: Font
|
||||
public let title2Bold: Font
|
||||
public let title3: Font
|
||||
public let title3Bold: Font
|
||||
public let headline: Font
|
||||
public let headlineBold: Font
|
||||
public let body: Font
|
||||
public let bodyBold: Font
|
||||
public let callout: Font
|
||||
public let calloutBold: Font
|
||||
public let subheadline: Font
|
||||
public let subheadlineBold: Font
|
||||
public let footnote: Font
|
||||
public let footnoteBold: Font
|
||||
public let caption1: Font
|
||||
public let caption1Bold: Font
|
||||
public let caption2: Font
|
||||
public let caption2Bold: Font
|
||||
|
||||
public init(values: ElementBaseFonts) {
|
||||
largeTitle = values.largeTitle.font
|
||||
largeTitleBold = values.largeTitle.font.bold()
|
||||
title1 = values.title1.font
|
||||
title1Bold = values.title1.font.bold()
|
||||
title2 = values.title2.font
|
||||
title2Bold = values.title2.font.bold()
|
||||
title3 = values.title3.font
|
||||
title3Bold = values.title3.font.bold()
|
||||
headline = values.headline.font
|
||||
headlineBold = values.headline.font.bold()
|
||||
body = values.body.font
|
||||
bodyBold = values.body.font.bold()
|
||||
callout = values.callout.font
|
||||
calloutBold = values.callout.font.bold()
|
||||
subheadline = values.subheadline.font
|
||||
subheadlineBold = values.subheadline.font.bold()
|
||||
footnote = values.footnote.font
|
||||
footnoteBold = values.footnote.font.bold()
|
||||
caption1 = values.caption1.font
|
||||
caption1Bold = values.caption1.font.bold()
|
||||
caption2 = values.caption2.font
|
||||
caption2Bold = values.caption2.font.bold()
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
public extension UIFont {
|
||||
/// The fonts used by Element as defined in https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound?node-id=1362%3A0
|
||||
@available(*, deprecated, message: "Not yet available in compound.")
|
||||
@objc static let element = ElementUIFonts(values: ElementBaseFonts())
|
||||
}
|
||||
|
||||
/// ObjC class for holding fonts for use in UIKit.
|
||||
@objcMembers public class ElementUIFonts: NSObject, Fonts {
|
||||
public let largeTitle: UIFont
|
||||
public let largeTitleBold: UIFont
|
||||
public let title1: UIFont
|
||||
public let title1Bold: UIFont
|
||||
public let title2: UIFont
|
||||
public let title2Bold: UIFont
|
||||
public let title3: UIFont
|
||||
public let title3Bold: UIFont
|
||||
public let headline: UIFont
|
||||
public let headlineBold: UIFont
|
||||
public let body: UIFont
|
||||
public let bodyBold: UIFont
|
||||
public let callout: UIFont
|
||||
public let calloutBold: UIFont
|
||||
public let subheadline: UIFont
|
||||
public let subheadlineBold: UIFont
|
||||
public let footnote: UIFont
|
||||
public let footnoteBold: UIFont
|
||||
public let caption1: UIFont
|
||||
public let caption1Bold: UIFont
|
||||
public let caption2: UIFont
|
||||
public let caption2Bold: UIFont
|
||||
|
||||
public init(values: ElementBaseFonts) {
|
||||
largeTitle = values.largeTitle.uiFont
|
||||
largeTitleBold = values.largeTitle.uiFont.bold
|
||||
title1 = values.title1.uiFont
|
||||
title1Bold = values.title1.uiFont.bold
|
||||
title2 = values.title2.uiFont
|
||||
title2Bold = values.title2.uiFont.bold
|
||||
title3 = values.title3.uiFont
|
||||
title3Bold = values.title3.uiFont.bold
|
||||
headline = values.headline.uiFont
|
||||
headlineBold = values.headline.uiFont.bold
|
||||
body = values.body.uiFont
|
||||
bodyBold = values.body.uiFont.bold
|
||||
callout = values.callout.uiFont
|
||||
calloutBold = values.callout.uiFont.bold
|
||||
subheadline = values.subheadline.uiFont
|
||||
subheadlineBold = values.subheadline.uiFont.bold
|
||||
footnote = values.footnote.uiFont
|
||||
footnoteBold = values.footnote.uiFont.bold
|
||||
caption1 = values.caption1.uiFont
|
||||
caption1Bold = values.caption1.uiFont.bold
|
||||
caption2 = values.caption2.uiFont
|
||||
caption2Bold = values.caption2.uiFont.bold
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Describe fonts used in the application.
|
||||
/// Font names are based on Element typography https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound?node-id=1362%3A0 which is based on Apple font text styles (UIFont.TextStyle): https://developer.apple.com/documentation/uikit/uifonttextstyle
|
||||
/// Create a custom TextStyle enum (like DesignKit.Fonts.TextStyle) is also a possibility
|
||||
public protocol Fonts {
|
||||
associatedtype FontType
|
||||
|
||||
/// The font for large titles.
|
||||
var largeTitle: FontType { get }
|
||||
|
||||
/// `largeTitle` with a Bold weight.
|
||||
var largeTitleBold: FontType { get }
|
||||
|
||||
/// The font for first-level hierarchical headings.
|
||||
var title1: FontType { get }
|
||||
|
||||
/// `title1` with a Bold weight.
|
||||
var title1Bold: FontType { get }
|
||||
|
||||
/// The font for second-level hierarchical headings.
|
||||
var title2: FontType { get }
|
||||
|
||||
/// `title2` with a Bold weight.
|
||||
var title2Bold: FontType { get }
|
||||
|
||||
/// The font for third-level hierarchical headings.
|
||||
var title3: FontType { get }
|
||||
|
||||
/// `title3` with a Bold weight.
|
||||
var title3Bold: FontType { get }
|
||||
|
||||
/// The font for headings.
|
||||
var headline: FontType { get }
|
||||
|
||||
/// `headline` with a Bold weight.
|
||||
var headlineBold: FontType { get }
|
||||
|
||||
/// The font for body text.
|
||||
var body: FontType { get }
|
||||
|
||||
/// `body` with a Bold weight.
|
||||
var bodyBold: FontType { get }
|
||||
|
||||
/// The font for callouts.
|
||||
var callout: FontType { get }
|
||||
|
||||
/// `callout` with a Bold weight.
|
||||
var calloutBold: FontType { get }
|
||||
|
||||
/// The font for subheadings.
|
||||
var subheadline: FontType { get }
|
||||
|
||||
/// `subheadline` with a Bold weight.
|
||||
var subheadlineBold: FontType { get }
|
||||
|
||||
/// The font for footnotes.
|
||||
var footnote: FontType { get }
|
||||
|
||||
/// `footnote` with a Bold weight.
|
||||
var footnoteBold: FontType { get }
|
||||
|
||||
/// The font for standard captions.
|
||||
var caption1: FontType { get }
|
||||
|
||||
/// `caption1` with a Bold weight.
|
||||
var caption1Bold: FontType { get }
|
||||
|
||||
/// The font for alternate captions.
|
||||
var caption2: FontType { get }
|
||||
|
||||
/// `caption2` with a Bold weight.
|
||||
var caption2Bold: FontType { get }
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
public extension UIFont {
|
||||
// MARK: - Convenient methods
|
||||
|
||||
/// Update current font with a SymbolicTraits
|
||||
func withTraits(_ traits: UIFontDescriptor.SymbolicTraits) -> UIFont {
|
||||
guard let descriptor = fontDescriptor.withSymbolicTraits(traits) else {
|
||||
return self
|
||||
}
|
||||
|
||||
// Size 0 means keep the size as it is
|
||||
return UIFont(descriptor: descriptor, size: 0)
|
||||
}
|
||||
|
||||
/// Update current font with a given Weight
|
||||
func withWeight(weight: Weight) -> UIFont {
|
||||
// Add the font weight to the descriptor
|
||||
let weightedFontDescriptor = fontDescriptor.addingAttributes([
|
||||
UIFontDescriptor.AttributeName.traits: [
|
||||
UIFontDescriptor.TraitKey.weight: weight
|
||||
]
|
||||
])
|
||||
return UIFont(descriptor: weightedFontDescriptor, size: 0)
|
||||
}
|
||||
|
||||
// MARK: - Shortcuts
|
||||
|
||||
var bold: UIFont {
|
||||
withTraits(.traitBold)
|
||||
}
|
||||
|
||||
var semiBold: UIFont {
|
||||
withWeight(weight: .semibold)
|
||||
}
|
||||
|
||||
var italic: UIFont {
|
||||
withTraits(.traitItalic)
|
||||
}
|
||||
}
|
||||
@@ -57,8 +57,7 @@ public struct ElementTextFieldStyle: TextFieldStyle {
|
||||
|
||||
/// The color of the text field's border.
|
||||
private var borderColor: Color {
|
||||
guard !isError else { return .element.alert }
|
||||
return isFocused ? .element.tertiaryContent : .element.quinaryContent
|
||||
isError ? .compound.textCriticalPrimary : .compound._borderTextFieldFocused
|
||||
}
|
||||
|
||||
/// The width of the text field's border.
|
||||
@@ -67,39 +66,32 @@ public struct ElementTextFieldStyle: TextFieldStyle {
|
||||
}
|
||||
|
||||
private var accentColor: Color {
|
||||
isError ? .element.alert : .element.brand
|
||||
isError ? .compound.textCriticalPrimary : .compound.iconAccentTertiary
|
||||
}
|
||||
|
||||
/// The color of the text inside the text field.
|
||||
private var textColor: Color {
|
||||
if colorScheme == .dark {
|
||||
return isEnabled ? .element.primaryContent : .element.tertiaryContent
|
||||
} else {
|
||||
return isEnabled ? .element.primaryContent : .element.quaternaryContent
|
||||
}
|
||||
isEnabled ? .compound.textPrimary : .compound.textDisabled
|
||||
}
|
||||
|
||||
/// The color of the text field's background.
|
||||
private var backgroundColor: Color {
|
||||
if !isEnabled, colorScheme == .dark {
|
||||
return .element.quinaryContent
|
||||
}
|
||||
return .element.system
|
||||
.compound.bgSubtleSecondary.opacity(isEnabled ? 1 : 0.5)
|
||||
}
|
||||
|
||||
/// The color of the placeholder text inside the text field.
|
||||
private var placeholderColor: Color {
|
||||
.element.tertiaryContent
|
||||
.compound.textPlaceholder
|
||||
}
|
||||
|
||||
/// The color of the label above the text field.
|
||||
private var labelColor: Color {
|
||||
isEnabled ? .element.primaryContent : .element.quaternaryContent
|
||||
isEnabled ? .compound.textPrimary : .compound.textDisabled
|
||||
}
|
||||
|
||||
/// The color of the footer label below the text field.
|
||||
private var footerColor: Color {
|
||||
isError ? .element.alert : .element.tertiaryContent
|
||||
isError ? .compound.textCriticalPrimary : .compound.textSecondary
|
||||
}
|
||||
|
||||
/// Creates the text field style configured as required.
|
||||
@@ -147,7 +139,7 @@ public struct ElementTextFieldStyle: TextFieldStyle {
|
||||
}
|
||||
|
||||
footerText
|
||||
.tint(.element.links)
|
||||
.tint(.compound.textLinkExternal)
|
||||
.font(.compound.bodyXS)
|
||||
.foregroundColor(footerColor)
|
||||
.padding(.horizontal, 16)
|
||||
|
||||
Reference in New Issue
Block a user