added the Loader class and SVG Asset

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2023-07-05 15:16:28 -05:00
parent 4154b13c08
commit 2ffc8f5293
5 changed files with 123 additions and 0 deletions

View File

@ -109,6 +109,7 @@
EAC9258F2911C9DE00091998 /* EntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC9258B2911C9DE00091998 /* EntryField.swift */; };
EAD062A72A3B67770015965D /* UIView+CALayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD062A62A3B67770015965D /* UIView+CALayer.swift */; };
EAD062B02A3B873E0015965D /* BadgeIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD062AF2A3B873E0015965D /* BadgeIndicator.swift */; };
EAD0688E2A55F819002E3A2D /* Loader.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD0688D2A55F819002E3A2D /* Loader.swift */; };
EAD8D2C128BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */; };
EAF1FE9929D4850E00101452 /* Clickable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF1FE9829D4850E00101452 /* Clickable.swift */; };
EAF1FE9B29DB1A6000101452 /* Changeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF1FE9A29DB1A6000101452 /* Changeable.swift */; };
@ -243,6 +244,7 @@
EAC9258B2911C9DE00091998 /* EntryField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryField.swift; sourceTree = "<group>"; };
EAD062A62A3B67770015965D /* UIView+CALayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+CALayer.swift"; sourceTree = "<group>"; };
EAD062AF2A3B873E0015965D /* BadgeIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeIndicator.swift; sourceTree = "<group>"; };
EAD0688D2A55F819002E3A2D /* Loader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Loader.swift; sourceTree = "<group>"; };
EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIGestureRecognizer+Publisher.swift"; sourceTree = "<group>"; };
EAF1FE9829D4850E00101452 /* Clickable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Clickable.swift; sourceTree = "<group>"; };
EAF1FE9A29DB1A6000101452 /* Changeable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Changeable.swift; sourceTree = "<group>"; };
@ -407,6 +409,7 @@
EA985BF3296C609E00F2FF2E /* Icon */,
EA3362412892EF700071C351 /* Label */,
44604AD529CE195300E62B51 /* Line */,
EAD0688C2A55F801002E3A2D /* Loader */,
445BA07629C07ABA0036A7C5 /* Notification */,
EA89200B28B530F0006B9984 /* RadioBox */,
EAF7F11428A1470D00B287F5 /* RadioButton */,
@ -703,6 +706,14 @@
path = BadgeIndicator;
sourceTree = "<group>";
};
EAD0688C2A55F801002E3A2D /* Loader */ = {
isa = PBXGroup;
children = (
EAD0688D2A55F819002E3A2D /* Loader.swift */,
);
path = Loader;
sourceTree = "<group>";
};
EAF7F092289985E200B287F5 /* Checkbox */ = {
isa = PBXGroup;
children = (
@ -918,6 +929,7 @@
EAF7F0A2289AFB3900B287F5 /* Errorable.swift in Sources */,
EA985C7D297DAED300F2FF2E /* Primitive.swift in Sources */,
EAF1FE9929D4850E00101452 /* Clickable.swift in Sources */,
EAD0688E2A55F819002E3A2D /* Loader.swift in Sources */,
EAB5FEF829393A7200998C17 /* ButtonGroupConstants.swift in Sources */,
EA3361AF288B26310071C351 /* FormFieldable.swift in Sources */,
EA513A952A4E1F82002A4DFF /* TitleLockupStyleConfiguration.swift in Sources */,

View File

@ -0,0 +1,89 @@
//
// Loader.swift
// VDS
//
// Created by Matt Bruce on 7/5/23.
//
import Foundation
import UIKit
import VDSColorTokens
@objc(VDSLoader)
/// A loader is an indicator that uses animation to show customers that there is an indefinite amount of wait time while a task is ongoing, e.g. a page is loading, a form is being submitted. The component disappears when the task is complete.
open class Loader: View {
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
private var icon = Icon().with { $0.name = .loader }
private var opacity: CGFloat = 0.8
private var iconColorConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark)
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
/// Loader will be active if 'active' prop is passed.
public var isActive: Bool = true { didSet { setNeedsUpdate() } }
/// The Int used to determine the height and width of the Loader
public var size: Int = 40 { didSet { setNeedsUpdate() } }
//--------------------------------------------------
// MARK: - Lifecycle
//--------------------------------------------------
override open var layer: CAShapeLayer {
get { return super.layer as! CAShapeLayer }
}
override open class var layerClass: AnyClass {
return CAShapeLayer.self
}
open override func setup() {
super.setup()
addSubview(icon)
NSLayoutConstraint.activate([
icon.centerXAnchor.constraint(equalTo: centerXAnchor),
icon.centerYAnchor.constraint(equalTo: centerYAnchor),
icon.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor),
icon.trailingAnchor.constraint(lessThanOrEqualTo: trailingAnchor),
icon.topAnchor.constraint(greaterThanOrEqualTo: topAnchor),
icon.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor)
])
}
open override func updateView() {
super.updateView()
icon.color = iconColorConfiguration.getColor(self)
icon.customSize = size
if isActive {
startAnimating()
} else {
stopAnimating()
}
}
//--------------------------------------------------
// MARK: - Animation
//--------------------------------------------------
private let rotationLayerName = "rotationAnimation"
func startAnimating() {
icon.layer.remove(layerName: rotationLayerName)
let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotation.toValue = NSNumber(value: Double.pi * 2)
rotation.duration = 0.5 // the speed of the rotation
rotation.isCumulative = true
rotation.repeatCount = Float.greatestFiniteMagnitude
icon.layer.add(rotation, forKey: rotationLayerName)
}
func stopAnimating() {
icon.layer.removeAnimation(forKey: rotationLayerName)
}
}
extension Icon.Name {
static let loader = Icon.Name(name: "loader")
}

View File

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

View File

@ -0,0 +1,3 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="Loader" fill-rule="evenodd" clip-rule="evenodd" d="M20 0C8.96842 0 0 8.96842 0 20C0 20.7158 0.0421053 21.4105 0.115789 22.1053H4.36842C4.27368 21.4105 4.21053 20.7158 4.21053 20C4.21053 11.2947 11.2947 4.21053 20 4.21053C28.7053 4.21053 35.7895 11.2947 35.7895 20C35.7895 28.7053 28.7053 35.7895 20 35.7895C19.6421 35.7895 19.2947 35.7579 18.9474 35.7368V39.9474C19.2947 39.9684 19.6421 40 20 40C31.0316 40 40 31.0316 40 20C40 8.96842 31.0316 0 20 0Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 580 B

View File

@ -1,3 +1,7 @@
1.0.27
=======
- Added Loader View
1.0.26
=======
- CXTDT-426626 - Toggle - Disabled "on" state