diff --git a/CHANGES.rst b/CHANGES.rst index cac04f6a2..bb208076a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,7 @@ Changes to be released in next version * 🙌 Improvements - * + * DesignKit: Add Fonts (#4356). 🐛 Bugfix * diff --git a/DesignKit/Extensions/UIFont.swift b/DesignKit/Extensions/UIFont.swift new file mode 100644 index 000000000..7804c8066 --- /dev/null +++ b/DesignKit/Extensions/UIFont.swift @@ -0,0 +1,55 @@ +// +// Copyright 2021 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 vc_withTraits(_ traits: UIFontDescriptor.SymbolicTraits) -> UIFont { + guard let descriptor = fontDescriptor.withSymbolicTraits(traits) else { + return self + } + return UIFont(descriptor: descriptor, size: 0) // Size 0 means keep the size as it is + } + + /// Update current font with a given Weight + func vc_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 vc_bold: UIFont { + return self.vc_withTraits(.traitBold) + } + + var vc_semiBold: UIFont { + return self.vc_withWeight(weight: .semibold) + } + + var vc_italic: UIFont { + return self.vc_withTraits(.traitItalic) + } +} diff --git a/DesignKit/Source/Fonts.swift b/DesignKit/Source/Fonts.swift new file mode 100644 index 000000000..1cce963ed --- /dev/null +++ b/DesignKit/Source/Fonts.swift @@ -0,0 +1,83 @@ +// +// Copyright 2021 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 + +/// Describe fonts used in the application. +/// Font names are based on Element typograhy 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 possiblity +@objc public protocol Fonts { + + /// The font for large titles. + var largeTitle: UIFont { get } + + /// `largeTitle` with a Bold weight. + var largeTitleB: UIFont { get } + + /// The font for first-level hierarchical headings. + var title1: UIFont { get } + + /// `title1` with a Bold weight. + var title1B: UIFont { get } + + /// The font for second-level hierarchical headings. + var title2: UIFont { get } + + /// `title2` with a Bold weight. + var title2B: UIFont { get } + + /// The font for third-level hierarchical headings. + var title3: UIFont { get } + + /// `title3` with a Semi Bold weight. + var title3SB: UIFont { get } + + /// The font for headings. + var headline: UIFont { get } + + /// The font for subheadings. + var subheadline: UIFont { get } + + /// The font for body text. + var body: UIFont { get } + + /// `body` with a Semi Bold weight. + var bodySB: UIFont { get } + + /// The font for callouts. + var callout: UIFont { get } + + /// `callout` with a Semi Bold weight. + var calloutSB: UIFont { get } + + /// The font for footnotes. + var footnote: UIFont { get } + + /// `footnote` with a Semi Bold weight. + var footnoteSB: UIFont { get } + + /// The font for standard captions. + var caption1: UIFont { get } + + /// `caption1` with a Semi Bold weight. + var caption1SB: UIFont { get } + + /// The font for alternate captions. + var caption2: UIFont { get } + + /// `caption2` with a Semi Bold weight. + var caption2SB: UIFont { get } +} diff --git a/DesignKit/Source/ThemeV2.swift b/DesignKit/Source/ThemeV2.swift index 48f310992..785639861 100644 --- a/DesignKit/Source/ThemeV2.swift +++ b/DesignKit/Source/ThemeV2.swift @@ -23,6 +23,9 @@ import UIKit /// Colors object var colors: Colors { get } + /// Fonts object + var fonts: Fonts { get } + /// may contain more design components in future, like icons, audio files etc. } diff --git a/DesignKit/Variants/Dark/DarkColors.swift b/DesignKit/Variants/Colors/Dark/DarkColors.swift similarity index 100% rename from DesignKit/Variants/Dark/DarkColors.swift rename to DesignKit/Variants/Colors/Dark/DarkColors.swift diff --git a/DesignKit/Variants/Light/LightColors.swift b/DesignKit/Variants/Colors/Light/LightColors.swift similarity index 100% rename from DesignKit/Variants/Light/LightColors.swift rename to DesignKit/Variants/Colors/Light/LightColors.swift diff --git a/DesignKit/Variants/Fonts/ElementFonts.swift b/DesignKit/Variants/Fonts/ElementFonts.swift new file mode 100644 index 000000000..6612d3dc1 --- /dev/null +++ b/DesignKit/Variants/Fonts/ElementFonts.swift @@ -0,0 +1,119 @@ +// +// Copyright 2021 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 + +/// Fonts at https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound?node-id=1362%3A0 +@objcMembers +public class ElementFonts { + + // MARK: - Setup + + public init() { + } + + // 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. + fileprivate func font(forTextStyle textStyle: UIFont.TextStyle, compatibleWith traitCollection: UITraitCollection? = nil) -> UIFont { + return UIFont.preferredFont(forTextStyle: textStyle, compatibleWith: traitCollection) + } +} + +// MARK: - Fonts protocol +extension ElementFonts: Fonts { + + public var largeTitle: UIFont { + return self.font(forTextStyle: .largeTitle) + } + + public var largeTitleB: UIFont { + return self.largeTitle.vc_bold + } + + public var title1: UIFont { + return self.font(forTextStyle: .title1) + } + + public var title1B: UIFont { + return self.title1.vc_bold + } + + public var title2: UIFont { + return self.font(forTextStyle: .title2) + } + + public var title2B: UIFont { + return self.title2.vc_bold + } + + public var title3: UIFont { + return self.font(forTextStyle: .title3) + } + + public var title3SB: UIFont { + return self.title3.vc_semiBold + } + + public var headline: UIFont { + return self.font(forTextStyle: .headline) + } + + public var subheadline: UIFont { + return self.font(forTextStyle: .subheadline) + } + + public var body: UIFont { + return self.font(forTextStyle: .body) + } + + public var bodySB: UIFont { + return self.body.vc_semiBold + } + + public var callout: UIFont { + return self.font(forTextStyle: .callout) + } + + public var calloutSB: UIFont { + return self.callout.vc_semiBold + } + + public var footnote: UIFont { + return self.font(forTextStyle: .footnote) + } + + public var footnoteSB: UIFont { + return self.footnote.vc_semiBold + } + + public var caption1: UIFont { + return self.font(forTextStyle: .caption1) + } + + public var caption1SB: UIFont { + return self.caption1.vc_semiBold + } + + public var caption2: UIFont { + return self.font(forTextStyle: .caption2) + } + + public var caption2SB: UIFont { + return self.caption2.vc_semiBold + } +} diff --git a/Riot/Managers/Theme/Themes/DarkTheme.swift b/Riot/Managers/Theme/Themes/DarkTheme.swift index a3bc39557..7ce49c214 100644 --- a/Riot/Managers/Theme/Themes/DarkTheme.swift +++ b/Riot/Managers/Theme/Themes/DarkTheme.swift @@ -146,4 +146,8 @@ class DarkTheme: NSObject, Theme { lazy var colors: Colors = { return DarkColors() }() + + lazy var fonts: Fonts = { + return ElementFonts() + }() } diff --git a/Riot/Managers/Theme/Themes/DefaultTheme.swift b/Riot/Managers/Theme/Themes/DefaultTheme.swift index 7f6ae77b1..770f33a90 100644 --- a/Riot/Managers/Theme/Themes/DefaultTheme.swift +++ b/Riot/Managers/Theme/Themes/DefaultTheme.swift @@ -153,4 +153,8 @@ class DefaultTheme: NSObject, Theme { lazy var colors: Colors = { return LightColors() }() + + lazy var fonts: Fonts = { + return ElementFonts() + }() } diff --git a/Riot/Modules/SideMenu/SideMenuViewController.swift b/Riot/Modules/SideMenu/SideMenuViewController.swift index 0851ec8df..57f98b059 100644 --- a/Riot/Modules/SideMenu/SideMenuViewController.swift +++ b/Riot/Modules/SideMenu/SideMenuViewController.swift @@ -107,6 +107,7 @@ final class SideMenuViewController: UIViewController { self.userAvatarView.update(theme: theme) self.userDisplayNameLabel.textColor = theme.textPrimaryColor + self.userDisplayNameLabel.font = theme.fonts.title3SB self.userIdLabel.textColor = theme.textSecondaryColor for sideMenuActionView in self.sideMenuActionViews {