Digital ACT191 story ONEAPP-6682 Character limit, error text, and readonly changes.

- show error text when exceeds character limit.
- No restriction if character counter does not display.
- color changes for character counter label, error text, and readonly.
- Showing Character count overflow.
This commit is contained in:
vasavk 2024-02-26 11:52:06 +05:30
parent c2662aaf30
commit f7134b9b8c
2 changed files with 72 additions and 24 deletions

View File

@ -107,11 +107,15 @@ open class EntryFieldBase: Control, Changeable {
} }
internal var borderColorConfiguration = ControlColorConfiguration().with { internal var borderColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.borderOnlight, VDSFormControlsColor.borderOnlight, forState: .normal) $0.setSurfaceColors(VDSFormControlsColor.borderOnlight, VDSFormControlsColor.borderOndark, forState: .normal)
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled) $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forState: .disabled)
$0.setSurfaceColors(VDSColor.feedbackErrorOnlight, VDSColor.feedbackErrorOndark, forState: .error) $0.setSurfaceColors(VDSColor.feedbackErrorOnlight, VDSColor.feedbackErrorOndark, forState: .error)
} }
internal var readOnlyBorderColorConfiguration = ControlColorConfiguration().with {
$0.setSurfaceColors(VDSFormControlsColor.borderReadonlyOnlight, VDSFormControlsColor.borderReadonlyOndark, forState: .normal)
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Public Properties // MARK: - Public Properties
//-------------------------------------------------- //--------------------------------------------------
@ -160,8 +164,22 @@ open class EntryFieldBase: Control, Changeable {
} }
} }
open var errorText: String? { didSet { setNeedsUpdate() } } private var _errorText: String?
open var errorText: String? {
get { return _errorText }
set {
if let newValue {
_errorText = newValue
} else {
_errorText = nil
}
updateContainerView()
updateErrorLabel()
setNeedsUpdate()
}
}
open var tooltipModel: Tooltip.TooltipModel? { didSet { setNeedsUpdate() } } open var tooltipModel: Tooltip.TooltipModel? { didSet { setNeedsUpdate() } }
open var transparentBackground: Bool = false { didSet { setNeedsUpdate() } } open var transparentBackground: Bool = false { didSet { setNeedsUpdate() } }
@ -212,7 +230,7 @@ open class EntryFieldBase: Control, Changeable {
//this is the horizontal stack that contains //this is the horizontal stack that contains
//the left, InputContainer, Icons, Buttons //the left, InputContainer, Icons, Buttons
container.addSubview(containerStackView) container.addSubview(containerStackView)
containerStackView.pinToSuperView(.uniform(VDSFormControls.spaceInset)) containerStackView.pinToSuperView(.uniform(12))
//add the view to add input fields //add the view to add input fields
containerStackView.addArrangedSubview(controlContainerView) containerStackView.addArrangedSubview(controlContainerView)
@ -279,11 +297,7 @@ open class EntryFieldBase: Control, Changeable {
open override func updateView() { open override func updateView() {
super.updateView() super.updateView()
containerView.backgroundColor = backgroundColorConfiguration.getColor(self) updateContainerView()
containerView.layer.borderColor = borderColorConfiguration.getColor(self).cgColor
containerView.layer.borderWidth = VDSFormControls.widthBorder
containerView.layer.cornerRadius = VDSFormControls.borderradius
updateTitleLabel() updateTitleLabel()
updateErrorLabel() updateErrorLabel()
updateHelperLabel() updateHelperLabel()
@ -291,6 +305,16 @@ open class EntryFieldBase: Control, Changeable {
backgroundColor = surface.color backgroundColor = surface.color
} }
//--------------------------------------------------
// MARK: - Private Methods
//--------------------------------------------------
private func updateContainerView() {
containerView.backgroundColor = backgroundColorConfiguration.getColor(self)
containerView.layer.borderColor = borderColorConfiguration.getColor(self).cgColor
containerView.layer.borderWidth = VDSFormControls.widthBorder
containerView.layer.cornerRadius = VDSFormControls.borderradius
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Public Methods // MARK: - Public Methods
//-------------------------------------------------- //--------------------------------------------------

View File

@ -61,9 +61,11 @@ open class TextArea: EntryFieldBase {
} }
}() }()
open var characterCountLabel = Label().with { open var characterCounterLabel = Label().with {
$0.setContentCompressionResistancePriority(.required, for: .vertical) $0.setContentCompressionResistancePriority(.required, for: .vertical)
$0.textStyle = .bodySmall $0.textStyle = .bodySmall
$0.textAlignment = .right
$0.numberOfLines = 1
} }
//-------------------------------------------------- //--------------------------------------------------
@ -112,8 +114,8 @@ open class TextArea: EntryFieldBase {
open override func reset() { open override func reset() {
super.reset() super.reset()
textView.text = "" textView.text = ""
characterCountLabel.reset() characterCounterLabel.reset()
characterCountLabel.textStyle = .bodySmall characterCounterLabel.textStyle = .bodySmall
} }
/// Container for the area in which the user interacts. /// Container for the area in which the user interacts.
@ -139,11 +141,20 @@ open class TextArea: EntryFieldBase {
minWidthConstraint?.isActive = true minWidthConstraint?.isActive = true
} }
// allow - 20% of character limit if ((maxLength ?? 0) > 0) {
let overflowLimit = Double(maxLength ?? 0) * 0.20 // allow - 20% of character limit
allowCharCount = Int(overflowLimit) + (maxLength ?? 0) let overflowLimit = Double(maxLength ?? 0) * 0.20
characterCountLabel.text = getLimitText() allowCharCount = Int(overflowLimit) + (maxLength ?? 0)
characterCounterLabel.text = getCharacterCounterText()
} else {
characterCounterLabel.text = ""
}
icon.size = .medium
containerView.layer.borderColor = readOnly ? readOnlyBorderColorConfiguration.getColor(self).cgColor : borderColorConfiguration.getColor(self).cgColor
textView.isEditable = readOnly ? false : true
textView.backgroundColor = backgroundColorConfiguration.getColor(self)
characterCounterLabel.textColorConfiguration = primaryColorConfiguration.eraseToAnyColorable()
} }
/// Container for the area which shows helper text, error text, character count, max length value. /// Container for the area which shows helper text, error text, character count, max length value.
@ -151,18 +162,25 @@ open class TextArea: EntryFieldBase {
bottomView.addSubview(bottomStackView) bottomView.addSubview(bottomStackView)
bottomStackView.pinToSuperView() bottomStackView.pinToSuperView()
bottomStackView.addArrangedSubview(bottomContainerView) bottomStackView.addArrangedSubview(bottomContainerView)
bottomStackView.addArrangedSubview(characterCountLabel) bottomStackView.addArrangedSubview(characterCounterLabel)
return bottomView return bottomView
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Private Methods // MARK: - Private Methods
//-------------------------------------------------- //--------------------------------------------------
private func getLimitText() -> String { private func getCharacterCounterText() -> String {
let count = textView.text.count let count = textView.text.count
let countStr = (count > maxLength ?? 0) ? ("-" + "\(count-(maxLength ?? 0))") : "\(count)" let countStr = (count > maxLength ?? 0) ? ("-" + "\(count-(maxLength ?? 0))") : "\(count)"
let text = "\(countStr)" + "/" + "\(maxLength ?? 0)" if count > maxLength ?? 0 {
return text showError = true
errorText = "You have exceeded the character limit."
return countStr
} else {
showError = false
errorText = ""
return ("\(countStr)" + "/" + "\(maxLength ?? 0)")
}
} }
} }
@ -187,12 +205,18 @@ extension TextArea: UITextViewDelegate {
textViewHeightConstraint.isActive = true textViewHeightConstraint.isActive = true
} }
if textView.text.count <= allowCharCount { if ((maxLength ?? 0) > 0) {
if textView.text.count <= allowCharCount {
//setting the value and firing control event
value = textView.text
sendActions(for: .valueChanged)
} else {
textView.text.removeLast()
}
} else {
//setting the value and firing control event //setting the value and firing control event
value = textView.text value = textView.text
sendActions(for: .valueChanged) sendActions(for: .valueChanged)
} else {
textView.text.removeLast()
} }
} }
} }