Merge branch 'develop' into feature/Table

# Conflicts:
#	VDSSample.xcodeproj/project.pbxproj

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2024-06-07 09:37:48 -05:00
commit 8fb99a7880
26 changed files with 1926 additions and 209 deletions

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:workspaceSettings.xcconfig">
</FileRef>
<FileRef
location = "container:VDSSample.xcodeproj">
</FileRef>

View File

@ -35,6 +35,7 @@
1808BEBE2BA4479500129230 /* CarouselScrollbarViewConttroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1808BEBD2BA4479500129230 /* CarouselScrollbarViewConttroller.swift */; };
1832AC5B2BA1347B008AE476 /* BreadcrumbsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1832AC5A2BA1347B008AE476 /* BreadcrumbsViewController.swift */; };
186D13CD2BBA990800986B53 /* DropdownSelectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 186D13CC2BBA990800986B53 /* DropdownSelectViewController.swift */; };
18A3F1302BD9332500498E4A /* CalendarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18A3F12F2BD9332500498E4A /* CalendarViewController.swift */; };
440B84CC2BD8E98B004A732A /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 440B84CB2BD8E98B004A732A /* TableViewController.swift */; };
445BA07A29C088470036A7C5 /* NotificationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 445BA07929C088470036A7C5 /* NotificationViewController.swift */; };
44604AD929CE1CF900E62B51 /* LineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD829CE1CF900E62B51 /* LineViewController.swift */; };
@ -44,6 +45,7 @@
EA0D1C312A673F3500E5C127 /* RadioButtonViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C302A673F3500E5C127 /* RadioButtonViewController.swift */; };
EA0D1C332A673FD400E5C127 /* RadioButtonItemViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0D1C322A673FD400E5C127 /* RadioButtonItemViewController.swift */; };
EA0FC2C12912DC5500DF80B4 /* TextLinkCaretViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0FC2C02912DC5500DF80B4 /* TextLinkCaretViewController.swift */; };
EA1758462BC8893700A5C0D9 /* DatePickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1758452BC8893700A5C0D9 /* DatePickerViewController.swift */; };
EA21C5D82B600E4200CFC139 /* VDSTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA21C5D72B600E4200CFC139 /* VDSTokens.xcframework */; };
EA21C5D92B600E4200CFC139 /* VDSTokens.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EA21C5D72B600E4200CFC139 /* VDSTokens.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
EA297A682A02F5320031ED56 /* TableViewTestController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA297A672A02F5320031ED56 /* TableViewTestController.swift */; };
@ -130,6 +132,7 @@
1808BEBD2BA4479500129230 /* CarouselScrollbarViewConttroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselScrollbarViewConttroller.swift; sourceTree = "<group>"; };
1832AC5A2BA1347B008AE476 /* BreadcrumbsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BreadcrumbsViewController.swift; sourceTree = "<group>"; };
186D13CC2BBA990800986B53 /* DropdownSelectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropdownSelectViewController.swift; sourceTree = "<group>"; };
18A3F12F2BD9332500498E4A /* CalendarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarViewController.swift; sourceTree = "<group>"; };
440B84CB2BD8E98B004A732A /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = "<group>"; };
445BA07929C088470036A7C5 /* NotificationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationViewController.swift; sourceTree = "<group>"; };
44604AD829CE1CF900E62B51 /* LineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineViewController.swift; sourceTree = "<group>"; };
@ -139,6 +142,7 @@
EA0D1C302A673F3500E5C127 /* RadioButtonViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonViewController.swift; sourceTree = "<group>"; };
EA0D1C322A673FD400E5C127 /* RadioButtonItemViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonItemViewController.swift; sourceTree = "<group>"; };
EA0FC2C02912DC5500DF80B4 /* TextLinkCaretViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLinkCaretViewController.swift; sourceTree = "<group>"; };
EA1758452BC8893700A5C0D9 /* DatePickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatePickerViewController.swift; sourceTree = "<group>"; };
EA21C5D72B600E4200CFC139 /* VDSTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSTokens.xcframework; path = SharedFrameworks/VDSTokens.xcframework; sourceTree = "<group>"; };
EA297A672A02F5320031ED56 /* TableViewTestController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewTestController.swift; sourceTree = "<group>"; };
EA3C3B99289966EF000CA526 /* VDSSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VDSSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -159,6 +163,8 @@
EA5E305B295111050082B959 /* TileletViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileletViewController.swift; sourceTree = "<group>"; };
EA5F86CD2A1E863F00BC83E4 /* TabsContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsContainerViewController.swift; sourceTree = "<group>"; };
EA6642962BD1B2E700D81DC4 /* ColorPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerView.swift; sourceTree = "<group>"; };
EA78C7A42C0E64A800430AD1 /* vds-sample-dev.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "vds-sample-dev.xcconfig"; sourceTree = "<group>"; };
EA78C7A52C0E64CC00430AD1 /* vds-sample.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "vds-sample.xcconfig"; sourceTree = "<group>"; };
EA81410D2A0ED8DC004F60D2 /* ButtonIconViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonIconViewController.swift; sourceTree = "<group>"; };
EA89201828B56DF5006B9984 /* RadioBoxGroupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioBoxGroupViewController.swift; sourceTree = "<group>"; };
EA89203F28B66CE2006B9984 /* ScrollViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScrollViewController.swift; sourceTree = "<group>"; };
@ -319,10 +325,12 @@
EAB5FEEE2927E28400998C17 /* ButtonGroupViewController.swift */,
EA81410D2A0ED8DC004F60D2 /* ButtonIconViewController.swift */,
5FC35BE828D5235A004EBEAC /* ButtonViewController.swift */,
18A3F12F2BD9332500498E4A /* CalendarViewController.swift */,
1808BEBD2BA4479500129230 /* CarouselScrollbarViewConttroller.swift */,
EA89204D28B67332006B9984 /* CheckBoxGroupViewController.swift */,
EAF7F09B2899B92400B287F5 /* CheckboxItemViewController.swift */,
EA0D1C2E2A66CFE900E5C127 /* CheckboxViewController.swift */,
EA1758452BC8893700A5C0D9 /* DatePickerViewController.swift */,
186D13CC2BBA990800986B53 /* DropdownSelectViewController.swift */,
EA985C00296CC21C00F2FF2E /* IconViewController.swift */,
EAA5EEAC28EB6924003B3210 /* InputFieldViewController.swift */,
@ -356,6 +364,8 @@
children = (
EAF7F0C4289DA24F00B287F5 /* Artifactory */,
EAF7F0792899698800B287F5 /* Resources */,
EA78C7A42C0E64A800430AD1 /* vds-sample-dev.xcconfig */,
EA78C7A52C0E64CC00430AD1 /* vds-sample.xcconfig */,
);
path = "Supporting Files";
sourceTree = "<group>";
@ -518,6 +528,7 @@
EA3C3BB428996775000CA526 /* PickerBase.swift in Sources */,
EAB2376C29E9E74900AABE9A /* TrailingTooltipLabelViewController.swift in Sources */,
EAB1D2C928AAAA1D00DAE764 /* BaseViewController.swift in Sources */,
EA1758462BC8893700A5C0D9 /* DatePickerViewController.swift in Sources */,
EAD062AD2A3B86950015965D /* BadgeIndicatorViewController.swift in Sources */,
EA5E305C295111050082B959 /* TileletViewController.swift in Sources */,
EAD062A32A3913920015965D /* DropShawdowViewController.swift in Sources */,
@ -532,6 +543,7 @@
71B23C312B921D740027F7D9 /* PaginationViewController.swift in Sources */,
EAF7F09C2899B92400B287F5 /* CheckboxItemViewController.swift in Sources */,
EA0D1C2F2A66CFE900E5C127 /* CheckboxViewController.swift in Sources */,
18A3F1302BD9332500498E4A /* CalendarViewController.swift in Sources */,
EA596ABA2A16B2ED00300C4B /* TabsViewController.swift in Sources */,
EA89204E28B67332006B9984 /* CheckBoxGroupViewController.swift in Sources */,
EAA5EEAD28EB6924003B3210 /* InputFieldViewController.swift in Sources */,
@ -575,6 +587,7 @@
/* Begin XCBuildConfiguration section */
EA3C3BAB289966F1000CA526 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = EA78C7A42C0E64A800430AD1 /* vds-sample-dev.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
@ -635,6 +648,7 @@
};
EA3C3BAC289966F1000CA526 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = EA78C7A52C0E64CC00430AD1 /* vds-sample.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
@ -689,6 +703,7 @@
};
EA3C3BAE289966F1000CA526 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = EA78C7A42C0E64A800430AD1 /* vds-sample-dev.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@ -696,7 +711,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 60;
CURRENT_PROJECT_VERSION = 65;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = FCMA4QKS77;
GENERATE_INFOPLIST_FILE = YES;
@ -724,6 +739,7 @@
};
EA3C3BAF289966F1000CA526 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = EA78C7A52C0E64CC00430AD1 /* vds-sample.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
@ -731,7 +747,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 60;
CURRENT_PROJECT_VERSION = 65;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = FCMA4QKS77;
GENERATE_INFOPLIST_FILE = YES;
@ -759,6 +775,7 @@
};
EAF7F0C0289DA16000B287F5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = EA78C7A42C0E64A800430AD1 /* vds-sample-dev.xcconfig */;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = FCMA4QKS77;
@ -768,6 +785,7 @@
};
EAF7F0C1289DA16000B287F5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = EA78C7A52C0E64CC00430AD1 /* vds-sample.xcconfig */;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = FCMA4QKS77;
@ -777,6 +795,7 @@
};
EAF7F0D0289DA44300B287F5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = EA78C7A42C0E64A800430AD1 /* vds-sample-dev.xcconfig */;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = FCMA4QKS77;
@ -786,6 +805,7 @@
};
EAF7F0D1289DA44300B287F5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = EA78C7A52C0E64CC00430AD1 /* vds-sample.xcconfig */;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = FCMA4QKS77;

View File

@ -31,9 +31,12 @@ public class ColorPickerView<EnumType>: UIStackView {
$0.text = "Select"
}
public init(with pickerType: EnumType, onClick: @escaping (ColorPickerView)->Void) {
public init(with pickerType: EnumType, color: UIColor? = nil, onClick: @escaping (ColorPickerView)->Void) {
self.pickerType = pickerType
super.init(frame: .zero)
if let color {
selectedColor = color
}
setup()
button.onClick = { _ in onClick(self) }
}

File diff suppressed because one or more lines are too long

View File

@ -134,8 +134,15 @@ public class PickerSelectorView<EnumType: RawRepresentable>: UIStackView, Picker
}
private func title(for row: Int) -> String {
guard let item = items[row].rawValue as? String else { return "" }
return item
let item = items[row]
if let item = item as? CustomStringConvertible {
return item.description
} else if let raw = item.rawValue as? String {
return raw
} else {
return ""
}
}
}

View File

