Commit Graph

41 Commits

Author SHA1 Message Date
Dmitry Rykun 9187e20752 Selection prop is applied for TextInput when component is mounting
Summary:
Changelog: [Internal]
TextInput's predefined "selection" prop is now applied when view did move to window, and when attributed string is set.

Reviewed By: sammy-SC

Differential Revision: D30045271

fbshipit-source-id: e5495171b07a25e1e822421ff1627a8686cd0904
2021-08-23 10:07:57 -07:00
Dmitry Rykun 8434177722 Added Selection prop to TextInputProps
Summary:
Changelog: [iOS][Added]
1. Added new primitive type "Selection" to C++
2. Added property "selection" to TextInputProps
3. Added parser for that

Reviewed By: sammy-SC

Differential Revision: D30043256

fbshipit-source-id: eefa67ca23759761901cba1d2ab3052877a153a7
2021-08-23 06:04:01 -07:00
Samuel Susla b0e39b2ed9 Maintain cursor position when text changes in text input
Summary:
Changelog: [internal]

Cursor position needs to be calculated when attributed string changes.

Reviewed By: JoshuaGross

Differential Revision: D29786190

fbshipit-source-id: 99a42dc4d7c84e77c40f75bf4a9108d010bb1792
2021-07-20 15:14:48 -07:00
Samuel Susla b52950bda2 Apply correct text attributes in TextInput.setTextAndSelection
Summary:
Changelog: [internal]

Make sure correct text attributes are used inside of view command.

Reviewed By: sshic

Differential Revision: D29585943

fbshipit-source-id: 4748c843ff586f1dd42f3a89460afb624f9b371a
2021-07-07 07:11:03 -07:00
Samuel Susla 592e92fc90 Fix missing space when using iOS's autocomplete
Summary:
Changelog: [internal]

Using keyboard's autocomplete did not insert space at the end of the word.

Reviewed By: fkgozali

Differential Revision: D29085654

fbshipit-source-id: 35fee726ea7d2030fdfa64300e045a303ea98ce9
2021-06-13 04:36:32 -07:00
Samuel Susla a5b92f34c4 Resign text input as first responder in prepareForRecycle
Summary:
Changelog: [internal]

To prevent wrong TextInput becoming first responder, force a resign when preparing for a reuse.

Reviewed By: JoshuaGross

Differential Revision: D29085923

fbshipit-source-id: 246cdf0628f914c3928cc9c7499d029b77684f2c
2021-06-12 12:26:27 -07:00
Shuhao Zhang f3b8d4976f Bug fix: <TextInput> content is reset when emoji is entered at the max length
Summary:
When maxLength is defined in <TextInput>, if the last character at max length is an emoji, the content of the input is cleared:

{F620865178} {F620865237}

Related Github issues:

https://github.com/facebook/react-native/issues/10929
https://github.com/facebook/react-native/issues/10964

## Root cause:

When NSString was created, unicode characters were 16-bit long, so Objective-C considers every unicode character as 16-bit. However, unicode was later extended to more than 16bit, for example, emojis, which causes NSString substring method cuts off at the wrong position.

Example:

```
NSString *s = @"abc{emoji:1f601}";
NSInteger len = s.length; //length is 5 (as {emoji:1f601} occupies two 16-bit characters)
NSString *s3 = [s substringToIndex: 3]; //s3 is "abc"
NSString *s4 = [s substringToIndex: 4]; //s4 is null!
```

If string s, "abc{emoji:1f601}", is entered in <TextInput>, which has max length 4, it will truncate the string to the first 4 characters, "cutting" the emoji in half which causes encoding error and returns null. The text input is cleared.

## Solution:

If the character at max length is longer than 16-bit, truncate the character BEFORE it instead. In the previous example, truncate till index 3 instead of 4. The end result will be "abc" and the emoji is dropped.

## Changelog:

[iOS] [Fixed] - <TextInput> content is reset when emoji is entered at the max length

Reviewed By: p-sun

Differential Revision: D28821909

fbshipit-source-id: 4720d864970b554160ed5388f65b352ce95a6199
2021-06-04 13:40:42 -07:00
Paige Sun d90253da36 iOS: Fix InputAccessoryView disappearing when inputAccessoryViewID exists
Summary:
InputAccessoryView disappears on Fabric (not Paper) when the text prop changes.

Changelog: [Fabric] [iOS] Fix InputAccessoryView disappearing when inputAccessoryViewID exists

Differential Revision: D27721549

