vds_ios/VDS/Components/TextFields/TextArea/TextArea.swift

151 lines
5.5 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// TextArea.swift
// VDS
//
// Created by Matt Bruce on 1/10/23.
//
import Foundation
import UIKit
import VDSColorTokens
import VDSFormControlsTokens
import Combine
/// A text area is an input wherein a customer enters long-form information.
/// Use a text area when you want customers to enter text thats longer than a single line.
@objc(VDSTextArea)
open class TextArea: EntryFieldBase {
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
required public init() {
super.init(frame: .zero)
}
public override init(frame: CGRect) {
super.init(frame: .zero)
}
public required init?(coder: NSCoder) {
super.init(coder: coder)
}
//--------------------------------------------------
// MARK: - Private Properties
//--------------------------------------------------
internal var minWidthConstraint: NSLayoutConstraint?
internal var textViewHeightConstraint: NSLayoutConstraint?
internal var inputFieldStackView: UIStackView = {
return UIStackView().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.axis = .horizontal
$0.distribution = .fill
$0.spacing = 12
}
}()
//--------------------------------------------------
// MARK: - Public Properties
//--------------------------------------------------
override var containerSize: CGSize { CGSize(width: 182, height: 88) }
/// UITextView shown in the TextArea.
open var textView = UITextView().with {
$0.translatesAutoresizingMaskIntoConstraints = false
$0.font = TextStyle.bodyLarge.font
$0.sizeToFit()
$0.isScrollEnabled = false
}
/// Color configuration for the textView.
open var textViewTextColorConfiguration: AnyColorable = ViewColorConfiguration().with {
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forDisabled: true)
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: false)
}.eraseToAnyColorable() { didSet { setNeedsUpdate() } }
//--------------------------------------------------
// MARK: - Overrides
//--------------------------------------------------
/// Called once when a view is initialized and is used to Setup additional UI or other constants and configurations.
open override func setup() {
super.setup()
minWidthConstraint = containerView.widthAnchor.constraint(greaterThanOrEqualToConstant: containerSize.width)
minWidthConstraint?.isActive = true
controlContainerView.addSubview(textView)
textView
.pinTop()
.pinLeading()
.pinTrailingLessThanOrEqualTo(nil, 0, .defaultHigh)
.pinBottom(0, .defaultHigh)
textView.isScrollEnabled = true
textViewHeightConstraint = textView.heightAnchor.constraint(greaterThanOrEqualToConstant: containerSize.height)
textViewHeightConstraint?.isActive = true
backgroundColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessBackgroundOnlight, VDSColor.feedbackSuccessBackgroundOndark, forState: .success)
borderColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessOnlight, VDSColor.feedbackSuccessOndark, forState: .success)
textView.delegate = self
}
/// Resets to default settings.
open override func reset() {
super.reset()
textView.text = ""
}
/// Container for the area in which the user interacts.
open override func getContainer() -> UIView {
inputFieldStackView.addArrangedSubview(containerView)
return inputFieldStackView
}
/// Used to make changes to the View based off a change events or from local properties.
open override func updateView() {
super.updateView()
textView.isEditable = isEnabled
textView.textColor = textViewTextColorConfiguration.getColor(self)
//set the width constraints
if let width {
widthConstraint?.constant = width
widthConstraint?.isActive = true
minWidthConstraint?.isActive = false
} else {
minWidthConstraint?.constant = containerSize.width
widthConstraint?.isActive = false
minWidthConstraint?.isActive = true
}
}
}
extension TextArea: UITextViewDelegate {
//--------------------------------------------------
// MARK: - UITextViewDelegate
//--------------------------------------------------
public func textViewDidChange(_ textView: UITextView) {
//dynamic textView Height sizing based on Figma
//if you want it to work "as-is" delete this code
//since it will autogrow with the current settings
if let textViewHeightConstraint, textView.isEditable {
let height = textView.contentSize.height
if height > 88 && height < 176 {
textViewHeightConstraint.constant = 176
} else if height > 176 {
textViewHeightConstraint.constant = 352
} else {
textViewHeightConstraint.constant = 88
}
textViewHeightConstraint.isActive = true
}
//setting the value and firing control event
value = textView.text
sendActions(for: .valueChanged)
}
}