Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PBIOS-425] Button kit refactor #419

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
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
53 changes: 53 additions & 0 deletions .swiftpm/xcode/xcshareddata/xcschemes/SnapshotTests.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1520"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "SnapshotTests"
BuildableName = "SnapshotTests"
BlueprintName = "SnapshotTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
12 changes: 6 additions & 6 deletions Sources/Playbook/Components/Button/ButtonsCatalog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ extension ButtonsCatalog {
VStack(alignment: .leading, spacing: Spacing.small) {
PBButton(
title: "Button Primary",
isLoading: $isLoading,
action: { isLoading = true }
isLoading: $isLoading,
action: { isLoading.toggle() }
)
PBButton(
variant: .secondary,
Expand Down Expand Up @@ -64,8 +64,8 @@ extension ButtonsCatalog {
}
var fullWidthButtonView: some View {
PBButton(
fullWidth: true,
title: "Full Width",
fullWidth: true,
action: {}
)
}
Expand Down Expand Up @@ -105,24 +105,24 @@ extension ButtonsCatalog {
var buttonLoadingView: some View {
VStack(alignment: .leading, spacing: Spacing.small) {
PBButton(
fullWidth: true,
variant: .primary,
title: "Button lg",
isLoading: .constant(true),
fullWidth: true,
action: {}
)
PBButton(
fullWidth: true,
variant: .secondary,
title: "Button lg",
isLoading: .constant(true),
fullWidth: true,
action: {}
)
PBButton(
fullWidth: true,
variant: .link,
title: "Button lg",
isLoading: .constant(true),
fullWidth: true,
action: {}
)
}
Expand Down
224 changes: 124 additions & 100 deletions Sources/Playbook/Components/Button/PBButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,118 +10,142 @@
import SwiftUI

public struct PBButton: View {
var fullWidth: Bool
var variant: Variant
var size: Size
var shape: Shape
var title: String?
var icon: PBIcon?
var iconPosition: IconPosition?
@Binding var isLoading: Bool
let action: (() -> Void)?
var fullWidth: Bool
var variant: Variant
var size: Size
var shape: Shape
var title: String?
var icon: PBIcon?
var iconPosition: IconPosition?
let action: (() -> Void)?
@Binding var isLoading: Bool
@Environment(\.colorScheme) private var colorScheme

public init(
fullWidth: Bool = false,
variant: Variant = .primary,
size: Size = .medium,
shape: Shape = .primary,
title: String? = nil,
icon: PBIcon? = nil,
iconPosition: IconPosition? = .left,
isLoading: Binding<Bool> = .constant(false),
action: (() -> Void)? = nil
) {
self.fullWidth = fullWidth
self.variant = variant
self.size = size
self.shape = shape
self.title = title
self.icon = icon
self.iconPosition = iconPosition
self._isLoading = isLoading
self.action = action
}

public var body: some View {
Button {
action?()
} label: {
HStack {
icon
if isLoading {
PBLoader(color: variant.foregroundColor(colorScheme: colorScheme))
} else {
if let title = title, shape == .primary {
Text(title)
}

public init(
variant: Variant = .primary,
size: Size = .medium,
shape: Shape = .primary,
title: String? = nil,
icon: PBIcon? = nil,
iconPosition: IconPosition? = .left,
isLoading: Binding<Bool> = .constant(false),
fullWidth: Bool = false,
action: (() -> Void)? = nil
) {
self.fullWidth = fullWidth
self.variant = variant
self.size = size
self.shape = shape
self.title = title
self.icon = icon
self.iconPosition = iconPosition
self._isLoading = isLoading
self.action = action
}

public var body: some View {
Button {
action?()
} label: {
HStack {
icon
if isLoading {
PBLoader(color: variant.foregroundColor(colorScheme: colorScheme))
} else {
if let title = title, shape == .primary {
Text(title)
}
}
}
.environment(\.layoutDirection, iconPosition == .left ? .leftToRight : .rightToLeft)
.frame(maxWidth: fullWidth ? .infinity : nil)
}
}
.environment(\.layoutDirection, iconPosition == .left ? .leftToRight : .rightToLeft)
.frame(maxWidth: fullWidth ? .infinity : nil)
.buttonStyle(PBButtonStyle(variant: variant, size: size, shape: shape))
.disabled(variant == .disabled ? true : false)
}
.customButtonStyle(
variant: variant,
shape: shape,
size: size
)
.disabled(variant == .disabled ? true : false)
}
}

public extension PBButton {
enum Shape {
case primary
case circle
}

enum Size {
case small
case medium
case large

public var fontSize: CGFloat {
switch self {
case .small:
return 12
case .medium:
return 14
case .large:
return 18
}
}

func verticalPadding(_ variant: PBButton.Variant) -> CGFloat {
return variant == .link ? 0 : fontSize / 2
enum Shape {
case primary
case circle

var minWidth: CGFloat {
switch self {
case .primary: return 0
case .circle: return 40
}
}

func minHeight(size: PBButton.Size, variant: PBButton.Variant) -> CGFloat {
switch self {
case .primary: return size.minHeight(variant)
case .circle: return 40
}
}

func verticalPadding(size: PBButton.Size, variant: PBButton.Variant) -> CGFloat {
switch self {
case .primary: return size.verticalPadding(variant)
case .circle: return 0
}
}

func horizontalPadding(size: PBButton.Size, variant: PBButton.Variant) -> CGFloat {
switch self {
case .primary: return size.horizontalPadding(variant)
case .circle: return 0
}
}
}

func horizontalPadding(_ variant: PBButton.Variant) -> CGFloat {
return variant == .link ? 0 : fontSize * 2.42
enum Size {
case small
case medium
case large

public var fontSize: CGFloat {
switch self {
case .small:
return 12
case .medium:
return 14
case .large:
return 18
}
}

func verticalPadding(_ variant: PBButton.Variant) -> CGFloat {
return variant == .link ? 0 : fontSize / 2
}

func horizontalPadding(_ variant: PBButton.Variant) -> CGFloat {
return variant == .link ? 0 : fontSize * 2.42
}

func minHeight(_ variant: PBButton.Variant) -> CGFloat {
if variant != .link {
switch self {
case .small:
return 30
case .medium:
return 40
case .large:
return 45
}
} else {
return 0
}
}
}

func minHeight(_ variant: PBButton.Variant) -> CGFloat {
if variant != .link {
switch self {
case .small:
return 30
case .medium:
return 40
case .large:
return 45
}
} else {
return 0
}
enum IconPosition {
case left
case right
}
}

enum IconPosition {
case left
case right
}
}

#Preview {
registerFonts()
return ButtonsCatalog()
registerFonts()
return ButtonsCatalog()
}
Loading