Skip to content

Commit

Permalink
[change] Support W3C props on TextInput
Browse files Browse the repository at this point in the history
* Add support for 'enterKeyHint' prop.
* Add support for 'inputMode' prop.
* Add support for 'readOnly' prop.
* Add support for 'rows' prop.
* Deprecate 'keyboardType' prop.
* Deprecate 'returnKeyType' prop.
* Deprecate 'editable' prop.
* Deprecate 'numberOfLines' prop.

Ref #2379
  • Loading branch information
necolas committed Mar 20, 2023
1 parent 67d52a4 commit 42bf402
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,62 @@ describe('components/TextInput', () => {
});
});

describe('prop "inputMode"', () => {
test('value "decimal"', () => {
const { container } = render(<TextInput inputMode="decimal" />);
const input = findInput(container);
expect(input.inputMode).toEqual('decimal');
});

test('value "email"', () => {
const { container } = render(<TextInput inputMode="email" />);
const input = findInput(container);
expect(input.inputMode).toEqual('email');
expect(input.type).toEqual('email');
});

test('default value', () => {
const { container } = render(<TextInput inputMode="none" />);
const input = findInput(container);
expect(input.inputMode).toEqual('none');
expect(input.type).toEqual('text');
});

test('value "numeric"', () => {
const { container } = render(<TextInput inputMode="numeric" />);
const input = findInput(container);
expect(input.inputMode).toEqual('numeric');
});

test('value "search"', () => {
const { container } = render(<TextInput inputMode="search" />);
const input = findInput(container);
expect(input.inputMode).toEqual('search');
expect(input.type).toEqual('search');
});

test('value "tel"', () => {
const { container } = render(<TextInput inputMode="tel" />);
const input = findInput(container);
expect(input.inputMode).toEqual('tel');
expect(input.type).toEqual('tel');
});

test('value "text"', () => {
const { container } = render(<TextInput inputMode="text" />);
const input = findInput(container);
expect(input.inputMode).toEqual('text');
expect(input.type).toEqual('text');
});

test('value "url"', () => {
const { container } = render(<TextInput inputMode="url" />);
const input = findInput(container);
expect(input.inputMode).toEqual('url');
expect(input.type).toEqual('url');
});
});

describe('prop "keyboardType"', () => {
test('default value', () => {
const { container } = render(<TextInput keyboardType="default" />);
Expand Down
83 changes: 60 additions & 23 deletions packages/react-native-web/src/exports/TextInput/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import useResponderEvents from '../../modules/useResponderEvents';
import { getLocaleDirection, useLocaleContext } from '../../modules/useLocale';
import StyleSheet from '../StyleSheet';
import TextInputState from '../../modules/TextInputState';
import { warnOnce } from '../../modules/warnOnce';

/**
* Determines whether a 'selection' prop differs from a node's existing
Expand Down Expand Up @@ -101,6 +102,8 @@ const TextInput: React.AbstractComponent<
clearTextOnFocus,
dir,
editable = true,
enterKeyHint,
inputMode,
keyboardType = 'default',
multiline = false,
numberOfLines = 1,
Expand Down Expand Up @@ -130,39 +133,57 @@ const TextInput: React.AbstractComponent<
onStartShouldSetResponderCapture,
onSubmitEditing,
placeholderTextColor,
readOnly,
returnKeyType,
rows,
secureTextEntry = false,
selection,
selectTextOnFocus,
spellCheck
} = props;

let type;
let inputMode;
let _inputMode;

switch (keyboardType) {
case 'email-address':
if (inputMode != null) {
_inputMode = inputMode;
if (inputMode === 'email') {
type = 'email';
break;
case 'number-pad':
case 'numeric':
inputMode = 'numeric';
break;
case 'decimal-pad':
inputMode = 'decimal';
break;
case 'phone-pad':
} else if (inputMode === 'tel') {
type = 'tel';
break;
case 'search':
case 'web-search':
} else if (inputMode === 'search') {
type = 'search';
break;
case 'url':
} else if (inputMode === 'url') {
type = 'url';
break;
default:
} else {
type = 'text';
}
} else if (keyboardType != null) {
warnOnce('keyboardType', 'keyboardType is deprecated. Use inputMode.');
switch (keyboardType) {
case 'email-address':
type = 'email';
break;
case 'number-pad':
case 'numeric':
_inputMode = 'numeric';
break;
case 'decimal-pad':
_inputMode = 'decimal';
break;
case 'phone-pad':
type = 'tel';
break;
case 'search':
case 'web-search':
type = 'search';
break;
case 'url':
type = 'url';
break;
default:
type = 'text';
}
}

if (secureTextEntry) {
Expand Down Expand Up @@ -355,15 +376,31 @@ const TextInput: React.AbstractComponent<
supportedProps.autoCorrect = autoCorrect ? 'on' : 'off';
// 'auto' by default allows browsers to infer writing direction
supportedProps.dir = dir !== undefined ? dir : 'auto';
supportedProps.enterKeyHint = returnKeyType;
supportedProps.inputMode = inputMode;
if (returnKeyType != null) {
warnOnce('returnKeyType', 'returnKeyType is deprecated. Use enterKeyHint.');
}
supportedProps.enterKeyHint = enterKeyHint || returnKeyType;
supportedProps.inputMode = _inputMode;
supportedProps.onBlur = handleBlur;
supportedProps.onChange = handleChange;
supportedProps.onFocus = handleFocus;
supportedProps.onKeyDown = handleKeyDown;
supportedProps.onSelect = handleSelectionChange;
supportedProps.readOnly = !editable;
supportedProps.rows = multiline ? numberOfLines : undefined;
if (editable != null) {
warnOnce('editable', 'editable is deprecated. Use readOnly.');
}
supportedProps.readOnly = readOnly || !editable;
if (numberOfLines != null) {
warnOnce(
'numberOfLines',
'TextInput numberOfLines is deprecated. Use rows.'
);
}
supportedProps.rows = multiline
? rows != null
? rows
: numberOfLines
: undefined;
supportedProps.spellCheck = spellCheck != null ? spellCheck : autoCorrect;
supportedProps.style = [
{ '--placeholderTextColor': placeholderTextColor },
Expand Down
58 changes: 39 additions & 19 deletions packages/react-native-web/src/exports/TextInput/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,26 @@ export type TextInputProps = {
defaultValue?: ?string,
dir?: ?('auto' | 'ltr' | 'rtl'),
disabled?: ?boolean,
editable?: ?boolean,
enterKeyHint?:
| 'enter'
| 'done'
| 'go'
| 'next'
| 'previous'
| 'search'
| 'send',
inputAccessoryViewID?: ?string,
keyboardType?:
| 'default'
| 'email-address'
| 'number-pad'
| 'numbers-and-punctuation'
inputMode?:
| 'decimal'
| 'email'
| 'none'
| 'numeric'
| 'phone-pad'
| 'search'
| 'url'
| 'web-search',
| 'tel'
| 'text'
| 'url',
maxLength?: ?number,
multiline?: ?boolean,
numberOfLines?: ?number,
onChange?: (e: any) => void,
onChangeText?: (e: string) => void,
onContentSizeChange?: (e: any) => void,
Expand All @@ -54,14 +59,8 @@ export type TextInputProps = {
onSubmitEditing?: (e: any) => void,
placeholder?: ?string,
placeholderTextColor?: ?ColorValue,
returnKeyType?:
| 'enter'
| 'done'
| 'go'
| 'next'
| 'previous'
| 'search'
| 'send',
readOnly?: ?boolean,
rows?: ?number,
secureTextEntry?: ?boolean,
selectTextOnFocus?: ?boolean,
selection?: {|
Expand All @@ -71,5 +70,26 @@ export type TextInputProps = {
selectionColor?: ?ColorValue,
spellCheck?: ?boolean,
style?: ?GenericStyleProp<TextInputStyle>,
value?: ?string
value?: ?string,
// deprecated
editable?: ?boolean,
keyboardType?:
| 'default'
| 'email-address'
| 'number-pad'
| 'numbers-and-punctuation'
| 'numeric'
| 'phone-pad'
| 'search'
| 'url'
| 'web-search',
numberOfLines?: ?number,
returnKeyType?:
| 'enter'
| 'done'
| 'go'
| 'next'
| 'previous'
| 'search'
| 'send'
};

0 comments on commit 42bf402

Please sign in to comment.