added tilelet linebreak mode config & text position

This commit is contained in:
Krishna Kishore Bandaru 2024-03-01 17:17:04 +05:30
parent 119b71bb3a
commit add8e974c0
10 changed files with 275 additions and 20 deletions

View File

@ -14,6 +14,7 @@
44604AD729CE196600E62B51 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD629CE196600E62B51 /* Line.swift */; };
5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */; };
5FC35BE328D51405004EBEAC /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FC35BE228D51405004EBEAC /* Button.swift */; };
710607952B91A99500F2863F /* TitleletChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 710607942B91A99500F2863F /* TitleletChangeLog.txt */; };
7115BD3C2B84C0C200E0A610 /* TileContainerChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 7115BD3B2B84C0C200E0A610 /* TileContainerChangeLog.txt */; };
71BFA70A2B7F70E6000DCE33 /* Dropshadowable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BFA7092B7F70E6000DCE33 /* Dropshadowable.swift */; };
71C02B382B7BD98F00E93E66 /* NotificationChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */; };
@ -180,6 +181,7 @@
44604AD629CE196600E62B51 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Useable.swift; sourceTree = "<group>"; };
5FC35BE228D51405004EBEAC /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = "<group>"; };
710607942B91A99500F2863F /* TitleletChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = TitleletChangeLog.txt; sourceTree = "<group>"; };
7115BD3B2B84C0C200E0A610 /* TileContainerChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = TileContainerChangeLog.txt; sourceTree = "<group>"; };
71BFA7092B7F70E6000DCE33 /* Dropshadowable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dropshadowable.swift; sourceTree = "<group>"; };
71C02B372B7BD98F00E93E66 /* NotificationChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = NotificationChangeLog.txt; sourceTree = "<group>"; };
@ -676,6 +678,7 @@
EA985BE929689B6D00F2FF2E /* TileletSubTitleModel.swift */,
EA985BE72968951C00F2FF2E /* TileletTitleModel.swift */,
EA985C2C296F03FE00F2FF2E /* TileletIconModels.swift */,
710607942B91A99500F2863F /* TitleletChangeLog.txt */,
);
path = Tilelet;
sourceTree = "<group>";
@ -947,6 +950,7 @@
71C02B382B7BD98F00E93E66 /* NotificationChangeLog.txt in Resources */,
EAEEECA72B1F952000531FC2 /* TabsChangeLog.txt in Resources */,
EAEEEC962B1F893B00531FC2 /* ButtonChangeLog.txt in Resources */,
710607952B91A99500F2863F /* TitleletChangeLog.txt in Resources */,
EA5F86CC2A1D28B500BC83E4 /* ReleaseNotes.txt in Resources */,
EAEEEC982B1F8DD100531FC2 /* LineChangeLog.txt in Resources */,
EAEEECA22B1F92AD00531FC2 /* LabelChangeLog.txt in Resources */,

View File

@ -147,6 +147,7 @@ open class Badge: View {
label.widthGreaterThanEqualTo(constant: minWidth)
maxWidthConstraint = label.widthLessThanEqualTo(constant: 0).with { $0.isActive = false }
clipsToBounds = true
}
/// Resets to default settings.

View File

