Digital ACT-191 ONEAPP-7013 story: slot alignment and rendering data
This commit is contained in:
parent
8619c64109
commit
77288e4c54
@ -7,6 +7,8 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
18013CED2C355BF900907F18 /* CarouselSlotItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18013CEC2C355BF900907F18 /* CarouselSlotItemModel.swift */; };
|
||||
18013CEF2C355C5200907F18 /* CarouselRenderItemStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18013CEE2C355C5200907F18 /* CarouselRenderItemStyle.swift */; };
|
||||
1808BEBC2BA41C3200129230 /* CarouselScrollbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1808BEBB2BA41C3200129230 /* CarouselScrollbar.swift */; };
|
||||
1832AC572BA0791D008AE476 /* BreadcrumbCellItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1832AC562BA0791D008AE476 /* BreadcrumbCellItem.swift */; };
|
||||
1842B1DF2BECE28B0021AFCA /* CalendarDateViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1842B1DE2BECE28B0021AFCA /* CalendarDateViewCell.swift */; };
|
||||
@ -19,11 +21,9 @@
|
||||
18A65A022B96E848006602CC /* Breadcrumbs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18A65A012B96E848006602CC /* Breadcrumbs.swift */; };
|
||||
18A65A042B96F050006602CC /* BreadcrumbItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18A65A032B96F050006602CC /* BreadcrumbItem.swift */; };
|
||||
18AE87502C06FDA60075F181 /* Carousel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18AE874F2C06FDA60075F181 /* Carousel.swift */; };
|
||||
18AE87542C06FE610075F181 /* CarouselChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 18AE87532C06FE610075F181 /* CarouselChangeLog.txt */; };
|
||||
18B42AC62C09D197008D6262 /* CarouselSlotAlignmentModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18B42AC52C09D197008D6262 /* CarouselSlotAlignmentModel.swift */; };
|
||||
18B463A42BBD3C46005C4528 /* DropdownOptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18B463A32BBD3C46005C4528 /* DropdownOptionModel.swift */; };
|
||||
18B9763F2C11BA4A009271DF /* CarouselPaginationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18B9763E2C11BA4A009271DF /* CarouselPaginationModel.swift */; };
|
||||
18BDEE822B75316E00452358 /* ButtonIconChangeLog.txt in Resources */ = {isa = PBXBuildFile; fileRef = 18BDEE812B75316E00452358 /* ButtonIconChangeLog.txt */; };
|
||||
18FEA1AD2BDD137500A56439 /* CalendarIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18FEA1AC2BDD137500A56439 /* CalendarIndicatorModel.swift */; };
|
||||
18FEA1B52BE0E63600A56439 /* Date+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18FEA1B42BE0E63600A56439 /* Date+Extension.swift */; };
|
||||
445BA07829C07B3D0036A7C5 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 445BA07729C07B3D0036A7C5 /* Notification.swift */; };
|
||||
@ -209,6 +209,8 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
18013CEC2C355BF900907F18 /* CarouselSlotItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselSlotItemModel.swift; sourceTree = "<group>"; };
|
||||
18013CEE2C355C5200907F18 /* CarouselRenderItemStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselRenderItemStyle.swift; sourceTree = "<group>"; };
|
||||
1808BEBB2BA41C3200129230 /* CarouselScrollbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselScrollbar.swift; sourceTree = "<group>"; };
|
||||
1808BEBF2BA456B700129230 /* CarouselScrollbarChangeLog.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CarouselScrollbarChangeLog.txt; sourceTree = "<group>"; };
|
||||
1832AC562BA0791D008AE476 /* BreadcrumbCellItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BreadcrumbCellItem.swift; sourceTree = "<group>"; };
|
||||
@ -502,6 +504,8 @@
|
||||
18AE874F2C06FDA60075F181 /* Carousel.swift */,
|
||||
18B9763E2C11BA4A009271DF /* CarouselPaginationModel.swift */,
|
||||
18B42AC52C09D197008D6262 /* CarouselSlotAlignmentModel.swift */,
|
||||
18013CEC2C355BF900907F18 /* CarouselSlotItemModel.swift */,
|
||||
18013CEE2C355C5200907F18 /* CarouselRenderItemStyle.swift */,
|
||||
18AE87532C06FE610075F181 /* CarouselChangeLog.txt */,
|
||||
);
|
||||
path = Carousel;
|
||||
@ -1363,6 +1367,7 @@
|
||||
EAC71A1D2A2E155A00E47A9F /* Checkbox.swift in Sources */,
|
||||
EAF7F0AB289B13FD00B287F5 /* TextStyleLabelAttribute.swift in Sources */,
|
||||
18AE87502C06FDA60075F181 /* Carousel.swift in Sources */,
|
||||
18013CEF2C355C5200907F18 /* CarouselRenderItemStyle.swift in Sources */,
|
||||
EAB1D29C28A5618900DAE764 /* RadioButtonGroup.swift in Sources */,
|
||||
EA81410B2A0E8E3C004F60D2 /* ButtonIcon.swift in Sources */,
|
||||
EA985BE629688F6A00F2FF2E /* TileletBadgeModel.swift in Sources */,
|
||||
@ -1405,6 +1410,7 @@
|
||||
EA596ABF2A16B4F500300C4B /* Tabs.swift in Sources */,
|
||||
EAD062A72A3B67770015965D /* UIView+CALayer.swift in Sources */,
|
||||
EAD068942A560C13002E3A2D /* LoaderLaunchable.swift in Sources */,
|
||||
18013CED2C355BF900907F18 /* CarouselSlotItemModel.swift in Sources */,
|
||||
18FEA1AD2BDD137500A56439 /* CalendarIndicatorModel.swift in Sources */,
|
||||
EA985BEC2968A91200F2FF2E /* TitleLockupTitleModel.swift in Sources */,
|
||||
5FC35BE328D51405004EBEAC /* Button.swift in Sources */,
|
||||
|
||||
@ -33,21 +33,6 @@ open class Carousel: View {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Enums
|
||||
//--------------------------------------------------
|
||||
/// Space between each tile. The default value will be 24px (6X) in tablet and 12px (3X) in mobile.
|
||||
public enum Gutter: String, CaseIterable {
|
||||
case twelvePX = "12px"
|
||||
case twentyFourPX = "24px"
|
||||
|
||||
var value: CGFloat {
|
||||
switch self {
|
||||
case .twelvePX:
|
||||
VDSLayout.space3X
|
||||
case .twentyFourPX:
|
||||
VDSLayout.space6X
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Enum used to describe the pagination display for this component.
|
||||
public enum PaginationDisplay: String, CaseIterable {
|
||||
case persistent, none
|
||||
@ -75,6 +60,21 @@ open class Carousel: View {
|
||||
case value(CGFloat)
|
||||
}
|
||||
|
||||
/// Space between each tile. The default value will be 24px (6X) in tablet and 12px (3X) in mobile.
|
||||
public enum Gutter: String, CaseIterable {
|
||||
case twelvePX = "12px"
|
||||
case twentyFourPX = "24px"
|
||||
|
||||
var value: CGFloat {
|
||||
switch self {
|
||||
case .twelvePX:
|
||||
VDSLayout.space3X
|
||||
case .twentyFourPX:
|
||||
VDSLayout.space6X
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
@ -123,11 +123,12 @@ open class Carousel: View {
|
||||
get { return _layout }
|
||||
set {
|
||||
_layout = newValue
|
||||
carouselScrollBar.position = 0
|
||||
setNeedsUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
/// A callback when moving the carousel. Returns event object and selectedGroupIndex.
|
||||
/// A callback when moving the carousel. Returns initial visible slide's index in the carousel.
|
||||
open var onChange: ((Int) -> Void)? {
|
||||
get { nil }
|
||||
set {
|
||||
@ -182,7 +183,42 @@ open class Carousel: View {
|
||||
open var selectedIndex: Int? { didSet { setNeedsUpdate() } }
|
||||
|
||||
/// If provided, will set the alignment for slot content when the slots has different heights.
|
||||
open var slotAlignment: [CarouselSlotAlignmentModel] = [] { didSet { setNeedsUpdate() } }
|
||||
open var slotAlignment: CarouselSlotAlignmentModel? {
|
||||
get { return _slotAlignment }
|
||||
set {
|
||||
if let newValue {
|
||||
_slotAlignment = newValue
|
||||
} else {
|
||||
_slotAlignment = nil
|
||||
}
|
||||
setNeedsUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
/// Render item style. If provided, the slot gets the background, width, height, border-radius.
|
||||
open var renderItemStyle: CarouselRenderItemStyle? {
|
||||
get { return _renderItemStyle }
|
||||
set {
|
||||
if let newValue {
|
||||
_renderItemStyle = newValue
|
||||
} else {
|
||||
_renderItemStyle = nil
|
||||
}
|
||||
setNeedsUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
/// Render item. It passes a data array object and expects the styled component to apply in return.
|
||||
open var renderItem: CarouselSlotItemModel? {
|
||||
get { _renderItem }
|
||||
set {
|
||||
if let newValue {
|
||||
_renderItem = newValue
|
||||
} else {
|
||||
_renderItem = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Properties
|
||||
@ -250,9 +286,12 @@ open class Carousel: View {
|
||||
internal var _gutter: Gutter = UIDevice.isIPad ? .twentyFourPX : .twelvePX
|
||||
internal var _peek: Peek = .standard
|
||||
internal var _numberOfSlides: Int = 1
|
||||
internal var _slotAlignment: CarouselSlotAlignmentModel? = nil
|
||||
internal var _renderItemStyle: CarouselRenderItemStyle? = nil
|
||||
internal var _renderItem: CarouselSlotItemModel? = nil
|
||||
|
||||
private var _width: Width? = nil
|
||||
private var selectedGroupIndex: Int? { didSet { setNeedsUpdate() } }
|
||||
private var selectedGroupIndex: Int? = nil
|
||||
private var containerStackHeightConstraint: NSLayoutConstraint?
|
||||
private var containerViewHeightConstraint: NSLayoutConstraint?
|
||||
private var prevButtonLeadingConstraint: NSLayoutConstraint?
|
||||
@ -323,6 +362,7 @@ open class Carousel: View {
|
||||
.heightGreaterThanEqualTo(containerSize.height)
|
||||
|
||||
addlisteners()
|
||||
updatePaginationInset()
|
||||
}
|
||||
|
||||
/// Used to make changes to the View based off a change events or from local properties.
|
||||
@ -348,7 +388,9 @@ open class Carousel: View {
|
||||
|
||||
carouselScrollBar.numberOfSlides = data.count
|
||||
carouselScrollBar.layout = _layout
|
||||
carouselScrollBar.position = (carouselScrollBar.position == 0 || carouselScrollBar.position > carouselScrollBar.numberOfSlides) ? 1 : carouselScrollBar.position
|
||||
if (carouselScrollBar.position == 0 || carouselScrollBar.position > carouselScrollBar.numberOfSlides) {
|
||||
carouselScrollBar.position = 1
|
||||
}
|
||||
carouselScrollBar.isHidden = (totalPositions() <= 1) ? true : false
|
||||
|
||||
// Mobile/Tablet layouts without peek - must show pagination controls.
|
||||
@ -392,31 +434,32 @@ open class Carousel: View {
|
||||
nextButton.onClick = { _ in self.nextButtonClick() }
|
||||
previousButton.onClick = { _ in self.previousButtonClick() }
|
||||
|
||||
/// Will be called when the thumb move forward.
|
||||
/// Will be called when the scrollbar thumb move forward.
|
||||
carouselScrollBar.onMoveForward = { [weak self] scrubberId in
|
||||
guard let self else { return }
|
||||
updateScrollPosition(position: scrubberId, callbackText:"onMoveForward")
|
||||
}
|
||||
|
||||
/// Will be called when the thumb move backward.
|
||||
/// Will be called when the scrollbar thumb move backward.
|
||||
carouselScrollBar.onMoveBackward = { [weak self] scrubberId in
|
||||
guard let self else { return }
|
||||
updateScrollPosition(position: scrubberId, callbackText:"onMoveBackward")
|
||||
}
|
||||
|
||||
/// Will be called when the thumb touch start.
|
||||
/// Will be called when the scrollbar thumb touch start.
|
||||
carouselScrollBar.onThumbTouchStart = { [weak self] scrubberId in
|
||||
guard let self else { return }
|
||||
updateScrollPosition(position: scrubberId, callbackText:"onThumbTouchStart")
|
||||
}
|
||||
|
||||
/// Will be called when the thumb touch end.
|
||||
/// Will be called when the scrollbar thumb touch end.
|
||||
carouselScrollBar.onThumbTouchEnd = { [weak self] scrubberId in
|
||||
guard let self else { return }
|
||||
updateScrollPosition(position: scrubberId, callbackText:"onThumbTouchEnd")
|
||||
}
|
||||
}
|
||||
|
||||
// Update pagination buttons with selected surface, kind, floating values
|
||||
private func updatePaginationControls() {
|
||||
containerView.surface = surface
|
||||
showPaginationControls()
|
||||
@ -428,6 +471,7 @@ open class Carousel: View {
|
||||
nextButton.surface = surface
|
||||
}
|
||||
|
||||
// Show/Hide pagination buttons of Carousel based on First or Middle or Last
|
||||
private func showPaginationControls() {
|
||||
if carouselScrollBar.numberOfSlides == _layout.value {
|
||||
previousButton.isHidden = true
|
||||
@ -438,6 +482,7 @@ open class Carousel: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Add carousel slots and load data if any
|
||||
private func addCarouselSlots() {
|
||||
getSlotWidth()
|
||||
if containerView.frame.size.width > 0 {
|
||||
@ -454,6 +499,8 @@ open class Carousel: View {
|
||||
if data.count > 0 {
|
||||
var xPos = 0.0
|
||||
for x in 0...data.count - 1 {
|
||||
|
||||
// Add Carousel Slot
|
||||
let carouselSlot = View().with {
|
||||
$0.clipsToBounds = true
|
||||
$0.backgroundColor = UIColor(red: CGFloat(216) / 255.0, green: CGFloat(218) / 255.0, blue: CGFloat(218) / 255.0, alpha: 1)
|
||||
@ -470,6 +517,29 @@ open class Carousel: View {
|
||||
.height(slotHeight)
|
||||
carouselSlot.layer.cornerRadius = 12.0
|
||||
xPos = xPos + minimumSlotWidth + gutter.value
|
||||
|
||||
// Add subview for content to Carousel Slot
|
||||
let contentView = View().with {
|
||||
$0.clipsToBounds = true
|
||||
$0.backgroundColor = UIColor(red: CGFloat(216) / 255.0, green: CGFloat(218) / 255.0, blue: CGFloat(218) / 255.0, alpha: 1)
|
||||
}
|
||||
carouselSlot.addSubview(contentView)
|
||||
|
||||
// Add received component
|
||||
let item : CarouselSlotItemModel = .init(style: renderItemStyle, component: data[x] as? UIView)
|
||||
if let component = item.component {
|
||||
if slotAlignment != nil {
|
||||
setSlotAlignment(contentView: contentView, parentView: carouselSlot)
|
||||
} else {
|
||||
contentView.pinToSuperView()
|
||||
}
|
||||
contentView.addSubview(component)
|
||||
component.pinToSuperView()
|
||||
contentView.layer.cornerRadius = component.layer.cornerRadius
|
||||
if var surfacedView = component as? Surfaceable {
|
||||
surfacedView.surface = surface
|
||||
}
|
||||
}
|
||||
}
|
||||
scrollView.contentSize = CGSize(width: xPos - gutter.value, height: slotHeight)
|
||||
}
|
||||
@ -487,6 +557,37 @@ open class Carousel: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Set slot alignment if provided. Used only when slot content have different heights or widths.
|
||||
private func setSlotAlignment(contentView: View, parentView: View) {
|
||||
parentView.backgroundColor = .clear
|
||||
switch slotAlignment?.vertical {
|
||||
case .top:
|
||||
contentView.topAnchor.constraint(equalTo: parentView.topAnchor).activate()
|
||||
break
|
||||
case .middle:
|
||||
contentView.centerYAnchor.constraint(equalTo: parentView.centerYAnchor).activate()
|
||||
break
|
||||
case .bottom:
|
||||
contentView.bottomAnchor.constraint(equalTo: parentView.bottomAnchor).activate()
|
||||
break
|
||||
default: break
|
||||
}
|
||||
|
||||
switch slotAlignment?.horizontal {
|
||||
case .left:
|
||||
contentView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor).activate()
|
||||
break
|
||||
case .center:
|
||||
contentView.centerXAnchor.constraint(equalTo: parentView.centerXAnchor).activate()
|
||||
break
|
||||
case .right:
|
||||
parentView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).activate()
|
||||
break
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
// Get the slot width relative to the peak
|
||||
private func getSlotWidth() {
|
||||
let actualWidth = containerView.frame.size.width
|
||||
let isScrollbarSuppressed = data.count > 0 && layout.value == data.count
|
||||
@ -505,7 +606,7 @@ open class Carousel: View {
|
||||
case .minimum:
|
||||
// Peek Mimumum Width: 24px from edge of container (at the default view of the carousel with one peek visible)
|
||||
// Minimum (Mobile only) Supported only on Mobile viewports. If a user passes Minimum for tablet carousel, the peek reverts to Standard.
|
||||
minimumSlotWidth = isPeekMinimumOnTablet ? minimumSlotWidth : minimumSlotWidth - peekMinimum
|
||||
minimumSlotWidth = isPeekMinimumOnTablet ? minimumSlotWidth : minimumSlotWidth - peekMinimum - gutter.value
|
||||
case .none:
|
||||
break
|
||||
}
|
||||
@ -525,6 +626,7 @@ open class Carousel: View {
|
||||
updateScrollPosition(position: carouselScrollBar.position, callbackText:"pageControlClicks")
|
||||
}
|
||||
|
||||
// The size of slot depends on the selected aspect ratio
|
||||
private func ratioSize(for width: CGFloat) -> CGSize {
|
||||
var height: CGFloat = width
|
||||
|
||||
@ -575,6 +677,7 @@ open class Carousel: View {
|
||||
updateScrollPosition(position: contentPos, callbackText: "ScrollViewMoved")
|
||||
}
|
||||
|
||||
// Update scrollview offset relative to scrollbar thumb position
|
||||
private func updateScrollPosition(position: Int, callbackText: String) {
|
||||
if carouselScrollBar.numberOfSlides > 0 {
|
||||
let scrollContentSizeWidth = scrollView.contentSize.width
|
||||
@ -598,7 +701,7 @@ open class Carousel: View {
|
||||
xPos = xPosition - gutter.value - (minimumSlotWidth/4)/2
|
||||
}
|
||||
case .minimum:
|
||||
xPos = isPeekMinimumOnTablet ? xPosition : xPosition - peekMinimum/2
|
||||
xPos = isPeekMinimumOnTablet ? xPosition : xPosition - peekMinimum
|
||||
case .none:
|
||||
xPos = xPosition
|
||||
}
|
||||
@ -608,9 +711,13 @@ open class Carousel: View {
|
||||
let yPos = scrollView.contentOffset.y
|
||||
scrollView.setContentOffset(CGPoint(x: xPos, y: yPos), animated: true)
|
||||
showPaginationControls()
|
||||
selectedIndex = ((position-1) * layout.value) + 1
|
||||
onChangePublisher.send(selectedIndex ?? 1)
|
||||
selectedGroupIndex = position
|
||||
}
|
||||
}
|
||||
|
||||
// Get the overall positions of the carousel scrollbar relative to the slides and selected layout
|
||||
private func totalPositions() -> Int {
|
||||
return Int (ceil (Double(carouselScrollBar.numberOfSlides) / Double(_layout.value)))
|
||||
}
|
||||
|
||||
33
VDS/Components/Carousel/CarouselRenderItemStyle.swift
Normal file
33
VDS/Components/Carousel/CarouselRenderItemStyle.swift
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// CarouselRenderItemStyle.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Kanamarlapudi, Vasavi on 30/06/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import VDSCoreTokens
|
||||
|
||||
/// A custom data type that holds the style props if provided any.
|
||||
public struct CarouselRenderItemStyle {
|
||||
|
||||
/// BackgroundColor for slot
|
||||
public let backgroundColor: String?
|
||||
|
||||
/// Height for slot
|
||||
public var height: CGFloat?
|
||||
|
||||
/// BorderRadius for slot
|
||||
public var borderRadius: CGFloat?
|
||||
|
||||
/// Width for slot
|
||||
public var width: CGFloat?
|
||||
|
||||
public init(backgroundColor: String?, height: CGFloat?, width: CGFloat?, borderRadius: CGFloat?) {
|
||||
self.backgroundColor = backgroundColor
|
||||
self.height = height
|
||||
self.borderRadius = borderRadius ?? 12.0
|
||||
self.width = width
|
||||
}
|
||||
}
|
||||
@ -7,17 +7,19 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Custom data type for slotAlignment prop for 'Carousel' component.
|
||||
/// Custom data type for the SlotAlignment prop for the 'carousel' component.
|
||||
extension Carousel {
|
||||
|
||||
/// Used only when slot content have different heights or widths.
|
||||
public struct CarouselSlotAlignmentModel {
|
||||
|
||||
/// Text that shown to an indicator for legend
|
||||
public var vertical: String
|
||||
/// Used for vertical alignment of slot alignment.
|
||||
public var vertical: Carousel.Vertical
|
||||
|
||||
/// Date to an indicator
|
||||
public var horizontal: String
|
||||
/// Used for horizontal alignment of slot alignment.
|
||||
public var horizontal: Carousel.Horizontal
|
||||
|
||||
public init(vertical: String, horizontal: String) {
|
||||
public init(vertical: Carousel.Vertical, horizontal: Carousel.Horizontal) {
|
||||
self.vertical = vertical
|
||||
self.horizontal = horizontal
|
||||
}
|
||||
|
||||
31
VDS/Components/Carousel/CarouselSlotItemModel.swift
Normal file
31
VDS/Components/Carousel/CarouselSlotItemModel.swift
Normal file
@ -0,0 +1,31 @@
|
||||
//
|
||||
// CarouselSlotItemModel.swift
|
||||
// VDS
|
||||
//
|
||||
// Created by Kanamarlapudi, Vasavi on 30/06/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import VDSCoreTokens
|
||||
|
||||
/// A custom data type that holds the style and component for a slot of the 'Carousel' component.
|
||||
public struct CarouselSlotItemModel {
|
||||
|
||||
/// Style props if provided any
|
||||
public var style: CarouselRenderItemStyle?
|
||||
|
||||
/// Component to be show on Carousel slot
|
||||
public var component: UIView?
|
||||
|
||||
public init(style: CarouselRenderItemStyle? = nil, component: UIView? = nil) {
|
||||
self.style = style
|
||||
self.component = component
|
||||
if let color = style?.backgroundColor {
|
||||
self.component?.backgroundColor = .init(hexString: color)
|
||||
}
|
||||
if let borderRadius = style?.borderRadius {
|
||||
self.component?.layer.cornerRadius = borderRadius
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user