// // TextArea.swift // VDS // // Created by Matt Bruce on 1/10/23. // import Foundation import Foundation import UIKit import VDSColorTokens import VDSFormControlsTokens import Combine @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 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: 45, height: 88) } private var textView = UITextView().with { $0.translatesAutoresizingMaskIntoConstraints = false $0.font = TextStyle.bodyLarge.font $0.sizeToFit() $0.isScrollEnabled = false } 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() }} internal var minWidthConstraint: NSLayoutConstraint? internal var textViewHeightConstraint: NSLayoutConstraint? //-------------------------------------------------- // 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: 0) minWidthConstraint?.isActive = true controlContainerView.addSubview(textView) textView.pinToSuperView() textViewHeightConstraint = textView.heightAnchor.constraint(greaterThanOrEqualToConstant: 64) 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 = "" } 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.frame.size.height let constraintHeight = textViewHeightConstraint.constant if height > constraintHeight { if height > 64 && height < 152 { textViewHeightConstraint.constant = 152 } else if height > 152 { textViewHeightConstraint.constant = 328 } else { textViewHeightConstraint.constant = 64 } } } //setting the value and firing control event value = textView.text sendActions(for: .valueChanged) } }