-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create Textarea component and update documentation for both text inpu…
…t components
- Loading branch information
1 parent
9b380f7
commit 02a0f77
Showing
18 changed files
with
851 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
import SwiftUI | ||
import UIKit | ||
|
||
/// An Orbit component that offers multiline text input. The component is an Orbit equivalent of the native `TextField` component with vertical axis specified. | ||
/// | ||
/// The Textarea is created with an optional label and a binding to a string value. | ||
/// | ||
/// ```swift | ||
/// Textarea("Label", value: $text, prompt: "Description") | ||
/// .focused($isDescriptionFocused) | ||
/// .inputFieldReturnAction { | ||
/// // Action after the value is submitted | ||
/// } | ||
/// .frame(height: 200) | ||
/// ``` | ||
/// | ||
/// The component uses a custom ``TextView`` component (implemented using `UITextView`) that represents the native `TextField`. | ||
/// | ||
/// ### Layout | ||
/// | ||
/// The component expands horizontally and vertically, unless limited by a `frame` modifier. | ||
/// | ||
/// - Note: [Orbit definition](https://orbit.kiwi/components/input/textarea/) | ||
public struct Textarea: View, TextFieldBuildable { | ||
|
||
@Environment(\.inputFieldBeginEditingAction) private var inputFieldBeginEditingAction | ||
@Environment(\.inputFieldEndEditingAction) private var inputFieldEndEditingAction | ||
@Environment(\.isEnabled) private var isEnabled | ||
@Environment(\.sizeCategory) private var sizeCategory | ||
|
||
@State private var isFocused: Bool = false | ||
|
||
private let label: String | ||
@Binding private var value: String | ||
private let prompt: String | ||
private let state: InputState | ||
|
||
private let message: Message? | ||
@Binding private var messageHeight: CGFloat | ||
|
||
// Builder properties (keyboard related) | ||
var autocapitalizationType: UITextAutocapitalizationType = .none | ||
var isAutocorrectionDisabled: Bool? = false | ||
var keyboardType: UIKeyboardType = .default | ||
var returnKeyType: UIReturnKeyType = .default | ||
var textContentType: UITextContentType? | ||
var shouldDeleteBackwardAction: (String) -> Bool = { _ in true } | ||
|
||
public var body: some View { | ||
FieldWrapper( | ||
label, | ||
message: message, | ||
messageHeight: $messageHeight | ||
) { | ||
InputContent( | ||
state: state, | ||
message: message, | ||
isFocused: isFocused | ||
) { | ||
textView | ||
} | ||
} | ||
} | ||
|
||
@ViewBuilder var textView: some View { | ||
TextView( | ||
value: $value, | ||
prompt: prompt, | ||
insets: .init( | ||
top: .small, | ||
left: .small, | ||
bottom: .small, | ||
right: .small | ||
) | ||
) | ||
.returnKeyType(returnKeyType) | ||
.autocorrectionDisabled(isAutocorrectionDisabled) | ||
.keyboardType(keyboardType) | ||
.textContentType(textContentType) | ||
.autocapitalization(autocapitalizationType) | ||
.shouldDeleteBackwardAction(shouldDeleteBackwardAction) | ||
.accessibility(label: .init(label)) | ||
.inputFieldBeginEditingAction { | ||
isFocused = true | ||
inputFieldBeginEditingAction() | ||
} | ||
.inputFieldEndEditingAction { | ||
isFocused = false | ||
inputFieldEndEditingAction() | ||
} | ||
} | ||
} | ||
|
||
// MARK: - Inits | ||
public extension Textarea { | ||
|
||
/// Creates Orbit ``Textarea`` component. | ||
/// | ||
/// - Parameters: | ||
/// - message: Optional message below the text field. | ||
/// - messageHeight: Binding to the current height of the optional message. | ||
init( | ||
_ label: String = "", | ||
value: Binding<String>, | ||
prompt: String = "", | ||
state: InputState = .default, | ||
message: Message? = nil, | ||
messageHeight: Binding<CGFloat> = .constant(0) | ||
) { | ||
self.label = label | ||
self._value = value | ||
self.prompt = prompt | ||
self.state = state | ||
self.message = message | ||
self._messageHeight = messageHeight | ||
} | ||
} | ||
|
||
// MARK: - Previews | ||
struct TextareaPreviews: PreviewProvider { | ||
|
||
static var previews: some View { | ||
PreviewWrapper { | ||
VStack(alignment: .leading, spacing: .medium) { | ||
StateWrapper("Enter \(String(repeating: "values ", count: 20))") { $value in | ||
Textarea( | ||
"Label", | ||
value: $value, | ||
prompt: "Enter \(String(repeating: "values ", count: 20))" | ||
) | ||
.frame(height: 100) | ||
} | ||
|
||
StateWrapper("") { $value in | ||
Textarea( | ||
"Label", | ||
value: $value, | ||
prompt: "Enter \(String(repeating: "values ", count: 20))" | ||
) | ||
.frame(height: 100) | ||
} | ||
|
||
HStack(alignment: .top, spacing: .medium) { | ||
StateWrapper("This is my value") { $value in | ||
Textarea( | ||
"Label", | ||
value: $value, | ||
prompt: "Enter value" | ||
) | ||
.frame(height: 200) | ||
} | ||
|
||
StateWrapper("This is my value") { $value in | ||
Textarea( | ||
"Label", | ||
value: $value, | ||
prompt: "Enter value" | ||
) | ||
.frame(height: 200) | ||
} | ||
} | ||
} | ||
} | ||
.padding(.medium) | ||
.previewLayout(.sizeThatFits) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
Sources/Orbit/Orbit.docc/Components/Extensions/Textarea.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# ``Orbit/Textarea`` | ||
|
||
@Metadata { | ||
@DocumentationExtension(mergeBehavior: append) | ||
} | ||
|
||
## Topics | ||
|
||
### Input and event modifiers | ||
|
||
- ``disabled(_:)`` | ||
- ``inputFieldBeginEditingAction(_:)-6qvc9`` | ||
- ``inputFieldBeginEditingAction(_:)-4935w`` | ||
- ``inputFieldEndEditingAction(_:)-238ir`` | ||
- ``inputFieldEndEditingAction(_:)-38zwl`` | ||
- ``inputFieldFocus(_:)`` | ||
- ``inputFieldReturnAction(_:)-2dxhj`` | ||
- ``inputFieldReturnAction(_:)-4sxsc`` | ||
- ``inputFieldShouldReturnAction(_:)-7ydww`` | ||
- ``inputFieldShouldReturnAction(_:)-8trm2`` | ||
- ``inputFieldShouldChangeCharactersAction(_:)-6g5c3`` | ||
- ``inputFieldShouldChangeCharactersAction(_:)-50iz2`` | ||
- ``InputFieldShouldChangeResult`` | ||
|
||
### Managing text entry | ||
|
||
- ``autocapitalization(_:)-9k9yh`` | ||
- ``autocorrectionDisabled(_:)-4x1d6`` | ||
- ``keyboardType(_:)-7khza`` | ||
- ``returnKeyType(_:)`` | ||
- ``shouldDeleteBackwardAction(_:)`` | ||
- ``textContentType(_:)-6etk6`` | ||
|
||
### UIKit components | ||
|
||
- ``TextView`` | ||
- ``InsetableTextView`` | ||
|
||
### Customizing Appearance | ||
|
||
- ``textColor(_:)`` | ||
- ``textFontWeight(_:)`` | ||
- ``textSize(_:)`` | ||
- ``textSize(custom:)`` | ||
- ``InputLabelStyle`` |
Oops, something went wrong.