From c41599578a99d1b58022473602c3852fbf7ecf27 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 22 Aug 2024 16:03:47 -0500 Subject: [PATCH] added ParentViewProtocol to views and updated children Signed-off-by: Matt Bruce --- VDS/BaseClasses/Selector/SelectorBase.swift | 3 ++- VDS/BaseClasses/Selector/SelectorGroupBase.swift | 3 ++- VDS/BaseClasses/Selector/SelectorItemBase.swift | 5 +++-- VDS/Components/Badge/Badge.swift | 4 +++- VDS/Components/BadgeIndicator/BadgeIndicator.swift | 4 +++- VDS/Components/Breadcrumbs/Breadcrumbs.swift | 4 +++- VDS/Components/DatePicker/DatePicker.swift | 6 ++++++ VDS/Components/DropdownSelect/DropdownSelect.swift | 2 +- VDS/Components/Icon/ButtonIcon/ButtonIcon.swift | 4 +++- VDS/Components/InputStepper/InputStepper.swift | 6 ++++++ VDS/Components/Notification/Notification.swift | 4 +++- VDS/Components/PriceLockup/PriceLockup.swift | 3 ++- VDS/Components/RadioBox/RadioBoxItem.swift | 3 ++- VDS/Components/Tabs/Tabs.swift | 4 +++- VDS/Components/TextFields/EntryFieldBase.swift | 4 +++- VDS/Components/TileContainer/TileContainer.swift | 10 +++++----- VDS/Components/Tilelet/Tilelet.swift | 4 +++- VDS/Components/TitleLockup/TitleLockup.swift | 4 +++- VDS/Components/Toggle/Toggle.swift | 4 +++- VDS/Components/Tooltip/TooltipDialog.swift | 4 +++- VDS/Protocols/ViewProtocol.swift | 14 +++++++------- 21 files changed, 69 insertions(+), 30 deletions(-) diff --git a/VDS/BaseClasses/Selector/SelectorBase.swift b/VDS/BaseClasses/Selector/SelectorBase.swift index 2d12cf07..97e72afd 100644 --- a/VDS/BaseClasses/Selector/SelectorBase.swift +++ b/VDS/BaseClasses/Selector/SelectorBase.swift @@ -31,7 +31,6 @@ public protocol SelectorControlable: Control, Changeable { @objcMembers @objc(VDSSelectorBase) open class SelectorBase: Control, SelectorControlable, ParentViewProtocol { - public var children: [any ViewProtocol] { [selectorView] } //-------------------------------------------------- // MARK: - Initializers @@ -51,6 +50,8 @@ open class SelectorBase: Control, SelectorControlable, ParentViewProtocol { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [selectorView] } + open var onChangeSubscriber: AnyCancellable? open var size = CGSize(width: 20, height: 20) { didSet { setNeedsUpdate() } } diff --git a/VDS/BaseClasses/Selector/SelectorGroupBase.swift b/VDS/BaseClasses/Selector/SelectorGroupBase.swift index ebb0512b..63556c95 100644 --- a/VDS/BaseClasses/Selector/SelectorGroupBase.swift +++ b/VDS/BaseClasses/Selector/SelectorGroupBase.swift @@ -40,7 +40,6 @@ extension SelectorGroupSingleSelect { /// Base Class used for any Grouped Form Control of a Selector Type. open class SelectorGroupBase: Control, SelectorGroup, Changeable, ParentViewProtocol { - public var children: [any ViewProtocol] { items } //-------------------------------------------------- // MARK: - Private Properties @@ -58,6 +57,8 @@ open class SelectorGroupBase: Control, SelectorGrou //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { items } + /// Array of the HandlerType registered. /// Array of HandlerType that the user will have the ability to select from. open var items: [SelectorItemType] = [] { diff --git a/VDS/BaseClasses/Selector/SelectorItemBase.swift b/VDS/BaseClasses/Selector/SelectorItemBase.swift index d2ccc293..321df2a8 100644 --- a/VDS/BaseClasses/Selector/SelectorItemBase.swift +++ b/VDS/BaseClasses/Selector/SelectorItemBase.swift @@ -12,7 +12,6 @@ import VDSCoreTokens /// Base Class used to build out a SelectorControlable control. open class SelectorItemBase: Control, Errorable, Changeable, Groupable, ParentViewProtocol { - public var children: [any ViewProtocol] { [label, childLabel, errorLabel, selectorView] } //-------------------------------------------------- // MARK: - Initializers @@ -62,7 +61,9 @@ open class SelectorItemBase: Control, Errorable, Changea //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- - open var onChangeSubscriber: AnyCancellable? + open var children: [any ViewProtocol] { [label, childLabel, errorLabel, selectorView] } + + open var onChangeSubscriber: AnyCancellable? /// Label used to render labelText. open var label = Label().with { diff --git a/VDS/Components/Badge/Badge.swift b/VDS/Components/Badge/Badge.swift index 1c47133f..19c40bbc 100644 --- a/VDS/Components/Badge/Badge.swift +++ b/VDS/Components/Badge/Badge.swift @@ -17,7 +17,7 @@ import Combine /// to its parent this object will stretch to the parent's width. @objcMembers @objc(VDSBadge) -open class Badge: View { +open class Badge: View, ParentViewProtocol { //-------------------------------------------------- // MARK: - Initializers @@ -45,6 +45,8 @@ open class Badge: View { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [label] } + /// Label used to render text open var label = Label().with { $0.isAccessibilityElement = false diff --git a/VDS/Components/BadgeIndicator/BadgeIndicator.swift b/VDS/Components/BadgeIndicator/BadgeIndicator.swift index daecddf4..403c7d46 100644 --- a/VDS/Components/BadgeIndicator/BadgeIndicator.swift +++ b/VDS/Components/BadgeIndicator/BadgeIndicator.swift @@ -13,7 +13,7 @@ import Combine /// A badge indicator is a visual label used to convey status or highlight supplemental information. @objcMembers @objc(VDSBadgeIndicator) -open class BadgeIndicator: View { +open class BadgeIndicator: View, ParentViewProtocol { //-------------------------------------------------- // MARK: - Initializers @@ -135,6 +135,8 @@ open class BadgeIndicator: View { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [label, badgeView] } + /// Label used for the numeric kind. open var label = Label().with { $0.setContentCompressionResistancePriority(.required, for: .vertical) diff --git a/VDS/Components/Breadcrumbs/Breadcrumbs.swift b/VDS/Components/Breadcrumbs/Breadcrumbs.swift index 808b5548..938a22a4 100644 --- a/VDS/Components/Breadcrumbs/Breadcrumbs.swift +++ b/VDS/Components/Breadcrumbs/Breadcrumbs.swift @@ -15,11 +15,13 @@ import Combine /// Breadcrumbs are secondary navigation that use a hierarchy of internal links to tell customers where they are in an experience. Each breadcrumb links to its respective page, except for that of current page. @objcMembers @objc(VDSBreadcrumbs) -open class Breadcrumbs: View { +open class Breadcrumbs: View, ParentViewProtocol { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { breadcrumbs } + /// Array of ``BreadcrumbItem`` views for the Breadcrumbs. open var breadcrumbs: [BreadcrumbItem] = [] { didSet { setNeedsUpdate() } } diff --git a/VDS/Components/DatePicker/DatePicker.swift b/VDS/Components/DatePicker/DatePicker.swift index e9137ad9..bd53a2a2 100644 --- a/VDS/Components/DatePicker/DatePicker.swift +++ b/VDS/Components/DatePicker/DatePicker.swift @@ -94,6 +94,12 @@ open class DatePicker: EntryFieldBase { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open override var children: [any ViewProtocol] { + var current = super.children + current.append(selectedDateLabel) + return current + } + open var calendarIcon = Icon().with { $0.name = .calendar $0.size = .medium diff --git a/VDS/Components/DropdownSelect/DropdownSelect.swift b/VDS/Components/DropdownSelect/DropdownSelect.swift index 2c243a26..98a5a61f 100644 --- a/VDS/Components/DropdownSelect/DropdownSelect.swift +++ b/VDS/Components/DropdownSelect/DropdownSelect.swift @@ -31,7 +31,7 @@ open class DropdownSelect: EntryFieldBase { //-------------------------------------------------- // MARK: - Public Properties - //-------------------------------------------------- + //-------------------------------------------------- /// If true, the label will be displayed inside the dropdown containerView. Otherwise, the label will be above the dropdown containerView like a normal text input. open var showInlineLabel: Bool = false { didSet { setNeedsUpdate() }} diff --git a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift index b6b51601..92be222d 100644 --- a/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift +++ b/VDS/Components/Icon/ButtonIcon/ButtonIcon.swift @@ -14,7 +14,7 @@ import Combine /// 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, Changeable { +open class ButtonIcon: Control, Changeable, ParentViewProtocol { //-------------------------------------------------- // MARK: - Initializers @@ -109,6 +109,8 @@ open class ButtonIcon: Control, Changeable { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [icon] } + public var onChangeSubscriber: AnyCancellable? ///Badge Indicator object used to render for the ButtonIcon. diff --git a/VDS/Components/InputStepper/InputStepper.swift b/VDS/Components/InputStepper/InputStepper.swift index 6c44b58f..1323bd25 100644 --- a/VDS/Components/InputStepper/InputStepper.swift +++ b/VDS/Components/InputStepper/InputStepper.swift @@ -70,6 +70,12 @@ open class InputStepper: EntryFieldBase { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open override var children: [any ViewProtocol] { + var current = super.children + current.append(contentsOf: [decrementButton, incrementButton, textLabel]) + return current + } + /// If there is a width that is larger than this size's minimumWidth, the input stepper will resize to this width. open var controlWidth: ControlWidth? { get { _controlWidth } diff --git a/VDS/Components/Notification/Notification.swift b/VDS/Components/Notification/Notification.swift index 59d2b78f..0fb05caa 100644 --- a/VDS/Components/Notification/Notification.swift +++ b/VDS/Components/Notification/Notification.swift @@ -16,7 +16,7 @@ import Combine /// experience-wide. @objcMembers @objc(VDSNotification) -open class Notification: View { +open class Notification: View, ParentViewProtocol { //-------------------------------------------------- // MARK: - Initializers @@ -101,6 +101,8 @@ open class Notification: View { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [typeIcon, closeButton, titleLabel, subTitleLabel, primaryButton, secondaryButton] } + /// Icon used for denoting type. open var typeIcon = Icon().with { $0.name = .infoBold diff --git a/VDS/Components/PriceLockup/PriceLockup.swift b/VDS/Components/PriceLockup/PriceLockup.swift index 990e5b76..d36fe7ee 100644 --- a/VDS/Components/PriceLockup/PriceLockup.swift +++ b/VDS/Components/PriceLockup/PriceLockup.swift @@ -11,7 +11,7 @@ import VDSCoreTokens @objcMembers @objc(VDSPriceLockup) -open class PriceLockup: View { +open class PriceLockup: View, ParentViewProtocol { //-------------------------------------------------- // MARK: - Initializers @@ -90,6 +90,7 @@ open class PriceLockup: View { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [priceLockupLabel] } /// If true, the component will render as bold. open var bold: Bool = false { didSet { setNeedsUpdate() } } diff --git a/VDS/Components/RadioBox/RadioBoxItem.swift b/VDS/Components/RadioBox/RadioBoxItem.swift index b8530363..695b1261 100644 --- a/VDS/Components/RadioBox/RadioBoxItem.swift +++ b/VDS/Components/RadioBox/RadioBoxItem.swift @@ -15,7 +15,6 @@ import VDSCoreTokens @objcMembers @objc(VDSRadioBoxItem) open class RadioBoxItem: Control, Changeable, FormFieldable, Groupable, ParentViewProtocol { - public var children: [any ViewProtocol] { [textLabel, subTextLabel, subTextRightLabel, selectorView] } //-------------------------------------------------- // MARK: - Initializers @@ -54,6 +53,8 @@ open class RadioBoxItem: Control, Changeable, FormFieldable, Groupable, ParentVi //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [textLabel, subTextLabel, subTextRightLabel, selectorView] } + open var onChangeSubscriber: AnyCancellable? /// Label used to render the text. diff --git a/VDS/Components/Tabs/Tabs.swift b/VDS/Components/Tabs/Tabs.swift index ac9e7269..fe967338 100644 --- a/VDS/Components/Tabs/Tabs.swift +++ b/VDS/Components/Tabs/Tabs.swift @@ -12,7 +12,7 @@ import VDSCoreTokens /// Tabs are organizational components that group content and allow customers to navigate its display. Use them to separate content when the content is related but doesn’t need to be compared. @objcMembers @objc(VDSTabs) -open class Tabs: View { +open class Tabs: View, ParentViewProtocol { //-------------------------------------------------- // MARK: - Initializers @@ -84,6 +84,8 @@ open class Tabs: View { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { tabViews } + /// A callback when the selectedIndex changes. Passes parameters (tabIndex). open var onTabDidSelect: ((Int) -> Void)? diff --git a/VDS/Components/TextFields/EntryFieldBase.swift b/VDS/Components/TextFields/EntryFieldBase.swift index 0a815e08..8d4aeadc 100644 --- a/VDS/Components/TextFields/EntryFieldBase.swift +++ b/VDS/Components/TextFields/EntryFieldBase.swift @@ -11,7 +11,7 @@ import VDSCoreTokens import Combine /// Base Class used to build out a Input controls. -open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable { +open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable, ParentViewProtocol { //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -155,6 +155,8 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalVali //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [titleLabel, helperLabel, errorLabel, statusIcon] } + /// This is the view that will be wrapped with the border for userInteraction. /// The only subview of this view is the fieldStackView open var containerView = View().with { diff --git a/VDS/Components/TileContainer/TileContainer.swift b/VDS/Components/TileContainer/TileContainer.swift index b00d0388..6c695112 100644 --- a/VDS/Components/TileContainer/TileContainer.swift +++ b/VDS/Components/TileContainer/TileContainer.swift @@ -44,7 +44,7 @@ open class TileContainer: TileContainerBase { } } -open class TileContainerBase: View where PaddingType.ValueType == CGFloat { +open class TileContainerBase: View where PaddingType.ValueType == CGFloat { //-------------------------------------------------- // MARK: - Initializers @@ -122,7 +122,7 @@ open class TileContainerBase: View where //-------------------------------------------------- // MARK: - Public Properties - //-------------------------------------------------- + //-------------------------------------------------- /// This takes an image source url and applies it as a background image. open var backgroundImage: UIImage? { didSet { setNeedsUpdate() } } @@ -340,21 +340,21 @@ open class TileContainerBase: View where open override func touchesBegan(_ touches: Set, with event: UIEvent?) { super.touchesBegan(touches, with: event) - if let onClickSubscriber { + if onClickSubscriber != nil { isHighlighted = true } } open override func touchesEnded(_ touches: Set, with event: UIEvent?) { super.touchesEnded(touches, with: event) - if let onClickSubscriber { + if onClickSubscriber != nil { isHighlighted = false } } open override func touchesCancelled(_ touches: Set, with event: UIEvent?) { super.touchesCancelled(touches, with: event) - if let onClickSubscriber { + if onClickSubscriber != nil { isHighlighted = false } } diff --git a/VDS/Components/Tilelet/Tilelet.swift b/VDS/Components/Tilelet/Tilelet.swift index cb154056..3a6e0150 100644 --- a/VDS/Components/Tilelet/Tilelet.swift +++ b/VDS/Components/Tilelet/Tilelet.swift @@ -17,7 +17,7 @@ import Combine /// function. @objcMembers @objc(VDSTilelet) -open class Tilelet: TileContainerBase { +open class Tilelet: TileContainerBase, ParentViewProtocol { /// Enum used to describe the padding choices used for this component. public enum Padding: String, DefaultValuing, Valuing, CaseIterable { @@ -110,6 +110,8 @@ open class Tilelet: TileContainerBase { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [badge, titleLockup, descriptiveIcon, directionalIcon] } + /// Title lockup positioned in the contentView. open var titleLockup = TitleLockup().with { $0.standardStyleConfiguration = .init(styleConfigurations: [ diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift index 1711939c..ad56813b 100644 --- a/VDS/Components/TitleLockup/TitleLockup.swift +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -14,7 +14,7 @@ import Combine /// with approved built in text size configurations. @objcMembers @objc(VDSTitleLockup) -open class TitleLockup: View { +open class TitleLockup: View, ParentViewProtocol { //-------------------------------------------------- // MARK: - Initializers @@ -62,6 +62,8 @@ open class TitleLockup: View { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [eyebrowLabel, titleLabel, subTitleLabel] } + /// Aligns TitleLockup's subcomponent's text open var textAlignment: TextAlignment = .left { didSet { setNeedsUpdate() } } diff --git a/VDS/Components/Toggle/Toggle.swift b/VDS/Components/Toggle/Toggle.swift index 304b18ce..8c11004b 100644 --- a/VDS/Components/Toggle/Toggle.swift +++ b/VDS/Components/Toggle/Toggle.swift @@ -14,7 +14,7 @@ import Combine /// or turn off a single option, setting or function. @objcMembers @objc(VDSToggle) -open class Toggle: Control, Changeable, FormFieldable { +open class Toggle: Control, Changeable, FormFieldable, ParentViewProtocol { //-------------------------------------------------- // MARK: - Initializers @@ -90,6 +90,8 @@ open class Toggle: Control, Changeable, FormFieldable { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [toggleView, label] } + open var onChangeSubscriber: AnyCancellable? /// Actual toggle used in this component. diff --git a/VDS/Components/Tooltip/TooltipDialog.swift b/VDS/Components/Tooltip/TooltipDialog.swift index bb6b5653..bbccb8f5 100644 --- a/VDS/Components/Tooltip/TooltipDialog.swift +++ b/VDS/Components/Tooltip/TooltipDialog.swift @@ -11,7 +11,7 @@ import VDSCoreTokens @objcMembers @objc(VDSTooltipDialog) -open class TooltipDialog: View, UIScrollViewDelegate { +open class TooltipDialog: View, UIScrollViewDelegate, ParentViewProtocol { //-------------------------------------------------- // MARK: - Initializers @@ -55,6 +55,8 @@ open class TooltipDialog: View, UIScrollViewDelegate { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- + open var children: [any ViewProtocol] { [titleLabel, contentLabel] } + open var tooltipModel = Tooltip.TooltipModel() { didSet { setNeedsUpdate() } } open var titleLabel = Label().with { label in diff --git a/VDS/Protocols/ViewProtocol.swift b/VDS/Protocols/ViewProtocol.swift index b282062a..e38d5df4 100644 --- a/VDS/Protocols/ViewProtocol.swift +++ b/VDS/Protocols/ViewProtocol.swift @@ -42,15 +42,15 @@ extension ViewProtocol { public func setNeedsUpdate() { if shouldUpdateView { shouldUpdateView = false - //let parent = self as? ParentViewProtocol - //parent?.children.forEach{ $0.shouldUpdateView = false } + let parent = self as? ParentViewProtocol + parent?.children.forEach{ $0.shouldUpdateView = false } updateView() updateAccessibility() -// parent?.children.forEach{ -// $0.updateView() -// $0.updateAccessibility() -// $0.shouldUpdateView = true -// } + parent?.children.forEach{ + $0.updateView() + $0.updateAccessibility() + $0.shouldUpdateView = true + } shouldUpdateView = true } }