Files
ladill-mini/apps/ios/LadillMini/Core/Components/LadillButton.swift
T
isaaccladandCursor ea6afb80a4
Deploy Ladill Mini / deploy (push) Successful in 35s
Add Ladill Mini native Android and iOS apps.
Ship full-featured mobile clients with auth, payments, QRs, push notifications, and iOS polish including Figtree typography, app icons, and QR previews.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-11 22:30:35 +00:00

141 lines
4.4 KiB
Swift

import SwiftUI
struct LadillButton: View {
let title: String
var loading = false
var enabled = true
let action: () -> Void
var body: some View {
Button(action: action) {
ZStack {
RoundedRectangle(cornerRadius: 28)
.fill(LadillColors.primaryGradient)
.frame(height: 56)
.opacity(enabled && !loading ? 1 : 0.5)
if loading {
ProgressView().tint(.white)
} else {
HStack {
Text(title)
.font(.ladill(size: 15, weight: .semibold))
.foregroundStyle(.white)
.frame(maxWidth: .infinity)
Circle()
.fill(.white)
.frame(width: 44, height: 44)
.overlay {
Image(systemName: "arrow.up.right")
.font(.system(size: 14, weight: .semibold))
.foregroundStyle(LadillColors.indigo)
}
}
.padding(.leading, 22)
.padding(.trailing, 6)
}
}
}
.disabled(!enabled || loading)
.buttonStyle(.plain)
}
}
struct LadillSecondaryButton: View {
let title: String
var enabled = true
let action: () -> Void
var body: some View {
Button(action: action) {
Text(title)
.font(.ladill(size: 15, weight: .semibold))
.foregroundStyle(LadillColors.ink)
.frame(maxWidth: .infinity)
.frame(height: 52)
.background(LadillColors.surfaceSoft)
.clipShape(Capsule())
.opacity(enabled ? 1 : 0.5)
}
.disabled(!enabled)
.buttonStyle(.plain)
}
}
struct LadillTextField: View {
let label: String
let placeholder: String
@Binding var text: String
var secure = false
var keyboard: UIKeyboardType = .default
var enabled = true
var body: some View {
VStack(alignment: .leading, spacing: 6) {
Text(label)
.font(.ladill(size: 13, weight: .medium))
.foregroundStyle(LadillColors.muted)
Group {
if secure {
SecureField(placeholder, text: $text)
} else {
TextField(placeholder, text: $text)
.keyboardType(keyboard)
.textInputAutocapitalization(keyboard == .emailAddress ? .never : .words)
.autocorrectionDisabled(keyboard == .emailAddress)
}
}
.font(.ladill(size: 16))
.padding(.horizontal, 16)
.padding(.vertical, 14)
.background(LadillColors.surface)
.overlay(RoundedRectangle(cornerRadius: 14).stroke(LadillColors.border, lineWidth: 1))
.clipShape(RoundedRectangle(cornerRadius: 14))
.disabled(!enabled)
}
}
}
struct StepBar: View {
let current: Int
let total: Int
var body: some View {
HStack(spacing: 6) {
ForEach(0..<total, id: \.self) { index in
Capsule()
.fill(index <= current ? LadillColors.indigo : LadillColors.border)
.frame(height: 4)
}
}
.padding(.vertical, 8)
}
}
struct MenuScaffold<Content: View>: View {
let title: String
let onBack: () -> Void
@ViewBuilder let content: Content
var body: some View {
VStack(spacing: 0) {
HStack {
Button(action: onBack) {
Image(systemName: "chevron.left")
.font(.system(size: 17, weight: .semibold))
.foregroundStyle(LadillColors.ink)
}
Text(title)
.font(.ladill(size: 18, weight: .semibold))
.foregroundStyle(LadillColors.ink)
Spacer()
}
.padding(.horizontal, 16)
.padding(.vertical, 8)
content
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
.background(LadillColors.page)
}
}