diff --git a/VDS/Components/InputStepper/InputStepper.swift b/VDS/Components/InputStepper/InputStepper.swift index 84651c85..d9b4b6b8 100644 --- a/VDS/Components/InputStepper/InputStepper.swift +++ b/VDS/Components/InputStepper/InputStepper.swift @@ -10,6 +10,7 @@ import UIKit import VDSCoreTokens import Combine +/// A stepper is a two-segment control that people use to increase or decrease an incremental value. @objc(VDSInputStepper) open class InputStepper: EntryFieldBase { @@ -28,4 +29,141 @@ open class InputStepper: EntryFieldBase { super.init(coder: coder) } + //-------------------------------------------------- + // MARK: - Enums + //-------------------------------------------------- + + /// Enum used to describe the control width of Input Stepper. + public enum controlWidth: String, CaseIterable { + case auto, value + } + + /// Enum used to describe the size of Input Stepper. + public enum Size: String, CaseIterable { + case large, small + } + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + /// Accepts a string or number value to control the width of input stepper to a fixed pixel or percentage value. + open var controlWidth: CGFloat? { didSet { setNeedsUpdate() } } + + /// Maximum value of the input stepper, defaults to '99'. + open var maxValue: Int? { + get { return _maxValue } + set { + if let newValue, newValue < 100 && newValue > 0 { + _maxValue = newValue + } else { + _maxValue = 99 + } + setNeedsUpdate() + } + } + + /// Minimum value of the input stepper, defaults to '0'. + open var minValue: Int? { + get { return _minValue } + set { + if let newValue, newValue >= 0 && newValue < 99 { + _minValue = newValue + } else { + _minValue = 0 + } + setNeedsUpdate() + } + } + + /// The size of the input stepper. Defaults to 'large'. + open var size: Size { + get { return _size } + set { + _size = newValue + setNeedsUpdate() + } + } + + /// Accepts any text or character to appear next to input stepper value. + open var trailingText: String? { didSet { setNeedsUpdate() } } + + //-------------------------------------------------- + // MARK: - Private Properties + //-------------------------------------------------- + internal var _maxValue: Int = 99 + internal var _minValue: Int = 0 + internal var _size: Size = .large + + private var stepperWidthConstraint: NSLayoutConstraint? + private var stepperHeightConstraint: NSLayoutConstraint? + + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + open override func initialSetup() { + super.initialSetup() + } + + open override func setup() { + super.setup() + isAccessibilityElement = false + accessibilityLabel = "Input Stepper" + + containerView.isEnabled = false + } + + open override func getFieldContainer() -> UIView { + // stackview for controls in EntryFieldBase.controlContainerView + let controlStackView = UIStackView().with { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.axis = .horizontal + $0.spacing = VDSLayout.space3X + $0.backgroundColor = .clear + } + let view = View().with { + $0.clipsToBounds = true + $0.backgroundColor = .clear + } + + let controlView = View().with { + $0.clipsToBounds = true + $0.backgroundColor = .clear + } + + let label = Label().with { + $0.text = "Label" + } + + let minusButton = ButtonIcon().with { + $0.kind = .ghost + $0.iconName = .leftCaret + $0.iconOffset = .init(x: -2, y: 0) + $0.customContainerSize = 40 + $0.icon.customSize = 16 + } + + let plusButton = ButtonIcon().with { + $0.kind = .ghost + $0.iconName = .rightCaret + $0.iconOffset = .init(x: 2, y: 0) + $0.customContainerSize = 40 + $0.icon.customSize = 16 + } + + controlStackView.addArrangedSubview(minusButton) + controlStackView.addArrangedSubview(label) + controlStackView.addArrangedSubview(plusButton) + controlView.addSubview(controlStackView) + controlStackView.pinToSuperView() + + view.addSubview(controlView) + controlView.pinToSuperView() + view.pinToSuperView() + return view + } + + open override func updateView() { + super.updateView() + updateContainerView(flag: false) + } }