diff --git a/MVMCoreUI/Atomic/Atoms/Views/ButtonIcon.swift b/MVMCoreUI/Atomic/Atoms/Views/ButtonIcon.swift index 71aef24a..389033cb 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ButtonIcon.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ButtonIcon.swift @@ -7,3 +7,66 @@ // import Foundation +import VDS + +open class ButtonIcon: VDS.ButtonIcon, VDSMoleculeViewProtocol { + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + public var viewModel: ButtonIconModel! + + public var delegateObject: MVMCoreUIDelegateObject? + + public var additionalData: [AnyHashable : Any]? + + //-------------------------------------------------- + // MARK: - Public Methods + //-------------------------------------------------- + + public func viewModelDidUpdate() { + surface = viewModel.surface + + badgeIndicatorModel = viewModel.badgeIndicatorModel + kind = viewModel.kind + surfaceType = viewModel.surfaceType + iconName = viewModel.iconName + selectedIconName = viewModel.selectedIconName + size = viewModel.size + customSize = viewModel.customSize + floating = viewModel.floating + fitToIcon = viewModel.fitToIcon + hideBorder = viewModel.hideBorder + showBadgeIndicator = viewModel.showBadgeIndicator + selectable = viewModel.selectable + iconOffset = viewModel.iconOffset + + } + + public func updateView(_ size: CGFloat) {} + + //-------------------------------------------------- + // MARK: - Overrides + //-------------------------------------------------- + open override func updateAccessibility() { + super.updateAccessibility() + + if let viewModel { + if let accessibilityText = viewModel.accessibilityText { + //since this is a container control and the + //icon & badgeIndicator (gets from it's own model) are traversed separatly + icon.accessibilityLabel = accessibilityText + } + } + } + +} + +//to deal with how it's parent constrains this control +extension ButtonIcon: MVMCoreUIViewConstrainingProtocol { + + public func needsToBeConstrained() -> Bool { true } + + public func horizontalAlignment() -> UIStackView.Alignment { .leading } +} + diff --git a/MVMCoreUI/Atomic/Atoms/Views/ButtonIconModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ButtonIconModel.swift index ea6f7a8e..ed93e969 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ButtonIconModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ButtonIconModel.swift @@ -9,8 +9,7 @@ import Foundation import VDS - -open class ButtonIconModel: MoleculeModelProtocol { +open class ButtonIconModel: ButtonModelProtocol, MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -23,8 +22,10 @@ open class ButtonIconModel: MoleculeModelProtocol { //-------------------------------------------------- public var surface: Surface { inverted ? .dark : .light } public var inverted: Bool = false - public var badgeIndicator: BadgeIndicatorModel? - public var expandDirection = ButtonIcon.BadgeIndicatorModel.ExpandDirection.right + public var accessibilityText: String? + + public var action: ActionModelProtocol + public var kind = ButtonIcon.Kind.ghost public var surfaceType = ButtonIcon.SurfaceType.colorFill public var iconName: Icon.Name = .info @@ -35,12 +36,48 @@ open class ButtonIconModel: MoleculeModelProtocol { public var fitToIcon: Bool = false public var hideBorder: Bool = true public var showBadgeIndicator: Bool = false - public var selectedable: Bool = false - public var iconOffSet: CGPoint = .zero + public var selectable: Bool = false + public var iconOffset: CGPoint = .zero + public var badgeIndicatorModel: VDS.ButtonIcon.BadgeIndicatorModel? { + guard let model = badgeIndicator else { return nil } + return .init(kind: model.kind, + fillColor: model.fillColor, + expandDirection: expandDirection, + size: model.size, + maximumDigits: model.maximumDigits, + width: model.width, + height: model.height, + number: model.number, + leadingCharacter: model.leadingCharacter, + trailingText: model.trailingText, + dotSize: model.dotSize, + verticalPadding: model.verticalPadding, + horizontalPadding: model.horizontalPadding, + hideDot: model.hideDot, + hideBorder: model.hideBorder) + } + + private var badgeIndicator: BadgeIndicatorModel? + private var expandDirection = ButtonIcon.BadgeIndicatorModel.ExpandDirection.right + + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + public init(with iconName: VDS.Icon.Name, action: ActionModelProtocol) { + self.iconName = iconName + self.action = action + } + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- private enum CodingKeys: String, CodingKey { case id case inverted + case accessibilityText + case action case badgeIndicator case expandDirection case kind @@ -53,15 +90,19 @@ open class ButtonIconModel: MoleculeModelProtocol { case fitToIcon case hideBorder case showBadgeIndicator - case selectedable - case iconOffSet + case selectable + case iconOffset } - - required public convenience init(from decoder: Decoder) throws { - self.init() + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) + action = try container.decodeModel(codingKey: .action) id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString inverted = try container.decodeIfPresent(Bool.self, forKey: .inverted) ?? false + accessibilityText = try container.decodeIfPresent(String.self, forKey: .accessibilityText) badgeIndicator = try container.decodeIfPresent(BadgeIndicatorModel.self, forKey: .badgeIndicator) expandDirection = try container.decodeIfPresent(ButtonIcon.BadgeIndicatorModel.ExpandDirection.self, forKey: .expandDirection) ?? .right kind = try container.decodeIfPresent(ButtonIcon.Kind.self, forKey: .kind) ?? .ghost @@ -69,12 +110,33 @@ open class ButtonIconModel: MoleculeModelProtocol { iconName = try container.decode(Icon.Name.self, forKey: .iconName) selectedIconName = try container.decodeIfPresent(Icon.Name.self, forKey: .selectedIconName) size = try container.decodeIfPresent(ButtonIcon.Size.self, forKey: .size) ?? .large - + customSize = try container.decodeIfPresent(Int.self, forKey: .customSize) + floating = try container.decodeIfPresent(Bool.self, forKey: .floating) ?? false + fitToIcon = try container.decodeIfPresent(Bool.self, forKey: .fitToIcon) ?? false + hideBorder = try container.decodeIfPresent(Bool.self, forKey: .hideBorder) ?? false + showBadgeIndicator = try container.decodeIfPresent(Bool.self, forKey: .showBadgeIndicator) ?? false + selectable = try container.decodeIfPresent(Bool.self, forKey: .selectable) ?? false + iconOffset = try container.decodeIfPresent(CGPoint.self, forKey: .iconOffset) ?? .zero } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(id, forKey: .id) try container.encode(inverted, forKey: .inverted) + try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) + try container.encodeIfPresent(badgeIndicator, forKey: .badgeIndicator) + try container.encodeIfPresent(expandDirection, forKey: .expandDirection) + try container.encodeIfPresent(kind, forKey: .kind) + try container.encodeIfPresent(surfaceType, forKey: .kind) + try container.encode(iconName, forKey: .iconName) + try container.encodeIfPresent(selectedIconName, forKey: .selectedIconName) + try container.encodeIfPresent(size, forKey: .size) + try container.encodeIfPresent(customSize, forKey: .customSize) + try container.encodeIfPresent(floating, forKey: .floating) + try container.encodeIfPresent(fitToIcon, forKey: .fitToIcon) + try container.encodeIfPresent(hideBorder, forKey: .hideBorder) + try container.encodeIfPresent(showBadgeIndicator, forKey: .showBadgeIndicator) + try container.encodeIfPresent(selectable, forKey: .selectable) + try container.encodeIfPresent(iconOffset, forKey: .iconOffset) } } diff --git a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift index c864acdb..97f87e28 100644 --- a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift @@ -76,6 +76,7 @@ open class CoreUIModelMapping: ModelMapping { ModelRegistry.register(handler: Badge.self, for: BadgeModel.self) ModelRegistry.register(handler: BadgeIndicator.self, for: BadgeIndicatorModel.self) ModelRegistry.register(handler: Icon.self, for: IconModel.self) + ModelRegistry.register(handler: ButtonIcon.self, for: ButtonIconModel.self) ModelRegistry.register(handler: Tooltip.self, for: TooltipModel.self) // MARK:- Horizontal Combination Molecules