diff --git a/android_kmp/app-sample/.idea/caches/deviceStreaming.xml b/android_kmp/app-sample/.idea/caches/deviceStreaming.xml
new file mode 100644
index 0000000..04e6f50
--- /dev/null
+++ b/android_kmp/app-sample/.idea/caches/deviceStreaming.xml
@@ -0,0 +1,1017 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android_kmp/app-sample/.idea/gradle.xml b/android_kmp/app-sample/.idea/gradle.xml
new file mode 100644
index 0000000..72cb247
--- /dev/null
+++ b/android_kmp/app-sample/.idea/gradle.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android_kmp/app-sample/.idea/migrations.xml b/android_kmp/app-sample/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/android_kmp/app-sample/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android_kmp/app-sample/.idea/misc.xml b/android_kmp/app-sample/.idea/misc.xml
new file mode 100644
index 0000000..3040d03
--- /dev/null
+++ b/android_kmp/app-sample/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android_kmp/app-sample/.idea/runConfigurations.xml b/android_kmp/app-sample/.idea/runConfigurations.xml
new file mode 100644
index 0000000..16660f1
--- /dev/null
+++ b/android_kmp/app-sample/.idea/runConfigurations.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android_kmp/app-sample/.idea/workspace.xml b/android_kmp/app-sample/.idea/workspace.xml
new file mode 100644
index 0000000..6ced158
--- /dev/null
+++ b/android_kmp/app-sample/.idea/workspace.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1763425035519
+
+
+ 1763425035519
+
+
+
+
\ No newline at end of file
diff --git a/ios/craftd-swiftui/Sources/craftd-swiftui/data/model/progressBar/ProgressBarProperties.swift b/ios/craftd-swiftui/Sources/craftd-swiftui/data/model/progressBar/ProgressBarProperties.swift
new file mode 100644
index 0000000..aa57143
--- /dev/null
+++ b/ios/craftd-swiftui/Sources/craftd-swiftui/data/model/progressBar/ProgressBarProperties.swift
@@ -0,0 +1,10 @@
+struct ProgressBarProperties: Decodable {
+ let text: String?
+ let alignment: CraftDAlign?
+ let textAlign: CraftDAlign?
+ let progressColor: String?
+ let textColor: String?
+ let progress: Double?
+ let height: Double?
+ let spaceBetween: Double?
+}
diff --git a/ios/craftd-swiftui/Sources/craftd-swiftui/presentation/builder/CraftDBuilderManager.swift b/ios/craftd-swiftui/Sources/craftd-swiftui/presentation/builder/CraftDBuilderManager.swift
index 6019bd2..b4ec9a5 100644
--- a/ios/craftd-swiftui/Sources/craftd-swiftui/presentation/builder/CraftDBuilderManager.swift
+++ b/ios/craftd-swiftui/Sources/craftd-swiftui/presentation/builder/CraftDBuilderManager.swift
@@ -5,7 +5,8 @@ public class CraftDBuilderManager {
add(builders: [
CraftDTextBuilder(),
CraftDButtonBuilder(),
- CraftDCheckBoxBuilder()
+ CraftDCheckBoxBuilder(),
+ CraftDProgressBarBuilder(),
])
}
diff --git a/ios/craftd-swiftui/Sources/craftd-swiftui/presentation/ui/progressBar/CraftDProgressBar.swift b/ios/craftd-swiftui/Sources/craftd-swiftui/presentation/ui/progressBar/CraftDProgressBar.swift
new file mode 100644
index 0000000..95ad1e8
--- /dev/null
+++ b/ios/craftd-swiftui/Sources/craftd-swiftui/presentation/ui/progressBar/CraftDProgressBar.swift
@@ -0,0 +1,145 @@
+import SwiftUI
+
+struct CraftDProgressBar: View {
+ let text: String
+ let textAlign: Alignment
+ let alignment: CraftDAlign
+ let progressColor: String
+ let textColor: String
+ let progress: Double
+ let height: CGFloat
+ let spaceBetween: CGFloat
+ let listener: CraftDViewListener
+
+ init(
+ _ properties: ProgressBarProperties,
+ listener: @escaping CraftDViewListener
+ ) {
+ self.text = properties.text ?? ""
+ self.textAlign = properties.textAlign?.alignment ?? .center
+ self.progressColor = properties.progressColor ?? "#0000FF"
+ self.progress = properties.progress ?? 0.0
+ self.height = CGFloat(properties.height ?? 0.0)
+ self.alignment = properties.alignment ?? .top
+ self.textColor = properties.textColor ?? "#000000"
+ self.spaceBetween = properties.spaceBetween ?? 0.0
+ self.listener = listener
+ }
+
+ @ViewBuilder
+ private var topAlignmentLayout: some View {
+ VStack(spacing: .zero) {
+ Text(text)
+ .font(.body)
+ .foregroundStyle(Color(hex: textColor))
+
+ GeometryReader { geometry in
+ ZStack(alignment: .leading) {
+ RoundedRectangle(cornerRadius: 16)
+ .stroke(Color.gray.opacity(0.6), lineWidth: 2)
+ .fill(Color.clear)
+ .frame(height: height)
+
+ RoundedRectangle(cornerRadius: 16)
+ .fill(Color(hex: progressColor))
+ .frame(width: geometry.size.width * progress, height: height)
+ .animation(.easeInOut, value: progress)
+ }
+ }
+ }
+ }
+
+ @ViewBuilder
+ private var bottomAlignmentLayout: some View {
+ VStack(spacing: .zero) {
+
+ GeometryReader { geometry in
+ ZStack(alignment: .leading) {
+ RoundedRectangle(cornerRadius: 16)
+ .stroke(Color.gray.opacity(0.6), lineWidth: 2)
+ .fill(Color.clear)
+ .frame(height: height)
+
+ RoundedRectangle(cornerRadius: 16)
+ .fill(Color(hex: progressColor))
+ .frame(width: geometry.size.width * progress, height: height)
+ .animation(.easeInOut, value: progress)
+ }
+ }
+
+ Spacer()
+ .frame(height: spaceBetween)
+
+ Text(text)
+ .font(.body)
+ .foregroundStyle(Color(hex: textColor))
+ }
+ }
+
+ @ViewBuilder
+ private var leadingAlignmentLayout: some View {
+ HStack(alignment: .top, spacing: .zero) {
+ Text(text)
+ .font(.body)
+ .foregroundStyle(Color(hex: textColor))
+
+ Spacer()
+ .frame(width: spaceBetween)
+
+ GeometryReader { geometry in
+ ZStack(alignment: .leading) {
+ RoundedRectangle(cornerRadius: 16)
+ .stroke(Color.gray.opacity(0.6), lineWidth: 2)
+ .fill(Color.clear)
+ .frame(height: height)
+
+ RoundedRectangle(cornerRadius: 16)
+ .fill(Color(hex: progressColor))
+ .frame(width: geometry.size.width * progress, height: height)
+ .animation(.easeInOut, value: progress)
+ }
+ }
+ }
+ }
+
+ @ViewBuilder
+ private var trailingAlignmentLayout: some View {
+ HStack(alignment: .top, spacing: .zero) {
+
+ GeometryReader { geometry in
+ ZStack(alignment: .leading) {
+ RoundedRectangle(cornerRadius: 16)
+ .stroke(Color.gray.opacity(0.6), lineWidth: 2)
+ .fill(Color.clear)
+ .frame(height: height)
+
+ RoundedRectangle(cornerRadius: 16)
+ .fill(Color(hex: progressColor))
+ .frame(width: geometry.size.width * progress, height: height)
+ .animation(.easeInOut, value: progress)
+ }
+ }
+
+ Spacer()
+ .frame(width: spaceBetween)
+
+ Text(text)
+ .font(.body)
+ .foregroundStyle(Color(hex: textColor))
+ }
+ }
+
+ @ViewBuilder
+ private var content: some View {
+ switch alignment {
+ case .top, .center: topAlignmentLayout
+ case .bottom: bottomAlignmentLayout
+ case .left: leadingAlignmentLayout
+ case .right: trailingAlignmentLayout
+ }
+ }
+
+ var body: some View {
+ content
+ }
+}
diff --git a/ios/craftd-swiftui/Sources/craftd-swiftui/presentation/ui/progressBar/CraftDProgressBarBuilder.swift b/ios/craftd-swiftui/Sources/craftd-swiftui/presentation/ui/progressBar/CraftDProgressBarBuilder.swift
new file mode 100644
index 0000000..3b0446a
--- /dev/null
+++ b/ios/craftd-swiftui/Sources/craftd-swiftui/presentation/ui/progressBar/CraftDProgressBarBuilder.swift
@@ -0,0 +1,19 @@
+//
+// CraftDProgressBarBuilder.swift
+// CraftDSwiftUI
+//
+// Created by Pedro Alvarez on 17/11/25.
+//
+
+import SwiftUI
+
+class CraftDProgressBarBuilder: CraftDBuilder {
+ public func craft(model: SimpleProperties, listener: @escaping CraftDViewListener) -> any View {
+ do {
+ let properties = try model.decodeValue(ProgressBarProperties.self, using: decoder)
+ return CraftDProgressBar(properties, listener: listener)
+ } catch {
+ return EmptyView()
+ }
+ }
+}
diff --git a/ios/sample/CraftDSample/dynamic.json b/ios/sample/CraftDSample/dynamic.json
index ac070ca..83081e9 100644
--- a/ios/sample/CraftDSample/dynamic.json
+++ b/ios/sample/CraftDSample/dynamic.json
@@ -373,5 +373,18 @@
}
}
}
+ },
+ {
+ "key": "CraftDProgressBar",
+ "value": {
+ "text": "Loading...",
+ "alignment": "RIGHT",
+ "textAlign": "CENTER",
+ "progressColor": "#FFAA00",
+ "textColor": "#00FFBB",
+ "progress": 0.65,
+ "height": 12.0,
+ "spaceBetween": 32.0
+ }
}
]