Skip to content

Commit

Permalink
Merge pull request #724 from kiwicom/636-create-textarea-component
Browse files Browse the repository at this point in the history
Create ``Textarea`` component
  • Loading branch information
PavelHolec authored Nov 27, 2023
2 parents 9b380f7 + f854619 commit 55428d7
Show file tree
Hide file tree
Showing 33 changed files with 1,002 additions and 283 deletions.
Binary file added Snapshots/iPad/TextareaTests/testTextarea.1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 19 additions & 22 deletions Sources/Orbit/Components/Checkbox.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,27 @@ public struct Checkbox: View {
@Binding var isChecked: Bool

public var body: some View {
SwiftUI.Button(
action: {
if isHapticsEnabled {
HapticsProvider.sendHapticFeedback(.light(0.5))
}

isChecked.toggle()
},
label: {
if title.isEmpty == false || description.isEmpty == false {
VStack(alignment: .leading, spacing: 1) {
Text(title)
.textColor(labelColor)
.fontWeight(.medium)
.accessibility(.checkboxTitle)

Text(description)
.textSize(.small)
.textColor(descriptionColor)
.accessibility(.checkboxDescription)
}
SwiftUI.Button {
if isHapticsEnabled {
HapticsProvider.sendHapticFeedback(.light(0.5))
}

isChecked.toggle()
} label: {
if title.isEmpty == false || description.isEmpty == false {
VStack(alignment: .leading, spacing: 1) {
Text(title)
.textColor(labelColor)
.fontWeight(.medium)
.accessibility(.checkboxTitle)

Text(description)
.textSize(.small)
.textColor(descriptionColor)
.accessibility(.checkboxDescription)
}
}
)
}
.buttonStyle(
CheckboxButtonStyle(state: state, isChecked: isChecked)
)
Expand Down
41 changes: 19 additions & 22 deletions Sources/Orbit/Components/ChoiceTile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,28 @@ public struct ChoiceTile<Content: View, Icon: View, Header: View, Illustration:
@ViewBuilder let illustration: Illustration

public var body: some View {
SwiftUI.Button(
action: {
if isHapticsEnabled {
HapticsProvider.sendHapticFeedback(.light(0.3))
SwiftUI.Button {
if isHapticsEnabled {
HapticsProvider.sendHapticFeedback(.light(0.3))
}

action()
} label: {
HStack(spacing: 0) {
VStack(alignment: contentAlignment, spacing: padding) {
headerRow
content
messageView
centerIndicator
}

action()
},
label: {
HStack(spacing: 0) {
VStack(alignment: contentAlignment, spacing: padding) {
headerRow
content
messageView
centerIndicator
}

TextStrut()
.padding(.vertical, .xxSmall) // Minimum 52pt @ normal size
}
.frame(maxWidth: idealSize.horizontal == true ? nil: .infinity, alignment: .leading)
.overlay(indicatorOverlay, alignment: indicatorAlignment)
.padding(padding)
TextStrut()
.padding(.vertical, .xxSmall) // Minimum 52pt @ normal size
}
)
.frame(maxWidth: idealSize.horizontal == true ? nil: .infinity, alignment: .leading)
.overlay(indicatorOverlay, alignment: indicatorAlignment)
.padding(padding)
}
.buttonStyle(
TileButtonStyle(isSelected: isSelected)
)
Expand Down
69 changes: 35 additions & 34 deletions Sources/Orbit/Components/InputField.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,39 @@
import SwiftUI
import UIKit

/// Also known as textbox. Offers users a simple input for a form.
/// Orbit component that offers a simple text input. The component is an equivalent of the native `TextField` component.
///
/// When you have additional information or helpful examples, include prompt text to help users along.
/// The InputField is created with an optional label and a binding to a string value.
///
/// ```swift
/// InputField("Label", value: $email, prompt: "E-mail")
/// .keyboardType(.emailAddress)
/// .returnKeyType(.done)
/// .focused($isEmailFocused)
/// .inputFieldReturnAction {
/// // Action after the value is submitted
/// }
/// ```
///
/// For secure version, the `passwordStrength` hint can be provided.
///
/// ```swift
/// InputField(
/// "Password",
/// value: $password,
/// isSecure: true,
/// passwordStrength: passwordStrength,
/// message: .help("Must be at least 8 characters long")
/// )
/// ```
///
/// The custom Orbit version of ``TextField`` component is used internally.
/// The component uses a custom ``TextField`` component (implemented using `UITextField`) that represents the native `TextField`.
///
/// ### Layout
///
/// The component expands horizontally.
///
/// - Note: [Orbit definition](https://orbit.kiwi/components/inputfield/)
/// - Important: Component expands horizontally unless prevented by `fixedSize` modifier.
public struct InputField<Prefix: View, Suffix: View>: View, TextFieldBuildable {

@Environment(\.inputFieldBeginEditingAction) private var inputFieldBeginEditingAction
Expand Down Expand Up @@ -41,18 +66,8 @@ public struct InputField<Prefix: View, Suffix: View>: View, TextFieldBuildable {
var shouldDeleteBackwardAction: (String) -> Bool = { _ in true }

public var body: some View {
FieldWrapper(
defaultLabel,
message: message,
messageHeight: $messageHeight
) {
InputContent(
state: state,
label: compactLabel,
message: message,
isFocused: isFocused,
isPlaceholder: value.isEmpty
) {
FieldWrapper(defaultLabel, message: message, messageHeight: $messageHeight) {
InputContent(state: state, label: compactLabel, message: message, isFocused: isFocused) {
textField
} prefix: {
prefix
Expand Down Expand Up @@ -131,18 +146,11 @@ public struct InputField<Prefix: View, Suffix: View>: View, TextFieldBuildable {

public extension InputField {

/// Creates Orbit InputField component.
///
/// The keyboard related modifiers can be used directly on this component to modify the keyboard behaviour:
/// - `autocapitalization()`
/// - `autocorrectionDisabled()`
/// - `keyboardType()`
/// - `textContentType()`
/// Creates Orbit ``InputField`` component.
///
/// - Parameters:
/// - message: Optional message below the InputField.
/// - message: Optional message below the text field.
/// - messageHeight: Binding to the current height of the optional message.
/// - suffixAction: Optional action when suffix icon is tapped.
init(
_ label: String = "",
value: Binding<String>,
Expand Down Expand Up @@ -173,18 +181,11 @@ public extension InputField {
}
}

/// Creates Orbit InputField component with custom prefix or suffix.
///
/// The keyboard related modifiers can be used directly on this component to modify the keyboard behaviour:
/// - `autocapitalization()`
/// - `autocorrectionDisabled()`
/// - `keyboardType()`
/// - `textContentType()`
/// Creates Orbit ``InputField`` component with custom prefix or suffix.
///
/// - Parameters:
/// - message: Optional message below the InputField.
/// - message: Optional message below the text field.
/// - messageHeight: Binding to the current height of the optional message.
/// - suffixAction: Optional action when suffix icon is tapped.
init(
_ label: String = "",
value: Binding<String>,
Expand Down
41 changes: 19 additions & 22 deletions Sources/Orbit/Components/Radio.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,27 @@ public struct Radio: View {
@Binding var isChecked: Bool

public var body: some View {
SwiftUI.Button(
action: {
if isHapticsEnabled {
HapticsProvider.sendHapticFeedback(.light(0.5))
}

isChecked.toggle()
},
label: {
if title.isEmpty == false || description.isEmpty == false {
VStack(alignment: .leading, spacing: 1) {
Text(title)
.textColor(labelColor)
.fontWeight(.medium)
.accessibility(.radioTitle)

Text(description)
.textSize(.small)
.textColor(descriptionColor)
.accessibility(.radioDescription)
}
SwiftUI.Button {
if isHapticsEnabled {
HapticsProvider.sendHapticFeedback(.light(0.5))
}

isChecked.toggle()
} label: {
if title.isEmpty == false || description.isEmpty == false {
VStack(alignment: .leading, spacing: 1) {
Text(title)
.textColor(labelColor)
.fontWeight(.medium)
.accessibility(.radioTitle)

Text(description)
.textSize(.small)
.textColor(descriptionColor)
.accessibility(.radioDescription)
}
}
)
}
.buttonStyle(
RadioButtonStyle(state: state, isChecked: isChecked)
)
Expand Down
36 changes: 14 additions & 22 deletions Sources/Orbit/Components/Select.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,25 @@ public struct Select<Prefix: View, Suffix: View>: View {
@ViewBuilder private let suffix: Suffix

public var body: some View {
FieldWrapper(
defaultLabel,
message: message,
messageHeight: $messageHeight
) {
SwiftUI.Button(
action: {
if isHapticsEnabled {
HapticsProvider.sendHapticFeedback(.light(0.5))
}

action()
},
label: {
Text(value ?? prompt)
.textColor(valueColor)
.accessibility(.selectValue)
.padding(.horizontal, .small)
.padding(.vertical, verticalTextPadding)
FieldWrapper(defaultLabel, message: message, messageHeight: $messageHeight) {
SwiftUI.Button {
if isHapticsEnabled {
HapticsProvider.sendHapticFeedback(.light(0.5))
}
)

action()
} label: {
Text(value ?? prompt)
.textColor(valueColor)
.accessibility(.selectValue)
.padding(.horizontal, .small)
.padding(.vertical, verticalTextPadding)
}
.buttonStyle(
InputContentButtonStyle(
state: state,
label: compactLabel,
message: message,
isPlaceholder: value == nil
message: message
) {
prefix
.accessibility(.selectPrefix)
Expand Down
45 changes: 21 additions & 24 deletions Sources/Orbit/Components/Tag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,31 @@ public struct Tag<Icon: View>: View, PotentiallyEmptyView {

public var body: some View {
if isEmpty == false {
SwiftUI.Button(
action: {
if isHapticsEnabled {
HapticsProvider.sendHapticFeedback(.light(0.5))
SwiftUI.Button {
if isHapticsEnabled {
HapticsProvider.sendHapticFeedback(.light(0.5))
}

isSelected.toggle()
} label: {
HStack(spacing: 0) {
if idealSize.horizontal == false {
Spacer(minLength: 0)
}

HStack(spacing: 6) {
icon
.font(.system(size: Text.Size.normal.value))

Text(label)
}
.fixedSize(horizontal: true, vertical: false)

isSelected.toggle()
},
label: {
HStack(spacing: 0) {
if idealSize.horizontal == false {
Spacer(minLength: 0)
}

HStack(spacing: 6) {
icon
.font(.system(size: Text.Size.normal.value))

Text(label)
}
.fixedSize(horizontal: true, vertical: false)

if idealSize.horizontal == false {
Spacer(minLength: 0)
}
if idealSize.horizontal == false {
Spacer(minLength: 0)
}
}
)
}
.buttonStyle(
TagButtonStyle(
style: style,
Expand Down
Loading

0 comments on commit 55428d7

Please sign in to comment.