Skip to content

Commit 576828d

Browse files
committed
[FEAT] added disable functionality to increment and decrement
[UPDATE] change opacity for disable button, updated images, updated test cases
1 parent f983ce6 commit 576828d

File tree

3 files changed

+51
-42
lines changed

3 files changed

+51
-42
lines changed

Sources/YStepper/SwiftUI/Views/Stepper.swift

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ public struct Stepper {
1717
@ObservedObject private var appearanceObserver = Stepper.AppearanceObserver()
1818
@ObservedObject private var valueObserver = Stepper.ValueObserver()
1919

20+
var isIncrementDisabled: Bool {
21+
value >= maximumValue
22+
}
23+
var isDecrmentDisabled: Bool {
24+
value <= minimumValue
25+
}
26+
2027
/// Receive value change notification
2128
public weak var delegate: StepperDelegate?
2229

@@ -106,16 +113,26 @@ extension Stepper: View {
106113
func getIncrementButton() -> some View {
107114
Button { buttonAction(buttonType: .increment) } label: {
108115
getIncrementImage().renderingMode(.template)
116+
.foregroundColor(
117+
isIncrementDisabled ?
118+
Color(appearance.textStyle.textColor).opacity(0.5) : Color(appearance.textStyle.textColor)
119+
)
109120
}
110121
.accessibilityLabel(StepperControl.Strings.incrementA11yButton.localized)
122+
.disabled(isIncrementDisabled)
111123
}
112124

113125
@ViewBuilder
114126
func getDecrementButton() -> some View {
115127
Button { buttonAction(buttonType: .decrement) } label: {
116128
getImageForDecrementButton()?.renderingMode(.template)
129+
.foregroundColor(
130+
isDecrmentDisabled ?
131+
Color(appearance.textStyle.textColor).opacity(0.5) : Color(appearance.textStyle.textColor)
132+
)
117133
}
118134
.accessibilityLabel(getAccessibilityText())
135+
.disabled(isDecrmentDisabled)
119136
}
120137

121138
func getTextView() -> some View {
@@ -130,7 +147,7 @@ extension Stepper: View {
130147
.frame(width: getStringSize(sizeCategory).width)
131148
.accessibilityLabel(getAccessibilityLabelText())
132149
}
133-
150+
134151
@ViewBuilder
135152
func getShape() -> some View {
136153
switch appearance.layout.shape {
@@ -199,7 +216,7 @@ extension Stepper {
199216
}
200217

201218
func getAccessibilityText() -> String {
202-
if appearance.hasDeleteButton
219+
if appearance.showDeleteImage
203220
&& value <= stepValue
204221
&& minimumValue == 0 {
205222
return StepperControl.Strings.deleteA11yButton.localized
@@ -245,11 +262,8 @@ extension Stepper {
245262
}
246263

247264
extension Stepper {
248-
func getDeleteImage() -> Image? {
249-
if let image = appearance.deleteImage {
250-
return Image(uiImage: image)
251-
}
252-
return nil
265+
func getDeleteImage() -> Image {
266+
Image(uiImage: appearance.deleteImage)
253267
}
254268

255269
@ViewBuilder
@@ -263,7 +277,7 @@ extension Stepper {
263277
}
264278

265279
func getImageForDecrementButton() -> Image? {
266-
if appearance.hasDeleteButton
280+
if appearance.showDeleteImage
267281
&& value <= stepValue
268282
&& minimumValue == 0 {
269283
return getDeleteImage()

Sources/YStepper/UIKit/StepperControl+Appearance.swift

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ extension StepperControl {
2020
public var borderColor: UIColor
2121
/// Border width for stepper view
2222
public var borderWidth: CGFloat
23-
/// Delete button image. Nil means no delete button
24-
public var deleteImage: UIImage?
23+
/// Delete button image
24+
public var deleteImage: UIImage
2525
/// Increment button image
2626
public var incrementImage: UIImage
2727
/// Decrement button image
2828
public var decrementImage: UIImage
2929
/// Stepper's layout properties such as spacing between views. Default is `.default`
3030
public var layout: Layout
31-
/// Whether to show delete button or not
32-
var hasDeleteButton: Bool { deleteImage != nil }
31+
/// Whether to show delete image or not
32+
var showDeleteImage: Bool
3333

3434
/// Initializer for appearance
3535
/// - Parameters:
@@ -39,30 +39,36 @@ extension StepperControl {
3939
/// - backgroundColor: Background color for stepper view. Default is `.systemBackground`
4040
/// - borderColor: Border color for stepper view. Default is `UIColor.label`
4141
/// - borderWidth: Border width for day view. Default is `1.0`
42-
/// - deleteImage: Delete button image. Default is `Appearance.defaultDeleteImage`
43-
/// - incrementImage: Increment button image. Default is `Appearance.defaultIncrementImage`
44-
/// - decrementImage: Decrement button image. Default is `Appearance.defaultDecrementImage`
42+
/// - deleteImage: Delete button image. Default is `nil`.
43+
/// Nil means using `Appearance.defaultDeleteImage`
44+
/// - incrementImage: Increment button image. Default is `nil`
45+
/// Nil means using `Appearance.defaultIncrementImage`
46+
/// - decrementImage: Decrement button image. Default is `nil`
47+
/// Nil means using `Appearance.defaultDecrementImage`
4548
/// - layout: Stepper's layout properties like spacing between views
46-
49+
/// - showDeleteImage: Whether to show delete button or not. Default is`true`
50+
4751
public init(
4852
textStyle: (textColor: UIColor, typography: Typography) = (.label, .systemLabel),
4953
foregroundColor: UIColor = .label,
5054
backgroundColor: UIColor = .systemBackground,
5155
borderColor: UIColor = .label,
5256
borderWidth: CGFloat = 1.0,
53-
deleteImage: UIImage? = Appearance.defaultDeleteImage,
54-
incrementImage: UIImage = Appearance.defaultIncrementImage,
55-
decrementImage: UIImage = Appearance.defaultDecrementImage,
56-
layout: Layout = .default
57+
deleteImage: UIImage? = nil,
58+
incrementImage: UIImage? = nil,
59+
decrementImage: UIImage? = nil,
60+
layout: Layout = .default,
61+
showDeleteImage: Bool = true
5762
) {
5863
self.textStyle = textStyle
5964
self.backgroundColor = backgroundColor
6065
self.borderColor = borderColor
6166
self.borderWidth = borderWidth
62-
self.deleteImage = deleteImage
63-
self.incrementImage = incrementImage
64-
self.decrementImage = decrementImage
67+
self.deleteImage = deleteImage ?? Appearance.defaultDeleteImage
68+
self.incrementImage = incrementImage ?? Appearance.defaultIncrementImage
69+
self.decrementImage = decrementImage ?? Appearance.defaultDecrementImage
6570
self.layout = layout
71+
self.showDeleteImage = showDeleteImage
6672
}
6773
}
6874
}

Tests/YStepperTests/Views/StepperTests.swift

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,20 @@ final class StepperTests: XCTestCase {
9595

9696
func testImagesShouldNotBeNil() {
9797
let sut = makeSUT(appearance: StepperControl.Appearance(
98-
deleteImage: StepperControl.Appearance.defaultDeleteImage
98+
deleteImage: nil,
99+
incrementImage: nil,
100+
decrementImage: nil
99101
))
100102

101103
XCTAssertNotNil(sut.getIncrementImage())
102104
XCTAssertNotNil(sut.getDecrementImage())
103105
XCTAssertNotNil(sut.getDeleteImage())
104106
}
105107

106-
func testDeleteImageShouldBeNil() {
107-
let sut = makeSUT(appearance: StepperControl.Appearance(deleteImage: nil))
108-
XCTAssertNil(sut.getDeleteImage())
109-
110-
let decrementImage = sut.getDecrementImage()
111-
112-
XCTAssertEqual(decrementImage, sut.getImageForDecrementButton())
108+
func testDecrementImageshouldNotReturnDeleteImage() {
109+
let sut = makeSUT(appearance: StepperControl.Appearance(showDeleteImage: false))
110+
let decrementImage = sut.getDeleteImage()
111+
XCTAssertNotEqual(decrementImage, sut.getImageForDecrementButton())
113112
}
114113

115114
func testValueGreaterThanMaxValue() {
@@ -131,9 +130,6 @@ final class StepperTests: XCTestCase {
131130

132131
sut.value = sut.stepValue
133132
XCTAssertEqual(sut.getImageForDecrementButton(), deleteImage)
134-
135-
sut.appearance.deleteImage = nil
136-
XCTAssertEqual(sut.getImageForDecrementButton(), decrementImage)
137133
}
138134

139135
func testButtonAction() {
@@ -145,13 +141,6 @@ final class StepperTests: XCTestCase {
145141
XCTAssertEqual(sut.value, sut.minimumValue)
146142
}
147143

148-
func testBackgroundNotNil() {
149-
let sut = makeSUT()
150-
let button = sut.getDecrementButton()
151-
152-
XCTAssertNotNil(button)
153-
}
154-
155144
func testShapesNotNil() {
156145
var expectedAppearance = StepperControl.Appearance(layout: StepperControl.Appearance.Layout(shape: .rectangle))
157146
var sut = makeSUT(appearance: expectedAppearance)
@@ -242,7 +231,7 @@ final class StepperTests: XCTestCase {
242231
var sut = makeSUT()
243232
XCTAssertEqual(sut.getAccessibilityText(), StepperControl.Strings.deleteA11yButton.localized)
244233

245-
sut.appearance.deleteImage = nil
234+
sut.appearance.showDeleteImage = false
246235
XCTAssertEqual(sut.getAccessibilityText(), StepperControl.Strings.decrementA11yButton.localized)
247236
}
248237
}

0 commit comments

Comments
 (0)