Skip to content

feat: KeyboardExtender #982

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Jun 26, 2025
Merged

feat: KeyboardExtender #982

merged 27 commits into from
Jun 26, 2025

Conversation

kirillzyusko
Copy link
Owner

@kirillzyusko kirillzyusko commented Jun 15, 2025

📜 Description

Added KeyboardExtender component.

💡 Motivation and Context

This is a part of a big research that I did over several months.

This PR implements KeyboardExtender component. On iOS it utilizes native capabilities of the OS and on Android it uses polyfill (KeyboardBackgroundView+KeyboardStickyView+useKeyboardAnimation for opacity animation).

That component aims to help developers to build various keyboard extensions which will be shown above the keyboard and visually mimic to it. The initial idea of implementation was inspired by Revolut app:

IMG_3374.MP4

And the KeyboardExtender ideally fits for building such things, another example is:

And I think developers can take inspiration and build even more advanced features (such as voice search etc.)

To implement this on iOS I used UIInputView with keyboard style.

Warning

On iOS 26 it looks bad and the view is not getting embedded into the keyboard. See tweet about it. For now let's wait for Apple fixes and if they are not going to fix it, then most likely we'll have to write separate implementation for iSO 26 to use liquid glass design.

On Android I'm trying to re--create iOS effect, but it's obviously not possible to match it fully, so I'm trying to make it looking as close as possible to. For sure I can not fully hide the view and make it moving together with keyboard from the very beginning, so I decided to use opacity interpolation and always show it above the keyboard (using KeyboardStickyView).

I decided not to use parallax animation (as in KeyboardToolbar) here. Let's see if opacity + frame-in-frame motion looks better than parallax effect 👀


Last but not least - for now I decided to make this component very simple and barely customizable (I expose only enabled property). And it can cause certain issues, for example if you switch between QWERTY keyboard (where you don't want KeyboardExtender to be present) to numeric (where you'd like to see KeyboardExtender), then you will see how react updates everything asynchronously and for a fraction of a second you will see QWERTY-keyboard with KeyboardExtender. Theoretically I could introduce binding through nativeID and "connect" specific inputs with specific extenders, but for now let's not do an over-engineering and try to handle all cases. Let's handle everything step-by-step and when we get a bug report then we can do another round of investigation how such thing can be implemented 👀

📢 Changelog

Docs

  • added new page for KeyboardExtender;
  • added new chapter in Components Overview;
  • mention KeyboardExtender feature in README;

E2E

  • added new test for KeyboardExtender;

JS

  • added KeyboardExtender component;
  • added KeyboardExtender spec;
  • added KeyboardExtender mock.

iOS

  • expose KeyboardExtender view;

C++

  • added c++ bindings (shadow nodes, component descriptor, etc.) for KeyboardExtender;

🤔 How Has This Been Tested?

Tested manually on:

  • iPhone 15 Pro (iOS 17.5, simulator)
  • iPhone 16 Pro (iOS 18.4, simulator)
  • iPhone 6s (iOS 15.5, real device)
  • iPhone 16 Pro (iOS 26.0, simulator) - doesn't look good there, filled bug to Apple
  • Medium Phone API 35 (emulator)
  • Pixel 7 Pro (API 36, real device)
  • Xiaomi Redmi Note 5 Pro (API 28, real device)

📸 Screenshots (if appropriate):

iOS Android
Simulator.Screen.Recording.-.iPhone.16.-.2025-06-23.at.13.43.22.mov
Screen.Recording.2025-06-23.at.13.32.59.mov

📝 Checklist

  • CI successfully passed
  • I added new mocks and corresponding unit-tests if library API was changed

@kirillzyusko kirillzyusko self-assigned this Jun 15, 2025
@kirillzyusko kirillzyusko added documentation Improvements or additions to documentation enhancement New feature or request 🚨 requires API changes 🚨 Changes that requires changes in library API labels Jun 15, 2025
Copy link
Contributor

Images automagically compressed by Calibre's image-actions

Compression reduced images by 46.2%, saving 13.58 KB.

Filename Before After Improvement Visual comparison
example/src/screens/Examples/KeyboardExtender/background.jpg 29.38 KB 15.80 KB -46.2% View diff

205 images did not require optimisation.

Copy link
Contributor

github-actions bot commented Jun 15, 2025

📊 Package size report

Current size Target Size Difference
210267 bytes 204142 bytes 6125 bytes 📈

@kirillzyusko kirillzyusko force-pushed the feat/keyboard-extender branch from ab5a457 to b11f5df Compare June 15, 2025 19:45
Copy link
Contributor

Images automagically compressed by Calibre's image-actions

Compression reduced images by 46.2%, saving 13.58 KB.

Filename Before After Improvement Visual comparison
example/src/screens/Examples/KeyboardExtender/background.jpg 29.38 KB 15.80 KB -46.2% View diff

205 images did not require optimisation.

Copy link
Contributor

github-actions bot commented Jun 15, 2025

PR Preview Action v1.6.1
Preview removed because the pull request was closed.
2025-06-26 13:19 UTC

Copy link

argos-ci bot commented Jun 15, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Jun 26, 2025, 12:40 PM

@kirillzyusko kirillzyusko added the KeyboardExtender 🧩 Anything about keyboard extending (i. e. `KeyboardExtender` component) label Jun 17, 2025
@kirillzyusko kirillzyusko force-pushed the feat/keyboard-extender branch from fdf95fc to 7cff86c Compare June 20, 2025 08:52
@kirillzyusko kirillzyusko added e2e Anything about E2E tests tests You added or changed unit tests labels Jun 24, 2025
@kirillzyusko kirillzyusko marked this pull request as ready for review June 26, 2025 12:40
@kirillzyusko kirillzyusko merged commit 347fef3 into main Jun 26, 2025
33 checks passed
@kirillzyusko kirillzyusko deleted the feat/keyboard-extender branch June 26, 2025 13:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation e2e Anything about E2E tests enhancement New feature or request KeyboardExtender 🧩 Anything about keyboard extending (i. e. `KeyboardExtender` component) 🚨 requires API changes 🚨 Changes that requires changes in library API tests You added or changed unit tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant