Skip to content

Commit 7859097

Browse files
authored
button: merge rectangle and capsule buttons
1 parent 189bc13 commit 7859097

4 files changed

Lines changed: 90 additions & 190 deletions

File tree

Docs/button-dark.png

205 KB
Loading

Docs/buttons-dark.png

-207 KB
Binary file not shown.

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ The design system in the kit includes the basics:
2525
<img src='https://github.com/reez/WalletUI/blob/main/Docs/colors-dark.png?raw=true' height='200' alt='colors-code-preview' />
2626
</a>
2727
<a href='https://www.figma.com/community/file/916680391812923706/Bitcoin-Wallet-UI-Kit-(work-in-progress)'>
28-
<img src='https://github.com/reez/WalletUI/blob/main/Docs/buttons-dark.png?raw=true' height='200' alt='buttons-code-preview' />
28+
<img src='https://github.com/reez/WalletUI/blob/main/Docs/button-dark.png?raw=true' height='200' alt='buttons-code-preview' />
2929
</a>
3030
<a href='https://www.figma.com/community/file/916680391812923706/Bitcoin-Wallet-UI-Kit-(work-in-progress)'>
3131
<img src='https://github.com/reez/WalletUI/blob/main/Docs/text-dark.png?raw=true' height='200' alt='text-code-preview' />
@@ -65,15 +65,15 @@ They have a number of optional parameters, including: width, height, cornerRadiu
6565
*SwiftUI*
6666

6767
```swift
68-
Button("Capsule filled button") {
68+
Button("Filled button") {
6969
print("Button pressed!")
7070
}
71-
.buttonStyle(BitcoinCapsuleFilled())
71+
.buttonStyle(BitcoinFilled())
7272

73-
Button("Filled button") {
73+
Button("Outlined button") {
7474
print("Button pressed!")
7575
}
76-
.buttonStyle(BitcoinFilled())
76+
.buttonStyle(BitcoinOutlined())
7777
```
7878

7979
### Text Styles

Sources/WalletUI/ButtonStyles.swift

Lines changed: 85 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -17,69 +17,6 @@ public let defaultDisabledFillColor = Color.bitcoinNeutral2
1717
public let defaultDisabledTextColor = Color.bitcoinNeutral5
1818
public let defaultDisabledOutlineColor = Color.bitcoinNeutral4
1919