@ -1,15 +0,0 @@
{
"images" : [
{
"filename" : "external-link.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}

View File

@ -1 +0,0 @@
<svg id="f5a11f6b-f49f-40e8-9fef-b62ba7c1147d" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 21.6 21.6"><path d="M19.8,1.8V8.2H18.68V3.72L12.56,9.84l-.8-.8,6.12-6.11H13.4V1.8ZM15.3,18.68H2.93V6.3H12.8l1-1.12H1.8V19.8H16.43V7.8l-1.13,1Z"/></svg>

Before

Width:  |  Height:  |  Size: 266 B

View File

@ -0,0 +1,11 @@
//
// vds-sample-dev.xcconfig
// VDSSample
//
// Created by Matt Bruce on 6/3/24.
//
// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974
#include? "../../workspaceSettings.xcconfig"

View File

@ -0,0 +1,11 @@
//
// vds-sample.xcconfig
// VDSSample
//
// Created by Matt Bruce on 6/3/24.
//
// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974
#include? "../../workspaceSettings.xcconfig"

View File

@ -52,6 +52,7 @@ class BadgeIndicatorViewController: BaseViewController<BadgeIndicator> {
var textField = NumericField()
var leadingCharacterTextField = TextField()
var accessibilityTextField = TextField()
var trailingTextField = TextField()
var hideDotSwitch = Toggle()
var hideBorderSwitch = Toggle()
@ -85,7 +86,8 @@ class BadgeIndicatorViewController: BaseViewController<BadgeIndicator> {
addFormRow(label: "Border Light", view: borderColorLightPickerSelectorView)
addFormRow(label: "Border Dark", view: borderColorDarkPickerSelectorView)
addFormRow(label: "Size", view: textSizePickerSelectorView)
addFormRow(label: "Accessiblity Text", view: accessibilityTextField)
dotForm.addFormRow(label: "Hide Dot", view: hideDotSwitch)
dotForm.addFormRow(label: "Dot Size", view: dotSizeTextField)
numberedForm.addFormRow(label: "Leading Character", view: leadingCharacterTextField)
@ -122,6 +124,11 @@ class BadgeIndicatorViewController: BaseViewController<BadgeIndicator> {
self?.component.trailingText = text
}.store(in: &subscribers)
accessibilityTextField.textPublisher
.sink { [weak self] text in
self?.component.accessibilityText = text
}.store(in: &subscribers)
heightTextField
.numberPublisher
.sink { [weak self] number in

View File

@ -43,7 +43,7 @@ public class FormSection: UIStackView {
}
@discardableResult
open func addFormRow(label: String, view: UIView) -> UIView {
open func addFormRow(label: String, tooltip: Tooltip.TooltipModel? = nil, view: UIView) -> UIView {
let formRow = UIStackView().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.alignment = .fill
@ -56,6 +56,10 @@ public class FormSection: UIStackView {
$0.tag = 1
$0.text = label
$0.textStyle = .bodyLarge
$0.numberOfLines = 0
if let tooltip {
$0.addTooltip(tooltip)
}
}
formRow.addArrangedSubview(label)
@ -333,10 +337,10 @@ public class BaseViewController<Component: UIView>: UIViewController, Initable ,
}
@discardableResult
open func addFormRow(label: String, view: UIView) -> UIView {
return formStackView.addFormRow(label: label, view: view)
open func addFormRow(label: String, tooltip: Tooltip.TooltipModel? = nil, view: UIView) -> UIView {
return formStackView.addFormRow(label: label,tooltip: tooltip, view: view)
}
var activeTextField: UITextField?
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.

View File

@ -18,18 +18,20 @@ class BreadcrumbsViewController: BaseViewController<Breadcrumbs> {
var selectedCrumbLabel = Label().with { $0.textStyle = .boldBodyMedium }
var allBreadcrumbs: [Breadcrumbs.BreadcrumbItemModel] = [
.init(text: "Home"),
.init(text: "Support", enabeled: false),
.init(text: "Support"),
.init(text: "Service & Apps"),
.init(text: "My Verizon"),
.init(text: "Bill"),
.init(text: "Mobile Billing & Payments"),
.init(text: "Billing statement FAQs", selected: true)
]
var some: [Breadcrumbs.BreadcrumbItemModel] = [
.init(text: "Plans"),
.init(text: "Upgrade Plan"),
.init(text: "Billing Statement Frequently Asked Questions About Stuff You don't want to see", selected: true)
.init(text: "Home"),
.init(text: "Support"),
.init(text: "Service & Apps"),
.init(text: "My Verizon"),
.init(text: "Bill"),
.init(text: "Billing Statement Frequently Asked Questions to cause word wrap", selected: true)
]
override func viewDidLoad() {
@ -47,7 +49,7 @@ class BreadcrumbsViewController: BaseViewController<Breadcrumbs> {
super.setupForm()
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addFormRow(label: "Last Crumb Selected", view: selectedSwitch)
addFormRow(label: "Large Sample", view: sampleSwitch)
addFormRow(label: "No Long Breadcrumbs", view: sampleSwitch)
selectedSwitch.onChange = { [weak self] sender in
guard let self else { return }
@ -96,7 +98,7 @@ extension BreadcrumbsViewController: ComponentSampleable {
let component = Self.makeComponent()
component.breadcrumbModels = [
.init(text: "Home"),
.init(text: "Support", enabeled: false),
.init(text: "Support"),
.init(text: "Service & Apps"),
.init(text: "My Verizon"),
.init(text: "Bill"),

View File

@ -241,12 +241,12 @@ class ButtonIconViewController: BaseViewController<ButtonIcon> {
func setBadgeIndicatorModel() {
if variantOneSwitch.isOn {
if badgeIndicatorSwitch.isOn {
component.badgeIndicatorModel = ButtonIcon.BadgeIndicatorModel(kind: BadgeIndicator.Kind.simple, size: BadgeIndicator.Size.small)
component.badgeIndicatorModel = ButtonIcon.BadgeIndicatorModel(kind: BadgeIndicator.Kind.simple, size: BadgeIndicator.Size.small, accessibilityText: "Custom Text would go here by the developer")
} else {
component.badgeIndicatorModel = nil
}
} else {
component.badgeIndicatorModel = ButtonIcon.BadgeIndicatorModel(kind: BadgeIndicator.Kind.numbered, expandDirection: badgeIndicatorExpandDirectionPickerSelectorView.selectedItem, size: BadgeIndicator.Size.small, maximumDigits: BadgeIndicator.MaximumDigits.two, number: 999)
component.badgeIndicatorModel = ButtonIcon.BadgeIndicatorModel(kind: BadgeIndicator.Kind.numbered, expandDirection: badgeIndicatorExpandDirectionPickerSelectorView.selectedItem, size: BadgeIndicator.Size.small, maximumDigits: BadgeIndicator.MaximumDigits.two, number: 999, accessibilityText: "Custom Text would go here by the developer for the 999")
}
}
}

View File

@ -0,0 +1,305 @@
//
// CalendarViewController.swift
// VDSSample
//
// Created by Kanamarlapudi, Vasavi on 19/04/24.
//
import Foundation
import UIKit
import VDS
import Combine
import VDSTokens
class CalendarViewController: BaseViewController<CalendarBase> {
let label = Label()
var containerBorderSwitch = Toggle()
var hideCurrentDateIndicatorSwitch = Toggle()
var transparentBgSwitch = Toggle()
var indicatorOneSwitch = Toggle()
var indicatorTwoSwitch = Toggle()
var indicatorThreeSwitch = Toggle()
var clearActiveDatesSwitch = Toggle()
var clearInactiveDatesSwitch = Toggle()
var activeDatesField = TextField()
var inactiveDatesField = TextField()
var legendOneField = TextField()
var legendTwoField = TextField()
var legendThreeField = TextField()
private var minDatePicker: UIDatePicker = UIDatePicker()
private var maxDatePicker: UIDatePicker = UIDatePicker()
private var indicatorOnePicker: UIDatePicker = UIDatePicker()
private var indicatorTwoPicker: UIDatePicker = UIDatePicker()
private var indicatorThreePicker: UIDatePicker = UIDatePicker()
private var activeDatePicker: UIDatePicker = UIDatePicker().with { $0.datePickerMode = .date }
private var inactiveDatePicker: UIDatePicker = UIDatePicker().with { $0.datePickerMode = .date }
var indicators: [CalendarBase.CalendarIndicatorModel] = []
let indicatorOnePickerTag = 1
let indicatorTwoPickerTag = 2
let indicatorThreePickerTag = 3
let minDatePickerTag = 4
let maxDatePickerTag = 5
let activeDatePickerTag = 6
let inactiveDatePickerTag = 7
override func viewDidLoad() {
super.viewDidLoad()
addContentTopView(view: component)
component.minDate = Date().startOfMonth
component.maxDate = Date().endOfMonth
component.onChange = { [weak self] control in
self?.label.text = DateFormatter.localizedString(from: control.selectedDate, dateStyle: .short, timeStyle: .none)
}
minDatePicker.date = component.minDate
maxDatePicker.date = component.maxDate
setupPicker()
setupModel()
}
override func setupForm() {
super.setupForm()
configurePicker(indicatorOnePicker)
indicatorOnePicker.tag = indicatorOnePickerTag
configurePicker(indicatorTwoPicker)
indicatorTwoPicker.tag = indicatorTwoPickerTag
configurePicker(indicatorThreePicker)
indicatorThreePicker.tag = indicatorThreePickerTag
configurePicker(minDatePicker)
minDatePicker.tag = minDatePickerTag
configurePicker(maxDatePicker)
maxDatePicker.tag = maxDatePickerTag
configurePicker(activeDatePicker)
activeDatePicker.tag = activeDatePickerTag
configurePicker(inactiveDatePicker)
inactiveDatePicker.tag = inactiveDatePickerTag
indicators = [
.init(label: "Due Date", date: indicatorOnePicker.date),
.init(label: "Auto Pay", date: indicatorTwoPicker.date),
.init(label: "Scheduled", date: indicatorThreePicker.date)
]
//add form rows
addFormRow(label: "onChange", view: label)
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addFormRow(label: "Hide Container Border", view: containerBorderSwitch)
addFormRow(label: "Hide Current Date Indicator", view: hideCurrentDateIndicatorSwitch)
addFormRow(label: "Min Date", view: minDatePicker)
addFormRow(label: "Max Date", view: maxDatePicker)
addFormRow(label: "Transparent Background", view: transparentBgSwitch)
addFormRow(label: "Active Dates", view: activeDatesField)
addFormRow(label: "Select ActiveDate", view: activeDatePicker)
addFormRow(label: "Clear Active Dates", view: clearActiveDatesSwitch)
addFormRow(label: "Inactive Dates", view: inactiveDatesField)
addFormRow(label: "Select InActiveDate", view: inactiveDatePicker)
addFormRow(label: "Clear Inactive Dates", view: clearInactiveDatesSwitch)
addFormRow(label: "Indicator One", view: indicatorOneSwitch)
addFormRow(label: "Indicator Two", view: indicatorTwoSwitch)
addFormRow(label: "Indicator Three", view: indicatorThreeSwitch)
addFormRow(label: "Legend One", view: legendOneField)
addFormRow(label: "Legend Two", view: legendTwoField)
addFormRow(label: "Legend Three", view: legendThreeField)
addFormRow(label: "Indicator One Date", view: indicatorOnePicker)
addFormRow(label: "Indicator Two Date", view: indicatorTwoPicker)
addFormRow(label: "Indicator Three Date", view: indicatorThreePicker)
activeDatesField.isUserInteractionEnabled = false
inactiveDatesField.isUserInteractionEnabled = false
activeDatesField.isEnabled = false
inactiveDatesField.isEnabled = false
containerBorderSwitch.onChange = { [weak self] sender in
guard let self else { return }
component.hideContainerBorder = sender.isOn
}
hideCurrentDateIndicatorSwitch.onChange = { [weak self] sender in
guard let self else { return }
component.hideCurrentDateIndicator = sender.isOn
}
transparentBgSwitch.onChange = { [weak self] sender in
guard let self else { return }
component.transparentBackground = sender.isOn
}
clearActiveDatesSwitch.onChange = { [weak self] sender in
guard let self else { return }
if sender.isOn {
activeDatesField.text = ""
component.activeDates = []
}
}
clearInactiveDatesSwitch.onChange = { [weak self] sender in
guard let self else { return }
if sender.isOn {
inactiveDatesField.text = ""
component.inactiveDates = []
}
}
legendOneField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorOnePicker.date, index: 0)
}.store(in: &subscribers)
legendTwoField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorTwoPicker.date, index: 1)
}.store(in: &subscribers)
legendThreeField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorThreePicker.date, index: 2)
}.store(in: &subscribers)
indicatorOneSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
component.indicators.removeAll()
} else {
self.setIndicatorsData()
}
}
indicatorTwoSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
if component.indicators.count > 2 {
component.indicators.removeLast()
component.indicators.removeLast()
} else if component.indicators.count == 2 {
component.indicators.removeLast()
}
} else {
self.setIndicatorsData()
}
}
indicatorThreeSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
if component.indicators.count > 2 {
component.indicators.removeLast()
}
} else {
self.setIndicatorsData()
}
}
}
func setupPicker(){
surfacePickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.surface = item
self?.contentTopView.backgroundColor = item.color
}
}
func setupModel() {
let calendar = Calendar.current
let indicatorDate = calendar.startOfDay(for: calendar.date(byAdding: .day, value: 1, to: Date())!)
component.indicators = indicators
legendOneField.text = "Due Date"
legendTwoField.text = "Auto Pay"
legendThreeField.text = "Scheduled"
indicatorOneSwitch.isOn = true
indicatorTwoSwitch.isOn = true
indicatorThreeSwitch.isOn = true
hideCurrentDateIndicatorSwitch.isOn = false
indicatorOnePicker.date = indicatorDate
indicatorTwoPicker.date = indicatorDate
indicatorThreePicker.date = indicatorDate
updateIndicatorData(label: legendOneField.text ?? "", date: indicatorOnePicker.date, index: 0)
updateIndicatorData(label: legendTwoField.text ?? "", date: indicatorTwoPicker.date, index: 1)
updateIndicatorData(label: legendThreeField.text ?? "", date: indicatorThreePicker.date, index: 2)
}
func updateIndicatorData(label: String = "", date: Date?, index:Int) {
indicators[index].label = label
indicators[index].date = date ?? Date()
setIndicatorsData()
}
func setIndicatorsData() {
if indicatorOneSwitch.isOn && indicatorTwoSwitch.isOn && indicatorThreeSwitch.isOn {
component.indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
.init(label: self.legendTwoField.text ?? "", date: indicatorTwoPicker.date),
.init(label: self.legendThreeField.text ?? "", date: indicatorThreePicker.date)
]
} else if indicatorOneSwitch.isOn && indicatorTwoSwitch.isOn && !indicatorThreeSwitch.isOn {
component.indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
.init(label: self.legendTwoField.text ?? "", date: indicatorTwoPicker.date),
]
} else if indicatorOneSwitch.isOn && !indicatorTwoSwitch.isOn {
component.indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
]
}
}
func configurePicker(_ sender:UIDatePicker) {
// Set some of UIDatePicker properties
sender.timeZone = NSTimeZone.local
sender.backgroundColor = UIColor.white
// Add an event to call onDidChangeDate function when value is changed.
sender.addTarget(self, action: #selector(self.datePickerValueChanged(_:)), for: .valueChanged)
}
@objc func datePickerValueChanged(_ sender: UIDatePicker){
switch sender.tag {
case indicatorOnePickerTag:
updateIndicatorData(label: legendOneField.text ?? "", date: sender.date, index: 0)
case indicatorTwoPickerTag:
updateIndicatorData(label: legendTwoField.text ?? "", date: sender.date, index: 1)
case indicatorThreePickerTag:
updateIndicatorData(label: legendThreeField.text ?? "", date: sender.date, index: 2)
case minDatePickerTag:
component.minDate = sender.date
case maxDatePickerTag:
component.maxDate = sender.date
case activeDatePickerTag:
component.activeDates.append(sender.date)
var text = activeDatesField.text
if let textEmpty = text?.isEmpty, textEmpty == true {
text?.append("")
} else {
text?.append(", ")
}
text?.append("\(self.getSelectedDate(with: sender.date))")
clearActiveDatesSwitch.isOn = false
activeDatesField.text = text
case inactiveDatePickerTag:
component.inactiveDates.append(sender.date)
var text = inactiveDatesField.text
if let textEmpty = text?.isEmpty, textEmpty == true {
text?.append("")
} else {
text?.append(", ")
}
text?.append("\(self.getSelectedDate(with: sender.date))")
clearInactiveDatesSwitch.isOn = false
inactiveDatesField.text = text
default: break
}
}
func getSelectedDate(with date:Date) -> String {
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy"
let day: String = dateFormatter.string(from: date)
return day
}
}

View File

