Skip to content

Commit

Permalink
feat: updated tatb behaviour in textfield
Browse files Browse the repository at this point in the history
  • Loading branch information
vkaltyrin committed Mar 5, 2025
1 parent 067f0f6 commit 4fd3198
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,7 @@ public struct SDDSTextField: View {

HStack(spacing: 0) {
fieldView
.onTapGesture {
guard !displayChips else {
return
}
withAnimation {
isFocused = true
}
}
.debug(condition: debugConfiguration.fieldView)

}
HStack(spacing: 0) {
captionLabel
Expand All @@ -128,7 +120,14 @@ public struct SDDSTextField: View {
}
.opacity(disabled ? appearance.disabledAlpha : 1)
.disabled(disabled)
.debug(condition: debugConfiguration.textField)
.onTapGesture {
guard !displayChips && !disabled else {
return
}
withAnimation {
isFocused = true
}
}
}

// MARK: - Subviews
Expand Down Expand Up @@ -247,58 +246,61 @@ public struct SDDSTextField: View {
private var textField: some View {
switch value {
case .single:
GeometryReader { proxy in
VStack(spacing: 0) {
if shouldCenterText {
Spacer()
}
HStack(spacing: 0) {
if showSuffixOrPrefix {
textBeforeView
.padding(.leading, appearance.size.textBeforeLeadingPadding)
.padding(.trailing, appearance.size.textBeforeTrailingPadding)
ScrollViewReader { scrollViewProxy in
GeometryReader { proxy in
VStack(spacing: 0) {
if shouldCenterText {
Spacer()
}
PlaceholderTextField(
text: $text,
isFocused: $isFocused,
textColor: textColor,
textAlignment: appearance.inputTextAlignment,
cursorColor: appearance.cursorColor.color(for: colorScheme),
textTypography: textTypography,
readOnly: readOnly,
placeholderBeforeContent: {
textBeforeView
},
placeholderContent: {
placeholderView
},
placeholderAfterContent: {
HStack(spacing: 0) {
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 0) {
if showSuffixOrPrefix {
textBeforeView
}
PlaceholderTextField(
text: $text,
isFocused: $isFocused,
textColor: textColor,
textAlignment: appearance.inputTextAlignment,
cursorColor: appearance.cursorColor.color(for: colorScheme),
textTypography: textTypography,
readOnly: readOnly,
placeholderBeforeContent: {
EmptyView()
},
placeholderContent: {
placeholderView
},
placeholderAfterContent: {
EmptyView()
},
onEditingChanged: { focused in
isFocused = focused
},
textFieldConfiguration: { textField in
textFieldConfiguration(textField: textField)
.id(textFieldIdentifier)
.frame(
width: calculatedTextSize,
height: textTypography.lineHeight
)
}
)
if showSuffixOrPrefix {
textAfterView
.id(textAfterIdentifier)
}
},
onEditingChanged: { focused in
isFocused = focused
},
textFieldConfiguration: { textField in
textFieldConfiguration(textField: textField)
.frame(
width: calculateTextWidth(text: text, placeholder: placeholder, proxy: proxy),
height: textTypography.lineHeight,
debug: debugConfiguration.textField
)
}
)

if showSuffixOrPrefix {
textAfterView
.padding(.leading, appearance.size.textAfterLeadingPadding)
.padding(.trailing, appearance.size.textAfterTrailingPadding)
}
}

if shouldCenterText {
Spacer()
.onChange(of: text) { _ in
scroll(with: scrollViewProxy)
}
.onChange(of: textAfter) { _ in
scroll(with: scrollViewProxy)
}
if shouldCenterText {
Spacer()
}
}
}
}
Expand All @@ -320,20 +322,15 @@ public struct SDDSTextField: View {
textFieldConfiguration: { textField in
textFieldConfiguration(textField: textField)
.frame(
width: chipsTextSize,
width: calculatedTextSize,
height: textTypography.lineHeight,
debug: debugConfiguration.textField
)
}
)
}
}

private var chipsTextSize: CGFloat {
let textSize = (text as NSString).size(withAttributes: [NSAttributedString.Key.font: textTypography.uiFont])
return ceil(textSize.width)
}


@ViewBuilder
private func textFieldConfiguration(textField: FocusableTextField) -> some View {
textField
Expand Down Expand Up @@ -416,6 +413,8 @@ public struct SDDSTextField: View {
.typography(textBeforeTypography)
.frame(height: textTypography.lineHeight)
.foregroundColor(appearance.textBeforeColor.color(for: colorScheme))
.padding(.leading, appearance.size.textBeforeLeadingPadding)
.padding(.trailing, appearance.size.textBeforeTrailingPadding)
}
}

Expand All @@ -428,6 +427,8 @@ public struct SDDSTextField: View {
.typography(textAfterTypography)
.frame(height: textTypography.lineHeight)
.foregroundColor(appearance.textAfterColor.color(for: colorScheme))
.padding(.leading, appearance.size.textAfterLeadingPadding)
.padding(.trailing, appearance.size.textAfterTrailingPadding)
}
}

Expand Down Expand Up @@ -505,6 +506,14 @@ public struct SDDSTextField: View {
}
}

private func scroll(with proxy: ScrollViewProxy) {
if !textAfter.isEmpty {
proxy.scrollTo(textAfterIdentifier, anchor: .trailing)
} else {
proxy.scrollTo(textFieldIdentifier, anchor: .trailing)
}
}

private var endContentColor: Color {
if readOnly {
return appearance.endContentColorReadOnly?.color(for: colorScheme) ?? appearance.endContentColor.color(for: colorScheme)
Expand Down Expand Up @@ -630,34 +639,9 @@ public struct SDDSTextField: View {

// MARK: - Computed Properties for Conditions

private func calculateTextWidth(text: String, placeholder: String, proxy: GeometryProxy) -> CGFloat {
let deltaPadding: CGFloat = 1.0
private var calculatedTextSize: CGFloat {
let textSize = (text as NSString).size(withAttributes: [NSAttributedString.Key.font: textTypography.uiFont])
if displayChips {
if !text.isEmpty {
return textSize.width + deltaPadding
} else {
let placeholderSize = (placeholder as NSString).size(withAttributes: [NSAttributedString.Key.font: textTypography.uiFont])
return placeholderSize.width
}
}

var maxWidth = proxy.size.width
if !textBefore.isEmpty && !displayChips {
let textBeforeSize = (textBefore as NSString).size(withAttributes: [NSAttributedString.Key.font: textBeforeTypography.uiFont])
maxWidth -= (textBeforeSize.width + deltaPadding)
maxWidth -= (appearance.size.textBeforeLeadingPadding + appearance.size.textBeforeTrailingPadding)
}
if !textAfter.isEmpty && !displayChips {
let textBeforeSize = (textAfter as NSString).size(withAttributes: [NSAttributedString.Key.font: textAfterTypography.uiFont])
maxWidth -= (textBeforeSize.width + deltaPadding)
maxWidth -= (appearance.size.textAfterLeadingPadding + appearance.size.textAfterTrailingPadding)
}

return min(
textSize.width + deltaPadding,
maxWidth
)
return max(ceil(textSize.width), 1.0)
}

private var iconActionViewWidth: CGFloat {
Expand All @@ -677,7 +661,8 @@ public struct SDDSTextField: View {
!displayChips &&
appearance.innerTitleTypography.typography(with: appearance.size) != nil &&
(!text.isEmpty || isFocused) &&
!(title.isEmpty && required)
!(title.isEmpty && required) &&
(!title.isEmpty || !optionalTitle.isEmpty)
}

private var shouldShowEdgeIndicatorForDefaultLayout: Bool {
Expand Down Expand Up @@ -720,7 +705,7 @@ public struct SDDSTextField: View {
}

private var showSuffixOrPrefix: Bool {
!text.isEmpty && !displayChips
!displayChips
}

private var displayChips: Bool {
Expand Down Expand Up @@ -749,7 +734,12 @@ public struct SDDSTextField: View {
private var textFieldIdentifier: String {
var hasher = Hasher()
appearance.hash(into: &hasher)
text.hash(into: &hasher)
return String(hasher.finalize())
}

private var textAfterIdentifier: String {
var hasher = Hasher()
textAfter.hash(into: &hasher)
return String(hasher.finalize())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ struct FocusableTextField: UIViewRepresentable {
configure(textField)

DispatchQueue.main.async {
if isFocused {
textField.becomeFirstResponder()
if isFocused {
if !textField.isFirstResponder {
textField.becomeFirstResponder()
}
} else {
textField.resignFirstResponder()
}
Expand Down

0 comments on commit 4fd3198

Please sign in to comment.