Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8d1e0ab
Add keyboardType prop support to Fabric TextInput for parity with Paper
Nov 12, 2025
b23de66
Change files
Nov 12, 2025
c1d0caf
Add keyboardType support for Fabric TextInput using SetInputScopes API
Jan 8, 2026
92b458b
Fix prettier formatting in KeyboardTypeTest.tsx
Jan 9, 2026
765d2bc
Remove debug logging code from keyboardType implementation
Jan 15, 2026
ba1d99b
Add debug logging to keyboard_debug.log and fix touch identifier over…
Jan 15, 2026
5a0d39e
Add ITfInputScope implementation for Touch Keyboard layout support
Jan 16, 2026
9ccb881
Add debug logging to verify ITfInputScope implementation on CompTextHost
Jan 16, 2026
af59cbf
Add TSF ThreadMgr and DocumentMgr diagnostic logging
Jan 16, 2026
f8e4c47
Add proxy EDIT control for Touch Keyboard InputScope support
Jan 16, 2026
ac8dfa5
Fix proxy EDIT control - use WS_VISIBLE, transparent, positioned at T…
Jan 16, 2026
f98b4b8
Clean up keyboardType implementation - remove debug logging and unuse…
Jan 16, 2026
321bcfa
Fix formatting and code cleanup for keyboardType implementation
Jan 16, 2026
7499e0b
Remove keyboardType implementation summary doc
Jan 16, 2026
1fb5a49
Merge branch 'main' into nitin/parity-fabric/textinput-keyboardtype
Nitin-100 Jan 19, 2026
454fe16
Remove duplicate m_keyboardType member - use props directly
Jan 19, 2026
9371bee
Change files
Jan 21, 2026
dc4035d
Merge branch 'main' into nitin/parity-fabric/textinput-keyboardtype
Nitin-100 Jan 22, 2026
8af25cc
Merge branch 'nitin/parity-fabric/textinput-keyboardtype' of https://…
Jan 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Fix broken web links in markdown documentation files",
"packageName": "@react-native-windows/automation",
"email": "email not defined",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Fix broken web links in markdown documentation files",
"packageName": "@react-native-windows/automation-channel",
"email": "email not defined",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Fix broken web links in markdown documentation files",
"packageName": "@react-native-windows/automation-commands",
"email": "email not defined",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"comment": "Add keyboardType prop support to Fabric TextInput for parity with Paper",
"type": "prerelease",
"packageName": "react-native-windows",
"email": "nitchaudhary@microsoft.com",
"dependentChangeType": "patch"
}
230 changes: 230 additions & 0 deletions packages/playground/Samples/KeyboardTypeTest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
/**
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
* @format
*/

import React from 'react';
import {
AppRegistry,
StyleSheet,
ScrollView,
Text,
View,
TextInput,
} from 'react-native';

