Skip to content

Commit

Permalink
DON-788: Update BPKSearchInputSummary (#2066)
Browse files Browse the repository at this point in the history
Co-authored-by: Yura Reutskiy <[email protected]>
  • Loading branch information
yurareutskiy and Yura Reutskiy authored Oct 1, 2024
1 parent 86eeae9 commit 1516ec8
Show file tree
Hide file tree
Showing 44 changed files with 207 additions and 274 deletions.
33 changes: 20 additions & 13 deletions Backpack-SwiftUI/AppSearchModal/Classes/BPKAppSearchModal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,21 @@ public struct BPKAppSearchModal: View {
let title: String
@Binding var inputText: String
let inputPrefix: BPKSearchInputSummary.InputPrefix
let clearAction: BPKSearchInputSummary.ClearAction
let inputHint: String
let results: BPKAppSearchModalResults
let closeAccessibilityLabel: String
let onClose: () -> Void
private var textFieldState: TextFieldState = .default
@FocusState private var inputFieldIsFocussed: Bool

public init(
title: String,
inputText: Binding<String>,
inputHint: String,
results: BPKAppSearchModalResults,
closeAccessibilityLabel: String,
inputPrefix: BPKSearchInputSummary.InputPrefix = .icon(.search),
clearAction: BPKSearchInputSummary.ClearAction,
onClose: @escaping () -> Void
) {
self.title = title
Expand All @@ -44,6 +45,7 @@ public struct BPKAppSearchModal: View {
self.results = results
self.closeAccessibilityLabel = closeAccessibilityLabel
self.inputPrefix = inputPrefix
self.clearAction = clearAction
self.onClose = onClose
}

Expand All @@ -52,11 +54,7 @@ public struct BPKAppSearchModal: View {
makeNavigationBar(title: title, closeAccessibilityLabel: closeAccessibilityLabel, onClose: onClose)
.padding(.horizontal, .base)
if results.showTextField {
BPKSearchInputSummary(placeholder: inputHint, inputPrefix: inputPrefix, $inputText)
.inputState(textFieldState.inputState)
.focused($inputFieldIsFocussed)
.autocorrectionDisabled(true)
.padding(.horizontal, .base)
searchInputSummary
}
switch results {
case .loading(let loading):
Expand All @@ -76,6 +74,18 @@ public struct BPKAppSearchModal: View {
.background(.surfaceDefaultColor)
}

private var searchInputSummary: some View {
BPKSearchInputSummary(
placeholder: inputHint,
inputPrefix: inputPrefix,
clearAction: clearAction,
$inputText
)
.focused($inputFieldIsFocussed)
.autocorrectionDisabled(true)
.padding(.horizontal, .base)
}

func makeNavigationBar(
title: String,
closeAccessibilityLabel: String,
Expand All @@ -93,12 +103,6 @@ public struct BPKAppSearchModal: View {
.padding(.vertical, .md)
}

public func inputState(_ state: TextFieldState) -> BPKAppSearchModal {
var result = self
result.textFieldState = state
return result
}

private func onScroll(_ offset: CGPoint) {
inputFieldIsFocussed = false
}
Expand All @@ -125,6 +129,7 @@ struct BPKAppSearchModal_Previews: PreviewProvider {
)),
closeAccessibilityLabel: "Close",
inputPrefix: .icon(.search),
clearAction: .init(accessibilityLabel: "clear", action: {}),
onClose: { }
)
.previewDisplayName("Content")
Expand All @@ -136,6 +141,7 @@ struct BPKAppSearchModal_Previews: PreviewProvider {
results: .loading(.init(accessibilityLabel: "Loading")),
closeAccessibilityLabel: "Close",
inputPrefix: .text("From"),
clearAction: .init(accessibilityLabel: "clear", action: {}),
onClose: { }
)
.previewDisplayName("Loading")
Expand All @@ -152,6 +158,7 @@ struct BPKAppSearchModal_Previews: PreviewProvider {

)),
closeAccessibilityLabel: "Close",
clearAction: .init(accessibilityLabel: "clear", action: {}),
onClose: { }
)
.previewDisplayName("Error")
Expand Down
9 changes: 8 additions & 1 deletion Backpack-SwiftUI/AppSearchModal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ Example of a AppSearchModal in Content state:
import Backpack_SwiftUI
BPKAppSearchModal(
title: "Search Modal",
inputText: $myText,
inputPrefix: BPKSearchInputSummary.InputPrefix.text("Prefix")
clearAction: BPKSearchInputSummary.ClearAction(accessibilityLabel: "Clear", action: {}),
inputHint: "Search",
results: .content(.init(
sections: [ /* sections */ ],
shortcuts: [ /* shortcuts */ ]
)),
inputPrefix: BPKSearchInputSummary.InputPrefix.text("Prefix"),
clearAction: BPKSearchInputSummary.ClearAction(accessibilityLabel: "Clear", action: {}),
closeAccessibilityLabel: "Close",
onClose: { }
)
Expand All @@ -53,6 +56,8 @@ BPKAppSearchModal(
inputText: $myText,
inputHint: "Search",
results: .loading(.init(accessibilityLabel: "Loading")),
inputPrefix: BPKSearchInputSummary.InputPrefix.text("Prefix"),
clearAction: BPKSearchInputSummary.ClearAction(accessibilityLabel: "Clear", action: {}),
closeAccessibilityLabel: "Close",
onClose: { /* close modal*/ }
)
Expand All @@ -75,6 +80,8 @@ BPKAppSearchModal(

)),
closeAccessibilityLabel: "Close",
inputPrefix: BPKSearchInputSummary.InputPrefix.text("Prefix"),
clearAction: BPKSearchInputSummary.ClearAction(accessibilityLabel: "Clear", action: {}),
onClose: { /* close modal*/ }
)
```
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import SwiftUI
///
/// Use `inputState(_ state: State)` to change the state of the text field.
public struct BPKSearchInputSummary: View {

public enum InputPrefix {
case text(String)
case icon(BPKIcon)
Expand All @@ -35,22 +36,33 @@ public struct BPKSearchInputSummary: View {
@Binding private var text: String
@FocusState private var focused: Bool
private let placeholder: String
private let inputPrefix: InputPrefix
private var state: State = .default
private let inputPrefix: InputPrefix?
private var style: Style = .default

private let readOnly: Bool
private let clearAction: ClearAction

public struct ClearAction {
public let accessibilityLabel: String
public let action: () -> Void

public init(accessibilityLabel: String, action: @escaping () -> Void) {
self.accessibilityLabel = accessibilityLabel
self.action = action
}
}

/// Creates a `BPKSearchInputSummary`.
///
/// - Parameters:
/// - placeholder: The placeholder text to display when the text field is empty.
/// - inputPrefix: The prefix which would be displayed on the left of text input
/// - text: The text to display in the text field.
public init(
placeholder: String = "",
inputPrefix: InputPrefix = .icon(.search),
inputPrefix: InputPrefix? = nil,
clearAction: ClearAction,
readOnly: Bool = false,
_ text: Binding<String>
) {
self.placeholder = placeholder
self.inputPrefix = inputPrefix
self.clearAction = clearAction
self.readOnly = readOnly
self._text = text
}

Expand All @@ -60,42 +72,40 @@ public struct BPKSearchInputSummary: View {
.accessibilityHidden(true)
TextField(placeholder, text: $text, prompt: placeholderView)
.font(style: .bodyDefault)
.foregroundColor(state.textColor)
.disabled(state.isDisabled)
.foregroundColor(.textPrimaryColor)
.disabled(readOnly)
.accessibilityElement()
.accessibilityValue(text.isEmpty ? placeholder : text)
.accessibilityAddTraits(readOnly ? [] : .isSearchField)
.accessibilityAddTraits(style == .focused ? .isSelected : [])
.focused($focused)
.accessibilityAddTraits(.isSearchField)
.accessibilityLabel(placeholder)
.accessibilityIdentifier("search_field")
accessory
}
.frame(maxWidth: .infinity, minHeight: 48.0)
.padding(.horizontal, BPKSpacing.base)
.background(.surfaceDefaultColor)
.clipShape(RoundedRectangle(cornerRadius: .sm))
.outline(focused ? .textLinkColor : state.borderColor, cornerRadius: .sm, lineWidth: focused ? 2.0 : 1.0)
.clipShape(RoundedRectangle(cornerRadius: .md))
.outline(
isBorderHighlighted ? .textLinkColor : .lineColor,
cornerRadius: .md,
lineWidth: isBorderHighlighted ? 2.0 : 1.0
)

.if(!BPKFont.enableDynamicType, transform: {
$0.sizeCategory(.large)
})
}

@ViewBuilder
private var accessory: some View {
if let icon = state.icon {
if case let .clear(accessibilityLabel, action) = state {
Button(action: action) {
BPKIconView(icon.icon)
.foregroundColor(icon.color)
}
.accessibilityElement(children: .ignore)
.accessibilityLabel(accessibilityLabel)
.accessibilityAddTraits(.isButton)
.opacity(text.isEmpty ? 0.0 : 1.0)
} else {
BPKIconView(icon.icon)
.foregroundColor(icon.color)
.accessibilityHidden(true)
}
Button(action: clearAction.action) {
BPKIconView(.closeCircle)
.foregroundColor(.textSecondaryColor)
}
.accessibilityElement(children: .ignore)
.accessibilityLabel(clearAction.accessibilityLabel)
.accessibilityAddTraits(.isButton)
.opacity(text.isEmpty ? 0.0 : 1.0)
}

@ViewBuilder
Expand All @@ -106,21 +116,27 @@ public struct BPKSearchInputSummary: View {

@ViewBuilder
private var prefixView: some View {
switch inputPrefix {
case .text(let prefixText):
BPKText(prefixText, style: .bodyDefault)
.foregroundColor(.textSecondaryColor)
case .icon(let icon):
BPKIconView(icon)
.foregroundColor(.textPrimaryColor)
if let inputPrefix {
switch inputPrefix {
case .text(let prefixText):
BPKText(prefixText, style: .bodyDefault)
.foregroundColor(.textSecondaryColor)
case .icon(let icon):
BPKIconView(icon)
.foregroundColor(.textPrimaryColor)
}
}
}

public func inputState(_ state: State) -> BPKSearchInputSummary {
public func customStyle(_ style: Style) -> BPKSearchInputSummary {
var result = self
result.state = state
result.style = style
return result
}

private var isBorderHighlighted: Bool {
focused || style == .focused
}
}

fileprivate extension TextField {
Expand All @@ -131,19 +147,17 @@ fileprivate extension TextField {

struct BPKSearchInputSummary_Previews: PreviewProvider {
static var previews: some View {
// swiftlint:disable line_length
VStack {
BPKSearchInputSummary(.constant(""))
BPKSearchInputSummary(placeholder: "Enter", .constant(""))
BPKSearchInputSummary(.constant("Value"))
BPKSearchInputSummary(inputPrefix: .text("From"), .constant("Value"))
BPKSearchInputSummary(.constant("Disabled"))
.inputState(.disabled)
BPKSearchInputSummary(.constant("Value"))
.inputState(.error)
BPKSearchInputSummary(.constant("Value"))
.inputState(.clear(accessibilityLabel: "clear", action: {}))
BPKSearchInputSummary(.constant("Value"))
.inputState(.valid)
BPKSearchInputSummary(clearAction: .init(accessibilityLabel: "Clear", action: {}), .constant(""))
BPKSearchInputSummary(placeholder: "Enter", clearAction: .init(accessibilityLabel: "Clear", action: {}), .constant(""))
BPKSearchInputSummary(clearAction: .init(accessibilityLabel: "Clear", action: {}), .constant("Value"))
BPKSearchInputSummary(inputPrefix: .text("From"), clearAction: .init(accessibilityLabel: "Clear", action: {}), .constant("Value"))
BPKSearchInputSummary(clearAction: .init(accessibilityLabel: "Clear", action: {}), readOnly: true, .constant("Read Only"))
BPKSearchInputSummary(clearAction: .init(accessibilityLabel: "Clear", action: {}), .constant("Manually highlighted"))
.customStyle(.focused)
BPKSearchInputSummary(clearAction: .init(accessibilityLabel: "Clear", action: {}), .constant("Value"))
BPKSearchInputSummary(clearAction: .init(accessibilityLabel: "clear", action: {}), .constant("Value"))
}
.padding()
.background(.coreEcoColor)
Expand Down

This file was deleted.

Loading

0 comments on commit 1516ec8

Please sign in to comment.