fbshipit-source-id: 163dfcf0a8d5226453f4de356650a6ba82bee10b
2021-04-20 12:50:25 -07:00
Valentin Shergin 95116dbe6d Fabric: Correct implementation of RCTUITextContentTypeFromString for <TextInput contentType>
Summary:
Previous implementation was now correct because it assumed that all the constant values are aligned between RN and UIKit.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: JoshuaGross

Differential Revision: D26476566

fbshipit-source-id: 07bbe14d887d446bae34f448f5e62c3075fb0979
2021-02-17 09:53:37 -08:00
Valentin Shergin b426cbccb4 Back out "Use ConcreteStateTeller in RCTTextInputComponentView"
Summary:
Original commit changeset: 2b82e2d43cc6
ConcreteStateTeller is being replaced with a new built-in state autorepeat mechanism.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D25687699

fbshipit-source-id: d318155509b00064e29fc32efe893151a9723fd5
2020-12-23 10:09:24 -08:00
Samuel Susla d51cc6b5e6 Implement default input accessory view for text input
Summary:
Changelog: [internal]

Fabric didn't implement default input accessory view.

Paper implementation: https://www.internalfb.com/intern/diffusion/FBS/browse/master/xplat/js/react-native-github/Libraries/Text/TextInput/RCTBaseTextInputView.m?commit=1e2cd9ea1637&lines=589-629

Reviewed By: shergin

Differential Revision: D25612690

fbshipit-source-id: 7529c730211682bcffe17fdd4974e5df83c450d7
2020-12-17 10:52:23 -08:00
Samuel Susla 36b0f7d19b Fix controller <TextInput> on iOS when inputting in Chinese/japanese
Summary:
Changelog: [internal]

Solution copied over from https://github.com/facebook/react-native/commit/892212bad2daadd373f4be241e4cd9889b0a1005#diff-0874427511e8753d0037472fffbe6d7ee014d831e254d4b3c12ffb1dd8ce27c9

Reviewed By: JoshuaGross

Differential Revision: D24429166

fbshipit-source-id: 3c0588ac774041a9fd6d1b6685d94c5658f754b2
2020-10-20 15:56:56 -07:00
Samuel Susla 9b973f32e4 Fix TextInput value not restoring after reuse
Summary:
Changelog: [Internal]

# Problem

The problem was setting `_backedTextInputView.attributedText` to nil inside `[RCTTextInputComponentView prepareForRecycle]`.

Ordinarily this isn't a problem becase `UIManager::updateState` drops the update if the ShadowNode no longer exists. But in certain cases the ShadowNode can exist, empty string being set as its value

# Fix

Fix is trivial, invalidate state before nullifying `_backedTextInputView`. This prevents the state update from being dispatched.

# Discussion

We should go over all other components and make sure state is invalidated as first thing in `[RCTViewComponentView prepareForRecycle]`.

Reviewed By: shergin

Differential Revision: D23324929

fbshipit-source-id: 9568e920d99683ad95f965ef4b63c529f50f3283
2020-08-25 15:43:08 -07:00
Samuel Susla e454863bca Use ConcreteStateTeller in RCTTextInputComponentView
Summary: Changelog: [Internal]

Reviewed By: JoshuaGross

Differential Revision: D23216864

fbshipit-source-id: 2b82e2d43cc694251a1873ad9059eff4abca4e73
2020-08-24 06:43:17 -07:00
Samuel Susla 22c1032dbc Fix text not being restored from state in TextInput
Summary:
Changelog: [internal]

Restore text value from state when re-initialising RCTTextInputComponentView

Reviewed By: shergin

Differential Revision: D22844624

fbshipit-source-id: b47e3fe890793f8de429b637535d641262c42be2
2020-08-11 13:20:30 -07:00
David Vacca 3093010ea5 move fabric to ReactCommon/react/renderer
Summary:
This diff moves fabric C++ code from ReactCommon/fabric to ReactCommon/react/renderer
As part of this diff I also refactored components, codegen and callsites on CatalystApp, FB4A and venice

Script: P137350694

changelog: [internal] internal refactor

Reviewed By: fkgozali

Differential Revision: D22852139

fbshipit-source-id: f85310ba858b6afd81abfd9cbe6d70b28eca7415
2020-07-31 13:34:29 -07:00
Peter Argany 91d16bbd9f Hardcode @available(iOS 10) to YES
Summary:
RN removed support for iOS 9 last year, therefore iOS10+ is always available.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D22655069

fbshipit-source-id: 77e85e0403ea7ea0febc8766c10bb6f94ea417ad
2020-07-22 11:00:32 -07:00
Samuel Susla 3d4535a2bb Introduce InputAccessoryView
Summary:
Changelog: [Internal]

Introducing InputAccessoryView.

There is one big difference between Fabric's implementation and Paper's implementation.

Fabric searches for text input from InputAccessoryView, unlike Paper where it is the other way around.

Reviewed By: shergin

Differential Revision: D22160445

fbshipit-source-id: 55313fe50afeced7aead5b57137d711dd1cfd3ae
2020-06-30 01:36:04 -07:00
Samuel Susla 66057efc6d Organise methods in RCTTextInputComponentView into groups
Summary:
Changelog: [Internal]
The methods were out of order, this diff reorders them.

Reviewed By: shergin

Differential Revision: D22233255

fbshipit-source-id: ea66bc701c4d021ec5721e191bc0d3413b3d36ae
2020-06-28 03:41:11 -07:00
Samuel Susla 160f6ca54a Make TextInput accessible element
Summary:
Changelog: [Internal]

RCTTextInputComponentView didn't override `accessibilityElement`. This diff fixes it.

Reviewed By: shergin

Differential Revision: D22233182

fbshipit-source-id: 38fc2112aeabd514cd201920616e7d2b32e11d9b
2020-06-28 03:41:11 -07:00
Samuel Susla 36b586ada1 Font size in Text now respects preferredContentSizeCategory
Summary:
Changelog: [Internal]

Add support for dynamic font size.

New class `ThreadStorage` is introduced, which is used to pass LayoutContext to `YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector`.

## Shortcoming
This implementation doesn't cause re-render, if user changes font size and comes to the app without restarting it, it will show old font size. I believe this is fine for now as most people set their font size before they use the app and keep the same setting for a long time.

Reviewed By: shergin

Differential Revision: D22043728

fbshipit-source-id: 7453d165c280a2f4bcb73f4ee6daf9e64b637ded
2020-06-17 10:22:32 -07:00
Samuel Susla ccf5c86bd7 Implement autoFocus in TextInput
Summary:
Changelog: [Internal]

Prop autoFocus was not implemented in Fabric's TextInput.

Reviewed By: mdvacca

Differential Revision: D22019333

fbshipit-source-id: 03f043b93e1079a5d0bff55b08ebc9d2f973c55b
2020-06-13 11:04:40 -07:00
Samuel Susla 18b3680761 Cleanup of RCTTExtInputComponentView.mm
Summary:
Changelog: [Internal]

1. `UITextField.attributedText` and `UITextView.attributedText` default value is `nil`, not an empty NSAttributedString.
2. Assigning `_backedTextInputView.frame = self.bounds` inside constructor isn't needed as `self.bounds` during initialisation.

Reviewed By: JoshuaGross

Differential Revision: D21722661

fbshipit-source-id: 8725335d929b7d10736b540e12f1669ea824ad94
2020-05-26 09:51:41 -07:00
Samuel Susla 5223127abc Use plugins for TextInput component
Summary:
Leverage plugin infra for `TextInput`

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D21407584

fbshipit-source-id: 48b1a69aa834ab956724e6617197da57ccf99aa7
2020-05-11 09:01:34 -07:00
Samuel Susla b871979a89 Do not send events for changes coming from JavaScript
Summary:
Changelog: [Internal]

When there is a change coming from javascript, avoid triggering `onChange ` and `onSelectionChange` events since JavaScript already has these changes. This is only necessary for multiline text.

For changes coming through view commands, do not increment `_mostRecentEventCount`.

Reviewed By: shergin

Differential Revision: D21255228

fbshipit-source-id: e972dab0eb3dd21f611ee5c71d755bab593ae9cc
2020-04-27 12:33:44 -07:00
Samuel Susla 027e8f9b16 Send key when onKeyPress event is fired from TextInput
Summary:
Changelog: [Internal]

In `onKeyPress` event, we were not returning `key` property. This diff adds `key` property to `onKeyPress` event and removes other, redundant properties from `onKeyPress` event.

The implementation has been translated from Paper.

Reviewed By: shergin

Differential Revision: D21250411

fbshipit-source-id: f1e31381667acb9dec02d0b33883df8f8f5b2a4b
2020-04-27 12:33:44 -07:00
Samuel Susla 57099962b7 Apply placeholderColor to TextInput component
Summary:
Changelog: [Internal]

TextInput's `placeholderTextColor` prop was being ignored. This diff fixes that.

Reviewed By: JoshuaGross

Differential Revision: D21064118

fbshipit-source-id: 33f148c355cee846db010153e0c65ea43155c3c9
2020-04-20 10:13:56 -07:00
Samuel Susla b861782562 Remove setMostRecentEventCount from TextInput view commands
Summary:
Changelog: [Internal]

We don't use view command `setMostRecentEventCount`, let's get rid of it.

Reviewed By: JoshuaGross

Differential Revision: D21016600

fbshipit-source-id: 6491c063e9d6a89252300cb47c010b248e473f4b
2020-04-14 15:27:59 -07:00
Samuel Susla 00c4d950cf Implement event count for TextInput
Summary:
Changelog: [Internal]

Implementation of event count for Fabric's Text input.

Reviewed By: JoshuaGross

Differential Revision: D20800185

fbshipit-source-id: 988692cb2fc786649821cccb06e629b40b9b0479
2020-04-09 03:44:55 -07:00
Samuel Susla 0ef63d0cac Maintain selection and cursor location when setting string on TextInput
Summary:
Changelog: [Internal]

Calling `_backedTextInputView.attributedText = attributedString` causes cursor to be moved to the end of text input.
This applies to both, `UITextField` and `UITextView`.

This is not desired as when JS sets a new text, we don't want the cursor to be moved to the end of text input.
JS has the option to use view commands if it wishes to move cursor somewhere.

Reviewed By: JoshuaGross

Differential Revision: D20836201

fbshipit-source-id: 9234e54cfbc5fc206f723626988e505275788aae
2020-04-09 03:44:55 -07:00
Samuel Susla 7b4889937c Switch order of onSelectionChange and onChange events send from native
Summary:
Changelog: [Internal]

UIKit uses either `UITextField` or `UITextView` as its UIKit element for `<TextInput>`. `UITextField` is for single line entry, `UITextView` is for multiline entry.

There is a problem with order of events when user types a character.

In `UITextField` (single line text entry), typing a character first triggers `onChange` event and then `onSelectionChange`. JavaScript depends on this order of events because it uses `mostRecentEventCount` from this even to communicate to native that it is in sync with changes in native.

In `UITextView` (multi line text entry), typing a character first triggers `onSelectionChange` and then `onChange`. As JS depends on the correct order of events, this can cause issues. An example would be a TextInput which changes contents based as a result of `onSelectionChange`. Those changes would be ignored as native will throw them away because JavaScript doesn't have the newest version.

Reviewed By: JoshuaGross

Differential Revision: D20836195

fbshipit-source-id: fbae3b6c0d388fc059ca2541ae980073b8e5f6c7
2020-04-09 03:44:55 -07:00
Samuel Susla 3d61dc9f36 Back out "Fix controlled TextInput with child nodes"
Summary:
Changelog: [Internal]

Original commit changeset: 1b8a2efabbfa

Original diff D20587681 breaks non-controlled text input.

Reviewed By: motiz88

Differential Revision: D20815935

fbshipit-source-id: 70577ed1e5701850ff0e30a6592945a31c2a8bec
2020-04-02 08:26:04 -07:00
Samuel Susla a40cfc05b8 Fix controlled TextInput with child nodes
Summary:
Changelog: [Internal]

# There are three changes in this diff

## _stateRevision is replaced with a BOOL
`_stateRevision` was protecting against setting attributed string that is already visible to the user. Previously this was ok because the change was only coming from native, any changes from JS were ignored.

Imagine following scenario:

1. User taps key.
2. Update state is called on component initiated by native.
3. New state is created with incremented revision by one.
4. `_stateRevision` gets set to new state's revision + 1.
5. Now JS wants to change something because it just learnt that user tapped the key.
6. New state is created again with incremented revision by one.
7. Update state is called on the component, but the change isn't applied to the text view because `_state->getRevision()` will equal `_stateRevision`.

By having a BOOL instead of number, we very explicitly mark the region in which we don't want state changes to be applied to text view.

## Calling [_backedTextInputView setAttributedText] move cursor to the end of text input
This is prevented by storing what the current selection is and applying it after `[_backedTextInputView setAttributedText]` is called.
This was previously invisible because JS wasn't changing contents of `_backedTextInputView`.

## Storing of previously applied JS attributed string in state

This is the mechanism used to detect when value of text input changes come from JavaScript. JavaScript sends text input value changes through props and as children of TextInput.
We compare what previously was set from JavaScript to what is currently being send from JavaScript and if they differ, this change is communicated to the component.
Previously only first attributed string send from JavaScript was send to the component.

# Problem

If children are used to set text input's value, then there is a case in which we can't tell what source of truth should be.

Let's take following example
We have a text field that allows only 4 characters, again this is only a problem if those 4 characters come as children, not as value.
This is a controller text input.

1. User types 1234.
2. User types 5th character.
3. JavaScript updates TextInput, saying that the content should stay 1234.
4. In `TextInputShadowNode` `hasJSUpdatedAttributedString` will be set to false, because previous JS value is the same as current JS value.

Reviewed By: shergin

Differential Revision: D20587681

fbshipit-source-id: 1b8a2efabbfa0fc87cba210570142d162efe61e6
2020-03-23 04:42:09 -07:00
Samuel Susla 56cf99a96e Validate selection range passed to setTextAndSelection
Summary:
Changelog: [Internal]

# Fabric

1. If `start` and `end` parameters in `setTextAndSelection` are -1, we don't move the cursor. Previously the cursor would be moved to beginning of text input.

2. In view commands, do not validate `eventCount`. It is passed in as undefined from JS because Fabric's text input doesn't use `eventCount`.

# Paper

1. If `start` and `end` parameters in `setTextAndSelection` are -1, we don't move the cursor. Previously the cursor would be moved to beginning of text input.

Reviewed By: shergin

Differential Revision: D20538290

fbshipit-source-id: c7aeddc25f58697254474058ce901df958321f7c
2020-03-22 06:11:35 -07:00
Samuel Susla f936b65883 Creating new state should now correctly increment state revision
Summary:
Changelog: [Internal]

# Problem

Calling `UIManager::updateState` does not increment state revision because it calls `ConcreteComponentDescriptor::createState` which creates new state with state revision 1.

# How did this propagate?

This error propagated itself in TextInput when trying to input a value, you would be only allowed to type in 1 character.

Reviewed By: JoshuaGross

Differential Revision: D20072844

fbshipit-source-id: 37b8173307e1d91d6e9c41b5ff2e185dde31cc38
2020-02-26 03:32:19 -08:00
Samuel Susla 291a2ffea2 Change behaviour of view command setTextAndSelection
Summary:
Changelog: [Internal]

When I was originally implementing this view command (D19471025), I misunderstood the desired behaviour.

The text parameter isn't meant to change text in the specified `select` but it is supposed to override text of entire text input.

Reviewed By: shergin

Differential Revision: D19793484

fbshipit-source-id: 64ba36ddfa27ac5a0adf48495cb4e985a429e005
2020-02-10 04:25:01 -08:00
Valentin Shergin a69abb419a Fabric: Using State::getRevision() instead of TextInputState::revision
Summary:
Previously, State revision number was implemented manually as part of the StateData. Now we have it as a built-in concept in State, so we can rely on that.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: JoshuaGross

Differential Revision: D19467161

fbshipit-source-id: cac907265090730cdb89207aad2b52141cda5dc6
2020-01-23 10:39:14 -08:00
Samuel Susla 6449cc4363 Implement setMostRecentEventCount and setTextAndSelection commands in TextInput
Summary:
Implements JS interface and commands in native, however it isn't connected anywhere.
Changelog: [Internal]

Reviewed By: shergin

Differential Revision: D19471025

fbshipit-source-id: 7ec53c04b38cb27b84ef06dea7a0fdb9e1deee60
2020-01-22 05:12:11 -08:00
Samuel Susla f43c9316e1 Add blur and focus native commands to TextInput
Summary:
Add Native Commands handlers to TextInput.
It is intentionally done in a way so that it can be easily swapped for codegened implementation once we properly type TextInput.

We also add native commands to view managers for backwards compatibility.

Changelog: [Internal]

Reviewed By: TheSavior, shergin

Differential Revision: D19412026

fbshipit-source-id: 8dc64275cf1da599b1bd5992a41035d51dd4148f
2020-01-20 03:08:23 -08:00
Valentin Shergin 8219db9a4a Fabric: The basic implementation of <TextInput> for iOS
Summary:
This is the partial implementation of Fabric-compatible <TextInput> component on iOS. All features are supported besides those:
 * `focus()`, `blur()`, `clear()` imperative calls;
 * Controlled TextInput as the whole feature in general;
 * Controlling selection from JavaScript side;
 * `autoFocus` prop;
 * KeyboardAccessoryView.

Changelog: [Internal]

Reviewed By: JoshuaGross

Differential Revision: D17400907

fbshipit-source-id: 0ccd0e0923293e5f504d5fae7b7ba9f048f7d259
2020-01-13 23:22:10 -08:00
Valentin Shergin 41557966b5 Fabric: <TextInput> component on iOS: RCTTextInputUtils
Summary:
RCTTextInputUtils contains a bunch of conventions and convenience functions that we use in TextInput.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: JoshuaGross

Differential Revision: D19226658

fbshipit-source-id: df72dcdc052b96b6daef2cc0839235761005d914
2020-01-13 23:22:10 -08:00