20-
/// A `ButtonStyle` corresponding to a Filled Capsule type not currently in the Bitcoin Wallet UI Kit
21-
///
22-
/// ```swift
23-
/// Button("Label") {
24-
/// print("Button pressed!")
25-
/// }
26-
///.buttonStyle(BitcoinCapsuleFilled())
27-
/// ```
28-
/// - Parameter width: The width of the button (optional, default is 315.0)
29-
/// - Parameter height: The width of the button (optional, default is 48.0)
30-
/// - Parameter cornerRadius: The corner radius of the button (optional, default is 5.0)
31-
/// - Parameter tintColor: The background color of the button (optional, default is .bitcoinOrange)
32-
/// - Parameter textColor: The text color of the button (optional, default is .bitcoinWhite)
33-
/// - Parameter disabledFillColor: The disabled background color of the button (optional, default is .bitcoinNeutral2)
34-
/// - Parameter disabledTextColor: The disabled text color of the button (optional, default is .bitcoinNeutral5)
35-
///
36-
public struct BitcoinCapsuleFilled: ButtonStyle {
37-
@Environment(\.isEnabled) private var isEnabled
38-
39-
let width: CGFloat
40-
let height: CGFloat
41-
let tintColor: Color
42-
let textColor: Color
43-
let disabledFillColor: Color
44-
let disabledTextColor: Color
45-
46-
public init(
47-
width: CGFloat = defaultButtonWidth, height: CGFloat = defaultButtonHeight,
48-
tintColor: Color = defaultTintColor,
49-
textColor: Color = defaultTextColor, disabledFillColor: Color = defaultDisabledFillColor,
50-
disabledTextColor: Color = defaultDisabledTextColor
51-
) {
52-
self.width = width
53-
self.height = height
54-
self.tintColor = tintColor
55-
self.textColor = textColor
56-
self.disabledFillColor = disabledFillColor
57-
self.disabledTextColor = disabledTextColor
58-
}
59-
60-
public func makeBody(configuration: Configuration) -> some View {
61-
let stateBackgroundColor = stateBackgroundColor(configuration: configuration)
62-
configuration.label
63-
.font(Font.body.bold())
64-
.padding()
65-
.frame(width: width, height: height)
66-
.background(stateBackgroundColor.opacity(0.8))
67-
.clipShape(Capsule())
68-
.foregroundColor(stateTextColor())
69-
.scaleEffect(configuration.isPressed ? 0.95 : 1)
70-
.animation(.easeOut(duration: 0.1), value: configuration.isPressed)
71-
}
72-
73-
private func stateBackgroundColor(configuration: Configuration) -> Color {
74-
return isEnabled
75-
? configuration.isPressed ? tintColor.opacity(0.8) : tintColor : disabledFillColor
76-
}
77-
78-
private func stateTextColor() -> Color {
79-
return isEnabled ? textColor : disabledTextColor
80-
}
81-
}
82-
8320
/// A `ButtonStyle` corresponding to the Filled type in the Bitcoin Wallet UI Kit
8421
///
8522
/// ```swift
@@ -107,12 +44,13 @@ public struct BitcoinFilled: ButtonStyle {
10744
let textColor: Color
10845
let disabledFillColor: Color
10946
let disabledTextColor: Color
47+
let isCapsule: Bool
11048

11149
public init(
11250
width: CGFloat = defaultButtonWidth, height: CGFloat = defaultButtonHeight,
11351
cornerRadius: CGFloat = defaultCornerRadius, tintColor: Color = defaultTintColor,
11452
textColor: Color = defaultTextColor, disabledFillColor: Color = defaultDisabledFillColor,
115-
disabledTextColor: Color = defaultDisabledTextColor
53+
disabledTextColor: Color = defaultDisabledTextColor, isCapsule: Bool = false
11654
) {
11755
self.width = width
11856
self.height = height
@@ -121,6 +59,7 @@ public struct BitcoinFilled: ButtonStyle {
12159
self.textColor = textColor
12260
self.disabledFillColor = disabledFillColor
12361
self.disabledTextColor = disabledTextColor
62+
self.isCapsule = isCapsule
12463
}
12564

12665
public func makeBody(configuration: Configuration) -> some View {
@@ -129,7 +68,10 @@ public struct BitcoinFilled: ButtonStyle {
12968
.font(Font.body.bold())
13069
.padding()
13170
.frame(width: width, height: height)
132-
.background(stateBackgroundColor.opacity(0.8).cornerRadius(cornerRadius))
71+
.background(
72+
stateBackgroundColor.opacity(0.8)
73+
.clipShape(CustomShape(isCapsule: isCapsule, cornerRadius: cornerRadius))
74+
)
13375
.foregroundColor(stateTextColor())
13476
.scaleEffect(configuration.isPressed ? 0.95 : 1)
13577
.animation(.easeOut(duration: 0.1), value: configuration.isPressed)
@@ -145,66 +87,6 @@ public struct BitcoinFilled: ButtonStyle {
14587
}
14688
}
14789

148-
/// A `ButtonStyle` corresponding to a Capsule Outline type not yet in the Bitcoin Wallet UI Kit
149-
///
150-
/// ```swift
151-
/// Button("Label") {
152-
/// print("Button pressed!")
153-
/// }
154-
///.buttonStyle(BitcoinCapsuleOutlined())
155-
/// ```
156-
/// - Parameter width: The width of the button (optional, default is 315.0)
157-
/// - Parameter height: The width of the button (optional, default is 48.0)
158-
/// - Parameter cornerRadius: The corner radius of the button (optional, default is 5.0)
159-
/// - Parameter tintColor: The border and text color of the button (optional, default is .bitcoinOrange)
160-
/// - Parameter disabledColor: The disabled color of the button (optional, default is .bitcoinNeutral4)
161-
///
162-
public struct BitcoinCapsuleOutlined: ButtonStyle {
163-
@Environment(\.colorScheme) private var colorScheme
164-
@Environment(\.isEnabled) private var isEnabled
165-
166-
let width: CGFloat
167-
let height: CGFloat
168-
let tintColor: Color
169-
let disabledColor: Color
170-
171-
public init(
172-
width: CGFloat = defaultButtonWidth, height: CGFloat = defaultButtonHeight,
173-
tintColor: Color = defaultTintColor,
174-
disabledColor: Color = defaultDisabledOutlineColor
175-
) {
176-
self.width = width
177-
self.height = height
178-
self.tintColor = tintColor
179-
self.disabledColor = disabledColor
180-
}
181-
182-
public func makeBody(configuration: Configuration) -> some View {
183-
configuration.label
184-
.font(Font.body.bold())
185-
.padding()
186-
.frame(width: width, height: height)
187-
.background(stateBackgroundColor())
188-
.clipShape(Capsule())
189-
.foregroundColor(stateTextColor())
190-
.overlay(
191-
Capsule()
192-
.stroke(stateBorderColor(configuration: configuration), lineWidth: 1.5)
193-
)
194-
.scaleEffect(configuration.isPressed ? 0.95 : 1)
195-
.animation(.easeOut(duration: 0.1), value: configuration.isPressed)
196-
}
197-
private func stateBackgroundColor() -> Color {
198-
return colorScheme == .dark ? .bitcoinBlack : .bitcoinWhite
199-
}
200-
private func stateBorderColor(configuration: Configuration) -> Color {
201-
return isEnabled ? configuration.isPressed ? tintColor.opacity(0.8) : tintColor : disabledColor
202-
}
203-
private func stateTextColor() -> Color {
204-
return isEnabled ? tintColor : disabledColor
205-
}
206-
}
207-
20890
/// A `ButtonStyle` corresponding to the Outline type in the Bitcoin Wallet UI Kit
20991
///
21092
/// ```swift
@@ -220,50 +102,55 @@ public struct BitcoinCapsuleOutlined: ButtonStyle {
220102
/// - Parameter disabledColor: The disabled color of the button (optional, default is .bitcoinNeutral4)
221103
///
222104
public struct BitcoinOutlined: ButtonStyle {
223-
@Environment(\.colorScheme) private var colorScheme
224-
@Environment(\.isEnabled) private var isEnabled
225-
226-
let width: CGFloat
227-
let height: CGFloat
228-
let cornerRadius: CGFloat
229-
let tintColor: Color
230-
let disabledColor: Color
105+
@Environment(\.colorScheme) private var colorScheme
106+
@Environment(\.isEnabled) private var isEnabled
107+
108+
let width: CGFloat
109+
let height: CGFloat
110+
let cornerRadius: CGFloat
111+
let tintColor: Color
112+
let disabledColor: Color
113+
let isCapsule: Bool
114+
115+
public init(
116+
width: CGFloat = defaultButtonWidth, height: CGFloat = defaultButtonHeight,
117+
cornerRadius: CGFloat = defaultCornerRadius, tintColor: Color = defaultTintColor,
118+
disabledColor: Color = defaultDisabledOutlineColor,
119+
isCapsule: Bool = false
120+
) {
121+
self.width = width
122+
self.height = height
123+
self.cornerRadius = cornerRadius
124+
self.tintColor = tintColor
125+
self.disabledColor = disabledColor
126+
self.isCapsule = isCapsule
127+
}
231128

232-
public init(
233-
width: CGFloat = defaultButtonWidth, height: CGFloat = defaultButtonHeight,
234-
cornerRadius: CGFloat = defaultCornerRadius, tintColor: Color = defaultTintColor,
235-
disabledColor: Color = defaultDisabledOutlineColor
236-
) {
237-
self.width = width
238-
self.height = height
239-
self.cornerRadius = cornerRadius
240-
self.tintColor = tintColor
241-
self.disabledColor = disabledColor
242-
}
129+
public func makeBody(configuration: Configuration) -> some View {
130+
configuration.label
131+
.font(Font.body.bold())
132+
.padding()
133+
.frame(width: width, height: height)
134+
.background(stateBackgroundColor())
135+
.clipShape(CustomShape(isCapsule: isCapsule, cornerRadius: cornerRadius)) // Use CustomShape
136+
.foregroundColor(stateTextColor())
137+
.overlay(
138+
CustomShape(isCapsule: isCapsule, cornerRadius: cornerRadius) // Use CustomShape
139+
.stroke(stateBorderColor(configuration: configuration), lineWidth: 1.5)
140+
)
141+
.scaleEffect(configuration.isPressed ? 0.95 : 1)
142+
.animation(.easeOut(duration: 0.1), value: configuration.isPressed)
143+
}
243144

244-
public func makeBody(configuration: Configuration) -> some View {
245-
configuration.label
246-
.font(Font.body.bold())
247-
.padding()
248-
.frame(width: width, height: height)
249-
.background(stateBackgroundColor().cornerRadius(cornerRadius))
250-
.foregroundColor(stateTextColor())
251-
.overlay(
252-
RoundedRectangle(cornerRadius: cornerRadius)
253-
.stroke(stateBorderColor(configuration: configuration), lineWidth: 1.5)
254-
)
255-
.scaleEffect(configuration.isPressed ? 0.95 : 1)
256-
.animation(.easeOut(duration: 0.1), value: configuration.isPressed)
257-
}
258-
private func stateBackgroundColor() -> Color {
259-
return colorScheme == .dark ? .bitcoinBlack : .bitcoinWhite
260-
}
261-
private func stateBorderColor(configuration: Configuration) -> Color {
262-
return isEnabled ? configuration.isPressed ? tintColor.opacity(0.8) : tintColor : disabledColor
263-
}
264-
private func stateTextColor() -> Color {
265-
return isEnabled ? tintColor : disabledColor
266-
}
145+
private func stateBackgroundColor() -> Color {
146+
return colorScheme == .dark ? .bitcoinBlack : .bitcoinWhite
147+
}
148+
private func stateBorderColor(configuration: Configuration) -> Color {
149+
return isEnabled ? configuration.isPressed ? tintColor.opacity(0.8) : tintColor : disabledColor
150+
}
151+
private func stateTextColor() -> Color {
152+
return isEnabled ? tintColor : disabledColor
153+
}
267154
}
268155

269156
/// A `ButtonStyle` corresponding to the Plain type in the Bitcoin Wallet UI Kit
@@ -319,6 +206,19 @@ public struct BitcoinPlain: ButtonStyle {
319206
}
320207
}
321208

209+
private struct CustomShape: Shape {
210+
var isCapsule: Bool
211+
var cornerRadius: CGFloat
212+
213+
func path(in rect: CGRect) -> Path {
214+
if isCapsule {
215+
return Capsule().path(in: rect)
216+
} else {
217+
return RoundedRectangle(cornerRadius: cornerRadius).path(in: rect)
218+
}
219+
}
220+
}
221+
322222
struct ButtonStylesView: View {
323223
var body: some View {
324224

@@ -337,27 +237,27 @@ struct ButtonStylesView: View {
337237
.padding(.top, .wallet_grid_vertical_20())
338238

339239
Spacer()
340-
341-
Button("BitcoinCapsuleFilled") {}
342-
.buttonStyle(BitcoinCapsuleFilled())
343-
.padding()
344-
345-
Button("BitcoinFilled") {}
346-
.buttonStyle(BitcoinFilled())
347-
.padding()
348-
240+
241+
Button("BitcoinFilled") {}
242+
.buttonStyle(BitcoinFilled())
243+
.padding()
244+
245+
Button("BitcoinFilled") {}
246+
.buttonStyle(BitcoinFilled(isCapsule: true))
247+
.padding()
248+
349249
Button("BitcoinPlain") {}
350250
.buttonStyle(BitcoinPlain())
351251
.padding()
352-
353-
Button("BitcoinCapsuleOutlined") {}
354-
.buttonStyle(BitcoinCapsuleOutlined())
355-
.padding()
356-
357-
Button("BitcoinOutlined") {}
358-
.buttonStyle(BitcoinOutlined())
359-
.padding()
360-
252+
253+
Button("BitcoinOutlined") {}
254+
.buttonStyle(BitcoinOutlined())
255+
.padding()
256+
257+
Button("BitcoinOutlined") {}
258+
.buttonStyle(BitcoinOutlined(isCapsule: true))
259+
.padding()
260+
361261
Spacer()
362262

363263
}

0 commit comments

Comments
 (0)