Skip to content

Commit 9514d33

Browse files
committed
Initial Commit
0 parents  commit 9514d33

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1875
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
/*.xcodeproj
5+
xcuserdata/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Krishna Kumar
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Package.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// swift-tools-version:5.5
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "FastUI",
6+
platforms: [
7+
.iOS(.v15)
8+
],
9+
products: [
10+
.library(
11+
name: "FastUI",
12+
targets: ["FastUI"]),
13+
],
14+
dependencies: [],
15+
targets: [
16+
.target(
17+
name: "FastUI",
18+
dependencies: [],
19+
path: "Sources/Components")
20+
]
21+
)

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# FastUI - Components for SwiftUI
2+
3+
This repository contains a collection of reusable SwiftUI components, abstractions designed to get started with iOS app development in a clean, fast way.
4+
5+
6+
## Usage
7+
8+
To use these components, simply import the relevant Swift file into your project and integrate the component into your SwiftUI views.
9+
10+
```swift
11+
import FastUI
12+
13+
struct ContentView: View {
14+
var body: some View {
15+
Text("Hello world")
16+
.FITextStyle(.header3)
17+
}
18+
}
19+
```
20+
21+
## Documentation
22+
23+
For more detailed information on each component, please refer to the [documentation](docs/components.md).
24+
25+
## License
26+
27+
This project is licensed under the MIT License.

Sources/Components/FIConstants.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//
2+
// Constants+.swift
3+
// SwiftUIComponents
4+
//
5+
// Created by krishna on 3/12/24.
6+
// Copyright © 2024 MagicIve. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import SwiftUI
11+
12+
enum FIConstants {
13+
}
14+
15+
extension FIConstants {
16+
enum UI {
17+
static let cornerRadius = CGFloat(20.0)
18+
static let iconSize = CGSize(width: 24, height: 24)
19+
20+
enum NavigationBar {
21+
static let height = CGFloat(56)
22+
static let buttonSize = CGSize(width: 40, height: 40)
23+
static let backgroundColor = Color.blue
24+
}
25+
enum Padding {
26+
static let `default` = CGFloat(20.0)
27+
static let extraLarge = CGFloat(24)
28+
static let large = CGFloat(16.0)
29+
static let small = CGFloat(8.0)
30+
static let screenBottom = CGFloat(10)
31+
}
32+
enum Separator {
33+
static let height = CGFloat(1)
34+
}
35+
enum Shadow {
36+
static let color = Color.black
37+
static let radius = CGFloat(12)
38+
static let x = CGFloat(0)
39+
static let y = CGFloat(10)
40+
}
41+
enum AnimationDuration {
42+
static let `default` = CGFloat(0.3)
43+
static let fast = CGFloat(0.15)
44+
}
45+
}
46+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//
2+
// FISafeAreaInsetsKey.swift
3+
// SwiftUIComponents
4+
//
5+
// Created by krishna on 2/21/24.
6+
// Copyright © 2024 MagicIve. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
extension EnvironmentValues {
12+
var safeAreaInsets: EdgeInsets {
13+
self[FISafeAreaInsetsKey.self]
14+
}
15+
}
16+
17+
private struct FISafeAreaInsetsKey: EnvironmentKey {
18+
static var defaultValue: EdgeInsets {
19+
let insets = UIApplication.shared.keyWindow?.safeAreaInsets ?? .zero
20+
return EdgeInsets(top: insets.top, leading: insets.left, bottom: insets.bottom, trailing: insets.right)
21+
}
22+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// FIPreferenceKeys.swift
3+
// SwiftUIComponents
4+
//
5+
// Created by krishna on 2/20/24.
6+
// Copyright © 2024 MagicIve. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
struct FIFramePreferenceKey: PreferenceKey {
12+
static var defaultValue: CGRect = .zero
13+
static func reduce(value: inout CGRect, nextValue: () -> CGRect) {}
14+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//
2+
// FIButtonStyle.swift
3+
// SwiftUIComponents
4+
//
5+
// Created by krishna on 2/24/24.
6+
// Copyright © 2024 MagicIve. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
struct FIButtonStyle_Previews: PreviewProvider {
12+
static var previews: some View {
13+
VStack(alignment: .center, spacing: FIConstants.UI.Padding.large) {
14+
Button("TextButtonStyle") {}
15+
.buttonStyle(FITextButtonStyle())
16+
Button("DefaultButtonStyle") {}
17+
.buttonStyle(DefaultButtonStyle())
18+
Button("PrimaryButtonStyle") {}
19+
.buttonStyle(FIPrimaryButtonStyle())
20+
Button("") {}
21+
.buttonStyle(FIPrimaryButtonStyle(isLoading: true))
22+
Button("SecondaryButtonStyle") {}
23+
.buttonStyle(FISecondaryButtonStyle())
24+
Button("") {}
25+
.buttonStyle(FISecondaryButtonStyle(isLoading: true))
26+
Button("TertiaryButtonStyle") {}
27+
.buttonStyle(FITertiaryButtonStyle())
28+
Button("") {}
29+
.buttonStyle(FITertiaryButtonStyle(isLoading: true))
30+
}
31+
.padding()
32+
.previewLayout(.sizeThatFits)
33+
.background(Color.white)
34+
}
35+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//
2+
// FIButtonViewModifier.swift
3+
// SwiftUIComponents
4+
//
5+
// Created by krishna on 2/8/24.
6+
// Copyright © 2024 MagicIve. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import SwiftUI
11+
12+
struct FIButtonViewModifier: ViewModifier {
13+
@Environment(\.isEnabled) private var isEnabled
14+
15+
private let backgroundColor: Color
16+
private let foregroundColor: Color
17+
private let strokeColor: Color
18+
private let size: Layout.Size
19+
private let isLoading: Bool
20+
private let isPressed: Bool
21+
private let shouldExpand: Bool
22+
23+
init(
24+
backgroundColor: Color,
25+
foregroundColor: Color,
26+
strokeColor: Color = .clear,
27+
size: Layout.Size = .large,
28+
isLoading: Bool = false,
29+
isPressed: Bool,
30+
shouldExpand: Bool = true
31+
) {
32+
self.backgroundColor = backgroundColor
33+
self.foregroundColor = foregroundColor
34+
self.strokeColor = strokeColor
35+
self.size = size
36+
self.isLoading = isLoading
37+
self.isPressed = isPressed
38+
self.shouldExpand = shouldExpand
39+
}
40+
41+
func body(content: Content) -> some View {
42+
ZStack {
43+
if isLoading {
44+
FISpinningLoaderView(
45+
color: foregroundColor,
46+
size: Layout.loaderSize,
47+
lineWidth: Layout.loaderLineWidth
48+
)
49+
}
50+
content
51+
.font(size.font)
52+
.opacity(isLoading ? 0 : 1)
53+
}
54+
.padding(size.textPadding)
55+
.foregroundColor(foregroundColor)
56+
.frame(maxWidth: shouldExpand ? .infinity : nil)
57+
.background(
58+
ZStack {
59+
RoundedRectangle(cornerRadius: Layout.cornerRadius)
60+
.fill(strokeColor != .clear ? .clear : backgroundColor)
61+
RoundedRectangle(cornerRadius: Layout.cornerRadius)
62+
.stroke(
63+
strokeColor,
64+
lineWidth: Layout.strokeWidth
65+
)
66+
}
67+
)
68+
.opacity(isEnabled ? (isPressed ? Layout.pressedOpacity : 1) : Layout.disabledOpacity)
69+
.contentShape(Rectangle())
70+
.animation(.easeInOut, value: isLoading)
71+
}
72+
}
73+
74+
extension FIButtonViewModifier {
75+
enum Layout {
76+
static let cornerRadius = CGFloat(40)
77+
static let disabledOpacity = CGFloat(0.5)
78+
static let pressedOpacity = CGFloat(0.7)
79+
static let strokeWidth = CGFloat(2)
80+
}
81+
}
82+
83+
extension FIButtonViewModifier.Layout {
84+
enum Size {
85+
case small
86+
case large
87+
case text
88+
89+
var textPadding: EdgeInsets {
90+
switch self {
91+
case .large:
92+
return EdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24)
93+
case .small:
94+
return EdgeInsets(top: 10, leading: 16, bottom: 10, trailing: 16)
95+
case .text:
96+
return EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
97+
}
98+
}
99+
100+
var font: Font {
101+
switch self {
102+
case .large:
103+
return FITextStyle.buttonXLarge.font
104+
case .small:
105+
return FITextStyle.buttonSmall.font
106+
case .text:
107+
return FITextStyle.buttonLarge.font
108+
}
109+
}
110+
}
111+
static let loaderSize = CGSize(width: 24, height: 24)
112+
static let loaderLineWidth = CGFloat(4)
113+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// FIPrimaryButtonStyle.swift
3+
// SwiftUIComponents
4+
//
5+
// Created by krishna on 2/8/24.
6+
// Copyright © 2024 MagicIve. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import SwiftUI
11+
12+
struct FIPrimaryButtonStyle: ButtonStyle {
13+
@Environment(\.isEnabled) private var isEnabled
14+
15+
private let backgroundColor: Color
16+
private let foregroundColor: Color
17+
private let size: FIButtonViewModifier.Layout.Size
18+
private let shouldExpand: Bool
19+
private let isLoading: Bool
20+
21+
init(
22+
backgroundColor: Color = Color.blue,
23+
foregroundColor: Color = Color.white,
24+
size: FIButtonViewModifier.Layout.Size = .large,
25+
shouldExpand: Bool = true,
26+
isLoading: Bool = false
27+
) {
28+
self.backgroundColor = backgroundColor
29+
self.foregroundColor = foregroundColor
30+
self.size = size
31+
self.shouldExpand = shouldExpand
32+
self.isLoading = isLoading
33+
}
34+
35+
func makeBody(configuration: Self.Configuration) -> some View {
36+
configuration.label
37+
.modifier(
38+
FIButtonViewModifier(
39+
backgroundColor: backgroundColor,
40+
foregroundColor: foregroundColor,
41+
size: size,
42+
isLoading: isLoading,
43+
isPressed: configuration.isPressed,
44+
shouldExpand: shouldExpand
45+
)
46+
)
47+
}
48+
}

0 commit comments

Comments
 (0)