diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index dffbf7e5..67652e0a 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -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 = ""; }; + 18BDEE812B75316E00452358 /* ButtonIconChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = ButtonIconChangeLog.txt; sourceTree = ""; }; 445BA07729C07B3D0036A7C5 /* Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = ""; }; 44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationButtonModel.swift; sourceTree = ""; }; 44604AD629CE196600E62B51 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; @@ -674,6 +678,8 @@ isa = PBXGroup; children = ( EA81410A2A0E8E3C004F60D2 /* ButtonIcon.swift */, + 18792A8F2B7431F2008C0D29 /* ButtonIconBadgeIndicatorModel.swift */, + 18BDEE812B75316E00452358 /* ButtonIconChangeLog.txt */, ); path = ButtonIcon; sourceTree = ""; @@ -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 */, diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index 85e0ae6e..922b9153 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -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. diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIconBadgeIndicatorModel.swift b/VDS/Components/Icon/ButtonIcon/ButtonIconBadgeIndicatorModel.swift new file mode 100644 index 00000000..61b94c12 --- /dev/null +++ b/VDS/Components/Icon/ButtonIcon/ButtonIconBadgeIndicatorModel.swift @@ -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 + } + } +} diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIconChangeLog.txt b/VDS/Components/Icon/ButtonIcon/ButtonIconChangeLog.txt new file mode 100644 index 00000000..df1dcb5f --- /dev/null +++ b/VDS/Components/Icon/ButtonIcon/ButtonIconChangeLog.txt @@ -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).