Merge branch 'feature/buttonIcon' into 'develop'

VDS Components - VDS Brand 3.0 Button Icon for IOS

See merge request BPHV_MIPS/vds_ios!147
This commit is contained in:
Bruce, Matt R 2024-02-14 18:01:10 +00:00
commit a317125072
4 changed files with 370 additions and 34 deletions

View File

@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
18792A902B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18792A8F2B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift */; };
18BDEE822B75316E00452358 /* ButtonIconChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 18BDEE812B75316E00452358 /* ButtonIconChangeLog.txt */; };
445BA07829C07B3D0036A7C5 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 445BA07729C07B3D0036A7C5 /* Notification.swift */; };
44604AD429CE186A00E62B51 /* NotificationButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */; };
44604AD729CE196600E62B51 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD629CE196600E62B51 /* Line.swift */; };
@ -169,6 +171,8 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
18792A8F2B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonIconBadgeIndicatorModel.swift; sourceTree = "<group>"; };
18BDEE812B75316E00452358 /* ButtonIconChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = ButtonIconChangeLog.txt; sourceTree = "<group>"; };
445BA07729C07B3D0036A7C5 /* Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = "<group>"; };
44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationButtonModel.swift; sourceTree = "<group>"; };
44604AD629CE196600E62B51 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
@ -674,6 +678,8 @@
isa = PBXGroup;
children = (
EA81410A2A0E8E3C004F60D2 /* ButtonIcon.swift */,
18792A8F2B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift */,
18BDEE812B75316E00452358 /* ButtonIconChangeLog.txt */,
);
path = ButtonIcon;
sourceTree = "<group>";
@ -942,6 +948,7 @@
EAEEECAF2B1FC2BA00531FC2 /* ToggleViewChangeLog.txt in Resources */,
EAEEEC922B1F807300531FC2 /* BadgeChangeLog.txt in Resources */,
EAEEEC9E2B1F8F7700531FC2 /* ButtonGroupChangeLog.txt in Resources */,
18BDEE822B75316E00452358 /* ButtonIconChangeLog.txt in Resources */,
EA3362062891E14D0071C351 /* VerizonNHGeTX-Regular.otf in Resources */,
EA3362052891E14D0071C351 /* VerizonNHGeDS-Bold.otf in Resources */,
EAEEECA02B1F908200531FC2 /* BadgeIndicatorChangeLog.txt in Resources */,
@ -1064,6 +1071,7 @@
EA5E30532950DDA60082B959 /* TitleLockup.swift in Sources */,
EAD062B02A3B873E0015965D /* BadgeIndicator.swift in Sources */,
EAA5EEB528ECBFB4003B3210 /* ImageLabelAttribute.swift in Sources */,
18792A902B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift in Sources */,
EA0B18062A9E2D2D00F2D0CD /* SelectorItemBase.swift in Sources */,
EAB5FF0129424ACB00998C17 /* UIControl.swift in Sources */,
EA985BF5296C60C000F2FF2E /* Icon.swift in Sources */,

View File

