Skip to content

feat: custom keyboard support - #1548

Open
VladyslavMartynov10 wants to merge 1 commit into
kirillzyusko:mainfrom
VladyslavMartynov10:feat/custom-keyboard-support
Open

feat: custom keyboard support#1548
VladyslavMartynov10 wants to merge 1 commit into
kirillzyusko:mainfrom
VladyslavMartynov10:feat/custom-keyboard-support

Conversation

@VladyslavMartynov10

@VladyslavMartynov10 VladyslavMartynov10 commented Jul 13, 2026

Copy link
Copy Markdown

📜 Description

Adds a new CustomKeyboard component that replaces the system keyboard with arbitrary JSX whenever a text input is focused (iOS via inputView, Android via a bottom-anchored WindowManager panel with IME suppression). The keyboard content is regular React — it lives in the component tree, handles touches, and defines its own height.

<CustomKeyboard enabled={emojiKeyboardShown}>
  <EmojiPicker style={{ height: 300 }} onPick={insertEmoji} />
</CustomKeyboard>

💡 Motivation and Context

There was no maintained way to render a fully custom keyboard in RN — the library could extend (KeyboardExtender), overlay (OverKeyboardView), or mimic (KeyboardBackgroundView) the keyboard, but not replace it. The only prior art (Wix react-native-keyboard-input) is legacy-bridge and unmaintained. Unlike that approach, presenting inside the real keyboard window (iOS) / emitting synthetic keyboard events (Android) keeps the whole avoidance ecosystem working for free.

📢 Changelog

JS

  • added CustomKeyboard component (enabled prop, iOS + Android; web renders nothing)
  • added CustomKeyboardView codegen spec, types, and exports
  • added CustomKeyboard example screen (emoji keyboard + KeyboardAwareScrollView multi-input form)

iOS

  • added CustomKeyboardViewManager — attaches a shared UIInputView(.keyboard) to the focused input's inputView, with weak attach tracking and cleanup on focus change / unmount / window removal / recycle
  • added shadow-node-driven layout: host is absolute with state-provided width (Fabric adopt() + state push from the view; Paper CustomKeyboardShadowView)

Android

  • added CustomKeyboardHostView / CustomKeyboardRootViewGroupWindowManager panel (bottom gravity, non-focusable), IME suppression with focus preserved, per-IME background color, 250ms slide animations
  • added KeyboardAnimationCallback.animateSyntheticTransition() — animated synthetic keyboard events (will/did + per-frame Move) with cancellation handling; real IME events suspended while the panel owns the keyboard; instant focus-change events gated by isSuspended
  • added Fabric + Paper CustomKeyboardViewManager, package registration, RNKC.h descriptor, and shadow-node-driven width (StateWrapper push / CustomKeyboardHostShadowNode)

🤔 How Has This Been Tested?

Manually on iPhone 17 / 17 Pro simulators (iOS 26.2) and Pixel 9a emulator (API 36), old architecture (new-arch Kotlin/C++ compile-checked): custom keyboard presents on focus and inserts into the focused field across 10 inputs; live switching to/from the system keyboard; KeyboardAwareScrollView/KeyboardAvoidingView avoidance driven by the custom keyboard height; clean show/hide animations (Android hide verified frame-by-frame via screen recording — no flashes); navigation away restores the system keyboard; rapid focus/dismiss races.

📸 Screenshots (if appropriate):

iOS.mov
Android.mov

📝 Checklist

TODO

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

@kirillzyusko Can you check the Android part?

@kirillzyusko kirillzyusko self-assigned this Jul 15, 2026
@kirillzyusko kirillzyusko added enhancement New feature or request 🤖 android Android specific 🍎 iOS iOS specific labels Jul 15, 2026
@kirillzyusko
kirillzyusko self-requested a review July 15, 2026 14:04
@kirillzyusko kirillzyusko added the ⌨️ Custom keyboard Anything related to CustomKeyboard component label Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🤖 android Android specific ⌨️ Custom keyboard Anything related to CustomKeyboard component enhancement New feature or request 🍎 iOS iOS specific

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants