Commit 14ededa
authored
feat: sync layout from JS (#1213)
## 📜 Description
Added an ability to have a bi-directional communication and read/update
layout from JS on demand.
## 💡 Motivation and Context
This PR adds a command that we can dispatch from JS in order to get an
actual layout of focused input. The task sounds pretty simple, but I
anyway had some problems, and would like to describe solutions from them
here.
First of all the querying of layout is an async operation and we need to
wait for completion before running a worklet code (so that we can be
sure, that event has been actually dispatched and shared-value has
up-to-date value). But default mechanism for view commands not suppose
to return any kind of data back to the JS thread. Alternative option is
to define "module" method and return the data/completion status from
there. However in new architecture it is highly not recommended to use
such approach, because this approach relies on RN internals that can be
changed/removed from the future. So I decided to go with recommended
approach. To overcome asynchronous stuff I decided to set one-time
listener and resolve a promise when I get specific
`layoutDidSynchronize` event - this is not a perfect solution but does a
job for now and doesn't use deprecated stuff, so I'm pretty happy.
On a high level overview - we pass `update` function through the
`context`, because `context` has an access to `KeyboardControllerView`
and from there we dispatch/wait.
Also I decided to expose `assureFocusedInputVisible` method for
`KeyboardAwareScrollView`. In the past I had requirements to scroll a
little bit when validation error appears, and back to the time I just
hard-coded it like `ref.current.scrollTo(50)`, but of course this fix
didn't handle all the cases. Now it's just enough to call
`ref.current.assureFocusedInputVisible()` and enjoy pixel perfect
automatic calculations 😎
And in the end I decided to cover new functionality with e2e tests so
that we will not break them accidentally in the future 🤞
Closes
#1208
## 📢 Changelog
<!-- High level overview of important changes -->
<!-- For example: fixed status bar manipulation; added new types
declarations; -->
<!-- If your changes don't affect one of platform/language below - then
remove this platform/language -->
### Docs
- added info about new `update` method;
- added info about `assureFocusedInputVisible` method of ref;
### E2E
- cover new functionality described in
#1208
- cover use cases when we set a focus on input that doesn't belong to
`KeyboardAwareScrollView`;
### JS
- added `synchronizeFocusedInputLayout` command for
`KeyboardControllerView`;
- added `KeyboardController::layoutDidSynchronize` event;
- expose `assureFocusedInputVisible` method for
`KeyboardAwareScrollView`;
### iOS
- implement `synchronizeFocusedInputLayout` command for paper/fabric;
### Android
- implement `synchronizeFocusedInputLayout` command for paper/fabric;
## 🤔 How Has This Been Tested?
Tested manually on iPhone 16 Pro (iOS 26.0)/Pixel 6 Pro (API 31, 35)
both paper/fabric.
## 📸 Screenshots (if appropriate):
|Android|iOS|
|-------|-----|
|<video
src="https://github.com/user-attachments/assets/42a48042-e244-4a2d-8017-606d5fabfb7e">|<video
src="https://github.com/user-attachments/assets/d72ee356-3fd6-4019-b5c6-9e09ef60608d">|
## 📝 Checklist
- [x] CI successfully passed
- [x] I added new mocks and corresponding unit-tests if library API was
changed1 parent 41858c7 commit 14ededa
File tree
31 files changed
+247
-30
lines changed- android/src
- fabric/java/com/reactnativekeyboardcontroller
- main/java/com/reactnativekeyboardcontroller
- listeners
- managers
- views
- paper/java/com/reactnativekeyboardcontroller
- docs/docs/api
- components
- hooks/input
- e2e/kit
- assets
- android
- e2e_emulator_28
- e2e_emulator_31
- ios
- iPhone 13 Pro
- iPhone 14 Pro
- iPhone 15 Pro
- iPhone 16 Pro
- iPhone 17 Pro
- helpers/actions
- ios
- observers
- views
- src
- components
- KeyboardAwareScrollView
- hooks
- specs
- types
31 files changed
+247
-30
lines changedLines changed: 18 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
56 | 57 | | |
57 | 58 | | |
58 | 59 | | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
59 | 77 | | |
60 | 78 | | |
61 | 79 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
112 | | - | |
| 112 | + | |
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| |||
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
| 10 | + | |
9 | 11 | | |
10 | 12 | | |
11 | 13 | | |
| |||
25 | 27 | | |
26 | 28 | | |
27 | 29 | | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
28 | 35 | | |
29 | 36 | | |
30 | 37 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| |||
58 | 58 | | |
59 | 59 | | |
60 | 60 | | |
61 | | - | |
| 61 | + | |
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
| |||
Lines changed: 16 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
58 | 59 | | |
59 | 60 | | |
60 | 61 | | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
61 | 77 | | |
62 | 78 | | |
63 | 79 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
244 | 244 | | |
245 | 245 | | |
246 | 246 | | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
247 | 255 | | |
248 | 256 | | |
249 | 257 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
50 | 54 | | |
51 | 55 | | |
52 | 56 | | |
53 | | - | |
| 57 | + | |
54 | 58 | | |
55 | 59 | | |
56 | 60 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
10 | 16 | | |
11 | 17 | | |
12 | 18 | | |
| |||
32 | 38 | | |
33 | 39 | | |
34 | 40 | | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
35 | 72 | | |
0 commit comments