Add CI/CD configuration and API documentation

This commit is contained in:
2026-07-01 21:40:53 +08:00
commit c590135d68
4168 changed files with 740252 additions and 0 deletions
@@ -0,0 +1,78 @@
//
// CustomTF.swift
// LoginKit
//
// Created by zues on 04/08/23.
//
import SwiftUI
struct CustomTF: View {
var sfIcon: String
var iconTint: Color = .gray
var hint: String
/// Hides TextField
var isPassword: Bool = false
var hasDriveLine: Bool = true
@Binding var value: String
/// View Properties
@State private var showPassword: Bool = false
/// When Switching Between Hide/Reveal Password Field, The Keyboard is Closing, to avoid that using the FocusState
@FocusState private var passwordState: HideState?
enum HideState {
case hide
case reveal
}
var body: some View {
HStack(alignment: .top, spacing: 8, content: {
Image(systemName: sfIcon)
.foregroundStyle(iconTint)
/// Since I Need Same Width to Align TextFields Equally
.frame(width: 30)
/// Slightly Bringing Down
.offset(y: 2)
VStack(alignment: .leading, spacing: 8, content: {
if isPassword {
Group {
/// Revealing Password when users wants to show Password
if showPassword {
TextField(hint, text: $value)
.focused($passwordState, equals: .reveal)
} else {
SecureField(hint, text: $value)
.focused($passwordState, equals: .hide)
}
}
} else {
TextField(hint, text: $value)
}
if hasDriveLine {
Divider()
}
})
.overlay(alignment: .trailing) {
/// Password Reveal Button
if isPassword {
Button(action: {
withAnimation {
showPassword.toggle()
}
passwordState = showPassword ? .reveal : .hide
}, label: {
Image(systemName: showPassword ? "eye.slash" : "eye")
.foregroundStyle(.gray)
.padding(10)
.contentShape(.rect)
})
}
}
})
}
}
@@ -0,0 +1,28 @@
//
// GradientButton.swift
// LoginKit
//
// Created by zues on 04/08/23.
//
import SwiftUI
struct GradientButton: View {
var title: String
var icon: String
var onClick: () -> ()
var body: some View {
Button(action: onClick, label: {
HStack(spacing: 15) {
Text(title)
Image(systemName: icon)
}
////.fontWeight(.bold)
.foregroundStyle(.white)
.padding(.vertical, 12)
.padding(.horizontal, 35)
.background(.linearGradient(colors: [.main, .main2, ], startPoint: .top, endPoint: .bottom), in: .capsule)
})
}
}
@@ -0,0 +1,87 @@
//
// OTPVerificationView.swift
// AutoOtpTF
//
// Created by zues on 23/12/22.
//
import SwiftUI
struct OTPVerificationView: View {
/// - View Properties
@Binding var otpText: String
/// - Keyboard State
@FocusState private var isKeyboardShowing: Bool
var body: some View {
HStack(spacing: 0){
/// - OTP Text Boxes
/// Change Count Based on your OTP Text Size
ForEach(0..<6,id: \.self){index in
OTPTextBox(index)
}
}
.background(content: {
TextField("", text: $otpText.limit(6))
.keyboardType(.numberPad)
.textContentType(.oneTimeCode)
/// - Hiding it Out
.frame(width: 1, height: 1)
.opacity(0.001)
.blendMode(.screen)
.focused($isKeyboardShowing)
})
.contentShape(Rectangle())
/// - Opening Keyboard When Tapped
.onTapGesture {
isKeyboardShowing = true
}
.toolbar {
ToolbarItem(placement: .keyboard) {
Button("Done"){
isKeyboardShowing = false
}
.tint(.white)
////.fontWeight(.heavy)
.hSpacing(.trailing)
}
}
}
// MARK: OTP Text Box
@ViewBuilder
func OTPTextBox(_ index: Int)->some View{
ZStack{
if otpText.count > index{
/// - Finding Char At Index
let startIndex = otpText.startIndex
let charIndex = otpText.index(startIndex, offsetBy: index)
let charToString = String(otpText[charIndex])
Text(charToString)
}else{
Text(" ")
}
}
.frame(width: 45, height: 45)
.background {
/// - Highlighting Current Active Box
let status = (isKeyboardShowing && otpText.count == index)
RoundedRectangle(cornerRadius: 6, style: .continuous)
.stroke(status ? .main : Color.gray,lineWidth: status ? 3 : 0.5)
/// - Adding Animation
.animation(.easeInOut(duration: 0.2), value: isKeyboardShowing)
}
.frame(maxWidth: .infinity)
}
}
// MARK: Binding <String> Extension
extension Binding where Value == String{
func limit(_ length: Int)->Self{
if self.wrappedValue.count > length{
DispatchQueue.main.async {
self.wrappedValue = String(self.wrappedValue.prefix(length))
}
}
return self
}
}