@ -8,12 +8,13 @@
import Foundation
import UIKit
import VDSColorTokens
import Combine
/// A button icon is an interactive element that visually communicates the action it triggers via an icon.
/// It usually represents a supplementary or utilitarian action. A button icon can stand alone, but often
/// exists in a group when there are several actions that can be performed.
@objc(VDSButtonIcon)
open class ButtonIcon: Control {
open class ButtonIcon: Control, Changeable, FormFieldable {
//--------------------------------------------------
// MARK: - Initializers
@ -42,7 +43,7 @@ open class ButtonIcon: Control {
public enum SurfaceType: String, CaseIterable {
case colorFill, media
}
/// Enum used to describe the size of button icon.
public enum Size: String, EnumSubset {
case large
@ -67,17 +68,45 @@ open class ButtonIcon: Control {
private var centerYConstraint: NSLayoutConstraint?
private var layoutGuideWidthConstraint: NSLayoutConstraint?
private var layoutGuideHeightConstraint: NSLayoutConstraint?
private var badgeIndicatorLeadingConstraint: NSLayoutConstraint?
private var badgeIndicatorTrailingConstraint: NSLayoutConstraint?
private var badgeIndicatorCenterXConstraint: NSLayoutConstraint?
private var badgeIndicatorCenterYConstraint: NSLayoutConstraint?
private var currentIconName: Icon.Name? {
if let selectedIconName {
if let selectedIconName, isSelected {
return selectedIconName
} else {
return iconName
}
}
private var badgeIndicatorOffset: CGPoint {
switch (size, kind) {
case (.small, .ghost):
return .init(x: 1, y: 0)
case (.large, .ghost):
return .init(x: 1, y: 1)
case (.small, .lowContrast), (.small, .highContrast):
return .init(x: 4, y: 4)
case (.large, .lowContrast), (.large, .highContrast):
return .init(x: 6, y: 6)
}
}
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
///Badge Indicator object used to render for the ButtonIcon.
open var badgeIndicator = BadgeIndicator().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.size = .small
$0.isHidden = true
}
/// If set, this is used to render the badge indicator.
open var badgeIndicatorModel: BadgeIndicatorModel? { didSet { setNeedsUpdate() } }
/// Icon object used to render out the Icon for this ButtonIcon.
open var icon = Icon().with { $0.isUserInteractionEnabled = false }
@ -107,22 +136,40 @@ open class ButtonIcon: Control {
/// If set to true, the button icon will not have a border.
open var hideBorder: Bool = true { didSet { setNeedsUpdate() } }
/// If provided, the badge indicator will present.
open var showBadgeIndicator: Bool = false { didSet { setNeedsUpdate() } }
/// If true, button will be rendered as selected, when it is selectable.
open var selectable: Bool = false {
didSet {
//unselect
if !selectable && isSelected {
isSelected = false
}
setNeedsUpdate()
}
}
/// Used to move the icon inside the button in both x and y axis.
open var iconOffset: CGPoint = .init(x: 0, y: 0) { didSet { setNeedsUpdate() } }
open var onChangeSubscriber: AnyCancellable?
open var inputId: String? { didSet { setNeedsUpdate() } }
open var value: AnyHashable? { didSet { setNeedsUpdate() } }
//--------------------------------------------------
// MARK: - Configuration
//--------------------------------------------------
private var iconColorConfiguration: AnyColorable {
if selectedIconName != nil {
return selectedIconColorConfiguration
if kind == .highContrast {
return highContrastIconColorConfiguration
} else if kind == .lowContrast {
return (surfaceType == .colorFill) ? lowContrastIconColorConfiguration : (floating ? lowContrastIconColorConfiguration : standardIconColorConfiguration)
} else {
if kind == .highContrast {
return highContrastIconColorConfiguration
} else {
return standardIconColorConfiguration
}
return standardIconColorConfiguration
}
}
@ -147,7 +194,19 @@ open class ButtonIcon: Control {
return ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled])
}.eraseToAnyColorable()
}()
private var lowContrastIconColorConfiguration: AnyColorable = {
return ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.paletteBlack.withAlphaComponent(0.70), forState: .disabled)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .selected)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.paletteBlack.withAlphaComponent(0.70), forState: [.selected, .disabled])
}.eraseToAnyColorable()
}()
@ -155,14 +214,6 @@ open class ButtonIcon: Control {
return SurfaceColorConfiguration(VDSColor.elementsPrimaryOndark, VDSColor.elementsPrimaryOnlight).eraseToAnyColorable()
}()
private var selectedIconColorConfiguration: AnyColorable = {
return ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.elementsBrandhighlight, VDSColor.elementsPrimaryOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
}.eraseToAnyColorable()
}()
private struct GhostConfiguration: Configuration {
var kind: Kind = .ghost
var surfaceType: SurfaceType = .colorFill
@ -181,13 +232,19 @@ open class ButtonIcon: Control {
}()
}
private struct LowContrastColorFillFloatingConfiguration: Configuration {
private struct LowContrastColorFillFloatingConfiguration: Configuration, Dropshadowable {
var kind: Kind = .lowContrast
var surfaceType: SurfaceType = .colorFill
var floating: Bool = true
var backgroundColorConfiguration: AnyColorable = {
SurfaceColorConfiguration(VDSColor.backgroundPrimaryLight, .clear).eraseToAnyColorable()
SurfaceColorConfiguration(VDSColor.paletteWhite, VDSColor.paletteGray20).eraseToAnyColorable()
}()
var shadowColorConfiguration: AnyColorable = {
SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
}()
var shadowOpacity: CGFloat = 0.16
var shadowOffset: CGSize = .init(width: 0, height: 2)
var shadowRadius: CGFloat = 4
}
private struct LowContrastMediaConfiguration: Configuration, Borderable {
@ -195,11 +252,11 @@ open class ButtonIcon: Control {
var surfaceType: SurfaceType = .media
var floating: Bool = false
var backgroundColorConfiguration: AnyColorable = {
SurfaceColorConfiguration(VDSColor.backgroundPrimaryLight, .clear).eraseToAnyColorable()
SurfaceColorConfiguration(VDSColor.backgroundPrimaryLight, VDSColor.backgroundPrimaryDark).eraseToAnyColorable()
}()
var borderWidth: CGFloat = 1.0
var borderColorConfiguration: AnyColorable = {
SurfaceColorConfiguration(VDSColor.elementsLowcontrastOnlight, .clear).eraseToAnyColorable()
SurfaceColorConfiguration(VDSColor.elementsLowcontrastOnlight, VDSColor.elementsLowcontrastOndark).eraseToAnyColorable()
}()
}
@ -208,14 +265,14 @@ open class ButtonIcon: Control {
var surfaceType: SurfaceType = .media
var floating: Bool = true
var backgroundColorConfiguration: AnyColorable = {
SurfaceColorConfiguration(VDSColor.backgroundPrimaryLight, .clear).eraseToAnyColorable()
SurfaceColorConfiguration(VDSColor.paletteWhite, VDSColor.paletteGray20).eraseToAnyColorable()
}()
var shadowColorConfiguration: AnyColorable = {
SurfaceColorConfiguration(VDSColor.paletteBlack, .clear).eraseToAnyColorable()
SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
}()
var shadowOpacity: CGFloat = 0.16
var shadowOffset: CGSize = .init(width: 0, height: 2)
var shadowRadius: CGFloat = 2
var shadowRadius: CGFloat = 4
}
private struct HighContrastConfiguration: Configuration {
@ -225,33 +282,49 @@ open class ButtonIcon: Control {
var backgroundColorConfiguration: AnyColorable = {
return ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryLight, forState: .normal)
$0.setSurfaceColors(VDSColor.backgroundPrimaryDark, VDSColor.backgroundPrimaryLight, forState: .selected)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled])
}.eraseToAnyColorable()
}()
}
private struct HighContrastFloatingConfiguration: Configuration {
private struct HighContrastFloatingConfiguration: Configuration, Dropshadowable {
var kind: Kind = .highContrast
var surfaceType: SurfaceType = .colorFill
var floating: Bool = true
var backgroundColorConfiguration: AnyColorable = {
return ControlColorConfiguration().with {
$0.setSurfaceColors(VDSColor.backgroundPrimaryLight, VDSColor.backgroundPrimaryLight, forState: .normal)
$0.setSurfaceColors(VDSColor.paletteGray20, VDSColor.paletteWhite, forState: .normal)
$0.setSurfaceColors(VDSColor.paletteGray20, VDSColor.paletteWhite, forState: .selected)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: .highlighted)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.interactiveActiveOnlight, VDSColor.interactiveActiveOndark, forState: [.selected, .highlighted])
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: [.selected, .disabled])
}.eraseToAnyColorable()
}()
var shadowColorConfiguration: AnyColorable = {
SurfaceColorConfiguration(VDSColor.paletteBlack, VDSColor.paletteBlack).eraseToAnyColorable()
}()
var shadowOpacity: CGFloat = 0.16
var shadowOffset: CGSize = .init(width: 0, height: 2)
var shadowRadius: CGFloat = 6
}
private var badgeIndicatorDefaultSize: CGSize = .zero
//--------------------------------------------------
// MARK: - Overrides
//--------------------------------------------------
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
open override func setup() {
super.setup()
isAccessibilityElement = true
accessibilityTraits = .image
accessibilityElements = [badgeIndicator]
//create a layoutGuide for the icon to key off of
let iconLayoutGuide = UILayoutGuide()
addLayoutGuide(iconLayoutGuide)
@ -259,10 +332,21 @@ open class ButtonIcon: Control {
//add the icon
addSubview(icon)
//add badgeIndicator
addSubview(badgeIndicator)
badgeIndicator.isHidden = !showBadgeIndicator
badgeIndicatorDefaultSize = badgeIndicator.frame.size
//determines the height/width of the icon
layoutGuideWidthConstraint = iconLayoutGuide.width(constant: size.containerSize)
layoutGuideHeightConstraint = iconLayoutGuide.height(constant: size.containerSize)
badgeIndicatorLeadingConstraint = badgeIndicator.leadingAnchor.constraint(equalTo: icon.centerXAnchor)
badgeIndicatorTrailingConstraint = badgeIndicator.trailingAnchor.constraint(equalTo: icon.centerXAnchor)
badgeIndicatorCenterXConstraint = badgeIndicator.centerXAnchor.constraint(equalTo: icon.centerXAnchor)
badgeIndicatorCenterYConstraint = icon.centerYAnchor.constraint(equalTo: badgeIndicator.centerYAnchor)
badgeIndicatorCenterYConstraint?.isActive = true
badgeIndicatorLeadingConstraint?.isActive = true
//pin layout guide
iconLayoutGuide
.pinTop()
@ -277,6 +361,24 @@ open class ButtonIcon: Control {
centerYConstraint?.activate()
}
/// Executed on initialization for this View.
open override func initialSetup() {
super.initialSetup()
onClick = { control in
guard control.isEnabled else { return }
if control.selectedIconName != nil && control.selectable {
control.toggle()
}
}
}
/// This will change the state of the Selector and execute the actionBlock if provided.
open func toggle() {
//removed error
isSelected.toggle()
sendActions(for: .valueChanged)
}
/// Resets to default settings.
open override func reset() {
super.reset()
@ -288,6 +390,10 @@ open class ButtonIcon: Control {
hideBorder = true
iconOffset = .init(x: 0, y: 0)
iconName = nil
selectedIconName = nil
showBadgeIndicator = false
selectable = false
badgeIndicatorModel = nil
shouldUpdateView = true
setNeedsUpdate()
}
@ -306,6 +412,7 @@ open class ButtonIcon: Control {
} else {
icon.reset()
}
updateBadgeIndicator()
setNeedsLayout()
}
@ -338,7 +445,7 @@ open class ButtonIcon: Control {
layoutGuideHeightConstraint?.constant = iconLayoutSize
//border
if let borderable = currentConfig as? Borderable {
if let borderable = currentConfig as? Borderable, hideBorder {
layer.borderColor = borderable.borderColorConfiguration.getColor(self).cgColor
layer.borderWidth = borderable.borderWidth
} else {
@ -351,10 +458,70 @@ open class ButtonIcon: Control {
} else {
removeDropShadow()
}
badgeIndicatorCenterXConstraint?.constant = badgeIndicatorOffset.x + badgeIndicatorDefaultSize.width/2
badgeIndicatorCenterYConstraint?.constant = badgeIndicatorOffset.y + badgeIndicatorDefaultSize.height/2
badgeIndicatorLeadingConstraint?.constant = badgeIndicatorOffset.x
badgeIndicatorTrailingConstraint?.constant = badgeIndicatorOffset.x + badgeIndicatorDefaultSize.width
if showBadgeIndicator {
updateExpandDirectionalConstraints()
}
}
//--------------------------------------------------
// MARK: - Private Methods
//--------------------------------------------------
private func updateBadgeIndicator() {
badgeIndicator.isHidden = !showBadgeIndicator
guard let badgeIndicatorModel else {
badgeIndicator.isHidden = true
return
}
badgeIndicator.surface = surface
badgeIndicator.kind = badgeIndicatorModel.kind
badgeIndicator.fillColor = badgeIndicatorModel.fillColor
badgeIndicator.size = badgeIndicatorModel.size
badgeIndicator.maximumDigits = badgeIndicatorModel.maximumDigits
badgeIndicator.width = badgeIndicatorModel.width
badgeIndicator.height = badgeIndicatorModel.height
badgeIndicator.number = badgeIndicatorModel.number
badgeIndicator.leadingCharacter = badgeIndicatorModel.leadingCharacter
badgeIndicator.trailingText = badgeIndicatorModel.trailingText
badgeIndicator.dotSize = badgeIndicatorModel.dotSize
badgeIndicator.verticalPadding = badgeIndicatorModel.verticalPadding
badgeIndicator.horizontalPadding = badgeIndicatorModel.horizontalPadding
badgeIndicator.hideDot = badgeIndicatorModel.hideDot
badgeIndicator.hideBorder = badgeIndicatorModel.hideBorder
}
private func updateExpandDirectionalConstraints() {
guard let badgeIndicatorModel else { return }
switch badgeIndicatorModel.expandDirection {
case .right:
badgeIndicatorLeadingConstraint?.isActive = true
badgeIndicatorTrailingConstraint?.isActive = false
badgeIndicatorCenterXConstraint?.isActive = false
case .center:
badgeIndicatorLeadingConstraint?.isActive = false
badgeIndicatorTrailingConstraint?.isActive = false
badgeIndicatorCenterXConstraint?.isActive = true
case .left:
badgeIndicatorLeadingConstraint?.isActive = false
badgeIndicatorCenterXConstraint?.isActive = false
badgeIndicatorTrailingConstraint?.isActive = true
}
}
/// Used to update any Accessibility properties.
open override func updateAccessibility() {
super.updateAccessibility()
setAccessibilityLabel(for: [icon, badgeIndicator.label])
}
}
// MARK: AppleGuidelinesTouchable
extension ButtonIcon: AppleGuidelinesTouchable {
/// Overrides to ensure that the touch point meets a minimum of the minimumTappableArea.

View File

@ -0,0 +1,82 @@
//
// ButtonIconBadgeIndicatorModel.swift
// VDS
//
// Created by Kanamarlapudi, Vasavi on 08/02/24.
//
import Foundation
extension ButtonIcon {
//Model that represents the options available for the Badge Indicator
public struct BadgeIndicatorModel {
/// Enum used to describe the badge indicator direction of icon button determining the expand direction.
public enum ExpandDirection: String, CaseIterable {
case right, center, left
}
/// Applies expand direction to Badge Indicator if shows badge indicator.
public var expandDirection: ExpandDirection = .right
/// Kind that will be used for the badge indicator.
public var kind: BadgeIndicator.Kind
/// Fill color that will be used for the badge indicator.
public var fillColor: BadgeIndicator.FillColor
/// Size that will be used for the badge indicator.
public var size: BadgeIndicator.Size
/// Number of digits that will be used for the badge indicator.
public var maximumDigits: BadgeIndicator.MaximumDigits
/// Max width that will be used for the badge indicator.
public var width: CGFloat?
/// Max height that will be used for the badge indicator.
public var height: CGFloat?
/// Number that will be used for the badge indicator.
public var number: Int?
/// Leading Character that will be used for the badge indicator.
public var leadingCharacter: String?
/// Trailing Text height that will be used for the badge indicator.
public var trailingText: String?
/// Dot Size that will be used for the badge indicator.
public var dotSize: CGFloat?
/// Vertical Padding that will be used for the badge indicator.
public var verticalPadding: CGFloat?
/// Horizontal Padding that will be used for the badge indicator.
public var horizontalPadding: CGFloat?
/// Hide Dot that will be used for the badge indicator.
public var hideDot: Bool = false
/// Hide Border that will be used for the badge indicator.
public var hideBorder: Bool = false
public init(kind: BadgeIndicator.Kind = .simple, fillColor: BadgeIndicator.FillColor = .red, expandDirection: ExpandDirection = .right, size: BadgeIndicator.Size = .xxlarge, maximumDigits: BadgeIndicator.MaximumDigits = .two, width: CGFloat? = nil, height: CGFloat? = nil, number: Int? = nil, leadingCharacter: String = "", trailingText: String = "", dotSize: CGFloat? = nil, verticalPadding: CGFloat? = nil, horizontalPadding: CGFloat? = nil, hideDot: Bool = false, hideBorder: Bool = false) {
self.kind = kind
self.fillColor = fillColor
self.expandDirection = expandDirection
self.size = size
self.maximumDigits = maximumDigits
self.width = width
self.height = height
self.number = number
self.leadingCharacter = leadingCharacter
self.trailingText = trailingText
self.dotSize = dotSize
self.verticalPadding = verticalPadding
self.horizontalPadding = horizontalPadding
self.hideDot = hideDot
self.hideBorder = hideBorder
}
}
}

View File

@ -0,0 +1,79 @@
03/30/2023
----------------
- Dev handoff
04/06/2023
----------------
- Changed component name to Button Icon.
04/13/2023
----------------
- Dev handoff (additional states)
04/20/2023
----------------
- Added Selectable and Selected properties in Configuration.
05/01/2023
----------------
- Added fitToIcon prop for Ghost variation.
05/03/2023
----------------
- Updated drop shadows for light and dark floating buttons (all states)
- Removed border from all floating buttons
- Updated all dark floating button backgrounds to gray.20
- Disabled icons on gray.20 changed to palette.black 70% opacity for floating buttons
- Reduce Inside focusborderPosition to 1px
05/25/2023
----------------
- Added hideBorder prop back to Configurations
- Added showBadgeIndicator prop to Configurations
- Added Hit Area support for Button Icon with Badge Indicator
- Added Elements page for Badge Indicator with default settings and offset information
- Updated Badge Indicator Offset to be based on center of Icon container
05/30/2023
----------------
- Added expandDirection prop to Configurations under Badge Indicator section.
06/02/2023
----------------
- Added Additional Border Color specification if hideBorder=True on Low Contrast hover states.
06/12/2023
----------------
- Ghost Icon Cart position updated from {1,2} to {1,1}.
06/13/2023
----------------
- Updated Drop shadow properties layout in States.
06/29/2023
----------------
- Updated Badge Indicator simple dot size to 4px.
08/18/2023
----------------
- Updated default icon color for all selected Button Icon states to element.primary.onlight for light surfaces and element.primary.ondark for dark surfaces.
- Added a dev note that this default color can be set to a custom color (like red).
11/16/2023
----------------
- Added component tokens
- Applied component tokens throughout states
- Applied semantic inverse to primary element, background states on light and dark surfaces
12/1/2023
----------------
- Reapplied component token updates to Ghost States
1/9/2024
----------------
- Fixed incorrect Low Contrast border token
1/25/2024
----------------
- Removed redundant opacity specs in States (dark surface).