@ -39,6 +39,7 @@ open class Tilelet: TileContainer {
/// Enum to represent the Vertical Layout of the Text.
public enum TextPosition: String, CaseIterable {
case top
case middle
case bottom
}
@ -72,7 +73,7 @@ open class Tilelet: TileContainer {
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
//--------------------------------------------------
public override var onClickSubscriber: AnyCancellable? {
didSet {
isAccessibilityElement = onClickSubscriber != nil
@ -82,6 +83,27 @@ open class Tilelet: TileContainer {
/// Title lockup positioned in the contentView.
open var titleLockup = TitleLockup().with {
$0.standardStyleConfiguration = .init(styleConfigurations: [
.init(deviceType: .iPhone,
titleStandardStyles: [.bodySmall],
spacingConfigurations: [
.init(otherStandardStyles: [.bodySmall],
topSpacing: VDSLayout.Spacing.space1X.value,
bottomSpacing: VDSLayout.Spacing.space1X.value)
]),
.init(deviceType: .iPhone,
titleStandardStyles: [.bodyMedium],
spacingConfigurations: [
.init(otherStandardStyles: [.bodyMedium],
topSpacing: VDSLayout.Spacing.space1X.value,
bottomSpacing: VDSLayout.Spacing.space1X.value)
]),
.init(deviceType: .iPhone,
titleStandardStyles: [.bodyLarge],
spacingConfigurations: [
.init(otherStandardStyles: [.bodyLarge],
topSpacing: VDSLayout.Spacing.space1X.value,
bottomSpacing: VDSLayout.Spacing.space1X.value)
]),
.init(deviceType: .iPhone,
titleStandardStyles: [.titleSmall],
spacingConfigurations: [
@ -103,6 +125,27 @@ open class Tilelet: TileContainer {
topSpacing: VDSLayout.Spacing.space3X.value,
bottomSpacing: VDSLayout.Spacing.space3X.value)
]),
.init(deviceType: .iPad,
titleStandardStyles: [.bodySmall],
spacingConfigurations: [
.init(otherStandardStyles: [.bodySmall],
topSpacing: VDSLayout.Spacing.space2X.value,
bottomSpacing: VDSLayout.Spacing.space2X.value)
]),
.init(deviceType: .iPad,
titleStandardStyles: [.bodyMedium],
spacingConfigurations: [
.init(otherStandardStyles: [.bodyMedium],
topSpacing: VDSLayout.Spacing.space1X.value,
bottomSpacing: VDSLayout.Spacing.space1X.value)
]),
.init(deviceType: .iPad,
titleStandardStyles: [.bodyLarge],
spacingConfigurations: [
.init(otherStandardStyles: [.bodyLarge],
topSpacing: VDSLayout.Spacing.space1X.value,
bottomSpacing: VDSLayout.Spacing.space1X.value)
]),
.init(deviceType: .iPad,
titleStandardStyles: [.titleSmall, .titleMedium],
spacingConfigurations: [
@ -206,6 +249,12 @@ open class Tilelet: TileContainer {
//--------------------------------------------------
internal var titleLockupWidthConstraint: NSLayoutConstraint?
internal var titleLockupTrailingConstraint: NSLayoutConstraint?
internal var titleLockupTopConstraint: NSLayoutConstraint?
internal var titleLockupBottomConstraint: NSLayoutConstraint?
internal var titleLockupTopGreaterThanConstraint: NSLayoutConstraint?
internal var titleLockupBottomGreaterThanConstraint: NSLayoutConstraint?
internal var titleLockupCenterYConstraint: NSLayoutConstraint?
internal var titleLockupTitleLabelBottomConstraint: NSLayoutConstraint?
//--------------------------------------------------
// MARK: - Overrides
@ -230,11 +279,16 @@ open class Tilelet: TileContainer {
titleLockupContainerView.addSubview(titleLockup)
titleLockup
.pinTop()
.pinLeading()
.pinBottom()
titleLockupTopConstraint = titleLockup.topAnchor.constraint(equalTo: titleLockupContainerView.topAnchor)
titleLockupTopConstraint?.activate()
titleLockupBottomConstraint = titleLockupContainerView.bottomAnchor.constraint(equalTo: titleLockup.bottomAnchor)
titleLockupBottomConstraint?.activate()
titleLockupTrailingConstraint = titleLockup.trailingAnchor.constraint(equalTo: titleLockupContainerView.trailingAnchor)
titleLockupTrailingConstraint?.isActive = true
titleLockupBottomGreaterThanConstraint = titleLockupContainerView.bottomAnchor.constraint(greaterThanOrEqualTo: titleLockup.bottomAnchor)
titleLockupTopGreaterThanConstraint = titleLockup.topAnchor.constraint(greaterThanOrEqualTo: titleLockupContainerView.topAnchor)
titleLockupCenterYConstraint = titleLockup.centerYAnchor.constraint(equalTo: titleLockupContainerView.centerYAnchor)
iconContainerView.addSubview(descriptiveIcon)
iconContainerView.addSubview(directionalIcon)
@ -249,6 +303,12 @@ open class Tilelet: TileContainer {
.pinTop()
.pinBottom()
padding = .custom( UIDevice.isIPad ? VDSLayout.Spacing.space6X.value : VDSLayout.Spacing.space4X.value)
//If a Tilelet has Badge, Title and Subtitle, then Subtitle will be truncated first and Badge will be truncated second. Title will be truncated last (lowest priority).
var labelPriority = UILayoutPriority.defaultHigh.rawValue
titleLockup.titleLabel.setContentCompressionResistancePriority(UILayoutPriority(labelPriority), for: .vertical)
badge.label.setContentCompressionResistancePriority(UILayoutPriority(labelPriority-1), for: .vertical)
titleLockup.subTitleLabel.setContentCompressionResistancePriority(UILayoutPriority(labelPriority-2), for: .vertical)
}
/// Resets to default settings.
@ -261,7 +321,7 @@ open class Tilelet: TileContainer {
titleModel = nil
subTitleModel = nil
descriptiveIconModel = nil
directionalIconModel = nil
directionalIconModel = nil
shouldUpdateView = true
setNeedsUpdate()
}
@ -273,7 +333,11 @@ open class Tilelet: TileContainer {
updateBadge()
updateTitleLockup()
updateIcons()
///Content-driven height Tilelets - Minimum height is configurable.
///if width != nil && (aspectRatio != .none || height != nil) then tilelet is not self growing, so we can apply text position alignments.
if width != nil && (aspectRatio != .none || height != nil) {
updateTextPositionAlignment()
}
layoutIfNeeded()
}
@ -401,20 +465,59 @@ open class Tilelet: TileContainer {
} else {
removeFromSuperview(iconContainerView)
}
if let lastElement = titleLockup.lastElement {
titleLockupTitleLabelBottomConstraint?.deactivate()
let anchorConstraint = showIconContainerView ? iconContainerView.topAnchor : containerView.bottomAnchor
titleLockupTitleLabelBottomConstraint = anchorConstraint.constraint(greaterThanOrEqualTo: lastElement.bottomAnchor)
titleLockupTitleLabelBottomConstraint?.activate()
}
}
private func updateTextPositionAlignment() {
switch textPostion {
case .top:
titleLockupTopConstraint?.activate()
titleLockupTopGreaterThanConstraint?.deactivate()
titleLockupBottomConstraint?.deactivate()
titleLockupBottomGreaterThanConstraint?.activate()
titleLockupCenterYConstraint?.deactivate()
case .middle:
titleLockupTopConstraint?.deactivate()
titleLockupTopGreaterThanConstraint?.activate()
titleLockupBottomConstraint?.deactivate()
titleLockupBottomGreaterThanConstraint?.activate()
titleLockupCenterYConstraint?.activate()
case .bottom:
titleLockupTopConstraint?.deactivate()
titleLockupTopGreaterThanConstraint?.activate()
titleLockupBottomConstraint?.activate()
titleLockupBottomGreaterThanConstraint?.deactivate()
titleLockupCenterYConstraint?.deactivate()
}
}
}
extension TitleLockup {
fileprivate var lastElement: UIView? {
guard subTitleModel == nil else { return subTitleLabel }
guard titleModel == nil else { return titleLabel }
return nil
}
}
extension TileContainer.Padding {
fileprivate var tiletSpacing: CGFloat {
switch self {
case .padding2X:
return 16
case .padding4X:
return 24
case .padding6X:
return 32
case .padding8X:
return 48
case .custom(let padding):
if padding == VDSLayout.Spacing.space3X.value {
return 16
} else { fallthrough }
default:
return 16
}

View File

@ -6,6 +6,7 @@
//
import Foundation
import UIKit
extension Tilelet {
@ -26,12 +27,16 @@ extension Tilelet {
/// Max width that will be used for the badge.
public var maxWidth: CGFloat?
public init(text: String, fillColor: Badge.FillColor = .red, surface: Surface = .light, numberOfLines: Int = 0, maxWidth: CGFloat? = nil) {
/// LineBreakMode used in Badge label.
public var lineBreakMode: NSLineBreakMode
public init(text: String, fillColor: Badge.FillColor = .red, surface: Surface = .light, numberOfLines: Int = 0, maxWidth: CGFloat? = nil, lineBreakMode: NSLineBreakMode = .byTruncatingTail) {
self.text = text
self.fillColor = fillColor
self.surface = surface
self.numberOfLines = numberOfLines
self.maxWidth = maxWidth
self.lineBreakMode = lineBreakMode
}
}
}

View File

@ -6,6 +6,7 @@
//
import Foundation
import UIKit
extension Tilelet {
/// Model that represents the options available for the sub title label.
@ -18,7 +19,8 @@ extension Tilelet {
case bodyLarge
case bodyMedium
case bodySmall
case titleSmall
case titleMedium
public var defaultValue: TitleLockup.OtherStandardStyle { .bodySmall }
}
//--------------------------------------------------
@ -36,17 +38,22 @@ extension Tilelet {
/// Text color that will be used for the subTitle label.
public var textColor: Use = .primary
/// LineBreakMode used in Badge label.
public var lineBreakMode: NSLineBreakMode
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public init(text: String,
textColor: Use = .primary,
textAttributes: [any LabelAttributeModel]? = nil,
standardStyle: StandardStyle = .bodySmall) {
standardStyle: StandardStyle = .bodySmall,
lineBreakMode: NSLineBreakMode = .byTruncatingTail) {
self.text = text
self.textAttributes = textAttributes
self.textColor = textColor
self.standardStyle = standardStyle
self.lineBreakMode = lineBreakMode
}
//--------------------------------------------------
@ -57,7 +64,7 @@ extension Tilelet {
TitleLockup.SubTitleModel(text: text,
standardStyle: standardStyle.value,
textColor: textColor,
textAttributes: textAttributes)
textAttributes: textAttributes, lineBreakMode: lineBreakMode)
}
}
}

View File

@ -6,6 +6,7 @@
//
import Foundation
import UIKit
extension Tilelet {
/// Model that represents the options available for the title label.
@ -19,7 +20,10 @@ extension Tilelet {
case titleLarge
case titleMedium
case titleSmall
case bodyLarge
case bodyMedium
case bodySmall
public var defaultValue: TitleLockup.TitleStandardStyle { .titleSmall }
}
//--------------------------------------------------
@ -28,21 +32,30 @@ extension Tilelet {
/// Text that will be used for the title label.
public var text: String = ""
/// Used in combination with standardStyle to set the textStyle that will be used for the title label.
public var isBold: Bool = false
/// Text attributes that will be used for the title label.
public var textAttributes: [any LabelAttributeModel]?
/// Text style that will be used for the title label.
public var standardStyle: StandardStyle = .titleSmall
/// LineBreakMode used in Badge label.
public var lineBreakMode: NSLineBreakMode
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public init(text: String,
textAttributes: [any LabelAttributeModel]? = nil,
standardStyle: StandardStyle = .titleSmall) {
isBold: Bool = true,
standardStyle: StandardStyle = .titleSmall,
lineBreakMode: NSLineBreakMode = .byTruncatingTail) {
self.text = text
self.textAttributes = textAttributes
self.standardStyle = standardStyle
self.isBold = isBold
self.lineBreakMode = lineBreakMode
}
//--------------------------------------------------
@ -52,7 +65,7 @@ extension Tilelet {
public func toTitleLockupTitleModel() -> TitleLockup.TitleModel {
TitleLockup.TitleModel(text: text,
textAttributes: textAttributes,
standardStyle: standardStyle.value)
isBold: isBold, standardStyle: standardStyle.value, lineBreakMode: lineBreakMode)
}
}
}

View File

@ -0,0 +1,110 @@
MM/DD/YYYY
----------------
08/31/2022
----------------
- Updates to Typography and default Title Lockup configurations:
- Default
- Regular title updated to bold weight
- Subtitle updated to primary color
- Inverted
- Regular title updated to bold weight
- Subtitle updated to primary color
07/15/2022
----------------
- Updates to Typography and default Title Lockup configurations:
- Default
- Bold Title updated to Regular weight
- Subtitle updated to secondary color
- Inverted
- Bold Title updated to Regular weight
- Subtitle updated to secondary color
04/27/2022
----------------
- Updates to Title Lockup configurations.
04/14/2022
----------------
- Updates to Tilelet Group spec based on 4/14 handoff feedback.
04/04/2022
----------------
- Visuals added to Tilelet Group spec.
04/01/2022
----------------
- Updates based on 3/31 handoff feedback.
03/30/2022
----------------
- Tilelet added to Test App.
03/29/2022
----------------
- Interactive states updated.
03/22/2022
----------------
- Layout and spacing page added.
03/21/2022
----------------
- Updated anatomy, configuration, and element pages.
02/21/2022
----------------
- Title Lockups width properties added.
09/14/2022
----------------
- States section updated to reflect states inherited from Tile Container
- Dev note added to Layouts.
11/30/2022
----------------
- Added "(web only)" to any instance of "keyboard focus"
12/13/2022
----------------
- Replaced focus border pixel and style & spacing values with tokens.
06/19/2023
----------------
- Updated anatomy element names to be local to Tilelet and indicated the core component that powers them under the hood.
09/21/2023
----------------
- Updated Anatomy to include Title Lockup with Eyebrow and Tooltip
- Updated Configurations to include Title Lockup section
- Updated Layout and spacing to include Alignment (Left, Center) and textPosition (Middle)
- Updated Elements to include Eyebrow and uniform 1:1 pairings
10/09/2023
----------------
- Updated Configurations VDS Title Lockup and VDS Tile Container sections.
10/13/2023
----------------
- SPEC format changes to Anatomy to include nested component configurations
- Removed Configurations page
11/20/2023
----------------
- Updated visuals to reflect new corner radius value - 12px
- Updated focus border corner radius to 14px
- View changes
12/14/2023
----------------
- Added secondary, primary backgroundColor options
- Relabeled configurations section headings to use property names
- Relabeled surface sections to use “surface:” labeling convention
- Deprecated gray backgroundColor
- View changes
02/08/2024
----------------
- Added external-icon option to Descriptive Icon in Configurations
- View changes

View File

@ -350,7 +350,7 @@ open class TitleLockup: View {
titleLabel.attributes = titleModel.textAttributes
titleLabel.numberOfLines = titleModel.numberOfLines
titleLabel.surface = surface
titleLabel.lineBreakMode = titleModel.lineBreakMode
addSubview(titleLabel)
titleLabel
.pinTop(previousView?.bottomAnchor ?? self.topAnchor, eyebrowLabel == previousView ? topSpacing : 0)
@ -369,7 +369,7 @@ open class TitleLockup: View {
subTitleLabel.attributes = subTitleModel.textAttributes
subTitleLabel.numberOfLines = subTitleModel.numberOfLines
subTitleLabel.surface = surface
subTitleLabel.lineBreakMode = subTitleModel.lineBreakMode
addSubview(subTitleLabel)
subTitleLabel
.pinTop(previousView?.bottomAnchor ?? self.topAnchor, (eyebrowLabel == previousView || titleLabel == previousView) ? bottomSpacing : 0)

View File

@ -6,6 +6,7 @@
//
import Foundation
import UIKit
extension TitleLockup {
/// Model that represents the options available for the sub title label.
@ -25,16 +26,21 @@ extension TitleLockup {
/// Number of lines used in the subtitle label.
public var numberOfLines: Int
/// LineBreakMode used in subtitle label.
public var lineBreakMode: NSLineBreakMode
public init(text: String,
standardStyle: OtherStandardStyle = .bodyLarge,
textColor: Use = .primary,
textAttributes: [any LabelAttributeModel]? = nil,
numberOfLines: Int = 0) {
numberOfLines: Int = 0,
lineBreakMode: NSLineBreakMode = .byWordWrapping) {
self.text = text
self.standardStyle = standardStyle
self.textColor = textColor
self.textAttributes = textAttributes
self.numberOfLines = numberOfLines
self.lineBreakMode = lineBreakMode
}
/// TextStyle used to render the text.

View File

@ -6,6 +6,7 @@
//
import Foundation
import UIKit
extension TitleLockup {
/// Model that represents the options available for the sub title label.
@ -25,16 +26,21 @@ extension TitleLockup {
/// Number of lines that will be used for the title label.
public var numberOfLines: Int
/// LineBreakMode used in subtitle label.
public var lineBreakMode: NSLineBreakMode
public init(text: String,
textAttributes: [any LabelAttributeModel]? = nil,
isBold: Bool = true,
standardStyle: TitleStandardStyle = .featureXSmall,
numberOfLines: Int = 0) {
numberOfLines: Int = 0,
lineBreakMode: NSLineBreakMode = .byTruncatingTail) {
self.text = text
self.isBold = isBold
self.textAttributes = textAttributes
self.standardStyle = standardStyle
self.numberOfLines = numberOfLines
self.lineBreakMode = lineBreakMode
}
/// TextStyle used to render the text.