class KeyboardTypeTest extends React.Component<
{},
{
defaultValue: string;
numericValue: string;
numberPadValue: string;
decimalPadValue: string;
emailValue: string;
phonePadValue: string;
urlValue: string;
webSearchValue: string;
secureNumericValue: string;
}
> {
constructor(props: {}) {
super(props);
this.state = {
defaultValue: '',
numericValue: '',
numberPadValue: '',
decimalPadValue: '',
emailValue: '',
phonePadValue: '',
urlValue: '',
webSearchValue: '',
secureNumericValue: '',
};
}

render() {
return (
<ScrollView style={styles.container}>
<Text style={styles.title}>Keyboard Type Test (Fabric)</Text>
<Text style={styles.subtitle}>Test SetInputScopes on Parent HWND</Text>

<View style={styles.inputContainer}>
<Text style={styles.label}>Default Keyboard:</Text>
<TextInput
style={styles.input}
keyboardType="default"
value={this.state.defaultValue}
onChangeText={text => this.setState({defaultValue: text})}
placeholder="default keyboard"
/>
</View>

<View style={styles.inputContainer}>
<Text style={styles.label}>Numeric Keyboard:</Text>
<TextInput
style={styles.input}
keyboardType="numeric"
value={this.state.numericValue}
onChangeText={text => this.setState({numericValue: text})}
placeholder="numeric keyboard"
/>
</View>

<View style={styles.inputContainer}>
<Text style={styles.label}>Number Pad:</Text>
<TextInput
style={styles.input}
keyboardType="number-pad"
value={this.state.numberPadValue}
onChangeText={text => this.setState({numberPadValue: text})}
placeholder="number-pad"
/>
</View>

<View style={styles.inputContainer}>
<Text style={styles.label}>Decimal Pad:</Text>
<TextInput
style={styles.input}
keyboardType="decimal-pad"
value={this.state.decimalPadValue}
onChangeText={text => this.setState({decimalPadValue: text})}
placeholder="decimal-pad"
/>
</View>

<View style={styles.inputContainer}>
<Text style={styles.label}>Email Address:</Text>
<TextInput
style={styles.input}
keyboardType="email-address"
value={this.state.emailValue}
onChangeText={text => this.setState({emailValue: text})}
placeholder="email-address"
/>
</View>

<View style={styles.inputContainer}>
<Text style={styles.label}>Phone Pad:</Text>
<TextInput
style={styles.input}
keyboardType="phone-pad"
value={this.state.phonePadValue}
onChangeText={text => this.setState({phonePadValue: text})}
placeholder="phone-pad"
/>
</View>

<View style={styles.inputContainer}>
<Text style={styles.label}>URL Keyboard:</Text>
<TextInput
style={styles.input}
keyboardType="url"
value={this.state.urlValue}
onChangeText={text => this.setState({urlValue: text})}
placeholder="url"
/>
</View>

<View style={styles.inputContainer}>
<Text style={styles.label}>Web Search:</Text>
<TextInput
style={styles.input}
keyboardType="web-search"
value={this.state.webSearchValue}
onChangeText={text => this.setState({webSearchValue: text})}
placeholder="web-search"
/>
</View>

<View style={styles.inputContainer}>
<Text style={styles.label}>Secure + Numeric:</Text>
<TextInput
style={styles.input}
keyboardType="numeric"
secureTextEntry={true}
value={this.state.secureNumericValue}
onChangeText={text => this.setState({secureNumericValue: text})}
placeholder="numeric password"
/>
</View>

<View style={styles.instructions}>
<Text style={styles.instructionText}>
Instructions for Testing on Windows:{'\n'}
{'\n'}
This test uses SetInputScopes on the parent HWND.{'\n'}
{'\n'}
To test with Windows Touch Keyboard:{'\n'}
1. Right-click taskbar → Show touch keyboard button{'\n'}
2. Click the keyboard icon in system tray{'\n'}
3. Tap/click each TextInput field to focus it{'\n'}
4. Observe the touch keyboard layout changes{'\n'}
{'\n'}
Expected keyboard layouts:{'\n'}• default: Standard QWERTY{'\n'}•
numeric/number-pad: Number keys (IS_NUMBER/IS_DIGITS){'\n'}•
decimal-pad: Numbers with decimal point{'\n'}• email-address: QWERTY
with @ and .com keys{'\n'}• phone-pad: Phone dial pad layout{'\n'}•
url: QWERTY with .com/.net buttons{'\n'}• web-search:
Search-optimized layout{'\n'}• secure+numeric: PIN entry layout
{'\n'}
{'\n'}
Note: Physical keyboard allows all input (matches iOS/Android).
</Text>
</View>
</ScrollView>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 5,
color: '#333',
},
subtitle: {
fontSize: 14,
marginBottom: 20,
color: '#666',
fontStyle: 'italic',
},
inputContainer: {
marginBottom: 15,
},
label: {
fontSize: 14,
fontWeight: '600',
marginBottom: 5,
color: '#444',
},
input: {
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 4,
padding: 10,
fontSize: 16,
backgroundColor: '#fff',
},
instructions: {
marginTop: 30,
padding: 15,
backgroundColor: '#e3f2fd',
borderRadius: 8,
borderWidth: 1,
borderColor: '#90caf9',
},
instructionText: {
fontSize: 13,
color: '#1565c0',
lineHeight: 20,
},
});

AppRegistry.registerComponent('KeyboardTypeTest', () => KeyboardTypeTest);
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,13 @@ struct WindowData {
DialogBox(s_instance, MAKEINTRESOURCE(IDD_OPENJSBUNDLEBOX), hwnd, &Bundle);

if (!m_bundleFile.empty()) {
m_appName = (m_bundleFile == LR"(Samples\rntester)") ? L"RNTesterApp" : L"Bootstrap";
if (m_bundleFile == LR"(Samples\rntester)") {
m_appName = L"RNTesterApp";
} else if (m_bundleFile == LR"(Samples\KeyboardTypeTest)") {
m_appName = L"KeyboardTypeTest";
} else {
m_appName = L"Bootstrap";
}

WCHAR appDirectory[MAX_PATH];
GetModuleFileNameW(NULL, appDirectory, MAX_PATH);
Expand Down Expand Up @@ -370,16 +376,28 @@ struct WindowData {
return FALSE;
}

static constexpr std::wstring_view g_bundleFiles[] = {LR"(Samples\rntester)", LR"(Samples\accessible)",
LR"(Samples\callbackTest)", LR"(Samples\calculator)",
LR"(Samples\click)", LR"(Samples\control)",
LR"(Samples\flexbox)", LR"(Samples\focusTest)",
LR"(Samples\geosample)", LR"(Samples\image)",
LR"(Samples\index)", LR"(Samples\nativeFabricComponent)",
LR"(Samples\mouse)", LR"(Samples\scrollViewSnapSample)",
LR"(Samples\simple)", LR"(Samples\text)",
LR"(Samples\textinput)", LR"(Samples\ticTacToe)",
LR"(Samples\view)", LR"(Samples\debugTest01)"};
static constexpr std::wstring_view g_bundleFiles[] = {
LR"(Samples\rntester)",
LR"(Samples\accessible)",
LR"(Samples\callbackTest)",
LR"(Samples\calculator)",
LR"(Samples\click)",
LR"(Samples\control)",
LR"(Samples\flexbox)",
LR"(Samples\focusTest)",
LR"(Samples\geosample)",
LR"(Samples\image)",
LR"(Samples\index)",
LR"(Samples\KeyboardTypeTest)",
LR"(Samples\nativeFabricComponent)",
LR"(Samples\mouse)",
LR"(Samples\scrollViewSnapSample)",
LR"(Samples\simple)",
LR"(Samples\text)",
LR"(Samples\textinput)",
LR"(Samples\ticTacToe)",
LR"(Samples\view)",
LR"(Samples\debugTest01)"};

static INT_PTR CALLBACK Bundle(HWND hwnd, UINT message, WPARAM wparam, LPARAM /*lparam*/) noexcept {
switch (message) {
Expand Down
Loading
Loading