From ec1d34313cfa0cfd9e1968b985ca6b6f57f9a8fe Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Fri, 22 Mar 2024 00:54:49 +0100 Subject: [PATCH] Implemented the UnavailableView view in the UI library. --- .../Kit/Sources/Views/UnavailableView.swift | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 Libraries/UI/Kit/Sources/Views/UnavailableView.swift diff --git a/Libraries/UI/Kit/Sources/Views/UnavailableView.swift b/Libraries/UI/Kit/Sources/Views/UnavailableView.swift new file mode 100644 index 0000000..0dd103e --- /dev/null +++ b/Libraries/UI/Kit/Sources/Views/UnavailableView.swift @@ -0,0 +1,105 @@ +// +// UnavailableView.swift +// ReviewsUIKit +// +// Created by Javier Cicchelli on 22/03/2024. +// Copyright © 2024 Röck+Cöde VoF. All rights reserved. +// + +import SwiftUI + +public struct UnavailableView: View { + + // MARK: Constants + private let description: String + private let systemImage: String + private let title: String + + private let action: (() -> Void)? + private let button: String? + + // MARK: Initialisers + public init( + systemImage: String, + title: String, + description: String, + button: String? = nil, + action: (() -> Void)? = nil + ) { + self.action = action + self.button = button + self.description = description + self.systemImage = systemImage + self.title = title + } + + // MARK: Body + public var body: some View { + if #available(iOS 17.0, *) { + if let button, let action { + ContentUnavailableView { + Label(title, systemImage: systemImage) + } description: { + Text(description) + } actions: { + Button(action: action) { + Text(button) + } + } + } else { + ContentUnavailableView( + title, + systemImage: systemImage, + description: Text(description) + ) + } + } else { + VStack(spacing: 24) { + Image(systemName: systemImage) + .resizable() + .frame(width: 52, height: 52) + .foregroundColor(.secondary) + + VStack { + Text(title) + .font(.title2.bold()) + .foregroundColor(.primary) + + Text(description) + .font(.subheadline) + .foregroundColor(.secondary) + } + .multilineTextAlignment(.center) + + if let button, let action { + Button(action: action) { + Text(button) + .font(.subheadline) + } + } + } + .padding(.horizontal, 52) + } + } + +} + +// MARK: - Previews +#Preview("Unavailable View with image, title, and description") { + UnavailableView( + systemImage: "star", + title: "Some title goes here...", + description: "Some long, explanatory description goes in here..." + ) +} + +#Preview("Unavailable View with image, title, description, button, and action") { + UnavailableView( + systemImage: "star", + title: "Some title goes here...", + description: "Some long, explanatory description goes in here...", + button: "Some button text here..." + ) { + // On action closure. + } +}