// // Breadcrumbs.swift // VDS // // Created by Kanamarlapudi, Vasavi on 11/03/24. // import Foundation import VDSColorTokens import Combine /// A Breadcrumbs contains BreadcrumbItems. /// It contains Breadcrumb Item Default, Breadcrumb Item Selected, Separator. /// Breadcrumbs are secondary navigation that use a hierarchy of internal links to tell customers where they are in an experience. Each breadcrumb links to its respective page, except for that of current page. @objc(VDSBreadcrumbs) open class Breadcrumbs: View { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- /// Array of Breadcrumb Items that are shown in the group. open var breadcrumbItems: [BreadcrumbItem] = [] { didSet { setNeedsUpdate() } } /// Whether this object is enabled or not override open var isEnabled: Bool { didSet { breadcrumbItems.forEach { $0.isEnabled = isEnabled } } } /// Current Surface and this is used to pass down to child objects that implement Surfacable override open var surface: Surface { didSet { breadcrumbItems.forEach { $0.surface = surface } } } //-------------------------------------------------- // MARK: - Private Properties //-------------------------------------------------- let layout: UICollectionViewFlowLayout = LeftAlignedCollectionViewFlowLayout().with { $0.estimatedItemSize = UICollectionViewFlowLayout.automaticSize $0.minimumInteritemSpacing = VDSLayout.Spacing.space1X.value $0.minimumLineSpacing = VDSLayout.Spacing.space1X.value $0.sectionInset = .zero $0.scrollDirection = .vertical } ///Collectionview to render Breadcrumb Items private lazy var collectionView: UICollectionView = { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) collectionView.isScrollEnabled = false collectionView.translatesAutoresizingMaskIntoConstraints = false collectionView.delegate = self collectionView.dataSource = self collectionView.showsHorizontalScrollIndicator = false collectionView.showsVerticalScrollIndicator = false collectionView.register(BreadcrumbCellItem.self, forCellWithReuseIdentifier: BreadcrumbCellItem.identifier) collectionView.backgroundColor = .clear return collectionView }() //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- /// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations. open override func setup() { super.setup() } /// Executed on initialization for this View. open override func initialSetup() { super.initialSetup() addSubview(collectionView) collectionView.pinToSuperView() collectionView.heightAnchor.constraint(equalToConstant: 80).activate() } /// Resets to default settings. open override func reset() { super.reset() shouldUpdateView = false breadcrumbItems.forEach { $0.reset() } shouldUpdateView = true setNeedsUpdate() } /// Used to make changes to the View based off a change events or from local properties. open override func updateView() { super.updateView() collectionView.reloadData() } open override func layoutSubviews() { super.layoutSubviews() // Accounts for any collection size changes DispatchQueue.main.async { [weak self] in guard let self else { return } self.collectionView.collectionViewLayout.invalidateLayout() } } } extension Breadcrumbs: UICollectionViewDelegate, UICollectionViewDataSource { //-------------------------------------------------- // MARK: - UICollectionView Delegate & Datasource //-------------------------------------------------- public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { breadcrumbItems.count } public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BreadcrumbCellItem.identifier, for: indexPath) as? BreadcrumbCellItem else { return UICollectionViewCell() } let hideSlash = (indexPath.row == 0) cell.update(surface: surface, hideSlash: hideSlash, breadCrumbItem: breadcrumbItems[indexPath.row]) return cell } public func collectionView(_ collectionView: UICollectionView, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize { breadcrumbItems[indexPath.row].intrinsicContentSize } }