Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,017 changes: 1,017 additions & 0 deletions android_kmp/app-sample/.idea/caches/deviceStreaming.xml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#question
Can you remove this file? It is not necessary

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions android_kmp/app-sample/.idea/gradle.xml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#question
Can you remove this file? It is not necessary

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions android_kmp/app-sample/.idea/migrations.xml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#question
Can you remove this file? It is not necessary

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions android_kmp/app-sample/.idea/misc.xml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#question
Can you remove this file? It is not necessary

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions android_kmp/app-sample/.idea/runConfigurations.xml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#question
Can you remove this file? It is not necessary

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 51 additions & 0 deletions android_kmp/app-sample/.idea/workspace.xml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#question
Can you remove this file? It is not necessary

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -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?
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ public class CraftDBuilderManager {
add(builders: [
CraftDTextBuilder(),
CraftDButtonBuilder(),
CraftDCheckBoxBuilder()
CraftDCheckBoxBuilder(),
CraftDProgressBarBuilder(),
])
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#question
Can we create a constant to represent default values for example, here we can have one called Color.Unspecified?

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
}
}
Original file line number Diff line number Diff line change
@@ -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()
}
}
}
13 changes: 13 additions & 0 deletions ios/sample/CraftDSample/dynamic.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
]
Loading