Version 1.0.0

This commit is contained in:
Daniel Arantes Loverde
2025-03-23 00:27:49 -03:00
commit e4538f84e2
74 changed files with 12161 additions and 0 deletions

View File

@@ -0,0 +1,274 @@
//
// Copyright (c) 2024 Loverde Co.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if canImport(SwiftUI)
import SwiftUI
@available(iOS 15, *)
class LCENavigationState: ObservableObject {
@Published var rightButtonImage: AnyView? = nil
@Published var rightButtonText: Text = Text("")
@Published var rightButtonAction: () -> Void = {}
@Published var leftButtonImage: AnyView? = nil
@Published var leftButtonText: Text = Text("")
@Published var leftButtonAction: () -> Void = {}
@Published var hideNavigationBar: Bool = false
@Published var title: (any View) = Text("")
@Published var subTitle: (any View) = Text("")
}
@available(iOS 15, *)
public struct LCENavigationView<Content: View>: View {
@ObservedObject private var state: LCENavigationState
let content: Content
public init(
title: (any View) = Text(""),
subTitle: (any View) = Text(""),
@ViewBuilder content: () -> Content
) {
self.content = content()
self._state = ObservedObject(
wrappedValue: LCENavigationState()
)
self.state.title = title
self.state.subTitle = subTitle
}
public var body: some View {
VStack {
if !state.hideNavigationBar {
NavigationBarView
}
content
}
.navigationBarHidden(true)
}
private var NavigationBarView: some View {
HStack {
NavLeftButton
Spacer()
TitleView
Spacer()
NavRightButton
}
.font(.headline)
.padding()
.background {
Color.clear.ignoresSafeArea(edges: .top)
}
}
private var TitleView: some View {
VStack {
AnyView(state.title)
if (try? state.subTitle.getTag() ?? "hidden" ) != "hidden" {
AnyView(state.subTitle)
}
}
}
private var NavLeftButton: some View {
Button(action: state.leftButtonAction) {
HStack {
if let image = state.leftButtonImage {
image
}
state.leftButtonText
}
}
}
private var NavRightButton: some View {
Button(action: state.rightButtonAction) {
HStack {
state.rightButtonText
if let image = state.rightButtonImage {
image
}
}
}
}
public func setRightButton(
text: Text = Text(""),
image: (any View)? = nil,
action: @escaping () -> Void
) -> LCENavigationView {
if let image {
state.rightButtonImage = AnyView(image)
} else {
state.rightButtonImage = nil
}
state.rightButtonText = text
state.rightButtonAction = action
if let string = state.leftButtonText.string, string.isEmpty {
state.leftButtonText = text.foregroundColor(.clear)
}
if state.leftButtonImage == nil {
state.leftButtonImage = image?.foregroundColor(.clear) as? AnyView
}
return self
}
public func setLeftButton(
text: Text = Text(""),
image: (any View)? = nil,
action: @escaping () -> Void
) -> LCENavigationView {
if let image {
state.leftButtonImage = AnyView(image)
} else {
state.leftButtonImage = nil
}
state.leftButtonText = text
state.leftButtonAction = action
if let string = state.rightButtonText.string, string.isEmpty {
state.rightButtonText = text.foregroundColor(.clear)
}
if state.rightButtonImage == nil {
state.rightButtonImage = image?.foregroundColor(.clear) as? AnyView
}
return self
}
public func setTitle(
text: (any View) = Text(""),
subTitle: (any View)? = nil
) -> LCENavigationView {
state.title = text
state.subTitle = subTitle ?? Text("").tag("hidden")
return self
}
public func hideNavigationView(_ hide: Bool) -> LCENavigationView {
state.hideNavigationBar = hide
return self
}
}
@available(iOS 15.0, *)
extension FormatStyle {
func format(any value: Any) -> FormatOutput? {
if let v = value as? FormatInput {
return format(v)
}
return nil
}
}
@available(iOS 15.0, *)
extension LocalizedStringKey {
var resolved: String? {
let mirror = Mirror(reflecting: self)
guard let key = mirror.descendant("key") as? String else {
return nil
}
guard let args = mirror.descendant("arguments") as? [Any] else {
return nil
}
let values = args.map { arg -> Any? in
let mirror = Mirror(reflecting: arg)
if let value = mirror.descendant("storage", "value", ".0") {
return value
}
guard let format = mirror.descendant("storage", "formatStyleValue", "format") as? any FormatStyle,
let input = mirror.descendant("storage", "formatStyleValue", "input") else {
return nil
}
return format.format(any: input)
}
let va = values.compactMap { arg -> CVarArg? in
switch arg {
case let i as Int: return i
case let i as Int64: return i
case let i as Int8: return i
case let i as Int16: return i
case let i as Int32: return i
case let u as UInt: return u
case let u as UInt64: return u
case let u as UInt8: return u
case let u as UInt16: return u
case let u as UInt32: return u
case let f as Float: return f
case let f as CGFloat: return f
case let d as Double: return d
case let o as NSObject: return o
default: return nil
}
}
if va.count != values.count {
return nil
}
return String.localizedStringWithFormat(key, va)
}
}
@available(iOS 15.0, *)
extension Text {
var string: String? {
let mirror = Mirror(reflecting: self)
if let s = mirror.descendant("storage", "verbatim") as? String {
return s
} else if let attrStr = mirror.descendant("storage", "anyTextStorage", "str") as? AttributedString {
return String(attrStr.characters)
} else if let key = mirror.descendant("storage", "anyTextStorage", "key") as? LocalizedStringKey {
return key.resolved
} else if let format = mirror.descendant("storage", "anyTextStorage", "storage", "format") as? any FormatStyle,
let input = mirror.descendant("storage", "anyTextStorage", "storage", "input") {
return format.format(any: input) as? String
} else if let formatter = mirror.descendant("storage", "anyTextStorage", "formatter") as? Formatter,
let object = mirror.descendant("storage", "anyTextStorage", "object") {
return formatter.string(for: object)
}
return nil
}
}
//@available(iOS 15.0, *)
//struct LCENavigationView_Previews: PreviewProvider {
// static var previews: some View {
// LCENavigationView {
// Text("Hello, World!")
// }
// .setTitle(text: Text("Hellow Nav Title"))
// .setLeftButton(text: "Back") {
// print("Button tapped!")
// }
// }
//}
#endif