@ -0,0 +1,453 @@
//
// DatePickerViewController.swift
// VDSSample
//
// Created by Matt Bruce on 4/11/24.
//
import Foundation
import VDS
import UIKit
class DatePickerViewController: BaseViewController<DatePicker> {
// Datepicker
var label = Label()
var disabledSwitch = Toggle()
var requiredSwitch = Toggle()
var labelTextField = TextField()
var errorTextField = TextField()
var helperTextField = TextField()
var inlineLabelSwitch = Toggle()
var readonlySwitch = Toggle()
var transparentBgSwitch = Toggle()
var errorSwitch = Toggle()
var widthTextField = NumericField()
var tooltipTitleTextField = TextField()
var tooltipContentTextField = TextField()
lazy var dateFormatPickerSelectorView = {
PickerSelectorView(title: "shortNumeric",
picker: self.picker,
items: DatePicker.DateFormat.allCases )
}()
// Calendar
//props
var indicators: [CalendarBase.CalendarIndicatorModel] = []
var activeDates: [Date] = []
var inactiveDates: [Date] = []
var minDate: Date = Date().startOfMonth
var maxDate: Date = Date().endOfMonth
//form
var containerBorderSwitch = Toggle()
var hideCurrentDateIndicatorSwitch = Toggle()
var indicatorOneSwitch = Toggle()
var indicatorTwoSwitch = Toggle()
var indicatorThreeSwitch = Toggle()
var clearActiveDatesSwitch = Toggle()
var clearInactiveDatesSwitch = Toggle()
var activeDatesField = TextField()
var inactiveDatesField = TextField()
var legendOneField = TextField()
var legendTwoField = TextField()
var legendThreeField = TextField()
private var minDatePicker: UIDatePicker = UIDatePicker()
private var maxDatePicker: UIDatePicker = UIDatePicker()
private var indicatorOnePicker: UIDatePicker = UIDatePicker()
private var indicatorTwoPicker: UIDatePicker = UIDatePicker()
private var indicatorThreePicker: UIDatePicker = UIDatePicker()
private var activeDatePicker: UIDatePicker = UIDatePicker().with { $0.datePickerMode = .date }
private var inactiveDatePicker: UIDatePicker = UIDatePicker().with { $0.datePickerMode = .date }
let indicatorOnePickerTag = 1
let indicatorTwoPickerTag = 2
let indicatorThreePickerTag = 3
let minDatePickerTag = 4
let maxDatePickerTag = 5
let activeDatePickerTag = 6
let inactiveDatePickerTag = 7
override func viewDidLoad() {
super.viewDidLoad()
addContentTopView(view: component)
setupModel()
setupPicker()
setupCalendar()
}
override func setupForm(){
addFormRow(label: "onChange", view: label)
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addFormRow(label: "Disabled", view: disabledSwitch)
addFormRow(label: "Read Only", view: readonlySwitch)
addFormRow(label: "Required", view: requiredSwitch)
addFormRow(label: "Transparent Background", view: transparentBgSwitch)
addFormRow(label: "Date Format", view: dateFormatPickerSelectorView)
addFormRow(label: "Label Text", view: labelTextField)
addFormRow(label: "Helper Text", view: helperTextField)
addFormRow(label: "Error", view: .makeWrapper(for: errorSwitch))
addFormRow(label: "Error Text", view: errorTextField)
addFormRow(label: "Width", view: widthTextField)
addFormRow(label: "ToolTip Title", view: tooltipTitleTextField)
addFormRow(label: "ToolTip Content", view: tooltipContentTextField)
append(section: getCalendarSection())
disabledSwitch.onChange = { [weak self] sender in
self?.component.isEnabled = !sender.isOn
}
requiredSwitch.onChange = { [weak self] sender in
self?.component.isRequired = sender.isOn
}
readonlySwitch.onChange = { [weak self] sender in
self?.component.isReadOnly = sender.isOn
}
transparentBgSwitch.onChange = { [weak self] sender in
self?.component.transparentBackground = sender.isOn
}
errorSwitch
.publisher(for: .valueChanged)
.sink { [weak self] sender in
guard let self else { return }
component.showError = sender.isOn
if component.showError != sender.isOn {
self.errorSwitch.isOn = self.component.showError
}
}.store(in: &subscribers)
labelTextField
.textPublisher
.sink { [weak self] text in
self?.component.labelText = text
}.store(in: &subscribers)
helperTextField
.textPublisher
.sink { [weak self] text in
self?.component.helperText = text
}.store(in: &subscribers)
errorTextField
.textPublisher
.sink { [weak self] text in
self?.component.errorText = text
}.store(in: &subscribers)
widthTextField
.numberPublisher
.sink { [weak self] number in
self?.component.width = number?.cgFloatValue
}.store(in: &subscribers)
tooltipTitleTextField
.textPublisher
.sink { [weak self] text in
self?.updateTooltip()
}.store(in: &subscribers)
tooltipContentTextField
.textPublisher
.sink { [weak self] text in
self?.updateTooltip()
}.store(in: &subscribers)
}
func setupModel() {
component.selectedDate = Calendar.current.date(byAdding: .day, value: -5, to: Date())
component.labelText = "Date"
component.helperText = "Pick a date for your needs."
component.errorText = "Enter a date."
component.tooltipModel = .init(title: "Check your date.", content:"Here is the content for your date component")
component.onChange = { [weak self] control in
self?.label.text = DateFormatter.localizedString(from: control.selectedDate!, dateStyle: .short, timeStyle: .none)
}
//setup UI
disabledSwitch.isOn = !component.isEnabled
requiredSwitch.isOn = component.isRequired
surfacePickerSelectorView.text = component.surface.rawValue
labelTextField.text = component.labelText
helperTextField.text = component.helperText
readonlySwitch.isOn = false
transparentBgSwitch.isOn = false
errorSwitch.isOn = component.showError
errorTextField.text = component.errorText
tooltipTitleTextField.text = component.tooltipModel?.title
tooltipContentTextField.text = component.tooltipModel?.content
}
func setupPicker() {
surfacePickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.surface = item
self?.contentTopView.backgroundColor = item.color
}
dateFormatPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.dateFormat = item
}
}
func updateTooltip() {
let title = tooltipTitleTextField.text ?? ""
let content = tooltipContentTextField.text ?? ""
component.tooltipModel = !title.isEmpty || !content.isEmpty ? .init(title: title,
content: content) : nil
}
}
extension DatePickerViewController {
func getCalendarSection() -> FormSection {
let section = FormSection()
section.title = "Calendar Options"
section.addFormRow(label: "Hide Container Border", view: containerBorderSwitch)
section.addFormRow(label: "Hide Current Date Indicator", view: hideCurrentDateIndicatorSwitch)
section.addFormRow(label: "Min Date", view: minDatePicker)
section.addFormRow(label: "Max Date", view: maxDatePicker)
section.addFormRow(label: "Active Dates", view: activeDatesField)
section.addFormRow(label: "Select ActiveDate", view: activeDatePicker)
section.addFormRow(label: "Clear Active Dates", view: clearActiveDatesSwitch)
section.addFormRow(label: "Inactive Dates", view: inactiveDatesField)
section.addFormRow(label: "Select InActiveDate", view: inactiveDatePicker)
section.addFormRow(label: "Clear Inactive Dates", view: clearInactiveDatesSwitch)
section.addFormRow(label: "Indicator One", view: indicatorOneSwitch)
section.addFormRow(label: "Indicator Two", view: indicatorTwoSwitch)
section.addFormRow(label: "Indicator Three", view: indicatorThreeSwitch)
section.addFormRow(label: "Legend One", view: legendOneField)
section.addFormRow(label: "Legend Two", view: legendTwoField)
section.addFormRow(label: "Legend Three", view: legendThreeField)
section.addFormRow(label: "Indicator One Date", view: indicatorOnePicker)
section.addFormRow(label: "Indicator Two Date", view: indicatorTwoPicker)
section.addFormRow(label: "Indicator Three Date", view: indicatorThreePicker)
containerBorderSwitch.onChange = { [weak self] sender in
self?.updateCalendarModel()
}
hideCurrentDateIndicatorSwitch.onChange = { [weak self] sender in
self?.updateCalendarModel()
}
clearActiveDatesSwitch.onChange = { [weak self] sender in
self?.updateCalendarModel()
}
clearInactiveDatesSwitch.onChange = { [weak self] sender in
self?.updateCalendarModel()
}
legendOneField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorOnePicker.date, index: 0)
}.store(in: &subscribers)
legendTwoField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorTwoPicker.date, index: 1)
}.store(in: &subscribers)
legendThreeField
.textPublisher
.sink {
[weak self] text in
self?.updateIndicatorData(label: text, date: self?.indicatorThreePicker.date, index: 2)
}.store(in: &subscribers)
indicatorOneSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
self.indicators.removeAll()
} else {
self.setIndicatorsData()
}
self.updateCalendarModel()
}
indicatorTwoSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
if self.indicators.count > 2 {
self.indicators.removeLast()
self.indicators.removeLast()
} else if self.indicators.count == 2 {
self.indicators.removeLast()
}
} else {
self.setIndicatorsData()
}
self.updateCalendarModel()
}
indicatorThreeSwitch.onChange = { [weak self] sender in
guard let self else { return }
if !sender.isOn {
if self.indicators.count > 2 {
self.indicators.removeLast()
}
} else {
self.setIndicatorsData()
}
self.updateCalendarModel()
}
return section
}
func updateCalendarModel() {
component.calendarModel = .init(surface: component.surface,
hideContainerBorder: containerBorderSwitch.isOn,
hideCurrentDateIndicator: hideCurrentDateIndicatorSwitch.isOn,
activeDates: activeDates,
inactiveDates: inactiveDates,
minDate: minDate,
maxDate: maxDate,
indicators: indicators)
}
func setupCalendar() {
configurePicker(indicatorOnePicker)
indicatorOnePicker.tag = indicatorOnePickerTag
configurePicker(indicatorTwoPicker)
indicatorTwoPicker.tag = indicatorTwoPickerTag
configurePicker(indicatorThreePicker)
indicatorThreePicker.tag = indicatorThreePickerTag
configurePicker(minDatePicker)
minDatePicker.tag = minDatePickerTag
configurePicker(maxDatePicker)
maxDatePicker.tag = maxDatePickerTag
configurePicker(activeDatePicker)
activeDatePicker.tag = activeDatePickerTag
configurePicker(inactiveDatePicker)
inactiveDatePicker.tag = inactiveDatePickerTag
indicators = [
.init(label: "Due Date", date: indicatorOnePicker.date),
.init(label: "Auto Pay", date: indicatorTwoPicker.date),
.init(label: "Scheduled", date: indicatorThreePicker.date)
]
let calendar = Calendar.current
let indicatorDate = calendar.startOfDay(for: calendar.date(byAdding: .day, value: 1, to: Date())!)
legendOneField.text = "Due Date"
legendTwoField.text = "Auto Pay"
legendThreeField.text = "Scheduled"
indicatorOneSwitch.isOn = true
indicatorTwoSwitch.isOn = true
indicatorThreeSwitch.isOn = true
hideCurrentDateIndicatorSwitch.isOn = false
indicatorOnePicker.date = indicatorDate
indicatorTwoPicker.date = indicatorDate
indicatorThreePicker.date = indicatorDate
updateIndicatorData(label: legendOneField.text ?? "", date: indicatorOnePicker.date, index: 0)
updateIndicatorData(label: legendTwoField.text ?? "", date: indicatorTwoPicker.date, index: 1)
updateIndicatorData(label: legendThreeField.text ?? "", date: indicatorThreePicker.date, index: 2)
activeDatesField.isUserInteractionEnabled = false
inactiveDatesField.isUserInteractionEnabled = false
activeDatesField.isEnabled = false
inactiveDatesField.isEnabled = false
minDatePicker.date = minDate
maxDatePicker.date = maxDate
updateCalendarModel()
}
func updateIndicatorData(label: String = "", date: Date?, index:Int) {
indicators[index].label = label
indicators[index].date = date ?? Date()
updateCalendarModel()
}
func setIndicatorsData() {
if indicatorOneSwitch.isOn && indicatorTwoSwitch.isOn && indicatorThreeSwitch.isOn {
indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
.init(label: self.legendTwoField.text ?? "", date: indicatorTwoPicker.date),
.init(label: self.legendThreeField.text ?? "", date: indicatorThreePicker.date)
]
} else if indicatorOneSwitch.isOn && indicatorTwoSwitch.isOn && !indicatorThreeSwitch.isOn {
indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
.init(label: self.legendTwoField.text ?? "", date: indicatorTwoPicker.date),
]
} else if indicatorOneSwitch.isOn && !indicatorTwoSwitch.isOn {
indicators = [
.init(label: self.legendOneField.text ?? "", date: indicatorOnePicker.date),
]
}
}
func configurePicker(_ sender:UIDatePicker) {
// Set some of UIDatePicker properties
sender.timeZone = NSTimeZone.local
sender.backgroundColor = UIColor.white
// Add an event to call onDidChangeDate function when value is changed.
sender.addTarget(self, action: #selector(self.datePickerValueChanged(_:)), for: .valueChanged)
}
@objc func datePickerValueChanged(_ sender: UIDatePicker){
switch sender.tag {
case indicatorOnePickerTag:
updateIndicatorData(label: legendOneField.text ?? "", date: sender.date, index: 0)
case indicatorTwoPickerTag:
updateIndicatorData(label: legendTwoField.text ?? "", date: sender.date, index: 1)
case indicatorThreePickerTag:
updateIndicatorData(label: legendThreeField.text ?? "", date: sender.date, index: 2)
case minDatePickerTag:
minDate = sender.date
updateCalendarModel()
case maxDatePickerTag:
maxDate = sender.date
updateCalendarModel()
case activeDatePickerTag:
activeDates.append(sender.date)
var text = activeDatesField.text
if let textEmpty = text?.isEmpty, textEmpty == true {
text?.append("")
} else {
text?.append(", ")
}
text?.append("\(self.getSelectedDate(with: sender.date))")
clearActiveDatesSwitch.isOn = false
activeDatesField.text = text
updateCalendarModel()
case inactiveDatePickerTag:
inactiveDates.append(sender.date)
var text = inactiveDatesField.text
if let textEmpty = text?.isEmpty, textEmpty == true {
text?.append("")
} else {
text?.append(", ")
}
text?.append("\(self.getSelectedDate(with: sender.date))")
clearInactiveDatesSwitch.isOn = false
inactiveDatesField.text = text
updateCalendarModel()
default: break
}
}
func getSelectedDate(with date:Date) -> String {
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy"
let day: String = dateFormatter.string(from: date)
return day
}
}

View File

@ -34,9 +34,13 @@ class DropShadowViewController: BaseViewController<ShadowView> {
var componentWrapper: UIView!
var componentConstraints: NSLayoutConstraint.Container!
var secondView = View()
var thirdView = View()
var secondView = ShadowView()
var thirdView = ShadowView()
var shadowViews: [ShadowView] {
[component, secondView, thirdView]
}
lazy var backgroundColorPickerSelectorView = {
PickerSelectorView(title: "paletteWhite",
picker: self.picker,
@ -125,8 +129,8 @@ class DropShadowViewController: BaseViewController<ShadowView> {
thirdView.width(viewSize).height(viewSize)
componentWrapper.pinTop().pinLeading()
secondView.pinTop()
thirdView.pinLeading().pinBottom()
secondView.pinTop(VDSLayout.space2X)
thirdView.pinLeading(VDSLayout.space2X).pinBottom(VDSLayout.space2X)
secondView.pinTrailingLessThanOrEqualTo(contentTopView.trailingAnchor)
secondView.pinBottomLessThanOrEqualTo(contentTopView.bottomAnchor)
@ -194,7 +198,7 @@ class DropShadowViewController: BaseViewController<ShadowView> {
//shadow1
showShadow.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
self?.component.showShadow = slider.isOn
self?.shadowViews.forEach { $0.showShadow = slider.isOn }
self?.updateView()
}).store(in: &subscribers)
@ -202,7 +206,7 @@ class DropShadowViewController: BaseViewController<ShadowView> {
opacityRange.minimumValue = 0.0
opacityRange.value = 1.0
opacityRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
self?.component.opacityRange = CGFloat(slider.value)
self?.shadowViews.forEach { $0.opacityRange = CGFloat(slider.value) }
self?.updateView()
}).store(in: &subscribers)
@ -210,7 +214,7 @@ class DropShadowViewController: BaseViewController<ShadowView> {
radiusRange.minimumValue = 0.0
radiusRange.value = 2.0
radiusRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
self?.component.radiusRange = CGFloat(slider.value)
self?.shadowViews.forEach { $0.radiusRange = CGFloat(slider.value) }
self?.updateView()
}).store(in: &subscribers)
@ -218,7 +222,7 @@ class DropShadowViewController: BaseViewController<ShadowView> {
offsetXRange.minimumValue = -20
offsetXRange.value = 2.0
offsetXRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
self?.component.offsetXRange = CGFloat(slider.value)
self?.shadowViews.forEach { $0.offsetXRange = CGFloat(slider.value) }
self?.updateView()
}).store(in: &subscribers)
@ -226,13 +230,13 @@ class DropShadowViewController: BaseViewController<ShadowView> {
offsetYRange.minimumValue = -20
offsetYRange.value = 2.0
offsetYRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
self?.component.offsetYRange = CGFloat(slider.value)
self?.shadowViews.forEach { $0.offsetYRange = CGFloat(slider.value) }
self?.updateView()
}).store(in: &subscribers)
//shadow2
showShadow2.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
self?.component.showShadow2 = slider.isOn
self?.shadowViews.forEach { $0.showShadow2 = slider.isOn }
self?.updateView()
}).store(in: &subscribers)
@ -240,7 +244,7 @@ class DropShadowViewController: BaseViewController<ShadowView> {
opacityRange2.minimumValue = 0.0
opacityRange2.value = 1.0
opacityRange2.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
self?.component.opacityRange2 = CGFloat(slider.value)
self?.shadowViews.forEach { $0.opacityRange2 = CGFloat(slider.value) }
self?.updateView()
}).store(in: &subscribers)
@ -248,7 +252,7 @@ class DropShadowViewController: BaseViewController<ShadowView> {
radiusRange2.minimumValue = 0.0
radiusRange2.value = 2.0
radiusRange2.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
self?.component.radiusRange2 = CGFloat(slider.value)
self?.shadowViews.forEach { $0.radiusRange2 = CGFloat(slider.value) }
self?.updateView()
}).store(in: &subscribers)
@ -256,7 +260,7 @@ class DropShadowViewController: BaseViewController<ShadowView> {
offsetXRange2.minimumValue = -20
offsetXRange2.value = 2.0
offsetXRange2.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
self?.component.offsetXRange2 = CGFloat(slider.value)
self?.shadowViews.forEach { $0.offsetXRange2 = CGFloat(slider.value) }
self?.updateView()
}).store(in: &subscribers)
@ -264,7 +268,7 @@ class DropShadowViewController: BaseViewController<ShadowView> {
offsetYRange2.minimumValue = -20
offsetYRange2.value = 2.0
offsetYRange2.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
self?.component.offsetYRange2 = CGFloat(slider.value)
self?.shadowViews.forEach { $0.offsetYRange2 = CGFloat(slider.value) }
self?.updateView()
}).store(in: &subscribers)
@ -281,7 +285,7 @@ class DropShadowViewController: BaseViewController<ShadowView> {
viewRadiusRange.minimumValue = 0
viewRadiusRange.value = 8.0
viewRadiusRange.publisher(for: .valueChanged).sink(receiveValue: { [weak self] slider in
self?.component.viewRadiusRange = CGFloat(slider.value)
self?.shadowViews.forEach { $0.viewRadiusRange = CGFloat(slider.value) }
self?.updateView()
}).store(in: &subscribers)
@ -310,8 +314,8 @@ class DropShadowViewController: BaseViewController<ShadowView> {
}
override func updateView() {
secondView.backgroundColor = .red
thirdView.backgroundColor = .purple
secondView.viewLightColor = .paletteYellow53
thirdView.viewLightColor = .paletteBlue46
}
func setupPicker(){
@ -322,20 +326,21 @@ class DropShadowViewController: BaseViewController<ShadowView> {
}
dropShadowDarkColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.shadowDarkColor = item
self?.shadowViews.forEach { $0.shadowDarkColor = item }
}
dropShadowLightColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.shadowLightColor = item
self?.shadowViews.forEach { $0.shadowLightColor = item }
}
dropShadow2DarkColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.shadowDarkColor2 = item
self?.shadowViews.forEach { $0.shadowDarkColor2 = item }
}
dropShadow2LightColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.shadowLightColor2 = item
self?.shadowViews.forEach { $0.shadowLightColor2 = item }
}
viewLightColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.viewLightColor = item
}

View File

@ -10,6 +10,12 @@ import VDS
class DropdownSelectViewController: BaseViewController<DropdownSelect> {
lazy var helperTextPlacementPickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: InputField.HelperTextPlacement.allCases)
}()
var disabledSwitch = Toggle()
var requiredSwitch = Toggle()
var labelTextField = TextField()
@ -21,6 +27,7 @@ class DropdownSelectViewController: BaseViewController<DropdownSelect> {
var errorSwitch = Toggle()
var tooltipTitleTextField = TextField()
var tooltipContentTextField = TextField()
var widthTextField = NumericField()
var optionsSwitch = Toggle()
var moreOptions: [DropdownSelect.DropdownOptionModel] = [
.init(text: "Alabama"),
@ -58,14 +65,16 @@ class DropdownSelectViewController: BaseViewController<DropdownSelect> {
override func setupForm(){
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addFormRow(label: "Disabled", view: disabledSwitch)
addFormRow(label: "Read Only", view: readonlySwitch)
addFormRow(label: "Required", view: requiredSwitch)
addFormRow(label: "Transparent Background", view: transparentBgSwitch)
addFormRow(label: "Label Text", view: labelTextField)
addFormRow(label: "Helper Text Placement", view: helperTextPlacementPickerSelectorView)
addFormRow(label: "Helper Text", view: helperTextField)
addFormRow(label: "Inline Label", view: .makeWrapper(for: inlineLabelSwitch))
addFormRow(label: "Readonly", view: readonlySwitch)
addFormRow(label: "Transparent Background", view: transparentBgSwitch)
addFormRow(label: "Error", view: .makeWrapper(for: errorSwitch))
addFormRow(label: "Error Text", view: errorTextField)
addFormRow(label: "Width", view: widthTextField)
addFormRow(label: "ToolTip Title", view: tooltipTitleTextField)
addFormRow(label: "ToolTip Content", view: tooltipContentTextField)
addFormRow(label: "More Options", view: optionsSwitch)
@ -75,7 +84,7 @@ class DropdownSelectViewController: BaseViewController<DropdownSelect> {
}
requiredSwitch.onChange = { [weak self] sender in
self?.component.required = sender.isOn
self?.component.isRequired = sender.isOn
}
optionsSwitch.onChange = { [weak self] sender in
@ -84,7 +93,7 @@ class DropdownSelectViewController: BaseViewController<DropdownSelect> {
}
readonlySwitch.onChange = { [weak self] sender in
self?.component.readOnly = sender.isOn
self?.component.isReadOnly = sender.isOn
}
transparentBgSwitch.onChange = { [weak self] sender in
@ -119,6 +128,12 @@ class DropdownSelectViewController: BaseViewController<DropdownSelect> {
self?.component.errorText = text
}.store(in: &subscribers)
widthTextField
.numberPublisher
.sink { [weak self] number in
self?.component.width = number?.cgFloatValue
}.store(in: &subscribers)
tooltipTitleTextField
.textPublisher
.sink { [weak self] text in
@ -147,10 +162,6 @@ class DropdownSelectViewController: BaseViewController<DropdownSelect> {
component.options = moreOptions
/// callback to know which option chose
component.onItemSelected = { index, option in
print("selected index: \(index) text: \(option.text) value: \(option.value)")
}
component.onChange = { dropdown in
guard let option = dropdown.selectedItem, let index = dropdown.selectId else { print("nothing selected"); return }
print("selected index: \(index) text: \(option.text) value: \(option.value)")
@ -158,9 +169,10 @@ class DropdownSelectViewController: BaseViewController<DropdownSelect> {
//setup UI
disabledSwitch.isOn = !component.isEnabled
requiredSwitch.isOn = component.required
requiredSwitch.isOn = component.isRequired
surfacePickerSelectorView.text = component.surface.rawValue
labelTextField.text = component.labelText
helperTextPlacementPickerSelectorView.text = component.helperTextPlacement.rawValue
helperTextField.text = component.helperText
readonlySwitch.isOn = false
transparentBgSwitch.isOn = false
@ -176,6 +188,11 @@ class DropdownSelectViewController: BaseViewController<DropdownSelect> {
self?.component.surface = item
self?.contentTopView.backgroundColor = item.color
}
helperTextPlacementPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.helperTextPlacement = item
}
}
func updateTooltip() {

View File

@ -13,12 +13,18 @@ import Combine
class IconViewController: BaseViewController<Icon> {
lazy var colorPickerSelectorView = {
lazy var lightColorPickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: UIColor.VDSColor.allCases)
}()
lazy var darkColorPickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: UIColor.VDSColor.allCases)
}()
lazy var namePickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
@ -45,7 +51,8 @@ class IconViewController: BaseViewController<Icon> {
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addFormRow(label: "Size", view: sizePickerSelectorView)
addFormRow(label: "Custom Size", view: customSizeField)
addFormRow(label: "Color", view: colorPickerSelectorView)
addFormRow(label: "Light Color", view: lightColorPickerSelectorView)
addFormRow(label: "Dark Color", view: darkColorPickerSelectorView)
addFormRow(label: "Name", view: namePickerSelectorView)
customSizeField
@ -57,14 +64,13 @@ class IconViewController: BaseViewController<Icon> {
func setupModel() {
let name = Icon.Name.accessibility
let color = UIColor.VDSColor.paletteBlack
component.color = color.uiColor
component.name = name
//setup UI
surfacePickerSelectorView.text = component.surface.rawValue
sizePickerSelectorView.text = component.size.rawValue
colorPickerSelectorView.text = color.rawValue
lightColorPickerSelectorView.text = UIColor.VDSColor.elementsPrimaryOnlight.rawValue
darkColorPickerSelectorView.text = UIColor.VDSColor.elementsPrimaryOndark.rawValue
namePickerSelectorView.text = name.rawValue
}
func setupPicker(){
@ -78,14 +84,25 @@ class IconViewController: BaseViewController<Icon> {
self?.component.size = item
}
colorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.color = item.uiColor
lightColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.setColorConfiguration()
}
darkColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.setColorConfiguration()
}
namePickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.name = item
}
}
func setColorConfiguration() {
let light = lightColorPickerSelectorView.selectedItem.uiColor
let dark = darkColorPickerSelectorView.selectedItem.uiColor
component.colorConfiguration = .init(light, dark)
}
}
extension IconViewController: ComponentSampleable {

View File

@ -19,8 +19,16 @@ class InputFieldViewController: BaseViewController<InputField> {
items: InputField.HelperTextPlacement.allCases)
}()
lazy var inputTypePickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: InputField.FieldType.allCases)
}()
var disabledSwitch = Toggle()
var requiredSwitch = Toggle()
var readonlySwitch = Toggle()
var transparentBgSwitch = Toggle()
var labelTextField = TextField()
var errorTextField = TextField()
var successTextField = TextField()
@ -31,6 +39,52 @@ class InputFieldViewController: BaseViewController<InputField> {
var tooltipTitleTextField = TextField()
var tooltipContentTextField = TextField()
//FieldType sections
//password
var hidePasswordButtonTextField = TextField()
var showPasswordButtonTextField = TextField()
lazy var passwordSection = FormSection().with {
$0.title = "Password Settings"
$0.addFormRow(label: "Hide Button", view: hidePasswordButtonTextField)
$0.addFormRow(label: "Show Button", view: showPasswordButtonTextField)
$0.isHidden = true
}
//date
lazy var dateFormatPickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: InputField.DateFormat.allCases)
}()
lazy var dateSection = FormSection().with {
$0.title = "Date Settings"
$0.addFormRow(label: "Date Format", view: dateFormatPickerSelectorView)
$0.isHidden = true
}
//inlineAction
var inlineActionTextField = TextField()
lazy var inlineActionSection = FormSection().with {
$0.title = "inlineAction Settings"
$0.addFormRow(label: "Action Text", view: inlineActionTextField)
$0.isHidden = true
}
//securityCode
lazy var cardTypePickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: InputField.CreditCardType.allCases)
}()
lazy var securityCodeSection = FormSection().with {
$0.title = "Security Code Settings"
$0.addFormRow(label: "Card Type", view: cardTypePickerSelectorView)
$0.isHidden = true
}
override func viewDidLoad() {
super.viewDidLoad()
addContentTopView(view: component)
@ -40,22 +94,42 @@ class InputFieldViewController: BaseViewController<InputField> {
override func setupForm(){
super.setupForm()
addFormRow(label: "Disabled", view: disabledSwitch)
addFormRow(label: "Required", view: requiredSwitch)
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addFormRow(label: "Label Text", view: labelTextField)
addFormRow(label: "Helper Text Placement", view: helperTextPlacementPickerSelectorView)
addFormRow(label: "Helper Text", view: helperTextField)
addFormRow(label: "Error", view: showErrorSwitch)
addFormRow(label: "Error Text", view: errorTextField)
addFormRow(label: "Success", view: showSuccessSwitch)
addFormRow(label: "Success Text", view: successTextField)
addFormRow(label: "Width", view: widthTextField)
addFormRow(label: "ToolTip Title", view: tooltipTitleTextField)
addFormRow(label: "ToolTip Content", view: tooltipContentTextField)
let fieldType = FormSection().with {
$0.title = "Field Type Settings"
$0.addFormRow(label: "Field Type", view: inputTypePickerSelectorView)
}
let general = FormSection().with {
$0.title = "\n\nGeneral Settings"
}
general.addFormRow(label: "Surface", view: surfacePickerSelectorView)
general.addFormRow(label: "Disabled", view: disabledSwitch)
general.addFormRow(label: "Read Only", view: readonlySwitch)
general.addFormRow(label: "Required", view: requiredSwitch)
general.addFormRow(label: "Transparent Background", view: transparentBgSwitch)
general.addFormRow(label: "Label Text", view: labelTextField)
general.addFormRow(label: "Helper Text Placement", view: helperTextPlacementPickerSelectorView)
general.addFormRow(label: "Helper Text", view: helperTextField)
general.addFormRow(label: "Error", view: showErrorSwitch)
general.addFormRow(label: "Error Text", view: errorTextField)
general.addFormRow(label: "Success", view: showSuccessSwitch)
general.addFormRow(label: "Success Text", view: successTextField)
general.addFormRow(label: "Width", view: widthTextField)
general.addFormRow(label: "ToolTip Title", view: tooltipTitleTextField)
general.addFormRow(label: "ToolTip Content", view: tooltipContentTextField)
append(section: fieldType)
append(section: passwordSection)
append(section: dateSection)
append(section: inlineActionSection)
append(section: securityCodeSection)
append(section: general)
requiredSwitch.onChange = { [weak self] sender in
self?.component.required = sender.isOn
self?.component.isRequired = sender.isOn
}
showErrorSwitch.onChange = { [weak self] sender in
@ -77,6 +151,14 @@ class InputFieldViewController: BaseViewController<InputField> {
disabledSwitch.onChange = { [weak self] sender in
self?.component.isEnabled = !sender.isOn
}
readonlySwitch.onChange = { [weak self] sender in
self?.component.isReadOnly = sender.isOn
}
transparentBgSwitch.onChange = { [weak self] sender in
self?.component.transparentBackground = sender.isOn
}
labelTextField
.textPublisher
@ -114,17 +196,42 @@ class InputFieldViewController: BaseViewController<InputField> {
self?.updateTooltip()
}.store(in: &subscribers)
//field types
//password
hidePasswordButtonTextField
.textPublisher
.sink { [weak self] text in
self?.component.hidePasswordButtonText = text
}.store(in: &subscribers)
showPasswordButtonTextField
.textPublisher
.sink { [weak self] text in
self?.component.showPasswordButtonText = text
}.store(in: &subscribers)
//inlineAction
inlineActionTextField
.textPublisher
.sink { [weak self] text in
if !text.isEmpty {
self?.component.actionTextLinkModel = .init(text: text, onClick: { inputField in
var value = inputField.value ?? ""
value = !value.isEmpty ? value : "nil"
self?.present(UIAlertController(title: "inlineAction", message: "Clicked and you get the value: \(value)", preferredStyle: .alert).with{ $0.addAction(.init(title: "OK", style: .default)) }, animated: true)
})
} else {
self?.component.actionTextLinkModel = nil
}
}.store(in: &subscribers)
}
func setupModel() {
component.fieldType = .text
component.width = 328
component.text = "Starting Text"
component.labelText = "Street Address"
component.helperText = "For example: 123 Verizon St"
component.errorText = "Enter a valid address."
component.successText = "Good job entering a valid address!"
component.tooltipModel = .init(title: "Check the formatting of your address", content:"House/Building number then street name")
component.onChange = { component in
if let text = component.value {
@ -137,8 +244,10 @@ class InputFieldViewController: BaseViewController<InputField> {
//setup UI
surfacePickerSelectorView.text = component.surface.rawValue
helperTextPlacementPickerSelectorView.text = component.helperTextPlacement.rawValue
dateFormatPickerSelectorView.text = component.dateFormat.rawValue
inputTypePickerSelectorView.text = component.fieldType.rawValue
disabledSwitch.isOn = !component.isEnabled
requiredSwitch.isOn = component.required
requiredSwitch.isOn = component.isRequired
labelTextField.text = component.labelText
helperTextField.text = component.helperText
showErrorSwitch.isOn = component.showError
@ -162,6 +271,21 @@ class InputFieldViewController: BaseViewController<InputField> {
helperTextPlacementPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.helperTextPlacement = item
}
inputTypePickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.fieldType = item
self?.component.text = ""
self?.updateFormSections()
}
dateFormatPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.dateFormat = item
self?.updateFormSections()
}
cardTypePickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.component.cardType = item
}
}
func updateTooltip() {
@ -171,6 +295,35 @@ class InputFieldViewController: BaseViewController<InputField> {
component.tooltipModel = !title.isEmpty || !content.isEmpty ? .init(title: title,
content: content) : nil
}
func updateFormSections() {
[passwordSection, dateSection, inlineActionSection, securityCodeSection].forEach { $0.isHidden = true }
//reset other fields
component.actionTextLinkModel = nil
component.tooltipModel = nil
component.cardType = .placeholder
tooltipTitleTextField.text = nil
tooltipContentTextField.text = nil
dateFormatPickerSelectorView.text = component.dateFormat.rawValue
cardTypePickerSelectorView.text = component.cardType.rawValue
switch component.fieldType {
case .inlineAction:
inlineActionTextField.text = nil
inlineActionSection.isHidden = false
case .password:
passwordSection.isHidden = false
case .date:
dateSection.isHidden = false
case .securityCode:
securityCodeSection.isHidden = false
default:
break
}
}
}

View File

@ -74,13 +74,15 @@ class MenuViewController: UITableViewController, TooltipLaunchable {
MenuComponent(title: "Button", completed: true, viewController: ButtonViewController.self),
MenuComponent(title: "ButtonGroup", completed: true, viewController: ButtonGroupViewController.self),
MenuComponent(title: "ButtonIcon", completed: true, viewController: ButtonIconViewController.self),
MenuComponent(title: "Calendar", completed: true, viewController: CalendarViewController.self),
MenuComponent(title: "Carousel Scrollbar", completed: true, viewController: CarouselScrollbarViewConttroller.self),
MenuComponent(title: "Checkbox", completed: true, viewController: CheckboxViewController.self),
MenuComponent(title: "CheckboxItem", completed: true, viewController: CheckboxItemViewController.self),
MenuComponent(title: "CheckboxGroup", completed: true, viewController: CheckboxGroupViewController.self),
MenuComponent(title: "DatePicker", completed: true, viewController: DatePickerViewController.self),
MenuComponent(title: "DropdownSelect", completed: true, viewController: DropdownSelectViewController.self),
MenuComponent(title: "Icon", completed: true, viewController: IconViewController.self),
MenuComponent(title: "InputField", completed: false, viewController: InputFieldViewController.self),
MenuComponent(title: "InputField", completed: true, viewController: InputFieldViewController.self),
MenuComponent(title: "Label", completed: true, viewController: LabelViewController.self),
MenuComponent(title: "Line", completed: true, viewController: LineViewController.self),
MenuComponent(title: "Loader", completed: true, viewController: LoaderViewController.self),
@ -110,10 +112,15 @@ class MenuViewController: UITableViewController, TooltipLaunchable {
override func viewDidLoad() {
title = "VDS Sample: Build \(Bundle.main.build ?? "none")"
let tooltip = VDS.Tooltip()
tooltip.title = "Release Notes: \(VDSHelper.version)"
tooltip.content = VDSHelper.releaseNotes()
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: tooltip)
let content = VDSHelper.releaseNotes()
if !content.isEmpty {
let tooltip = VDS.Tooltip()
tooltip.title = "Release Notes: \(VDSHelper.version)"
tooltip.content = content
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: tooltip)
}
super.viewDidLoad()
overrideUserInterfaceStyle = .light
tableView.register(MenuCell.self, forCellReuseIdentifier: "cell")

View File

@ -172,30 +172,8 @@ public class TableViewTestController: UIViewController, Initable, Surfaceable {
}
var items: [MenuComponent] {
all
}
var all: [MenuComponent] {
MenuViewController.items
}
var batch1: [MenuComponent] {
[
MenuComponent(title: "Badge", completed: true, viewController: BadgeViewController.self),
MenuComponent(title: "Button", completed: true, viewController: ButtonViewController.self),
MenuComponent(title: "ButtonGroup", completed: true, viewController: ButtonGroupViewController.self),
MenuComponent(title: "Icon", completed: true, viewController: IconViewController.self),
MenuComponent(title: "Label", completed: true, viewController: LabelViewController.self),
MenuComponent(title: "Line", completed: true, viewController: LineViewController.self),
MenuComponent(title: "Loader", completed: true, viewController: LoaderViewController.self),
MenuComponent(title: "Tabs", completed: true, viewController: TabsViewController.self),
MenuComponent(title: "TextLink", completed: true, viewController: TextLinkViewController.self),
MenuComponent(title: "TextLinkCaret", completed: true, viewController: TextLinkCaretViewController.self),
MenuComponent(title: "TitleLockup", completed: true, viewController: TitleLockupViewController.self),
MenuComponent(title: "Tooltip", completed: true, viewController: TooltipViewController.self),
MenuComponent(title: "TrailingTooltip", completed: true, viewController: TrailingTooltipLabelViewController.self),
]
}
}
}
extension TableViewTestController : UITableViewDelegate, UITableViewDataSource {

View File

@ -15,6 +15,7 @@ class TextAreaViewController: BaseViewController<TextArea> {
var disabledSwitch = Toggle()
var requiredSwitch = Toggle()
var transparentBgSwitch = Toggle()
var labelTextField = TextField()
var errorTextField = TextField()
var helperTextField = TextField()
@ -34,28 +35,29 @@ class TextAreaViewController: BaseViewController<TextArea> {
override func viewDidLoad() {
super.viewDidLoad()
addContentTopView(view: component)
component.text = "Starting Text"
setupPicker()
setupModel()
}
override func setupForm(){
super.setupForm()
addFormRow(label: "Disabled", view: disabledSwitch)
addFormRow(label: "Required", view: requiredSwitch)
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addFormRow(label: "Disabled", view: disabledSwitch)
addFormRow(label: "Read Only", view: readOnlySwitch)
addFormRow(label: "Required", view: requiredSwitch)
addFormRow(label: "Transparent Background", view: transparentBgSwitch)
addFormRow(label: "Label Text", view: labelTextField)
addFormRow(label: "Helper Text", view: helperTextField)
addFormRow(label: "Read Only", view: readOnlySwitch)
addFormRow(label: "Error", view: showErrorSwitch)
addFormRow(label: "Error Text", view: errorTextField)
addFormRow(label: "Width", view: widthTextField)
addFormRow(label: "ToolTip Title", view: tooltipTitleTextField)
addFormRow(label: "ToolTip Content", view: tooltipContentTextField)
addFormRow(label: "Character Count", view: maxLengthTextField)
addFormRow(label: "Min Height", view: heightPickerSelectorView)
requiredSwitch.onChange = { [weak self] sender in
self?.component.required = sender.isOn
self?.component.isRequired = sender.isOn
}
showErrorSwitch.onChange = { [weak self] sender in
@ -71,7 +73,11 @@ class TextAreaViewController: BaseViewController<TextArea> {
}
readOnlySwitch.onChange = { [weak self] sender in
self?.component.readOnly = sender.isOn
self?.component.isReadOnly = sender.isOn
}
transparentBgSwitch.onChange = { [weak self] sender in
self?.component.transparentBackground = sender.isOn
}
labelTextField
@ -126,7 +132,6 @@ class TextAreaViewController: BaseViewController<TextArea> {
}
func setupModel() {
component.width = 328
component.labelText = "Street Address"
component.helperText = "For example: 123 Verizon St"
component.errorText = "Enter a valid address."
@ -143,7 +148,7 @@ class TextAreaViewController: BaseViewController<TextArea> {
//setup UI
surfacePickerSelectorView.text = component.surface.rawValue
disabledSwitch.isOn = !component.isEnabled
requiredSwitch.isOn = component.required
requiredSwitch.isOn = component.isRequired
labelTextField.text = component.labelText
helperTextField.text = component.helperText
showErrorSwitch.isOn = component.showError

View File

@ -50,6 +50,7 @@ class TileContainerViewController: BaseViewController<TileContainer> {
var gradientColorsFormStackView = FormSection().with { $0.isHidden = true }
var backgroundColor: BackgroundColor = .secondary
var padding: Padding = .padding4X
var isLinkSwitch = Toggle()
var clickableSwitch = Toggle()
var showBackgroundImageSwitch = Toggle()
var showBorderSwitch = Toggle()
@ -97,10 +98,53 @@ class TileContainerViewController: BaseViewController<TileContainer> {
override func viewDidLoad() {
super.viewDidLoad()
addContentTopView(view: .makeWrapper(for: component))
component.width = 150
component.width = 300
component.color = .secondary
component.accessibilityLabel = "Tile Container"
component.addContentView(Label().with { $0.text = "Testing Label" })
let level2View = View()
level2View.backgroundColor = .purple
let level3View = View()
level3View.backgroundColor = .yellow
level2View.addSubview(level3View)
level3View.pinToSuperView(.uniform(15))
let level2label = Label()
level2label.text = "Level 3 Label"
level3View.addSubview(level2label)
level2label.pinTop().pinLeading()
let level3Button = Button()
level3Button.setTitle("Level 3 Button", for: .normal)
level3View.addSubview(level3Button)
level3Button.pinTop(anchor: level2label.bottomAnchor, constant: 5)
level3Button.pinLeading()
let level4View = View()
level4View.backgroundColor = .green
level3View.addSubview(level4View)
level4View.pinTop(anchor: level3Button.bottomAnchor, constant: 10)
level4View.pinLeading()
level4View.pinBottom()
level4View.pinTrailing()
let level4Label = Label()
level4Label.text = "Level 4 Label"
level4View.addSubview(level4Label)
level4Label.pinTop().pinLeading()
let level4Button = Button()
level4Button.setTitle("Level 4 Button", for: .normal)
level4View.addSubview(level4Button)
level4Button.pinTop(anchor: level4Label.bottomAnchor, constant: 5)
level4Button.pinLeading().pinBottom()
component.addContentView(level2View)
setupPicker()
setupModel()
}
@ -115,6 +159,7 @@ class TileContainerViewController: BaseViewController<TileContainer> {
$0.text = "For testing max width is limited to 85% of view's width & 65% view's height."
})
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addFormRow(label: "Is Link", view: isLinkSwitch)
addFormRow(label: "Clickable", view: clickableSwitch)
addFormRow(label: "Width", view: widthTextField)
addFormRow(label: "Height", view: heightTextField)
@ -143,6 +188,11 @@ class TileContainerViewController: BaseViewController<TileContainer> {
}
}
isLinkSwitch.onChange = { [weak self] sender in
guard let self else { return }
self.component.accessibilityTraits = sender.isOn ? .link : .button
}
clickableSwitch.onChange = { [weak self] sender in
guard let self else { return }
if sender.isOn {
@ -254,7 +304,7 @@ class TileContainerViewController: BaseViewController<TileContainer> {
contentAreaBackgroundColorButton.onClick = { [weak self] _ in
guard let self else { return }
self.colorPickerType = .contentViewBackgroundColor
self.colorPicker.selectedColor = self.component.containerView.backgroundColor ?? .white
self.colorPicker.selectedColor = self.component.contentView.backgroundColor ?? .white
self.present(self.colorPicker, animated: true)
}
}
@ -285,12 +335,12 @@ extension TileContainerViewController: UIColorPickerViewControllerDelegate {
}
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
guard let hexString = viewController.selectedColor.hexString else { return }
let color = viewController.selectedColor
switch colorPickerType {
case .contentViewBackgroundColor:
component.containerView.backgroundColor = UIColor(hexString: hexString)
component.contentView.backgroundColor = color
case .backgroundColor:
component.color = .custom(hexString)
component.color = .custom(color)
case .gradientColor1:
gradientColorView1.selectedColor = viewController.selectedColor
updateGradientColors()
@ -301,8 +351,8 @@ extension TileContainerViewController: UIColorPickerViewControllerDelegate {
}
func updateGradientColors(){
if let selectedGradient1Color = gradientColorView1.selectedColor?.hexString,
let selectedGradient2Color = gradientColorView2.selectedColor?.hexString{
if let selectedGradient1Color = gradientColorView1.selectedColor,
let selectedGradient2Color = gradientColorView2.selectedColor{
component.backgroundEffect = .gradient(selectedGradient1Color, selectedGradient2Color)
}
}

View File

@ -12,7 +12,7 @@ import VDSTokens
import Combine
class TileletViewController: BaseViewController<Tilelet> {
lazy var titleStandardStylePickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
@ -25,12 +25,6 @@ class TileletViewController: BaseViewController<Tilelet> {
items: Tilelet.SubTitleModel.OtherStandardStyle.allCases.sorted{ $0.rawValue < $1.rawValue })
}()
lazy var subtitleColorPickerSelectorView = {
PickerSelectorView<Use>(title: "",
picker: self.picker,
items: [.primary, .secondary])
}()
lazy var textPositionPickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
@ -75,7 +69,9 @@ class TileletViewController: BaseViewController<Tilelet> {
var colorPickerType: ColorPickerType = .backgroundColor
enum ColorPickerType {
case backgroundColor, gradientColor1, gradientColor2, contentViewBackgroundColor
case backgroundColor
case gradientColor1, gradientColor2
case contentViewBackgroundColor, token, custom
}
lazy var gradientColorView1: ColorPickerView<ColorPickerType> = {
@ -104,6 +100,177 @@ class TileletViewController: BaseViewController<Tilelet> {
items: TitleLockup.TextAlignment.allCases)
}()
/// titleLockup
var currentSurfaceColorType: SurfaceColorType = .title
enum SurfaceColorType {
case eyebrow, title, subtitle, directionalIcon, descriptionIcon
}
enum TitleTextColor: String, CaseIterable {
case primary, token, custom
}
enum TextColor: String, CaseIterable {
case primary, secondary, token, custom
}
enum IconColor: String, CaseIterable {
case `default`, token, custom
}
/// eyebrow
var eyebrowTokenFormStackView = FormSection().with { $0.isHidden = true }
var eyebrowColorFormStackView = FormSection().with { $0.isHidden = true }
lazy var eyebrowColorPickerSelectorView = {
PickerSelectorView(title: "primary",
picker: self.picker,
items: TextColor.allCases)
}()
lazy var eyebrowTokenColorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: UIColor.VDSColor.allCases)
.with { $0.text = UIColor.VDSColor.paletteWhite.rawValue }
}()
lazy var eyebrowCustomColorView: ColorPickerView<ColorPickerType> = {
return .init(with: ColorPickerType.custom, color: .white) { [weak self] picker in
self?.currentSurfaceColorType = .eyebrow
self?.colorPickerType = picker.pickerType
self?.selectedColorTapped(picker)
}
}()
/// title
var titleTokenFormStackView = FormSection().with { $0.isHidden = true }
var titleColorFormStackView = FormSection().with { $0.isHidden = true }
lazy var titleColorPickerSelectorView = {
PickerSelectorView(title: "primary",
picker: self.picker,
items: TitleTextColor.allCases)
}()
lazy var titleTokenColorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: UIColor.VDSColor.allCases)
.with { $0.text = UIColor.VDSColor.paletteWhite.rawValue }
}()
lazy var titleCustomColorView: ColorPickerView<ColorPickerType> = {
return .init(with: ColorPickerType.custom, color: .white) { [weak self] picker in
self?.currentSurfaceColorType = .title
self?.colorPickerType = picker.pickerType
self?.selectedColorTapped(picker)
}
}()
/// subtitle
var subtitleTokenFormStackView = FormSection().with { $0.isHidden = true }
var subtitleColorFormStackView = FormSection().with { $0.isHidden = true }
lazy var subtitleColorPickerSelectorView = {
PickerSelectorView(title: "primary",
picker: self.picker,
items: TextColor.allCases)
}()
lazy var subtitleTokenColorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: UIColor.VDSColor.allCases)
.with { $0.text = UIColor.VDSColor.paletteWhite.rawValue }
}()
lazy var subtitleCustomColorView: ColorPickerView<ColorPickerType> = {
return .init(with: ColorPickerType.custom, color: .white) { [weak self] picker in
self?.currentSurfaceColorType = .subtitle
self?.colorPickerType = picker.pickerType
self?.selectedColorTapped(picker)
}
}()
var descriptionIconFormStackView = FormSection().with { $0.isHidden = true }
var descriptionIconTokenFormStackView = FormSection().with { $0.isHidden = true }
var descriptionIconColorFormStackView = FormSection().with { $0.isHidden = true }
lazy var descriptionNamePickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: Icon.Name.all.sorted{ $0.rawValue < $1.rawValue })
}()
lazy var descriptionIconSizePickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: Icon.Size.allCases)
}()
lazy var descriptionIconColorPickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: IconColor.allCases)
.with { $0.text = IconColor.default.rawValue }
}()
lazy var descriptionIconTokenColorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: UIColor.VDSColor.allCases)
.with { $0.text = UIColor.VDSColor.paletteWhite.rawValue }
}()
lazy var descriptionIconCustomColorView: ColorPickerView<ColorPickerType> = {
return .init(with: ColorPickerType.custom) { [weak self] picker in
self?.currentSurfaceColorType = .descriptionIcon
self?.colorPickerType = picker.pickerType
self?.selectedColorTapped(picker)
}
}()
var directionalIconFormStackView = FormSection().with { $0.isHidden = true }
var directionalIconTokenFormStackView = FormSection().with { $0.isHidden = true }
var directionalIconColorFormStackView = FormSection().with { $0.isHidden = true }
lazy var directionalIconSizePickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: Icon.Size.allCases)
}()
lazy var directionalIconColorPickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: IconColor.allCases)
.with { $0.text = IconColor.default.rawValue }
}()
lazy var directionalIconTokenColorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: UIColor.VDSColor.allCases)
.with { $0.text = UIColor.VDSColor.paletteWhite.rawValue }
}()
lazy var directionalIconCustomColorView: ColorPickerView<ColorPickerType> = {
return .init(with: ColorPickerType.custom) { [weak self] picker in
self?.currentSurfaceColorType = .directionalIcon
self?.colorPickerType = picker.pickerType
self?.selectedColorTapped(picker)
}
}()
lazy var directionIconPickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: Tilelet.DirectionalIcon.IconType.allCases.sorted{ $0.rawValue < $1.rawValue })
}()
lazy var directionIconSizePickerSelectorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: Tilelet.DirectionalIcon.IconSize.allCases.sorted{ $0.rawValue < $1.rawValue })
}()
let backgroundImage = UIImage(named: "backgroundTest")!
var clickableSwitch = Toggle()
var eyebrowTextField = TextField()
@ -125,6 +292,7 @@ class TileletViewController: BaseViewController<Tilelet> {
var showDropShadowSwitch = Toggle()
var backgroundColor: BackgroundColor = .black
var maxWidthTextField = NumericField()
var isLinkSwitch = Toggle()
var gradientColorsFormStackView = FormSection().with { $0.isHidden = true }
@ -139,6 +307,7 @@ class TileletViewController: BaseViewController<Tilelet> {
super.setupForm()
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addActionRow()
addFormRow(label: "Is Link", view: isLinkSwitch)
addFormRow(label: "Clickable", view: clickableSwitch)
addFormRow(label: "Aspect Ratio", view: scalingTypePickerSelectorView)
@ -148,27 +317,8 @@ class TileletViewController: BaseViewController<Tilelet> {
addFormRow(label: "Text Alignment", view: textAlignmentPickerSelectorView)
addFormRow(label: "Text Width", view: textWidthTextField)
addFormRow(label: "Text Percentage", view: textPercentageTextField)
addFormRow(label: "Text Position(Minimum height is configurable.)", view: textPositionPickerSelectorView)
addFormRow(label: "Description Icon", view: showDescriptionIconSwitch)
addFormRow(label: "Directional Icon", view: showDirectionalIconSwitch)
addFormRow(label: "Badge Text", view: badgeTextField)
addFormRow(label: "Badge Fill Color", view: badgeFillColorPickerSelectorView)
addFormRow(label: "Badge Number of Lines", view: badgeNumberOfLinesPickerSelectorView)
addFormRow(label: "Badge Max Width", view: maxWidthTextField)
addFormRow(label: "Eyebrow/Subtitle Style", view: otherStandardStylePickerSelectorView)
addFormRow(label: "Eyebrow Text", view: eyebrowTextField)
addFormRow(label: "Eyebrow is Bold", view: eyebrowIsBold)
addFormRow(label: "Title Style", view: titleStandardStylePickerSelectorView)
addFormRow(label: "Title Text", view: titleTextField)
addFormRow(label: "Title is Bold", view: titleIsBold)
addFormRow(label: "Subtitle Color", view: subtitleColorPickerSelectorView)
addFormRow(label: "Subtitle Text", view: subTitleTextField)
addFormRow(label: "Background Color", view: backgroundColorPickerSelectorView)
addFormRow(label: "Text Position", tooltip: .init(title:"Text Position", content: "Minimum height is configurable"), view: textPositionPickerSelectorView)
addFormRow(label: "Background Color", tooltip: .init(title:"Background Color", content: "This color takes precedence over surface and will set all children's surface property to this value."), view: backgroundColorPickerSelectorView)
addFormRow(label: "Background Image", view: showBackgroundImageSwitch)
addFormRow(label: "Show Drop Shadow", view: showDropShadowSwitch)
addFormRow(label: "Image Fallback Color", view: imageFallbackColorPickerSelectorView)
@ -178,6 +328,76 @@ class TileletViewController: BaseViewController<Tilelet> {
gradientColorsFormStackView.addFormRow(label: "Gradient Color2", view: gradientColorView2)
append(section: gradientColorsFormStackView)
append(section: .init().with({
$0.title = "Badge"
$0.addFormRow(label: "Text", view: badgeTextField)
$0.addFormRow(label: "Fill Color", view: badgeFillColorPickerSelectorView)
$0.addFormRow(label: "Number of Lines", view: badgeNumberOfLinesPickerSelectorView)
$0.addFormRow(label: "Max Width", view: maxWidthTextField)
}))
append(section: .init().with({
$0.title = "Eyebrow"
$0.addFormRow(label: "Text Style", tooltip: .init(title: "Text Style", content: "Eyebrow and Subtitle will share the same textStyle."), view: otherStandardStylePickerSelectorView)
$0.addFormRow(label: "is Bold", view: eyebrowIsBold)
$0.addFormRow(label: "Text", view: eyebrowTextField)
$0.addFormRow(label: "Color", view: eyebrowColorPickerSelectorView)
}))
eyebrowTokenFormStackView.addFormRow(label: "Token", view: eyebrowTokenColorView)
eyebrowColorFormStackView.addFormRow(label: "Custom", view: eyebrowCustomColorView)
append(section: eyebrowTokenFormStackView)
append(section: eyebrowColorFormStackView)
append(section: .init().with({
$0.title = "Title"
$0.addFormRow(label: "Text Style", view: titleStandardStylePickerSelectorView)
$0.addFormRow(label: "is Bold", view: titleIsBold)
$0.addFormRow(label: "Text", view: titleTextField)
$0.addFormRow(label: "Color", view: titleColorPickerSelectorView)
}))
titleTokenFormStackView.addFormRow(label: "Token", view: titleTokenColorView)
titleColorFormStackView.addFormRow(label: "Custom", view: titleCustomColorView)
append(section: titleTokenFormStackView)
append(section: titleColorFormStackView)
append(section: .init().with({
$0.title = "Subtitle"
$0.addFormRow(label: "Text", view: subTitleTextField)
$0.addFormRow(label: "Color", view: subtitleColorPickerSelectorView)
}))
subtitleTokenFormStackView.addFormRow(label: "Token", view: subtitleTokenColorView)
subtitleColorFormStackView.addFormRow(label: "Custom", view: subtitleCustomColorView)
append(section: subtitleTokenFormStackView)
append(section: subtitleColorFormStackView)
append(section: .init().with({
$0.title = "Description Icon "
$0.addFormRow(label: "Show", view: showDescriptionIconSwitch)
}))
append(section: descriptionIconFormStackView)
descriptionIconFormStackView.addFormRow(label: "Icon", view: descriptionNamePickerSelectorView)
descriptionIconFormStackView.addFormRow(label: "Size", view: descriptionIconSizePickerSelectorView)
descriptionIconFormStackView.addFormRow(label: "Color", view: descriptionIconColorPickerSelectorView)
descriptionIconTokenFormStackView.addFormRow(label: "Token", view: descriptionIconTokenColorView)
descriptionIconColorFormStackView.addFormRow(label: "Custom", view: descriptionIconCustomColorView)
append(section: descriptionIconTokenFormStackView)
append(section: descriptionIconColorFormStackView)
append(section: .init().with({
$0.title = "Directional Icon"
$0.addFormRow(label: "Show", view: showDirectionalIconSwitch)
}))
append(section: directionalIconFormStackView)
directionalIconFormStackView.addFormRow(label: "Icon", view: directionIconPickerSelectorView)
directionalIconFormStackView.addFormRow(label: "Size", view: directionIconSizePickerSelectorView)
directionalIconFormStackView.addFormRow(label: "Color", view: directionalIconColorPickerSelectorView)
directionalIconTokenFormStackView.addFormRow(label: "Token", view: directionalIconTokenColorView)
directionalIconColorFormStackView.addFormRow(label: "Dark", view: directionalIconCustomColorView)
append(section: directionalIconTokenFormStackView)
append(section: directionalIconColorFormStackView)
clickableSwitch.onChange = { [weak self] sender in
guard let self else { return }
if sender.isOn {
@ -187,6 +407,11 @@ class TileletViewController: BaseViewController<Tilelet> {
}
}
isLinkSwitch.onChange = { [weak self] sender in
guard let self else { return }
self.component.accessibilityTraits = sender.isOn ? .link : .button
}
heightTextField
.numberPublisher
.sink { [weak self] number in
@ -248,21 +473,13 @@ class TileletViewController: BaseViewController<Tilelet> {
}.store(in: &subscribers)
showDescriptionIconSwitch.onChange = { [weak self] sender in
if sender.isOn {
self?.showDirectionalIconSwitch.isOn = false
self?.component.descriptiveIconModel = .init(size: .medium, surface: .dark)
} else {
self?.component.descriptiveIconModel = nil
}
guard let self else { return }
self.setDescriptionIconForm()
}
showDirectionalIconSwitch.onChange = { [weak self] sender in
if sender.isOn {
self?.showDescriptionIconSwitch.isOn = false
self?.component.directionalIconModel = .init(size: .medium, surface: .dark)
} else {
self?.component.directionalIconModel = nil
}
guard let self else { return }
self.setDirectionalIconForm()
}
eyebrowIsBold.publisher(for: .valueChanged).sink { [weak self] toggle in
@ -306,6 +523,59 @@ class TileletViewController: BaseViewController<Tilelet> {
}.store(in: &subscribers)
}
func setIconColorForms() {
setDirectionalIconColorForm()
setDescriptionIconColorForm()
}
func setDescriptionIconForm() {
let showForm = showDescriptionIconSwitch.isOn
descriptionIconFormStackView.isHidden = !showForm
directionalIconFormStackView.isHidden = true
if showForm {
showDirectionalIconSwitch.isOn = false
setDescriptiveIconModel()
} else {
component.descriptiveIconModel = nil
}
setIconColorForms()
}
func setDirectionalIconForm() {
let showForm = showDirectionalIconSwitch.isOn
directionalIconFormStackView.isHidden = !showForm
descriptionIconFormStackView.isHidden = true
if showForm {
showDescriptionIconSwitch.isOn = false
setDirectionalIconModel()
} else {
component.directionalIconModel = nil
}
setIconColorForms()
}
func setDirectionalIconColorForm() {
let selectedItem = directionalIconColorPickerSelectorView.selectedItem
if showDirectionalIconSwitch.isOn && selectedItem != .default {
directionalIconTokenFormStackView.isHidden = selectedItem != .token
directionalIconColorFormStackView.isHidden = selectedItem != .custom
} else {
directionalIconTokenFormStackView.isHidden = true
directionalIconColorFormStackView.isHidden = true
}
}
func setDescriptionIconColorForm() {
let selectedItem = descriptionIconColorPickerSelectorView.selectedItem
if showDescriptionIconSwitch.isOn && selectedItem != .default {
descriptionIconTokenFormStackView.isHidden = selectedItem != .token
descriptionIconColorFormStackView.isHidden = selectedItem != .custom
} else {
descriptionIconTokenFormStackView.isHidden = true
descriptionIconColorFormStackView.isHidden = true
}
}
func setupModel() {
let titleModel = Tilelet.TitleModel(text: "Save $XX on your monthly bill.")
let subTitleModel = Tilelet.SubTitleModel(text: "Enroll in Auto Pay & paper-free billing to save on your monthly bill.")
@ -320,13 +590,20 @@ class TileletViewController: BaseViewController<Tilelet> {
surfacePickerSelectorView.text = component.surface.rawValue
otherStandardStylePickerSelectorView.text = subTitleModel.otherStandardStyle.rawValue
titleStandardStylePickerSelectorView.text = titleModel.standardStyle.rawValue
subtitleColorPickerSelectorView.text = subTitleModel.textColor.rawValue
titleTextField.text = titleModel.text
subTitleTextField.text = subTitleModel.text
widthTextField.text = component.width != nil ? "\(component.width!)" : ""
textPositionPickerSelectorView.text = component.textPostion.rawValue
scalingTypePickerSelectorView.text = component.aspectRatio.rawValue
updateOtherTextStyles()
descriptionIconCustomColorView.selectedColor = VDSColor.elementsPrimaryOnlight
descriptionNamePickerSelectorView.text = Icon.Name.multipleDocuments.rawValue
descriptionIconSizePickerSelectorView.text = Icon.Size.medium.rawValue
directionalIconCustomColorView.selectedColor = VDSColor.elementsPrimaryOnlight
directionIconPickerSelectorView.text = Tilelet.DirectionalIcon.IconType.rightArrow.rawValue
directionIconSizePickerSelectorView.text = Tilelet.DirectionalIcon.IconSize.medium.rawValue
}
//sub models
@ -340,7 +617,21 @@ class TileletViewController: BaseViewController<Tilelet> {
func setTitleModel() {
if let text = titleTextField.text, !text.isEmpty {
component.titleModel = Tilelet.TitleModel(text: text, isBold: titleIsBold.isOn, standardStyle: titleStandardStylePickerSelectorView.selectedItem)
var textColor: TitleLockup.TitleTextColor
switch titleColorPickerSelectorView.selectedItem {
case .primary:
textColor = .primary
case .token:
textColor = .token(titleTokenColorView.selectedItem)
case .custom:
if let color = titleCustomColorView.selectedColor {
textColor = .custom(color)
} else {
textColor = .custom(VDSColor.elementsPrimaryOnlight)
}
}
component.titleModel = Tilelet.TitleModel(text: text, textColor: textColor, isBold: titleIsBold.isOn, standardStyle: titleStandardStylePickerSelectorView.selectedItem)
} else {
component.titleModel = nil
}
@ -348,7 +639,23 @@ class TileletViewController: BaseViewController<Tilelet> {
func setSubTitleModel() {
if let text = subTitleTextField.text, !text.isEmpty {
component.subTitleModel = Tilelet.SubTitleModel(text: text, otherStandardStyle: otherStandardStylePickerSelectorView.selectedItem)
var textColor: TitleLockup.TextColor
switch subtitleColorPickerSelectorView.selectedItem {
case .primary:
textColor = .primary
case .secondary:
textColor = .secondary
case .token:
textColor = .token(subtitleTokenColorView.selectedItem)
case .custom:
if let color = subtitleCustomColorView.selectedColor {
textColor = .custom(color)
} else {
textColor = .custom(VDSColor.elementsPrimaryOnlight)
}
}
component.subTitleModel = Tilelet.SubTitleModel(text: text, otherStandardStyle: otherStandardStylePickerSelectorView.selectedItem, textColor: textColor)
} else {
component.subTitleModel = nil
}
@ -356,12 +663,57 @@ class TileletViewController: BaseViewController<Tilelet> {
func setEyebrowModel() {
if let text = eyebrowTextField.text, !text.isEmpty {
component.eyebrowModel = Tilelet.EyebrowModel(text: text, isBold: eyebrowIsBold.isOn, standardStyle: otherStandardStylePickerSelectorView.selectedItem)
var textColor: TitleLockup.TextColor
switch eyebrowColorPickerSelectorView.selectedItem {
case .primary:
textColor = .primary
case .secondary:
textColor = .secondary
case .token:
textColor = .token(eyebrowTokenColorView.selectedItem)
case .custom:
if let color = eyebrowCustomColorView.selectedColor {
textColor = .custom(color)
} else {
textColor = .custom(VDSColor.elementsPrimaryOnlight)
}
}
component.eyebrowModel = Tilelet.EyebrowModel(text: text, textColor: textColor, isBold: eyebrowIsBold.isOn, standardStyle: otherStandardStylePickerSelectorView.selectedItem)
} else {
component.eyebrowModel = nil
}
}
func setDescriptiveIconModel() {
let iconSize = descriptionIconSizePickerSelectorView.selectedItem
let iconName = descriptionNamePickerSelectorView.selectedItem
var iconColor: Tilelet.IconColor? = nil
switch descriptionIconColorPickerSelectorView.selectedItem {
case .token:
iconColor = .token(descriptionIconTokenColorView.selectedItem)
case .custom:
iconColor = .custom(descriptionIconCustomColorView.selectedColor ?? .white)
default:
break
}
component.descriptiveIconModel = .init(name: iconName, iconColor: iconColor, size: iconSize)
}
func setDirectionalIconModel() {
let iconType = directionIconPickerSelectorView.selectedItem
let iconSize = directionIconSizePickerSelectorView.selectedItem
var iconColor: Tilelet.IconColor? = nil
switch directionalIconColorPickerSelectorView.selectedItem {
case .token:
iconColor = .token(directionalIconTokenColorView.selectedItem)
case .custom:
iconColor = .custom(directionalIconCustomColorView.selectedColor ?? .white)
default:
break
}
component.directionalIconModel = .init(iconType: iconType, iconColor: iconColor, size: iconSize)
}
func updateOtherTextStyles() {
let items = component.titleLockup.standardStyleConfiguration.configuration(for: titleStandardStylePickerSelectorView.selectedItem.value)!.allOtherStandardStyles
let otheritems = items.compactMap { Tilelet.SubTitleModel.OtherStandardStyle(rawValue: $0.rawValue)! }
@ -387,10 +739,6 @@ class TileletViewController: BaseViewController<Tilelet> {
self?.setSubTitleModel()
}
subtitleColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.setSubTitleModel()
}
textPositionPickerSelectorView.onPickerDidSelect = { [weak self] item in
guard let self else { return }
self.component.textPostion = item
@ -436,6 +784,75 @@ class TileletViewController: BaseViewController<Tilelet> {
self.present(self.colorPicker, animated: true)
}
}
eyebrowColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.currentSurfaceColorType = .eyebrow
self?.eyebrowTokenFormStackView.isHidden = item != .token
self?.eyebrowColorFormStackView.isHidden = item != .custom
self?.setEyebrowModel()
}
eyebrowTokenColorView.onPickerDidSelect = { [weak self] item in
self?.setEyebrowModel()
}
titleColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.currentSurfaceColorType = .title
self?.titleTokenFormStackView.isHidden = item != .token
self?.titleColorFormStackView.isHidden = item != .custom
self?.setTitleModel()
}
titleTokenColorView.onPickerDidSelect = { [weak self] item in
self?.setTitleModel()
}
subtitleColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.currentSurfaceColorType = .subtitle
self?.subtitleTokenFormStackView.isHidden = item != .token
self?.subtitleColorFormStackView.isHidden = item != .custom
self?.setSubTitleModel()
}
subtitleTokenColorView.onPickerDidSelect = { [weak self] item in
self?.setSubTitleModel()
}
descriptionIconColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.setIconColorForms()
self?.setDescriptiveIconModel()
}
descriptionNamePickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.setDescriptiveIconModel()
}
descriptionIconSizePickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.setDescriptiveIconModel()
}
descriptionIconTokenColorView.onPickerDidSelect = { [weak self] item in
self?.colorPickerType = .token
self?.setDescriptiveIconModel()
}
directionalIconColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.setIconColorForms()
self?.setDirectionalIconModel()
}
directionIconPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.setDirectionalIconModel()
}
directionIconSizePickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.setDirectionalIconModel()
}
directionalIconTokenColorView.onPickerDidSelect = { [weak self] item in
self?.colorPickerType = .token
self?.setDirectionalIconModel()
}
}
func getTilelet(effect: TileContainer.BackgroundEffect) -> Tilelet.BackgroundEffect {
@ -494,24 +911,57 @@ extension TileletViewController: UIColorPickerViewControllerDelegate {
}
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
guard let hexString = viewController.selectedColor.hexString else { return }
let color = viewController.selectedColor
var lightColorView: ColorPickerView<ColorPickerType>
var darkColorView: ColorPickerView<ColorPickerType>
switch colorPickerType {
case .contentViewBackgroundColor:
component.containerView.backgroundColor = UIColor(hexString: hexString)
component.contentView.backgroundColor = color
case .backgroundColor:
component.color = .custom(hexString)
component.color = .custom(color)
case .gradientColor1:
gradientColorView1.selectedColor = viewController.selectedColor
updateGradientColors()
case .gradientColor2:
gradientColorView2.selectedColor = viewController.selectedColor
updateGradientColors()
case .custom:
var colorView: ColorPickerView<ColorPickerType>
switch currentSurfaceColorType {
case .eyebrow:
colorView = eyebrowCustomColorView
case .title:
colorView = titleCustomColorView
case .subtitle:
colorView = subtitleCustomColorView
case .directionalIcon:
colorView = directionalIconCustomColorView
case .descriptionIcon:
colorView = descriptionIconCustomColorView
}
colorView.selectedColor = viewController.selectedColor
switch currentSurfaceColorType {
case .eyebrow:
setEyebrowModel()
case .title:
setTitleModel()
case .subtitle:
setSubTitleModel()
case .directionalIcon:
setDirectionalIconModel()
case .descriptionIcon:
setDescriptiveIconModel()
}
default:
break
}
}
func updateGradientColors(){
if let selectedGradient1Color = gradientColorView1.selectedColor?.hexString,
let selectedGradient2Color = gradientColorView2.selectedColor?.hexString{
if let selectedGradient1Color = gradientColorView1.selectedColor,
let selectedGradient2Color = gradientColorView2.selectedColor{
component.backgroundEffect = .gradient(selectedGradient1Color, selectedGradient2Color)
}
}

View File

@ -29,12 +29,6 @@ class TitleLockupViewController: BaseViewController<TitleLockup> {
picker: self.picker,
items: TitleLockup.OtherStandardStyle.allCases.sorted{ $0.rawValue < $1.rawValue })
}()
lazy var subtitleColorPickerSelectorView = {
PickerSelectorView<Use>(title: "",
picker: self.picker,
items: [.primary, .secondary])
}()
var titleIsBold = Toggle().with { $0.isOn = true }
var eyebrowIsBold = Toggle().with { $0.isOn = true }
@ -42,6 +36,103 @@ class TitleLockupViewController: BaseViewController<TitleLockup> {
var titleTextField = TextField()
var subTitleTextField = TextField()
/// **********************************************
/// Text Color
lazy var colorPicker: UIColorPickerViewController = {
let picker = UIColorPickerViewController()
picker.delegate = self
return picker
}()
var currentLabelType: LabelType = .title
var colorPickerType: ColorPickerType = .custom
enum LabelType {
case eyebrow, title, subtitle
}
enum TitleTextColor: String, CaseIterable {
case primary, token, custom
}
enum TextColor: String, CaseIterable {
case primary, secondary, token, custom
}
enum ColorPickerType {
case custom
}
/// eyebrow
var eyebrowTokenFormStackView = FormSection().with { $0.isHidden = true }
var eyebrowColorFormStackView = FormSection().with { $0.isHidden = true }
lazy var eyebrowColorPickerSelectorView = {
PickerSelectorView(title: "primary",
picker: self.picker,
items: TextColor.allCases)
}()
lazy var eyebrowTokenColorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: UIColor.VDSColor.allCases)
.with { $0.text = UIColor.VDSColor.paletteBlack.rawValue }
}()
lazy var eyebrowCustomColorView: ColorPickerView<ColorPickerType> = {
return .init(with: ColorPickerType.custom, color: .black) { [weak self] picker in
self?.colorPickerType = picker.pickerType
self?.selectedColorTapped(picker)
}
}()
/// title
var titleTokenFormStackView = FormSection().with { $0.isHidden = true }
var titleColorFormStackView = FormSection().with { $0.isHidden = true }
lazy var titleColorPickerSelectorView = {
PickerSelectorView(title: "primary",
picker: self.picker,
items: TitleTextColor.allCases)
}()
lazy var titleTokenColorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: UIColor.VDSColor.allCases)
.with { $0.text = UIColor.VDSColor.paletteBlack.rawValue }
}()
lazy var titleCustomColorView: ColorPickerView<ColorPickerType> = {
return .init(with: ColorPickerType.custom, color: .black) { [weak self] picker in
self?.colorPickerType = picker.pickerType
self?.selectedColorTapped(picker)
}
}()
/// subtitle
var subtitleTokenFormStackView = FormSection().with { $0.isHidden = true }
var subtitleColorFormStackView = FormSection().with { $0.isHidden = true }
lazy var subtitleColorPickerSelectorView = {
PickerSelectorView(title: "primary",
picker: self.picker,
items: TextColor.allCases)
}()
lazy var subtitleTokenColorView = {
PickerSelectorView(title: "",
picker: self.picker,
items: UIColor.VDSColor.allCases)
.with { $0.text = UIColor.VDSColor.paletteBlack.rawValue }
}()
lazy var subtitleCustomColorView: ColorPickerView<ColorPickerType> = {
return .init(with: ColorPickerType.custom, color: .black) { [weak self] picker in
self?.colorPickerType = picker.pickerType
self?.selectedColorTapped(picker)
}
}()
override func viewDidLoad() {
super.viewDidLoad()
addContentTopView(view: component)
@ -55,18 +146,32 @@ class TitleLockupViewController: BaseViewController<TitleLockup> {
addFormRow(label: "Surface", view: surfacePickerSelectorView)
addFormRow(label: "Text Alignment", view: textAlignmentPickerSelectorView)
addFormRow(label: "Title is Bold", view: titleIsBold)
addFormRow(label: "Eyebrow/Subtitle Style", view: otherStandardStylePickerSelectorView)
addFormRow(label: "Eyebrow is Bold", view: eyebrowIsBold)
addFormRow(label: "Title Style", view: titleStandardStylePickerSelectorView)
addFormRow(label: "Other Style", view: otherStandardStylePickerSelectorView)
addFormRow(label: "Eyebrow Text", view: eyebrowTextField)
addFormRow(label: "Eyebrow Color", view: eyebrowColorPickerSelectorView)
eyebrowTokenFormStackView.addFormRow(label: "Token", view: eyebrowTokenColorView)
eyebrowColorFormStackView.addFormRow(label: "Custom", view: eyebrowCustomColorView)
append(section: eyebrowTokenFormStackView)
append(section: eyebrowColorFormStackView)
addFormRow(label: "Title is Bold", view: titleIsBold)
addFormRow(label: "Title Style", view: titleStandardStylePickerSelectorView)
addFormRow(label: "Title Text", view: titleTextField)
addFormRow(label: "Title Color", view: titleColorPickerSelectorView)
titleTokenFormStackView.addFormRow(label: "Token", view: titleTokenColorView)
titleColorFormStackView.addFormRow(label: "Custom", view: titleCustomColorView)
append(section: titleTokenFormStackView)
append(section: titleColorFormStackView)
addFormRow(label: "Subtitle Color", view: subtitleColorPickerSelectorView)
addFormRow(label: "Subtitle Text", view: subTitleTextField)
addFormRow(label: "Subtitle Color", view: subtitleColorPickerSelectorView)
subtitleTokenFormStackView.addFormRow(label: "Token", view: subtitleTokenColorView)
subtitleColorFormStackView.addFormRow(label: "Custom", view: subtitleCustomColorView)
append(section: subtitleTokenFormStackView)
append(section: subtitleColorFormStackView)
eyebrowIsBold.publisher(for: .valueChanged).sink { [weak self] toggle in
self?.setOtherModels()
}.store(in: &subscribers)
@ -108,7 +213,6 @@ class TitleLockupViewController: BaseViewController<TitleLockup> {
textAlignmentPickerSelectorView.text = TextAlignment.left.rawValue
otherStandardStylePickerSelectorView.text = subTitleModel.otherStandardStyle.rawValue
titleStandardStylePickerSelectorView.text = titleModel.standardStyle.rawValue
subtitleColorPickerSelectorView.text = subTitleModel.textColor.rawValue
eyebrowTextField.text = eyebrowModel.text
titleTextField.text = titleModel.text
subTitleTextField.text = subTitleModel.text
@ -120,7 +224,22 @@ class TitleLockupViewController: BaseViewController<TitleLockup> {
func setTitleModel() {
var titleTextStyle: TextStyle?
if let text = titleTextField.text, !text.isEmpty {
component.titleModel = TitleLockup.TitleModel(text: text, isBold: titleIsBold.isOn, standardStyle: titleStandardStylePickerSelectorView.selectedItem)
var textColor: TitleLockup.TitleTextColor
switch titleColorPickerSelectorView.selectedItem {
case .primary:
textColor = .primary
case .token:
textColor = .token(titleTokenColorView.selectedItem)
case .custom:
if let color = titleCustomColorView.selectedColor {
textColor = .custom(color)
} else {
textColor = .custom(VDSColor.elementsPrimaryOnlight)
}
}
component.titleModel = TitleLockup.TitleModel(text: text, textColor: textColor, isBold: titleIsBold.isOn, standardStyle: titleStandardStylePickerSelectorView.selectedItem)
titleTextStyle = titleIsBold.isOn ? titleStandardStylePickerSelectorView.selectedItem.value.bold : titleStandardStylePickerSelectorView.selectedItem.value.regular
} else {
component.titleModel = nil
@ -139,16 +258,46 @@ class TitleLockupViewController: BaseViewController<TitleLockup> {
let style = otherStandardStylePickerSelectorView.selectedItem
if let text = subTitleTextField.text, !text.isEmpty {
component.subTitleModel = TitleLockup.SubTitleModel(text: text, otherStandardStyle: style, textColor: subtitleColorPickerSelectorView.selectedItem)
var textColor: TitleLockup.TextColor
switch subtitleColorPickerSelectorView.selectedItem {
case .primary:
textColor = .primary
case .secondary:
textColor = .secondary
case .token:
textColor = .token(subtitleTokenColorView.selectedItem)
case .custom:
if let color = subtitleCustomColorView.selectedColor {
textColor = .custom(color)
} else {
textColor = .custom(VDSColor.elementsPrimaryOnlight)
}
}
component.subTitleModel = TitleLockup.SubTitleModel(text: text, otherStandardStyle: style, textColor: textColor)
debug(type: "SubTitle", textStyle: style.value.regular)
} else {
component.subTitleModel = nil
}
if let text = eyebrowTextField.text, !text.isEmpty {
component.eyebrowModel = TitleLockup.EyebrowModel(text: text, isBold: eyebrowIsBold.isOn, standardStyle: style)
var textColor: TitleLockup.TextColor
switch eyebrowColorPickerSelectorView.selectedItem {
case .primary:
textColor = .primary
case .secondary:
textColor = .secondary
case .token:
textColor = .token(eyebrowTokenColorView.selectedItem)
case .custom:
if let color = eyebrowCustomColorView.selectedColor {
textColor = .custom(color)
} else {
textColor = .custom(VDSColor.elementsPrimaryOnlight)
}
}
component.eyebrowModel = TitleLockup.EyebrowModel(text: text, textColor: textColor, isBold: eyebrowIsBold.isOn, standardStyle: style)
debug(type: "EyeBrow", textStyle: eyebrowIsBold.isOn ? style.value.bold : style.value.regular)
} else {
component.eyebrowModel = nil
}
@ -178,8 +327,38 @@ class TitleLockupViewController: BaseViewController<TitleLockup> {
otherStandardStylePickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.setOtherModels()
}
eyebrowColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.currentLabelType = .eyebrow
self?.eyebrowTokenFormStackView.isHidden = item != .token
self?.eyebrowColorFormStackView.isHidden = item != .custom
self?.setOtherModels()
}
eyebrowTokenColorView.onPickerDidSelect = { [weak self] item in
self?.setOtherModels()
}
titleColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.currentLabelType = .title
self?.titleTokenFormStackView.isHidden = item != .token
self?.titleColorFormStackView.isHidden = item != .custom
self?.setTitleModel()
}
titleTokenColorView.onPickerDidSelect = { [weak self] item in
self?.setTitleModel()
}
subtitleColorPickerSelectorView.onPickerDidSelect = { [weak self] item in
self?.currentLabelType = .subtitle
self?.subtitleTokenFormStackView.isHidden = item != .token
self?.subtitleColorFormStackView.isHidden = item != .custom
self?.setOtherModels()
}
subtitleTokenColorView.onPickerDidSelect = { [weak self] item in
self?.setOtherModels()
}
}
@ -198,3 +377,40 @@ extension TitleLockupViewController: ComponentSampleable {
return ComponentSample(component: component)
}
}
extension TitleLockupViewController: UIColorPickerViewControllerDelegate {
func selectedColorTapped(_ picker: ColorPickerView<ColorPickerType>) {
let selectedColor = picker.selectedColor
if let selectedColor {
colorPicker.selectedColor = selectedColor
}
present(colorPicker, animated: true)
}
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
dismiss(animated: true)
}
func colorPickerViewControllerDidSelectColor(_ viewController: UIColorPickerViewController) {
guard let hexString = viewController.selectedColor.hexString else { return }
var colorView: ColorPickerView<ColorPickerType>
switch currentLabelType {
case .eyebrow:
colorView = eyebrowCustomColorView
case .title:
colorView = titleCustomColorView
case .subtitle:
colorView = subtitleCustomColorView
}
colorView.selectedColor = viewController.selectedColor
if currentLabelType == .title {
setTitleModel()
} else {
setOtherModels()
}
}
}

View File

@ -0,0 +1,11 @@
//
// workspaceSettings.xcconfig
//
//
// Created by Matt Bruce on 6/3/24.
//
// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974
VDS_ADD_CHANGELOG_FILES = 1