From 45c7df4f1262ea7a66b17b66234e8597d6bb462d Mon Sep 17 00:00:00 2001 From: jameswilddev Date: Tue, 28 May 2024 15:37:09 +0100 Subject: [PATCH] Add autofocus throughout all input component types. Disabled is now a required prop. --- react-native/components/Hitbox/index.tsx | 4 +- react-native/components/Hitbox/unit.tsx | 49 +--- .../createBottomTabBarComponent/index.tsx | 1 + .../createBottomTabBarComponent/unit.tsx | 16 ++ .../createButtonComponent/index.tsx | 2 - .../components/createButtonComponent/unit.tsx | 131 --------- .../index.tsx | 2 +- .../unit.tsx | 13 +- .../index.tsx | 4 +- .../createFullHeightPopoverComponent/unit.tsx | 122 -------- .../createHeaderComponent/index.tsx | 2 + .../components/createHeaderComponent/unit.tsx | 35 +++ .../components/createInputComponent/index.tsx | 26 +- .../components/createInputComponent/readme.md | 3 +- .../components/createInputComponent/unit.tsx | 248 ++++++++-------- .../index.tsx | 4 +- .../unit.tsx | 206 +++++++++++++- .../index.tsx | 4 +- .../unit.tsx | 244 +++++++++++++++- .../index.tsx | 4 +- .../unit.tsx | 238 +++++++++++++++- .../index.tsx | 4 +- .../unit.tsx | 157 ++++++++++- .../createNullableTextAreaComponent/index.tsx | 4 +- .../createNullableTextAreaComponent/unit.tsx | 230 ++++++++++++++- .../index.tsx | 4 +- .../createNullableTextInputComponent/unit.tsx | 213 +++++++++++++- .../createOfflineTableComponent/index.tsx | 2 + .../createOfflineTableComponent/unit.tsx | 108 +++++++ .../createPickerButtonComponent/index.tsx | 4 +- .../createPickerButtonComponent/readme.md | 3 +- .../createPickerButtonComponent/unit.tsx | 265 ------------------ .../index.tsx | 4 +- .../unit.tsx | 211 +++++++++++++- .../index.tsx | 4 +- .../unit.tsx | 243 +++++++++++++++- .../index.tsx | 4 +- .../unit.tsx | 237 +++++++++++++++- .../index.tsx | 4 +- .../unit.tsx | 156 ++++++++++- .../createRequiredTextAreaComponent/index.tsx | 4 +- .../createRequiredTextAreaComponent/unit.tsx | 233 ++++++++++++++- .../index.tsx | 4 +- .../createRequiredTextInputComponent/unit.tsx | 196 ++++++++++++- .../index.tsx | 2 +- .../unit.tsx | 15 +- .../index.tsx | 2 +- .../index.tsx | 2 +- .../unit.tsx | 30 +- .../createSearchableSelectComponent/index.tsx | 2 +- react-native/types/ButtonProps/index.tsx | 2 +- .../types/CreatableSelectProps/index.tsx | 2 +- .../types/NullableEmailInputProps/index.tsx | 8 +- .../types/NullableEmailInputProps/readme.md | 1 + .../types/NullableFloatInputProps/index.tsx | 8 +- .../types/NullableFloatInputProps/readme.md | 1 + .../types/NullableIntegerInputProps/index.tsx | 8 +- .../types/NullableIntegerInputProps/readme.md | 1 + .../NullablePasswordInputProps/index.tsx | 8 +- .../NullablePasswordInputProps/readme.md | 1 + .../types/NullableTextAreaProps/index.tsx | 8 +- .../types/NullableTextAreaProps/readme.md | 1 + .../types/NullableTextInputProps/index.tsx | 8 +- .../types/NullableTextInputProps/readme.md | 1 + .../types/RequiredEmailInputProps/index.tsx | 8 +- .../types/RequiredEmailInputProps/readme.md | 1 + .../types/RequiredFloatInputProps/index.tsx | 8 +- .../types/RequiredFloatInputProps/readme.md | 1 + .../types/RequiredIntegerInputProps/index.tsx | 8 +- .../types/RequiredIntegerInputProps/readme.md | 1 + .../RequiredPasswordInputProps/index.tsx | 8 +- .../RequiredPasswordInputProps/readme.md | 1 + .../types/RequiredTextAreaProps/index.tsx | 8 +- .../types/RequiredTextAreaProps/readme.md | 1 + .../types/RequiredTextInputProps/index.tsx | 8 +- .../types/RequiredTextInputProps/readme.md | 1 + .../SearchableMultiSelectProps/index.tsx | 2 +- .../types/SearchableSelectProps/index.tsx | 2 +- 78 files changed, 2950 insertions(+), 871 deletions(-) diff --git a/react-native/components/Hitbox/index.tsx b/react-native/components/Hitbox/index.tsx index c449362c..7209c398 100644 --- a/react-native/components/Hitbox/index.tsx +++ b/react-native/components/Hitbox/index.tsx @@ -15,7 +15,7 @@ React.PropsWithChildren<{ * This will, of course, not apply until the next render. To synchronously * disable all Hitboxes, use the "enabled" static property. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean /** * Passed down to TouchableOpacity. @@ -60,7 +60,7 @@ export const Hitbox: Component & { return ( { renderer.unmount() }) -test('renders as expected when enabled by not disabling', () => { - const onPress = jest.fn() - const onMeasure = jest.fn() - - const renderer = TestRenderer.create( - - Test Children - - ) - - expect(renderer.toTree()?.rendered).toEqual( - expect.objectContaining({ - nodeType: 'component', - props: expect.objectContaining({ - disabled: false, - style: { backgroundColor: 'red' }, - hostRef: expect.any(Function), - onLayout: expect.any(Function), - onPress: expect.any(Function), - children: expect.objectContaining({ - type: Text, - props: { - children: 'Test Children' - } - }) - }) - }) - ) - expect( - ( - (renderer.toTree()?.rendered as TestRenderer.ReactTestRendererTree) - .type as unknown as () => void - ).name - ).toEqual('TouchableOpacity') - - expect(onPress).not.toHaveBeenCalled() - expect(onMeasure).not.toHaveBeenCalled() - - renderer.unmount() -}) - -test('renders as expected when enabled by disabled being undefined', () => { +test('renders as expected when enabled', () => { const onPress = jest.fn() const onMeasure = jest.fn() @@ -107,7 +62,7 @@ test('renders as expected when enabled by disabled being undefined', () => { style={{ backgroundColor: 'red' }} onPress={onPress} onMeasure={onMeasure} - disabled={undefined} + disabled={false} > Test Children diff --git a/react-native/components/createBottomTabBarComponent/index.tsx b/react-native/components/createBottomTabBarComponent/index.tsx index 8c26f1d0..dc71d1eb 100644 --- a/react-native/components/createBottomTabBarComponent/index.tsx +++ b/react-native/components/createBottomTabBarComponent/index.tsx @@ -94,6 +94,7 @@ export function createBottomTabBarComponent< }} key={bottomTab.tab} style={isActive ? styles.activeHitbox : styles.inactiveHitbox} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'purple' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'purple' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'purple' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'purple' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > { flexGrow: 1, backgroundColor: 'yellow' }} + disabled={false} > = ({ leftIcon, rightIcon, onPress, disabled, children }) => { - disabled = disabled ?? false - const color = disabled ? buttonStyle.disabled.color : buttonStyle.default.color diff --git a/react-native/components/createButtonComponent/unit.tsx b/react-native/components/createButtonComponent/unit.tsx index 9ca3bad9..6a4f33d1 100644 --- a/react-native/components/createButtonComponent/unit.tsx +++ b/react-native/components/createButtonComponent/unit.tsx @@ -74,137 +74,6 @@ test('renders when enabled', () => { expect(onPress).not.toHaveBeenCalled() }) -test('renders when enabled by not disabling', () => { - const Component = createButtonComponent({ - fontFamily: 'Example Font Family', - fontSize: 16, - horizontalPadding: 10, - verticalPadding: 2, - iconSpacing: 7, - default: { - backgroundColor: 'yellow', - color: 'blue', - radius: 25, - border: { - width: 5, - color: 'aquamarine' - } - }, - disabled: { - backgroundColor: 'orange', - color: 'purple', - radius: 7, - border: { - width: 2, - color: 'aquamarine' - } - } - }) - const onPress = jest.fn() - - const rendered = ( - null} rightIcon={() => null} onPress={onPress}> - Example Content - - ) - - expect(unwrapRenderedFunctionComponent(rendered)).toEqual( - - - Example Content - - - ) - expect(onPress).not.toHaveBeenCalled() -}) - -test('renders when enabled by disabled being undefined', () => { - const Component = createButtonComponent({ - fontFamily: 'Example Font Family', - fontSize: 16, - horizontalPadding: 10, - verticalPadding: 2, - iconSpacing: 7, - default: { - backgroundColor: 'yellow', - color: 'blue', - radius: 25, - border: { - width: 5, - color: 'aquamarine' - } - }, - disabled: { - backgroundColor: 'orange', - color: 'purple', - radius: 7, - border: { - width: 2, - color: 'aquamarine' - } - } - }) - const onPress = jest.fn() - - const rendered = ( - null} - rightIcon={() => null} - onPress={onPress} - disabled={undefined} - > - Example Content - - ) - - expect(unwrapRenderedFunctionComponent(rendered)).toEqual( - - - Example Content - - - ) - expect(onPress).not.toHaveBeenCalled() -}) - test('renders when disabled', () => { const Component = createButtonComponent({ fontFamily: 'Example Font Family', diff --git a/react-native/components/createCreatableSelectComponent/createCreatableSelectChildrenComponent/index.tsx b/react-native/components/createCreatableSelectComponent/createCreatableSelectChildrenComponent/index.tsx index a0fca2d2..24d4498a 100644 --- a/react-native/components/createCreatableSelectComponent/createCreatableSelectChildrenComponent/index.tsx +++ b/react-native/components/createCreatableSelectComponent/createCreatableSelectChildrenComponent/index.tsx @@ -71,7 +71,6 @@ export const createCreatableSelectChildrenComponent = < 'off', 'default', 'sentences', - true, false, 'left' ) @@ -225,6 +224,7 @@ export const createCreatableSelectChildrenComponent = < } }} context={null} + autoFocus /> ) diff --git a/react-native/components/createCreatableSelectComponent/createCreatableSelectChildrenComponent/unit.tsx b/react-native/components/createCreatableSelectComponent/createCreatableSelectChildrenComponent/unit.tsx index 2494014c..cf86cf46 100644 --- a/react-native/components/createCreatableSelectComponent/createCreatableSelectChildrenComponent/unit.tsx +++ b/react-native/components/createCreatableSelectComponent/createCreatableSelectChildrenComponent/unit.tsx @@ -172,6 +172,7 @@ test('renders as expected with an absent selected value', () => { onChange: expect.any(Function), secureTextEntry: false, disabled: false, + autoFocus: true, placeholder: 'Example Placeholder', onSubmit: expect.any(Function), context: null @@ -296,8 +297,7 @@ test('renders as expected with an absent selected value', () => { }, multiLine: false, autoComplete: 'off', - keyboardType: 'default', - autoFocus: true + keyboardType: 'default' } }) @@ -489,6 +489,7 @@ test('renders as expected with a present selected value', () => { onChange: expect.any(Function), secureTextEntry: false, disabled: false, + autoFocus: true, placeholder: 'Example Option B Label', onSubmit: expect.any(Function), context: null @@ -641,8 +642,7 @@ test('renders as expected with a present selected value', () => { }, multiLine: false, autoComplete: 'off', - keyboardType: 'default', - autoFocus: true + keyboardType: 'default' } }) @@ -831,6 +831,7 @@ test('renders as expected when exact matches are found for user input', async () onChange: expect.any(Function), secureTextEntry: false, disabled: false, + autoFocus: true, placeholder: 'Example Option B Label', onSubmit: expect.any(Function), context: null @@ -1028,6 +1029,7 @@ test('renders as expected when partial matches are found for user input', async onChange: expect.any(Function), secureTextEntry: false, disabled: false, + autoFocus: true, placeholder: 'Example Option B Label', onSubmit: expect.any(Function), context: null @@ -1216,6 +1218,7 @@ test('renders as expected when matches are not found for user input', async () = onChange: expect.any(Function), secureTextEntry: false, disabled: false, + autoFocus: true, placeholder: 'Example Option B Label', onSubmit: expect.any(Function), context: null @@ -2055,6 +2058,7 @@ test('renders as expected when horizontal padding is not present', async () => { onChange: expect.any(Function), secureTextEntry: false, disabled: false, + autoFocus: true, placeholder: 'Example Option B Label', onSubmit: expect.any(Function), context: null @@ -2249,6 +2253,7 @@ test('renders as expected when vertical padding is not present', async () => { onChange: expect.any(Function), secureTextEntry: false, disabled: false, + autoFocus: true, placeholder: 'Example Option B Label', onSubmit: expect.any(Function), context: null diff --git a/react-native/components/createFullHeightPopoverComponent/index.tsx b/react-native/components/createFullHeightPopoverComponent/index.tsx index 5b891d3f..7b8439c7 100644 --- a/react-native/components/createFullHeightPopoverComponent/index.tsx +++ b/react-native/components/createFullHeightPopoverComponent/index.tsx @@ -28,7 +28,7 @@ type Instance = React.FunctionComponent<{ /** * When true, the button cannot be pressed and the body is not shown. */ - readonly disabled: undefined | boolean + readonly disabled: boolean /** * When true, the control is styled as though it is valid. It is otherwise @@ -127,8 +127,6 @@ export const createFullHeightPopoverComponent = ( valid, children }) => { - disabled = disabled ?? false - const refresh = useRefresh() const state = React.useRef<{ diff --git a/react-native/components/createFullHeightPopoverComponent/unit.tsx b/react-native/components/createFullHeightPopoverComponent/unit.tsx index 19e019e2..161ff3d9 100644 --- a/react-native/components/createFullHeightPopoverComponent/unit.tsx +++ b/react-native/components/createFullHeightPopoverComponent/unit.tsx @@ -4071,125 +4071,3 @@ test('allows introspection when used in a higher-order component', () => { }) expect(RightIcon).not.toHaveBeenCalled() }) - -test('treats disabled undefined as disabled false', () => { - Dimensions.set({ - window: { - width: 640, - height: 480, - scale: 2.42, - fontScale: 3.51 - } - }) - - const controlStyle: ControlStyle = { - fontFamily: 'Example Font Family', - fontSize: 37, - paddingVertical: 12, - paddingHorizontal: 29, - blurredValid: { - textColor: '#FFEE00', - placeholderColor: '#E7AA32', - backgroundColor: '#32AE12', - radius: 5, - border: { - width: 4, - color: '#FF00FF' - }, - iconColor: '#43AE21' - }, - blurredInvalid: { - textColor: '#99FE88', - placeholderColor: '#CACA3A', - backgroundColor: '#259284', - radius: 10, - border: { - width: 6, - color: '#9A9A8E' - }, - iconColor: '#985E00' - }, - focusedValid: { - textColor: '#55EA13', - placeholderColor: '#273346', - backgroundColor: '#CABA99', - radius: 3, - border: { - width: 5, - color: '#646464' - }, - iconColor: '#789521' - }, - focusedInvalid: { - textColor: '#ABAADE', - placeholderColor: '#47ADAD', - backgroundColor: '#32AA88', - radius: 47, - border: { - width: 12, - color: '#98ADAA' - }, - iconColor: '#449438' - }, - disabledValid: { - textColor: '#AE2195', - placeholderColor: '#FFAAEE', - backgroundColor: '#772728', - radius: 100, - border: { - width: 14, - color: '#5E5E5E' - }, - iconColor: '#ADAADA' - }, - disabledInvalid: { - textColor: '#340297', - placeholderColor: '#233832', - backgroundColor: '#938837', - radius: 2, - border: { - width: 19, - color: '#573829' - }, - iconColor: '#709709' - } - } - - const Component = createFullHeightPopoverComponent(controlStyle, null) - - const renderer = TestRenderer.create( - - - {() => Example Pop Over Content} - - - ) - - expect(renderer.toTree()?.rendered).toEqual( - expect.objectContaining({ - props: { - onMeasure: expect.any(Function), - onPress: expect.any(Function), - disabled: false, - label: 'Example Button Content', - placeholder: 'Example Placeholder', - valid: true - } - }) - ) - - expect( - (renderer.toTree()?.rendered as TestRenderer.ReactTestRendererTree).type - ).toBeAFunctionWithTheStaticProperties({ - pickerButton: { controlStyle } - }) - - renderer.unmount() -}) diff --git a/react-native/components/createHeaderComponent/index.tsx b/react-native/components/createHeaderComponent/index.tsx index 0b927d23..9c97fb71 100644 --- a/react-native/components/createHeaderComponent/index.tsx +++ b/react-native/components/createHeaderComponent/index.tsx @@ -80,6 +80,7 @@ export const createHeaderComponent = ( key={String(index)} onPress={icon.onPress} style={styles.hitbox} + disabled={false} > {React.createElement(icon.icon, { fill: headerStyle.textColor })} @@ -94,6 +95,7 @@ export const createHeaderComponent = ( key={String(index)} onPress={icon.onPress} style={styles.hitbox} + disabled={false} > {React.createElement(icon.icon, { fill: headerStyle.textColor })} diff --git a/react-native/components/createHeaderComponent/unit.tsx b/react-native/components/createHeaderComponent/unit.tsx index bf12c9ef..3876d12c 100644 --- a/react-native/components/createHeaderComponent/unit.tsx +++ b/react-native/components/createHeaderComponent/unit.tsx @@ -98,6 +98,7 @@ test('renders as expected', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -108,6 +109,7 @@ test('renders as expected', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -118,6 +120,7 @@ test('renders as expected', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -128,6 +131,7 @@ test('renders as expected', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -160,6 +164,7 @@ test('renders as expected', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -170,6 +175,7 @@ test('renders as expected', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -180,6 +186,7 @@ test('renders as expected', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -285,6 +292,7 @@ test('renders as expected without vertical padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -295,6 +303,7 @@ test('renders as expected without vertical padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -305,6 +314,7 @@ test('renders as expected without vertical padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -315,6 +325,7 @@ test('renders as expected without vertical padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -346,6 +357,7 @@ test('renders as expected without vertical padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -356,6 +368,7 @@ test('renders as expected without vertical padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -366,6 +379,7 @@ test('renders as expected without vertical padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -470,6 +484,7 @@ test('renders as expected without inner horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -479,6 +494,7 @@ test('renders as expected without inner horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -488,6 +504,7 @@ test('renders as expected without inner horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -497,6 +514,7 @@ test('renders as expected without inner horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -528,6 +546,7 @@ test('renders as expected without inner horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -537,6 +556,7 @@ test('renders as expected without inner horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -546,6 +566,7 @@ test('renders as expected without inner horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -649,6 +670,7 @@ test('renders as expected without inner or outer horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -658,6 +680,7 @@ test('renders as expected without inner or outer horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -667,6 +690,7 @@ test('renders as expected without inner or outer horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -676,6 +700,7 @@ test('renders as expected without inner or outer horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -706,6 +731,7 @@ test('renders as expected without inner or outer horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -715,6 +741,7 @@ test('renders as expected without inner or outer horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -724,6 +751,7 @@ test('renders as expected without inner or outer horizontal padding', () => { justifyContent: 'center' }} onPress={expect.any(Function)} + disabled={false} > @@ -828,6 +856,7 @@ test('renders as expected without vertical or inner horizontal padding', () => { style={{ justifyContent: 'center' }} + disabled={false} > @@ -837,6 +866,7 @@ test('renders as expected without vertical or inner horizontal padding', () => { style={{ justifyContent: 'center' }} + disabled={false} > @@ -846,6 +876,7 @@ test('renders as expected without vertical or inner horizontal padding', () => { style={{ justifyContent: 'center' }} + disabled={false} > @@ -855,6 +886,7 @@ test('renders as expected without vertical or inner horizontal padding', () => { style={{ justifyContent: 'center' }} + disabled={false} > @@ -885,6 +917,7 @@ test('renders as expected without vertical or inner horizontal padding', () => { style={{ justifyContent: 'center' }} + disabled={false} > @@ -894,6 +927,7 @@ test('renders as expected without vertical or inner horizontal padding', () => { style={{ justifyContent: 'center' }} + disabled={false} > @@ -903,6 +937,7 @@ test('renders as expected without vertical or inner horizontal padding', () => { style={{ justifyContent: 'center' }} + disabled={false} > diff --git a/react-native/components/createInputComponent/index.tsx b/react-native/components/createInputComponent/index.tsx index 05958668..2243f76b 100644 --- a/react-native/components/createInputComponent/index.tsx +++ b/react-native/components/createInputComponent/index.tsx @@ -42,7 +42,13 @@ type Instance = React.FunctionComponent<{ * When true, the text box is rendered semi-transparently and does not accept * focus or input. */ - readonly disabled: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. @@ -114,12 +120,6 @@ interface Introspection { */ readonly autoCapitalize: 'none' | 'sentences' | 'words' | 'characters' - /** - * When true, the text input will steal focus on mount. It will otherwise - * wait for the user to interact with it. - */ - readonly autoFocus: boolean - /** * When true, the text input will keep focus on submit. It will otherwise * blur. @@ -150,9 +150,6 @@ interface Introspection { * @param autoComplete The type of auto-complete suggestions to provide. * @param keyboardType The type of keyboard to show. * @param autoCapitalize The capitalization behavior to use. - * @param autoFocus When true, the text input will steal focus on mount. - * It will otherwise wait for the user to interact with - * it. * @param keepFocusOnSubmit When true, the text input will keep focus on submit. * It will otherwise blur. * @param alignment The alignment of the text within the input. @@ -167,7 +164,6 @@ export function createInputComponent ( autoComplete: 'off' | 'email' | 'password', keyboardType: 'default' | 'email-address' | 'numeric', autoCapitalize: 'none' | 'sentences' | 'words' | 'characters', - autoFocus: boolean, keepFocusOnSubmit: boolean, alignment: 'left' | 'middle' | 'right' ): Instance & { @@ -399,12 +395,11 @@ export function createInputComponent ( onChange, secureTextEntry, disabled, + autoFocus, placeholder, onSubmit, context }) => { - disabled = disabled ?? false - const refresh = useRefresh() const stringifiedValue = @@ -434,6 +429,10 @@ export function createInputComponent ( const ref = React.useRef(null) const firstLayout = React.useRef(true) + if (!autoFocus) { + firstLayout.current = true + } + return ( ( autoComplete, keyboardType, autoCapitalize, - autoFocus, keepFocusOnSubmit, alignment } diff --git a/react-native/components/createInputComponent/readme.md b/react-native/components/createInputComponent/readme.md index 04e5a3e5..f909ab2c 100644 --- a/react-native/components/createInputComponent/readme.md +++ b/react-native/components/createInputComponent/readme.md @@ -89,7 +89,7 @@ const ExampleInput = createInputComponent( `email`, `numeric`, true, - true + `left` ); const ExampleScreen = () => { @@ -118,6 +118,7 @@ const ExampleScreen = () => { }} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Shown when no text has been entered" leftIcon={Shown to the left} rightIcon={Shown to the right} diff --git a/react-native/components/createInputComponent/unit.tsx b/react-native/components/createInputComponent/unit.tsx index 1fd45380..083c5a7d 100644 --- a/react-native/components/createInputComponent/unit.tsx +++ b/react-native/components/createInputComponent/unit.tsx @@ -94,7 +94,6 @@ test('renders as expected with a value', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -107,6 +106,7 @@ test('renders as expected with a value', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -262,7 +262,6 @@ test('renders as expected without a value', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -275,6 +274,7 @@ test('renders as expected without a value', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -431,7 +431,6 @@ test('renders as expected when disabled with a value', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -444,6 +443,7 @@ test('renders as expected when disabled with a value', () => { onSubmit={onSubmit} secureTextEntry={false} disabled + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -600,7 +600,6 @@ test('renders as expected when disabled without a value', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -613,6 +612,7 @@ test('renders as expected when disabled without a value', () => { onSubmit={onSubmit} secureTextEntry={false} disabled + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -769,7 +769,6 @@ test('can be focused when valid', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -782,6 +781,7 @@ test('can be focused when valid', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -949,7 +949,6 @@ test('can be focused when invalid', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -962,6 +961,7 @@ test('can be focused when invalid', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -1129,7 +1129,6 @@ test('can be blurred', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -1142,6 +1141,7 @@ test('can be blurred', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -1319,7 +1319,6 @@ test('can be disabled during edit', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -1332,6 +1331,7 @@ test('can be disabled during edit', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -1371,6 +1371,7 @@ test('can be disabled during edit', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -1528,7 +1529,6 @@ test('can be disabled during edit when starting invalid', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -1541,6 +1541,7 @@ test('can be disabled during edit when starting invalid', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -1580,6 +1581,7 @@ test('can be disabled during edit when starting invalid', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -1737,7 +1739,6 @@ test('can be re-enabled following edit', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -1750,6 +1751,7 @@ test('can be re-enabled following edit', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -1789,6 +1791,7 @@ test('can be re-enabled following edit', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -1806,6 +1809,7 @@ test('can be re-enabled following edit', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -1962,7 +1966,6 @@ test('does not lose pending changes on update', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -1975,6 +1978,7 @@ test('does not lose pending changes on update', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -2014,6 +2018,7 @@ test('does not lose pending changes on update', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Updated Placeholder" leftIcon={null} rightIcon={null} @@ -2171,7 +2176,6 @@ test('resets the value on external changes', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -2184,6 +2188,7 @@ test('resets the value on external changes', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -2201,6 +2206,7 @@ test('resets the value on external changes', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -2356,7 +2362,6 @@ test('ignores external changes to the value when an edit is in progress', async 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -2369,6 +2374,7 @@ test('ignores external changes to the value when an edit is in progress', async onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -2408,6 +2414,7 @@ test('ignores external changes to the value when an edit is in progress', async onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -2565,7 +2572,6 @@ test('allows valid incomplete edits', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -2578,6 +2584,7 @@ test('allows valid incomplete edits', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -2757,7 +2764,6 @@ test('allows valid incomplete edits', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -2770,6 +2776,7 @@ test('allows valid incomplete edits', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -2953,7 +2960,6 @@ test('allows valid incomplete edits', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -2966,6 +2972,7 @@ test('allows valid incomplete edits', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -3149,7 +3156,6 @@ test('allows invalid incomplete edits', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -3162,6 +3168,7 @@ test('allows invalid incomplete edits', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -3341,7 +3348,6 @@ test('allows invalid incomplete edits', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -3354,6 +3360,7 @@ test('allows invalid incomplete edits', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -3537,7 +3544,6 @@ test('allows invalid incomplete edits', async () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -3550,6 +3556,7 @@ test('allows invalid incomplete edits', async () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -3732,7 +3739,6 @@ test('renders as expected when the border width does not change', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -3745,6 +3751,7 @@ test('renders as expected when the border width does not change', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -3900,7 +3907,6 @@ test('passes down secureTextEntry', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -3913,6 +3919,7 @@ test('passes down secureTextEntry', () => { onSubmit={onSubmit} secureTextEntry disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -4068,7 +4075,6 @@ test('renders with a left icon', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -4081,6 +4087,7 @@ test('renders with a left icon', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={null} @@ -4244,7 +4251,6 @@ test('renders with a right icon', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -4257,6 +4263,7 @@ test('renders with a right icon', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={Right Icon} @@ -4420,7 +4427,6 @@ test('renders with left and right icons', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -4433,6 +4439,7 @@ test('renders with left and right icons', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={Right Icon} @@ -4603,7 +4610,6 @@ test('renders as expected with a left icon without a value', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -4616,6 +4622,7 @@ test('renders as expected with a left icon without a value', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={null} @@ -4780,7 +4787,6 @@ test('renders as expected with a left icon without a value', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -4793,6 +4799,7 @@ test('renders as expected with a left icon without a value', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={Right Icon} @@ -4957,7 +4964,6 @@ test('renders as expected with left and right icons without a value', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -4970,6 +4976,7 @@ test('renders as expected with left and right icons without a value', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={Right Icon} @@ -5141,7 +5148,6 @@ test('renders as expected with a left icon when focused and valid', async () => 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -5154,6 +5160,7 @@ test('renders as expected with a left icon when focused and valid', async () => onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={null} @@ -5329,7 +5336,6 @@ test('renders as expected with a right icon when focused and valid', async () => 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -5342,6 +5348,7 @@ test('renders as expected with a right icon when focused and valid', async () => onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={Right Icon} @@ -5517,7 +5524,6 @@ test('renders as expected with a right icon when focused and valid', async () => 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -5530,6 +5536,7 @@ test('renders as expected with a right icon when focused and valid', async () => onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={Right Icon} @@ -5712,7 +5719,6 @@ test('renders as expected with a left icon when focused and invalid', async () = 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -5725,6 +5731,7 @@ test('renders as expected with a left icon when focused and invalid', async () = onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={null} @@ -5900,7 +5907,6 @@ test('renders as expected with a right icon when focused and invalid', async () 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -5913,6 +5919,7 @@ test('renders as expected with a right icon when focused and invalid', async () onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={Right Icon} @@ -6088,7 +6095,6 @@ test('renders as expected with left and right icons when focused and invalid', a 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -6101,6 +6107,7 @@ test('renders as expected with left and right icons when focused and invalid', a onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={Right Icon} @@ -6283,7 +6290,6 @@ test('renders without horizontal padding', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -6296,6 +6302,7 @@ test('renders without horizontal padding', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -6450,7 +6457,6 @@ test('renders with a left icon without horizontal padding', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -6463,6 +6469,7 @@ test('renders with a left icon without horizontal padding', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={null} @@ -6624,7 +6631,6 @@ test('renders with a right icon without horizontal padding', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -6637,6 +6643,7 @@ test('renders with a right icon without horizontal padding', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={Right Icon} @@ -6798,7 +6805,6 @@ test('renders with left and right icons without horizontal padding', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -6811,6 +6817,7 @@ test('renders with left and right icons without horizontal padding', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={Right Icon} @@ -6979,7 +6986,6 @@ test('renders as expected without vertical padding', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -6992,6 +6998,7 @@ test('renders as expected without vertical padding', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -7134,7 +7141,6 @@ test('renders as expected without borders', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -7147,6 +7153,7 @@ test('renders as expected without borders', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -7300,7 +7307,6 @@ test('renders as expected when a state does not alter border thickness', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -7313,6 +7319,7 @@ test('renders as expected when a state does not alter border thickness', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -7468,7 +7475,6 @@ test('renders as expected without a radius', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -7481,6 +7487,7 @@ test('renders as expected without a radius', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -7635,7 +7642,6 @@ test('renders when disabled with a left icon', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -7648,6 +7654,7 @@ test('renders when disabled with a left icon', () => { onSubmit={onSubmit} secureTextEntry={false} disabled + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={null} @@ -7812,7 +7819,6 @@ test('renders when disabled with a right icon', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -7825,6 +7831,7 @@ test('renders when disabled with a right icon', () => { onSubmit={onSubmit} secureTextEntry={false} disabled + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={Right Icon} @@ -7989,7 +7996,6 @@ test('renders when disabled with left and right icons', () => { 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -8002,6 +8008,7 @@ test('renders when disabled with left and right icons', () => { onSubmit={onSubmit} secureTextEntry={false} disabled + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={Right Icon} @@ -8173,7 +8180,6 @@ test('renders as expected when disabled with a left icon without a value', () => 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -8186,6 +8192,7 @@ test('renders as expected when disabled with a left icon without a value', () => onSubmit={onSubmit} secureTextEntry={false} disabled + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={null} @@ -8350,7 +8357,6 @@ test('renders as expected when disabled with a right icon without a value', () = 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -8363,6 +8369,7 @@ test('renders as expected when disabled with a right icon without a value', () = onSubmit={onSubmit} secureTextEntry={false} disabled + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={Right Icon} @@ -8527,7 +8534,6 @@ test('renders as expected when disabled with left and right icons without a valu 'numeric', 'sentences', false, - false, 'left' ) const onChange = jest.fn() @@ -8540,6 +8546,7 @@ test('renders as expected when disabled with left and right icons without a valu onSubmit={onSubmit} secureTextEntry={false} disabled + autoFocus={false} placeholder="Test Placeholder" leftIcon={Left Icon} rightIcon={Right Icon} @@ -8710,7 +8717,6 @@ test('allows introspection when used in a higher-order component', () => { 'email', 'numeric', 'sentences', - true, false, 'left' ) @@ -8723,6 +8729,7 @@ test('allows introspection when used in a higher-order component', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={true} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -8746,7 +8753,6 @@ test('allows introspection when used in a higher-order component', () => { autoComplete: 'email', keyboardType: 'numeric', autoCapitalize: 'sentences', - autoFocus: true, keepFocusOnSubmit: false, alignment: 'left' } @@ -8840,7 +8846,6 @@ test('does nothing when auto-focus is enabled', () => { 'email', 'numeric', 'sentences', - true, false, 'left' ) @@ -8854,6 +8859,7 @@ test('does nothing when auto-focus is enabled', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={true} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -9009,7 +9015,6 @@ test('focuses the text input on layout when the ref is ready', () => { 'email', 'numeric', 'sentences', - true, false, 'left' ) @@ -9023,6 +9028,7 @@ test('focuses the text input on layout when the ref is ready', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={true} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -9142,7 +9148,6 @@ test('does not focus the text input a second time', () => { 'email', 'numeric', 'sentences', - true, false, 'left' ) @@ -9156,6 +9161,7 @@ test('does not focus the text input a second time', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={true} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -9282,7 +9288,6 @@ test('renders as expected with a value when focus is to be retained', () => { 'email', 'numeric', 'sentences', - false, true, 'left' ) @@ -9296,6 +9301,7 @@ test('renders as expected with a value when focus is to be retained', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -9450,7 +9456,6 @@ test('renders as expected without a value when focus is to be retained', () => { 'email', 'numeric', 'sentences', - false, true, 'left' ) @@ -9464,6 +9469,7 @@ test('renders as expected without a value when focus is to be retained', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -9532,7 +9538,7 @@ test('renders as expected without a value when focus is to be retained', () => { expect(onSubmit).not.toHaveBeenCalled() }) -test('treats disabled undefined as disabled false', () => { +test('renders as expected when middle-aligned', () => { interface ExampleContext { readonly character: string readonly regex: RegExp @@ -9620,8 +9626,7 @@ test('treats disabled undefined as disabled false', () => { 'numeric', 'sentences', false, - false, - 'left' + 'middle' ) const onChange = jest.fn() const onSubmit = jest.fn() @@ -9632,7 +9637,8 @@ test('treats disabled undefined as disabled false', () => { onChange={onChange} onSubmit={onSubmit} secureTextEntry={false} - disabled={undefined} + disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -9669,7 +9675,8 @@ test('treats disabled undefined as disabled false', () => { color: '#FFEE00', paddingVertical: 12, fontFamily: 'Example Font Family', - fontSize: 37 + fontSize: 37, + textAlign: 'center' }, value: 'GGGGGG', multiline: false, @@ -9700,7 +9707,7 @@ test('treats disabled undefined as disabled false', () => { expect(onSubmit).not.toHaveBeenCalled() }) -test('renders as expected when middle-aligned', () => { +test('renders as expected when right-aligned', () => { interface ExampleContext { readonly character: string readonly regex: RegExp @@ -9788,8 +9795,7 @@ test('renders as expected when middle-aligned', () => { 'numeric', 'sentences', false, - false, - 'middle' + 'right' ) const onChange = jest.fn() const onSubmit = jest.fn() @@ -9801,6 +9807,7 @@ test('renders as expected when middle-aligned', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={false} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -9838,7 +9845,7 @@ test('renders as expected when middle-aligned', () => { paddingVertical: 12, fontFamily: 'Example Font Family', fontSize: 37, - textAlign: 'center' + textAlign: 'right' }, value: 'GGGGGG', multiline: false, @@ -9869,7 +9876,7 @@ test('renders as expected when middle-aligned', () => { expect(onSubmit).not.toHaveBeenCalled() }) -test('renders as expected when right-aligned', () => { +test('handles a change from auto focus to non-auto focus to auto focus', () => { interface ExampleContext { readonly character: string readonly regex: RegExp @@ -9957,8 +9964,7 @@ test('renders as expected when right-aligned', () => { 'numeric', 'sentences', false, - false, - 'right' + 'left' ) const onChange = jest.fn() const onSubmit = jest.fn() @@ -9970,6 +9976,7 @@ test('renders as expected when right-aligned', () => { onSubmit={onSubmit} secureTextEntry={false} disabled={false} + autoFocus={true} placeholder="Test Placeholder" leftIcon={null} rightIcon={null} @@ -9978,60 +9985,67 @@ test('renders as expected when right-aligned', () => { character: 'G' }} /> - ) + ); - expect(renderer.toTree()?.rendered).toEqual( - expect.objectContaining({ - nodeType: 'component', - type: View, - props: expect.objectContaining({ - style: { - backgroundColor: '#32AE12', - flexDirection: 'row', - alignItems: 'center', - paddingHorizontal: 29, - borderWidth: 4, - borderColor: '#FF00FF', - borderRadius: 5 - } - }), - rendered: expect.objectContaining({ - rendered: [ - expect.objectContaining({ - nodeType: 'component', - type: TextInput, - props: { - style: { - flexGrow: 1, - color: '#FFEE00', - paddingVertical: 12, - fontFamily: 'Example Font Family', - fontSize: 37, - textAlign: 'right' - }, - value: 'GGGGGG', - multiline: false, - scrollEnabled: false, - autoComplete: 'email', - secureTextEntry: false, - keyboardType: 'numeric', - autoCapitalize: 'sentences', - editable: true, - placeholder: 'Test Placeholder', - placeholderTextColor: '#E7AA32', - onChangeText: expect.any(Function), - onEndEditing: expect.any(Function), - onFocus: expect.any(Function), - onBlur: expect.any(Function), - blurOnSubmit: true, - onSubmitEditing: expect.any(Function) - } - }) - ] - }) - }) + ( + ( + (renderer.toTree()?.rendered as TestRenderer.ReactTestRendererTree) + .rendered as TestRenderer.ReactTestRendererTree + ).rendered as readonly TestRenderer.ReactTestRendererTree[] + )[0]?.props['onLayout']() + + renderer.update( + ) + renderer.update( + + ); + + ( + ( + (renderer.toTree()?.rendered as TestRenderer.ReactTestRendererTree) + .rendered as TestRenderer.ReactTestRendererTree + ).rendered as readonly TestRenderer.ReactTestRendererTree[] + )[0]?.props['onLayout']() + + expect( + ( + ( + (renderer.toTree()?.rendered as TestRenderer.ReactTestRendererTree) + .rendered as TestRenderer.ReactTestRendererTree + ).rendered as readonly TestRenderer.ReactTestRendererTree[] + )[0]?.instance.focus + ).toHaveBeenCalledTimes(2) + renderer.unmount() expect(onChange).not.toHaveBeenCalled() diff --git a/react-native/components/createNullableEmailInputComponent/index.tsx b/react-native/components/createNullableEmailInputComponent/index.tsx index 10d2e9cf..36f695b3 100644 --- a/react-native/components/createNullableEmailInputComponent/index.tsx +++ b/react-native/components/createNullableEmailInputComponent/index.tsx @@ -58,17 +58,17 @@ export const createNullableEmailInputComponent = ( 'email-address', 'none', false, - false, 'left' ) - const NullableEmailInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, unique }) => ( + const NullableEmailInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, unique, autoFocus }) => ( { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -106,7 +107,6 @@ test('renders as expected without bounds', () => { multiLine: false, autoComplete: 'email', keyboardType: 'email-address', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -117,6 +117,7 @@ test('renders as expected without bounds', () => { value: 'Example String', onChange, disabled: true, + autoFocus: false, placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, @@ -291,6 +292,7 @@ test('renders as expected with a minimum length', () => { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -302,7 +304,6 @@ test('renders as expected with a minimum length', () => { multiLine: false, autoComplete: 'email', keyboardType: 'email-address', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -313,6 +314,7 @@ test('renders as expected with a minimum length', () => { value: 'Example String', onChange, disabled: true, + autoFocus: false, placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, @@ -521,6 +523,7 @@ test('renders as expected with a maximum length', () => { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -532,7 +535,6 @@ test('renders as expected with a maximum length', () => { multiLine: false, autoComplete: 'email', keyboardType: 'email-address', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -543,6 +545,7 @@ test('renders as expected with a maximum length', () => { value: 'Example String', onChange, disabled: true, + autoFocus: false, placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, @@ -661,3 +664,200 @@ test('renders as expected with a maximum length', () => { expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with auto focus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createNullableEmailInputComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: false, + autoComplete: 'email', + keyboardType: 'email-address', + keepFocusOnSubmit: false + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 'Example String', + onChange, + disabled: true, + autoFocus: true, + placeholder: 'Example Placeholder', + context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], + secureTextEntry: false, + onSubmit: expect.any(Function) + }) + + expect(rendered.type.inputComponent.stringify(null)).toEqual('') + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t EXAmple@St \t \r \n r.ing \n \r \t' + ) + ).toEqual('example@str.ing') + + expect( + rendered.type.inputComponent.tryParse('', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toBeNull() + expect( + rendered.type.inputComponent.tryParse(' \n \r \t ', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toBeNull() + expect( + rendered.type.inputComponent.tryParse('', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + '', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toBeNull() + expect( + rendered.type.inputComponent.tryParse(' \n \r \t ', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + '', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toBeNull() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t uniq@U.e \t \r \n B \n \r \t', + [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ] + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse('Example Non-Email', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse('Example@Str.ing', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toEqual('example@str.ing') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Exam@ple \t \r \n Str.ing \n \r \t', + [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ] + ) + ).toEqual('exam@plestr.ing') + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createNullableFloatInputComponent/index.tsx b/react-native/components/createNullableFloatInputComponent/index.tsx index 39675854..4b94677b 100644 --- a/react-native/components/createNullableFloatInputComponent/index.tsx +++ b/react-native/components/createNullableFloatInputComponent/index.tsx @@ -88,17 +88,17 @@ export const createNullableFloatInputComponent = ( 'numeric', 'none', false, - false, alignment ) - const NullableFloatInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder }) => ( + const NullableFloatInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, autoFocus }) => ( { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -109,7 +110,6 @@ test('renders as expected without bounds', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -124,7 +124,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -311,6 +312,7 @@ test('renders as expected with an inclusive lower bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -322,7 +324,6 @@ test('renders as expected with an inclusive lower bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -337,7 +338,8 @@ test('renders as expected with an inclusive lower bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -526,6 +528,7 @@ test('renders as expected with an exclusive lower bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -537,7 +540,6 @@ test('renders as expected with an exclusive lower bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -552,7 +554,8 @@ test('renders as expected with an exclusive lower bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -741,6 +744,7 @@ test('renders as expected with an inclusive upper bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -752,7 +756,6 @@ test('renders as expected with an inclusive upper bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -767,7 +770,8 @@ test('renders as expected with an inclusive upper bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -956,6 +960,7 @@ test('renders as expected with an exclusive upper bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -967,7 +972,6 @@ test('renders as expected with an exclusive upper bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -982,7 +986,8 @@ test('renders as expected with an exclusive upper bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -1171,6 +1176,7 @@ test('renders as expected without bounds', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -1182,7 +1188,6 @@ test('renders as expected without bounds', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -1197,7 +1202,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -1297,3 +1303,217 @@ test('renders as expected without bounds', () => { expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with autofocus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createNullableFloatInputComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null, + null, + null, + 'left', + null + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: false, + autoComplete: 'off', + keyboardType: 'numeric', + keepFocusOnSubmit: false, + alignment: 'left' + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 124, + onChange, + disabled: true, + placeholder: 'Example Placeholder', + context: null, + secureTextEntry: false, + onSubmit: expect.any(Function), + autoFocus: true + }) + + expect(rendered.type.inputComponent.stringify(null)).toEqual('') + expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') + expect(rendered.type.inputComponent.stringify(12.34)).toEqual('12.34') + expect(rendered.type.inputComponent.stringify(1234)).toEqual('1234') + expect(rendered.type.inputComponent.stringify(-0.1234)).toEqual('-0.1234') + expect(rendered.type.inputComponent.stringify(-12.34)).toEqual('-12.34') + expect(rendered.type.inputComponent.stringify(-1234)).toEqual('-1234') + + expect(rendered.type.inputComponent.tryParse('')).toBeNull() + expect(rendered.type.inputComponent.tryParse(' \n \r \t ')).toBeNull() + expect(rendered.type.inputComponent.tryParse('1e1')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-1e1')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('NaN')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-NaN')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('Infinity')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-Infinity')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('.1234')).toEqual(0.1234) + expect(rendered.type.inputComponent.tryParse('+.1234')).toEqual(0.1234) + expect(rendered.type.inputComponent.tryParse('-.1234')).toEqual(-0.1234) + expect(rendered.type.inputComponent.tryParse('12.34')).toEqual(12.34) + expect(rendered.type.inputComponent.tryParse('+12.34')).toEqual(12.34) + expect(rendered.type.inputComponent.tryParse('-12.34')).toEqual(-12.34) + expect(rendered.type.inputComponent.tryParse('1234')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('+1234')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('-1234')).toEqual(-1234) + expect(rendered.type.inputComponent.tryParse('1234.')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('+1234.')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('-1234.')).toEqual(-1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t .1234 \t \n \r ' + ) + ).toEqual(0.1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +.1234 \t \n \r ' + ) + ).toEqual(0.1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -.1234 \t \n \r ' + ) + ).toEqual(-0.1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t 12.34 \t \n \r ' + ) + ).toEqual(12.34) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +12.34 \t \n \r ' + ) + ).toEqual(12.34) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -12.34 \t \n \r ' + ) + ).toEqual(-12.34) + expect( + rendered.type.inputComponent.tryParse(' \n \r \t 1234 \t \n \r ') + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +1234 \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -1234 \t \n \r ' + ) + ).toEqual(-1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t 1234. \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +1234. \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -1234. \t \n \r ' + ) + ).toEqual(-1234) + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createNullableIntegerInputComponent/index.tsx b/react-native/components/createNullableIntegerInputComponent/index.tsx index bc44de6e..ef1d9ef4 100644 --- a/react-native/components/createNullableIntegerInputComponent/index.tsx +++ b/react-native/components/createNullableIntegerInputComponent/index.tsx @@ -66,11 +66,10 @@ export const createNullableIntegerInputComponent = ( 'numeric', 'none', false, - false, alignment ) - const NullableIntegerInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder }) => ( + const NullableIntegerInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, autoFocus }) => ( { /* No-op. */ }} + autoFocus={autoFocus} /> ) diff --git a/react-native/components/createNullableIntegerInputComponent/unit.tsx b/react-native/components/createNullableIntegerInputComponent/unit.tsx index be3262c8..99adaff6 100644 --- a/react-native/components/createNullableIntegerInputComponent/unit.tsx +++ b/react-native/components/createNullableIntegerInputComponent/unit.tsx @@ -97,6 +97,7 @@ test('renders as expected without bounds', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -108,7 +109,6 @@ test('renders as expected without bounds', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -123,7 +123,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -309,6 +310,7 @@ test('renders as expected with an inclusive lower bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -320,7 +322,6 @@ test('renders as expected with an inclusive lower bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -335,7 +336,8 @@ test('renders as expected with an inclusive lower bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -523,6 +525,7 @@ test('renders as expected with an exclusive lower bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -534,7 +537,6 @@ test('renders as expected with an exclusive lower bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -549,7 +551,8 @@ test('renders as expected with an exclusive lower bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -737,6 +740,7 @@ test('renders as expected with an inclusive upper bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -748,7 +752,6 @@ test('renders as expected with an inclusive upper bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -763,7 +766,8 @@ test('renders as expected with an inclusive upper bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -951,6 +955,7 @@ test('renders as expected with an exclusive upper bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -962,7 +967,6 @@ test('renders as expected with an exclusive upper bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -977,7 +981,8 @@ test('renders as expected with an exclusive upper bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -1073,3 +1078,216 @@ test('renders as expected with an exclusive upper bound', () => { expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with auto focus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createNullableIntegerInputComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null, + null, + null, + 'left' + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: false, + autoComplete: 'off', + keyboardType: 'numeric', + keepFocusOnSubmit: false, + alignment: 'left' + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 124, + onChange, + disabled: true, + placeholder: 'Example Placeholder', + context: null, + secureTextEntry: false, + onSubmit: expect.any(Function), + autoFocus: true + }) + + expect(rendered.type.inputComponent.stringify(null)).toEqual('') + expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') + expect(rendered.type.inputComponent.stringify(12.34)).toEqual('12.34') + expect(rendered.type.inputComponent.stringify(1234)).toEqual('1234') + expect(rendered.type.inputComponent.stringify(-0.1234)).toEqual('-0.1234') + expect(rendered.type.inputComponent.stringify(-12.34)).toEqual('-12.34') + expect(rendered.type.inputComponent.stringify(-1234)).toEqual('-1234') + + expect(rendered.type.inputComponent.tryParse('')).toBeNull() + expect(rendered.type.inputComponent.tryParse(' \n \r \t ')).toBeNull() + expect(rendered.type.inputComponent.tryParse('1e1')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-1e1')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('NaN')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-NaN')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('Infinity')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-Infinity')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('.1234')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('+.1234')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-.1234')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('12.34')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('+12.34')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-12.34')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('1234')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('+1234')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('-1234')).toEqual(-1234) + expect(rendered.type.inputComponent.tryParse('1234.')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('+1234.')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('-1234.')).toEqual(-1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t .1234 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +.1234 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -.1234 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t 12.34 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +12.34 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -12.34 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse(' \n \r \t 1234 \t \n \r ') + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +1234 \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -1234 \t \n \r ' + ) + ).toEqual(-1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t 1234. \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +1234. \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -1234. \t \n \r ' + ) + ).toEqual(-1234) + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createNullablePasswordInputComponent/index.tsx b/react-native/components/createNullablePasswordInputComponent/index.tsx index 74aee5aa..135cada9 100644 --- a/react-native/components/createNullablePasswordInputComponent/index.tsx +++ b/react-native/components/createNullablePasswordInputComponent/index.tsx @@ -45,11 +45,10 @@ export const createNullablePasswordInputComponent = ( 'default', 'sentences', false, - false, 'left' ) - const NullablePasswordInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, match }) => ( + const NullablePasswordInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, match, autoFocus }) => ( { /* No-op. */ }} + autoFocus={autoFocus} /> ) diff --git a/react-native/components/createNullablePasswordInputComponent/unit.tsx b/react-native/components/createNullablePasswordInputComponent/unit.tsx index ca4b408c..8a898ffd 100644 --- a/react-native/components/createNullablePasswordInputComponent/unit.tsx +++ b/react-native/components/createNullablePasswordInputComponent/unit.tsx @@ -95,6 +95,7 @@ test('renders as expected without bounds', () => { disabled placeholder="Example Placeholder" match="Example Match" + autoFocus={false} /> ) @@ -106,7 +107,6 @@ test('renders as expected without bounds', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -120,7 +120,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: 'Example Match', secureTextEntry: true, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -236,6 +237,7 @@ test('renders as expected with a minimum length', () => { disabled placeholder="Example Placeholder" match="Example Match" + autoFocus={false} /> ) @@ -247,7 +249,6 @@ test('renders as expected with a minimum length', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -261,7 +262,8 @@ test('renders as expected with a minimum length', () => { placeholder: 'Example Placeholder', context: 'Example Match', secureTextEntry: true, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -379,6 +381,7 @@ test('renders as expected with a maximum length', () => { disabled placeholder="Example Placeholder" match="Example Match" + autoFocus={false} /> ) @@ -390,7 +393,6 @@ test('renders as expected with a maximum length', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -404,7 +406,8 @@ test('renders as expected with a maximum length', () => { placeholder: 'Example Placeholder', context: 'Example Match', secureTextEntry: true, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -436,3 +439,145 @@ test('renders as expected with a maximum length', () => { expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with auto focus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createNullablePasswordInputComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: false, + autoComplete: 'off', + keyboardType: 'default', + keepFocusOnSubmit: false + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 'Example String', + onChange, + disabled: true, + placeholder: 'Example Placeholder', + context: 'Example Match', + secureTextEntry: true, + onSubmit: expect.any(Function), + autoFocus: true + }) + + expect(rendered.type.inputComponent.stringify(null)).toEqual('') + expect(rendered.type.inputComponent.stringify('Example String')).toEqual( + 'Example String' + ) + + expect(rendered.type.inputComponent.tryParse('', null)).toBeNull() + expect(rendered.type.inputComponent.tryParse('Example String', null)).toEqual( + 'Example String' + ) + expect( + rendered.type.inputComponent.tryParse('', 'Example Match') + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse('Example Match', 'Example Match') + ).toEqual('Example Match') + expect( + rendered.type.inputComponent.tryParse('Example Non-Match', 'Example Match') + ).toBeUndefined() + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createNullableTextAreaComponent/index.tsx b/react-native/components/createNullableTextAreaComponent/index.tsx index 7c860770..0973f51e 100644 --- a/react-native/components/createNullableTextAreaComponent/index.tsx +++ b/react-native/components/createNullableTextAreaComponent/index.tsx @@ -56,12 +56,11 @@ export const createNullableTextAreaComponent = ( 'off', 'default', 'sentences', - false, true, 'left' ) - const NullableTextArea: React.FunctionComponent = ({ value, onChange, disabled, placeholder }) => ( + const NullableTextArea: React.FunctionComponent = ({ value, onChange, disabled, placeholder, autoFocus }) => ( { /* No-op. */ }} + autoFocus={autoFocus} /> ) diff --git a/react-native/components/createNullableTextAreaComponent/unit.tsx b/react-native/components/createNullableTextAreaComponent/unit.tsx index 67cfa3fe..b6e3ee77 100644 --- a/react-native/components/createNullableTextAreaComponent/unit.tsx +++ b/react-native/components/createNullableTextAreaComponent/unit.tsx @@ -94,6 +94,7 @@ test('renders as expected without bounds', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -105,7 +106,6 @@ test('renders as expected without bounds', () => { multiLine: true, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: true } }) @@ -119,7 +119,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -308,6 +309,7 @@ test('renders as expected with a minimum length', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -319,7 +321,6 @@ test('renders as expected with a minimum length', () => { multiLine: true, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: true } }) @@ -333,7 +334,8 @@ test('renders as expected with a minimum length', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -468,6 +470,7 @@ test('renders as expected with a maximum length', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -479,7 +482,6 @@ test('renders as expected with a maximum length', () => { multiLine: true, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: true } }) @@ -493,7 +495,8 @@ test('renders as expected with a maximum length', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -539,3 +542,218 @@ test('renders as expected with a maximum length', () => { expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with auto focus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createNullableTextAreaComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: true, + autoComplete: 'off', + keyboardType: 'default', + keepFocusOnSubmit: true + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 'Example String', + onChange, + disabled: true, + placeholder: 'Example Placeholder', + context: null, + secureTextEntry: false, + onSubmit: expect.any(Function), + autoFocus: true + }) + + expect(rendered.type.inputComponent.stringify(null)).toEqual('') + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \t \r \n String \n \r \t' + ) + ).toEqual('Example\n\nString') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \t \t \t \t String \n \r \t' + ) + ).toEqual('Example \t \t \t \t String') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \r\n String \n \r \t' + ) + ).toEqual('Example\nString') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \r \n String \n \r \t' + ) + ).toEqual('Example\n\nString') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \n\n String \n \r \t' + ) + ).toEqual('Example\n\nString') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \n\n\n String \n \r \t' + ) + ).toEqual('Example\n\nString') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \n \n \n String \n \r \t' + ) + ).toEqual('Example\n\nString') + + expect(rendered.type.inputComponent.tryParse('', null)).toBeNull() + expect(rendered.type.inputComponent.tryParse(' \n \r \t ', null)).toBeNull() + expect(rendered.type.inputComponent.tryParse('', null)).toBeNull() + expect(rendered.type.inputComponent.tryParse(' \n \r \t ', null)).toBeNull() + expect(rendered.type.inputComponent.tryParse('Example String', null)).toEqual( + 'Example String' + ) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \t \r \n String \n \r \t', + null + ) + ).toEqual('Example\n\nString') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \t \t \t \t String \n \r \t', + null + ) + ).toEqual('Example \t \t \t \t String') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \r\n String \n \r \t', + null + ) + ).toEqual('Example\nString') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \r \n String \n \r \t', + null + ) + ).toEqual('Example\n\nString') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \n\n String \n \r \t', + null + ) + ).toEqual('Example\n\nString') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \n\n\n String \n \r \t', + null + ) + ).toEqual('Example\n\nString') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \n \n \n String \n \r \t', + null + ) + ).toEqual('Example\n\nString') + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createNullableTextInputComponent/index.tsx b/react-native/components/createNullableTextInputComponent/index.tsx index ac609925..6ade658f 100644 --- a/react-native/components/createNullableTextInputComponent/index.tsx +++ b/react-native/components/createNullableTextInputComponent/index.tsx @@ -55,11 +55,10 @@ export const createNullableTextInputComponent = ( 'default', 'sentences', false, - false, 'left' ) - const NullableTextInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, unique }) => ( + const NullableTextInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, unique, autoFocus }) => ( { /* No-op. */ }} + autoFocus={autoFocus} /> ) diff --git a/react-native/components/createNullableTextInputComponent/unit.tsx b/react-native/components/createNullableTextInputComponent/unit.tsx index 118413d2..d89c80f0 100644 --- a/react-native/components/createNullableTextInputComponent/unit.tsx +++ b/react-native/components/createNullableTextInputComponent/unit.tsx @@ -95,6 +95,7 @@ test('renders as expected without bounds', () => { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -106,7 +107,6 @@ test('renders as expected without bounds', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -120,7 +120,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -284,6 +285,7 @@ test('renders as expected with a minimum length', () => { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -295,7 +297,6 @@ test('renders as expected with a minimum length', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -309,7 +310,8 @@ test('renders as expected with a minimum length', () => { placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -507,6 +509,7 @@ test('renders as expected with a maximum length', () => { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -518,7 +521,6 @@ test('renders as expected with a maximum length', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -532,7 +534,8 @@ test('renders as expected with a maximum length', () => { placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(null)).toEqual('') @@ -730,6 +733,7 @@ test('passes down an empty array when unique is undefined', () => { disabled placeholder="Example Placeholder" unique={undefined} + autoFocus={false} /> ) @@ -742,7 +746,8 @@ test('passes down an empty array when unique is undefined', () => { placeholder: 'Example Placeholder', context: [], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(onChange).not.toHaveBeenCalled() @@ -836,6 +841,7 @@ test('passes down an empty array when unique is not given', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -848,8 +854,199 @@ test('passes down an empty array when unique is not given', () => { placeholder: 'Example Placeholder', context: [], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with auto focus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createNullableTextInputComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: false, + autoComplete: 'off', + keyboardType: 'default', + keepFocusOnSubmit: false + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 'Example String', + onChange, + disabled: true, + placeholder: 'Example Placeholder', + context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], + secureTextEntry: false, + onSubmit: expect.any(Function), + autoFocus: true + }) + + expect(rendered.type.inputComponent.stringify(null)).toEqual('') + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \t \r \n String \n \r \t' + ) + ).toEqual('Example String') + + expect( + rendered.type.inputComponent.tryParse('', [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ]) + ).toBeNull() + expect( + rendered.type.inputComponent.tryParse(' \n \r \t ', [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ]) + ).toBeNull() + expect( + rendered.type.inputComponent.tryParse('', [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + '', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ]) + ).toBeNull() + expect( + rendered.type.inputComponent.tryParse(' \n \r \t ', [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + '', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ]) + ).toBeNull() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Unique \t \r \n B \n \r \t', + [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ] + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse('Example String', [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ]) + ).toEqual('Example String') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \t \r \n String \n \r \t', + [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ] + ) + ).toEqual('Example String') + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createOfflineTableComponent/index.tsx b/react-native/components/createOfflineTableComponent/index.tsx index b9c02258..bd7cbde7 100644 --- a/react-native/components/createOfflineTableComponent/index.tsx +++ b/react-native/components/createOfflineTableComponent/index.tsx @@ -396,6 +396,7 @@ export const createOfflineTableComponent = < : 'ascending' ) }} + disabled={false} > { onPressRow(row) }} + disabled={false} > {cells} diff --git a/react-native/components/createOfflineTableComponent/unit.tsx b/react-native/components/createOfflineTableComponent/unit.tsx index 5c4b6348..8ef217ae 100644 --- a/react-native/components/createOfflineTableComponent/unit.tsx +++ b/react-native/components/createOfflineTableComponent/unit.tsx @@ -187,6 +187,7 @@ test('renders as expected', () => { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 27 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 64 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 27 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 64 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 27 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 64 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 27 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 64 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 44 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 22 }} onPress={expect.any(Function)} + disabled={false} > { flexGrow: 33 }} onPress={expect.any(Function)} + disabled={false} > { width: '100%' }} onPress={expect.any(Function)} + disabled={false} > {[ { width: '100%' }} onPress={expect.any(Function)} + disabled={false} > {[ { width: '100%' }} onPress={expect.any(Function)} + disabled={false} > {[ { width: '100%' }} onPress={expect.any(Function)} + disabled={false} > {[ { - disabled = disabled ?? false - const children: JSX.Element[] = [] if (leftIcon !== undefined) { diff --git a/react-native/components/createPickerButtonComponent/readme.md b/react-native/components/createPickerButtonComponent/readme.md index e65bdf5a..aa049f53 100644 --- a/react-native/components/createPickerButtonComponent/readme.md +++ b/react-native/components/createPickerButtonComponent/readme.md @@ -84,10 +84,11 @@ const ExamplePickerButton = createPickerButtonComponent( ); const ExampleScreen = () => ( - { alert(`Pressed.`); }} diff --git a/react-native/components/createPickerButtonComponent/unit.tsx b/react-native/components/createPickerButtonComponent/unit.tsx index 51a1cf14..3fedc94b 100644 --- a/react-native/components/createPickerButtonComponent/unit.tsx +++ b/react-native/components/createPickerButtonComponent/unit.tsx @@ -3594,268 +3594,3 @@ test('allows introspection when used in a higher-order component', () => { } }) }) - -test('treats disabled missing as disabled false', () => { - const Component = createPickerButtonComponent({ - fontFamily: 'Example Font Family', - fontSize: 37, - paddingVertical: 12, - paddingHorizontal: 29, - blurredValid: { - textColor: '#FFEE00', - placeholderColor: '#E7AA32', - backgroundColor: '#32AE12', - radius: 5, - border: { - width: 4, - color: '#FF00FF' - }, - iconColor: '#43AE21' - }, - blurredInvalid: { - textColor: '#99FE88', - placeholderColor: '#CACA3A', - backgroundColor: '#259284', - radius: 10, - border: { - width: 6, - color: '#9A9A8E' - }, - iconColor: '#985E00' - }, - focusedValid: { - textColor: '#55EA13', - placeholderColor: '#273346', - backgroundColor: '#CABA99', - radius: 3, - border: { - width: 5, - color: '#646464' - }, - iconColor: '#789521' - }, - focusedInvalid: { - textColor: '#ABAADE', - placeholderColor: '#47ADAD', - backgroundColor: '#32AA88', - radius: 47, - border: { - width: 12, - color: '#98ADAA' - }, - iconColor: '#449438' - }, - disabledValid: { - textColor: '#AE2195', - placeholderColor: '#FFAAEE', - backgroundColor: '#772728', - radius: 100, - border: { - width: 14, - color: '#5E5E5E' - }, - iconColor: '#ADAADA' - }, - disabledInvalid: { - textColor: '#340297', - placeholderColor: '#233832', - backgroundColor: '#938837', - radius: 2, - border: { - width: 19, - color: '#573829' - }, - iconColor: '#709709' - } - }) - const onPress = jest.fn() - const onMeasure = jest.fn() - - const renderer = TestRenderer.create( - - ) - - expect(renderer.toTree()?.rendered).toEqual( - expect.objectContaining({ - nodeType: 'component', - type: Hitbox, - props: { - style: { - backgroundColor: '#32AE12', - flexDirection: 'row', - alignItems: 'center', - paddingHorizontal: 29, - borderWidth: 4, - borderColor: '#FF00FF', - borderRadius: 5 - }, - onPress, - onMeasure, - disabled: false, - children: [ - expect.objectContaining({ - type: TextInput, - props: { - style: { - flexGrow: 1, - color: '#FFEE00', - paddingVertical: 12, - fontFamily: 'Example Font Family', - fontSize: 37 - }, - value: 'Example Label', - editable: false, - placeholder: 'Test Placeholder', - placeholderTextColor: '#E7AA32', - pointerEvents: 'none' - } - }) - ] - } - }) - ) - - renderer.unmount() - - expect(onPress).not.toHaveBeenCalled() - expect(onMeasure).not.toHaveBeenCalled() -}) - -test('treats disabled undefined as disabled false', () => { - const Component = createPickerButtonComponent({ - fontFamily: 'Example Font Family', - fontSize: 37, - paddingVertical: 12, - paddingHorizontal: 29, - blurredValid: { - textColor: '#FFEE00', - placeholderColor: '#E7AA32', - backgroundColor: '#32AE12', - radius: 5, - border: { - width: 4, - color: '#FF00FF' - }, - iconColor: '#43AE21' - }, - blurredInvalid: { - textColor: '#99FE88', - placeholderColor: '#CACA3A', - backgroundColor: '#259284', - radius: 10, - border: { - width: 6, - color: '#9A9A8E' - }, - iconColor: '#985E00' - }, - focusedValid: { - textColor: '#55EA13', - placeholderColor: '#273346', - backgroundColor: '#CABA99', - radius: 3, - border: { - width: 5, - color: '#646464' - }, - iconColor: '#789521' - }, - focusedInvalid: { - textColor: '#ABAADE', - placeholderColor: '#47ADAD', - backgroundColor: '#32AA88', - radius: 47, - border: { - width: 12, - color: '#98ADAA' - }, - iconColor: '#449438' - }, - disabledValid: { - textColor: '#AE2195', - placeholderColor: '#FFAAEE', - backgroundColor: '#772728', - radius: 100, - border: { - width: 14, - color: '#5E5E5E' - }, - iconColor: '#ADAADA' - }, - disabledInvalid: { - textColor: '#340297', - placeholderColor: '#233832', - backgroundColor: '#938837', - radius: 2, - border: { - width: 19, - color: '#573829' - }, - iconColor: '#709709' - } - }) - const onPress = jest.fn() - const onMeasure = jest.fn() - - const renderer = TestRenderer.create( - - ) - - expect(renderer.toTree()?.rendered).toEqual( - expect.objectContaining({ - nodeType: 'component', - type: Hitbox, - props: { - style: { - backgroundColor: '#32AE12', - flexDirection: 'row', - alignItems: 'center', - paddingHorizontal: 29, - borderWidth: 4, - borderColor: '#FF00FF', - borderRadius: 5 - }, - onPress, - onMeasure, - disabled: false, - children: [ - expect.objectContaining({ - type: TextInput, - props: { - style: { - flexGrow: 1, - color: '#FFEE00', - paddingVertical: 12, - fontFamily: 'Example Font Family', - fontSize: 37 - }, - value: 'Example Label', - editable: false, - placeholder: 'Test Placeholder', - placeholderTextColor: '#E7AA32', - pointerEvents: 'none' - } - }) - ] - } - }) - ) - - renderer.unmount() - - expect(onPress).not.toHaveBeenCalled() - expect(onMeasure).not.toHaveBeenCalled() -}) diff --git a/react-native/components/createRequiredEmailInputComponent/index.tsx b/react-native/components/createRequiredEmailInputComponent/index.tsx index 11e18fa7..b75700b8 100644 --- a/react-native/components/createRequiredEmailInputComponent/index.tsx +++ b/react-native/components/createRequiredEmailInputComponent/index.tsx @@ -58,11 +58,10 @@ export const createRequiredEmailInputComponent = ( 'email-address', 'none', false, - false, 'left' ) - const RequiredEmailInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, unique }) => ( + const RequiredEmailInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, unique, autoFocus }) => ( { /* No-op. */ }} + autoFocus={autoFocus} /> ) diff --git a/react-native/components/createRequiredEmailInputComponent/unit.tsx b/react-native/components/createRequiredEmailInputComponent/unit.tsx index e50eada1..fa99d1aa 100644 --- a/react-native/components/createRequiredEmailInputComponent/unit.tsx +++ b/react-native/components/createRequiredEmailInputComponent/unit.tsx @@ -95,6 +95,7 @@ test('renders as expected without bounds', () => { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -106,7 +107,6 @@ test('renders as expected without bounds', () => { multiLine: false, autoComplete: 'email', keyboardType: 'email-address', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -120,7 +120,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect( @@ -290,6 +291,7 @@ test('renders as expected with a minimum length', () => { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -301,7 +303,6 @@ test('renders as expected with a minimum length', () => { multiLine: false, autoComplete: 'email', keyboardType: 'email-address', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -315,7 +316,8 @@ test('renders as expected with a minimum length', () => { placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect( @@ -519,6 +521,7 @@ test('renders as expected with a maximum length', () => { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -530,7 +533,6 @@ test('renders as expected with a maximum length', () => { multiLine: false, autoComplete: 'email', keyboardType: 'email-address', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -544,7 +546,8 @@ test('renders as expected with a maximum length', () => { placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect( @@ -658,3 +661,199 @@ test('renders as expected with a maximum length', () => { expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with auto focus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createRequiredEmailInputComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: false, + autoComplete: 'email', + keyboardType: 'email-address', + keepFocusOnSubmit: false + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 'Example String', + onChange, + disabled: true, + placeholder: 'Example Placeholder', + context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], + secureTextEntry: false, + onSubmit: expect.any(Function), + autoFocus: true + }) + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t EXAmple@St \t \r \n r.ing \n \r \t' + ) + ).toEqual('example@str.ing') + + expect( + rendered.type.inputComponent.tryParse('', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse(' \n \r \t ', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse('', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + '', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse(' \n \r \t ', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + '', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t uniq@U.e \t \r \n B \n \r \t', + [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ] + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse('Example Non-Email', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse('Example@Str.ing', [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ]) + ).toEqual('example@str.ing') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Exam@ple \t \r \n Str.ing \n \r \t', + [ + ' \t \r \n Uniq@u.e \t \t \n A \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n B \n \r \t ', + ' \t \r \n Uniq@u.e \t \t \n C \n \r \t ' + ] + ) + ).toEqual('exam@plestr.ing') + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createRequiredFloatInputComponent/index.tsx b/react-native/components/createRequiredFloatInputComponent/index.tsx index efd1b8b2..58d3932c 100644 --- a/react-native/components/createRequiredFloatInputComponent/index.tsx +++ b/react-native/components/createRequiredFloatInputComponent/index.tsx @@ -82,11 +82,10 @@ export const createRequiredFloatInputComponent = ( 'numeric', 'none', false, - false, alignment ) - const RequiredFloatInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder }) => ( + const RequiredFloatInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, autoFocus }) => ( { /* No-op. */ }} + autoFocus={autoFocus} /> ) diff --git a/react-native/components/createRequiredFloatInputComponent/unit.tsx b/react-native/components/createRequiredFloatInputComponent/unit.tsx index fd973de2..65a7af35 100644 --- a/react-native/components/createRequiredFloatInputComponent/unit.tsx +++ b/react-native/components/createRequiredFloatInputComponent/unit.tsx @@ -97,6 +97,7 @@ test('renders as expected without bounds', () => { value={124} onChange={onChange} disabled + autoFocus={false} placeholder="Example Placeholder" /> ) @@ -109,7 +110,6 @@ test('renders as expected without bounds', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -124,7 +124,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') @@ -309,6 +310,7 @@ test('renders as expected with an inclusive lower bound', () => { value={124} onChange={onChange} disabled + autoFocus={false} placeholder="Example Placeholder" /> ) @@ -321,7 +323,6 @@ test('renders as expected with an inclusive lower bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -336,7 +337,8 @@ test('renders as expected with an inclusive lower bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') @@ -523,6 +525,7 @@ test('renders as expected with an exclusive lower bound', () => { value={124} onChange={onChange} disabled + autoFocus={false} placeholder="Example Placeholder" /> ) @@ -535,7 +538,6 @@ test('renders as expected with an exclusive lower bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -550,7 +552,8 @@ test('renders as expected with an exclusive lower bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') @@ -737,6 +740,7 @@ test('renders as expected with an inclusive upper bound', () => { value={124} onChange={onChange} disabled + autoFocus={false} placeholder="Example Placeholder" /> ) @@ -749,7 +753,6 @@ test('renders as expected with an inclusive upper bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -764,7 +767,8 @@ test('renders as expected with an inclusive upper bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') @@ -951,6 +955,7 @@ test('renders as expected with an exclusive upper bound', () => { value={124} onChange={onChange} disabled + autoFocus={false} placeholder="Example Placeholder" /> ) @@ -963,7 +968,6 @@ test('renders as expected with an exclusive upper bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -978,7 +982,8 @@ test('renders as expected with an exclusive upper bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') @@ -1165,6 +1170,7 @@ test('renders as expected with fixed decimal places', () => { value={124} onChange={onChange} disabled + autoFocus={false} placeholder="Example Placeholder" /> ) @@ -1177,7 +1183,6 @@ test('renders as expected with fixed decimal places', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -1192,7 +1197,8 @@ test('renders as expected with fixed decimal places', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.12') @@ -1291,3 +1297,216 @@ test('renders as expected with fixed decimal places', () => { expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with auto focus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createRequiredFloatInputComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null, + null, + null, + 'left', + null + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: false, + autoComplete: 'off', + keyboardType: 'numeric', + keepFocusOnSubmit: false, + alignment: 'left' + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 124, + onChange, + disabled: true, + placeholder: 'Example Placeholder', + context: null, + secureTextEntry: false, + onSubmit: expect.any(Function), + autoFocus: true + }) + + expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') + expect(rendered.type.inputComponent.stringify(12.34)).toEqual('12.34') + expect(rendered.type.inputComponent.stringify(1234)).toEqual('1234') + expect(rendered.type.inputComponent.stringify(-0.1234)).toEqual('-0.1234') + expect(rendered.type.inputComponent.stringify(-12.34)).toEqual('-12.34') + expect(rendered.type.inputComponent.stringify(-1234)).toEqual('-1234') + + expect(rendered.type.inputComponent.tryParse('')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse(' \n \r \t ')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('1e1')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-1e1')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('NaN')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-NaN')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('Infinity')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-Infinity')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('.1234')).toEqual(0.1234) + expect(rendered.type.inputComponent.tryParse('+.1234')).toEqual(0.1234) + expect(rendered.type.inputComponent.tryParse('-.1234')).toEqual(-0.1234) + expect(rendered.type.inputComponent.tryParse('12.34')).toEqual(12.34) + expect(rendered.type.inputComponent.tryParse('+12.34')).toEqual(12.34) + expect(rendered.type.inputComponent.tryParse('-12.34')).toEqual(-12.34) + expect(rendered.type.inputComponent.tryParse('1234')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('+1234')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('-1234')).toEqual(-1234) + expect(rendered.type.inputComponent.tryParse('1234.')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('+1234.')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('-1234.')).toEqual(-1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t .1234 \t \n \r ' + ) + ).toEqual(0.1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +.1234 \t \n \r ' + ) + ).toEqual(0.1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -.1234 \t \n \r ' + ) + ).toEqual(-0.1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t 12.34 \t \n \r ' + ) + ).toEqual(12.34) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +12.34 \t \n \r ' + ) + ).toEqual(12.34) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -12.34 \t \n \r ' + ) + ).toEqual(-12.34) + expect( + rendered.type.inputComponent.tryParse(' \n \r \t 1234 \t \n \r ') + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +1234 \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -1234 \t \n \r ' + ) + ).toEqual(-1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t 1234. \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +1234. \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -1234. \t \n \r ' + ) + ).toEqual(-1234) + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createRequiredIntegerInputComponent/index.tsx b/react-native/components/createRequiredIntegerInputComponent/index.tsx index 4964f977..f68cf2ad 100644 --- a/react-native/components/createRequiredIntegerInputComponent/index.tsx +++ b/react-native/components/createRequiredIntegerInputComponent/index.tsx @@ -61,11 +61,10 @@ export const createRequiredIntegerInputComponent = ( 'numeric', 'none', false, - false, alignment ) - const RequiredIntegerInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder }) => ( + const RequiredIntegerInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, autoFocus }) => ( { /* No-op. */ }} + autoFocus={autoFocus} /> ) diff --git a/react-native/components/createRequiredIntegerInputComponent/unit.tsx b/react-native/components/createRequiredIntegerInputComponent/unit.tsx index a9527dcc..87ed4b1d 100644 --- a/react-native/components/createRequiredIntegerInputComponent/unit.tsx +++ b/react-native/components/createRequiredIntegerInputComponent/unit.tsx @@ -97,6 +97,7 @@ test('renders as expected without bounds', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -108,7 +109,6 @@ test('renders as expected without bounds', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -123,7 +123,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') @@ -308,6 +309,7 @@ test('renders as expected with an inclusive lower bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -319,7 +321,6 @@ test('renders as expected with an inclusive lower bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -334,7 +335,8 @@ test('renders as expected with an inclusive lower bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') @@ -521,6 +523,7 @@ test('renders as expected with an exclusive lower bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -532,7 +535,6 @@ test('renders as expected with an exclusive lower bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -547,7 +549,8 @@ test('renders as expected with an exclusive lower bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') @@ -734,6 +737,7 @@ test('renders as expected with an inclusive upper bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -745,7 +749,6 @@ test('renders as expected with an inclusive upper bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -760,7 +763,8 @@ test('renders as expected with an inclusive upper bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') @@ -947,6 +951,7 @@ test('renders as expected with an exclusive upper bound', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -958,7 +963,6 @@ test('renders as expected with an exclusive upper bound', () => { multiLine: false, autoComplete: 'off', keyboardType: 'numeric', - autoFocus: false, keepFocusOnSubmit: false, alignment: 'left' } @@ -973,7 +977,8 @@ test('renders as expected with an exclusive upper bound', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') @@ -1068,3 +1073,215 @@ test('renders as expected with an exclusive upper bound', () => { expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with auto focus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createRequiredIntegerInputComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null, + null, + null, + 'left' + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: false, + autoComplete: 'off', + keyboardType: 'numeric', + keepFocusOnSubmit: false, + alignment: 'left' + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 124, + onChange, + disabled: true, + placeholder: 'Example Placeholder', + context: null, + secureTextEntry: false, + onSubmit: expect.any(Function), + autoFocus: true + }) + + expect(rendered.type.inputComponent.stringify(0.1234)).toEqual('0.1234') + expect(rendered.type.inputComponent.stringify(12.34)).toEqual('12.34') + expect(rendered.type.inputComponent.stringify(1234)).toEqual('1234') + expect(rendered.type.inputComponent.stringify(-0.1234)).toEqual('-0.1234') + expect(rendered.type.inputComponent.stringify(-12.34)).toEqual('-12.34') + expect(rendered.type.inputComponent.stringify(-1234)).toEqual('-1234') + + expect(rendered.type.inputComponent.tryParse('')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse(' \n \r \t ')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('1e1')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-1e1')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('NaN')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-NaN')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('Infinity')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-Infinity')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('.1234')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('+.1234')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-.1234')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('12.34')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('+12.34')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('-12.34')).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('1234')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('+1234')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('-1234')).toEqual(-1234) + expect(rendered.type.inputComponent.tryParse('1234.')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('+1234.')).toEqual(1234) + expect(rendered.type.inputComponent.tryParse('-1234.')).toEqual(-1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t .1234 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +.1234 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -.1234 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t 12.34 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +12.34 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -12.34 \t \n \r ' + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse(' \n \r \t 1234 \t \n \r ') + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +1234 \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -1234 \t \n \r ' + ) + ).toEqual(-1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t 1234. \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t +1234. \t \n \r ' + ) + ).toEqual(1234) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t -1234. \t \n \r ' + ) + ).toEqual(-1234) + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createRequiredPasswordInputComponent/index.tsx b/react-native/components/createRequiredPasswordInputComponent/index.tsx index 1e251fed..8c700a2d 100644 --- a/react-native/components/createRequiredPasswordInputComponent/index.tsx +++ b/react-native/components/createRequiredPasswordInputComponent/index.tsx @@ -45,11 +45,10 @@ export const createRequiredPasswordInputComponent = ( 'default', 'sentences', false, - false, 'left' ) - const RequiredPasswordInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, match }) => ( + const RequiredPasswordInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, match, autoFocus }) => ( { /* No-op. */ }} + autoFocus={autoFocus} /> ) diff --git a/react-native/components/createRequiredPasswordInputComponent/unit.tsx b/react-native/components/createRequiredPasswordInputComponent/unit.tsx index df88d28c..ba265ebd 100644 --- a/react-native/components/createRequiredPasswordInputComponent/unit.tsx +++ b/react-native/components/createRequiredPasswordInputComponent/unit.tsx @@ -95,6 +95,7 @@ test('renders as expected without bounds', () => { disabled placeholder="Example Placeholder" match="Example Match" + autoFocus={false} /> ) @@ -106,7 +107,6 @@ test('renders as expected without bounds', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -120,7 +120,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: 'Example Match', secureTextEntry: true, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify('Example String')).toEqual( @@ -235,6 +236,7 @@ test('renders as expected with a minimum length', () => { disabled placeholder="Example Placeholder" match="Example Match" + autoFocus={false} /> ) @@ -246,7 +248,6 @@ test('renders as expected with a minimum length', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -260,7 +261,8 @@ test('renders as expected with a minimum length', () => { placeholder: 'Example Placeholder', context: 'Example Match', secureTextEntry: true, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify('Example String')).toEqual( @@ -377,6 +379,7 @@ test('renders as expected with a maximum length', () => { disabled placeholder="Example Placeholder" match="Example Match" + autoFocus={false} /> ) @@ -388,7 +391,6 @@ test('renders as expected with a maximum length', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false } }) @@ -402,7 +404,8 @@ test('renders as expected with a maximum length', () => { placeholder: 'Example Placeholder', context: 'Example Match', secureTextEntry: true, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(rendered.type.inputComponent.stringify('Example String')).toEqual( @@ -433,3 +436,144 @@ test('renders as expected with a maximum length', () => { expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with auto focus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createRequiredPasswordInputComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: false, + autoComplete: 'off', + keyboardType: 'default', + keepFocusOnSubmit: false + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 'Example String', + onChange, + disabled: true, + placeholder: 'Example Placeholder', + context: 'Example Match', + secureTextEntry: true, + onSubmit: expect.any(Function), + autoFocus: true + }) + + expect(rendered.type.inputComponent.stringify('Example String')).toEqual( + 'Example String' + ) + + expect(rendered.type.inputComponent.tryParse('', null)).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('Example String', null)).toEqual( + 'Example String' + ) + expect( + rendered.type.inputComponent.tryParse('', 'Example Match') + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse('Example Match', 'Example Match') + ).toEqual('Example Match') + expect( + rendered.type.inputComponent.tryParse('Example Non-Match', 'Example Match') + ).toBeUndefined() + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createRequiredTextAreaComponent/index.tsx b/react-native/components/createRequiredTextAreaComponent/index.tsx index d18eaa4c..803c0aa4 100644 --- a/react-native/components/createRequiredTextAreaComponent/index.tsx +++ b/react-native/components/createRequiredTextAreaComponent/index.tsx @@ -54,12 +54,11 @@ export const createRequiredTextAreaComponent = ( 'off', 'default', 'sentences', - false, true, 'left' ) - const RequiredTextArea: React.FunctionComponent = ({ value, onChange, disabled, placeholder }) => ( + const RequiredTextArea: React.FunctionComponent = ({ value, onChange, disabled, placeholder, autoFocus }) => ( { /* No-op. */ }} + autoFocus={autoFocus} /> ) diff --git a/react-native/components/createRequiredTextAreaComponent/unit.tsx b/react-native/components/createRequiredTextAreaComponent/unit.tsx index c8d110cd..e38f20dd 100644 --- a/react-native/components/createRequiredTextAreaComponent/unit.tsx +++ b/react-native/components/createRequiredTextAreaComponent/unit.tsx @@ -94,6 +94,7 @@ test('renders as expected without bounds', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -105,7 +106,6 @@ test('renders as expected without bounds', () => { multiLine: true, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: true } }) @@ -119,7 +119,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect( @@ -311,6 +312,7 @@ test('renders as expected with a minimum length', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -322,7 +324,6 @@ test('renders as expected with a minimum length', () => { multiLine: true, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: true } }) @@ -336,7 +337,8 @@ test('renders as expected with a minimum length', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect( @@ -474,6 +476,7 @@ test('renders as expected with a maximum length', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -485,7 +488,6 @@ test('renders as expected with a maximum length', () => { multiLine: true, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: true } }) @@ -499,7 +501,8 @@ test('renders as expected with a maximum length', () => { placeholder: 'Example Placeholder', context: null, secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect( @@ -548,3 +551,221 @@ test('renders as expected with a maximum length', () => { expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with auto focus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createRequiredTextAreaComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: true, + autoComplete: 'off', + keyboardType: 'default', + keepFocusOnSubmit: true + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 'Example String', + onChange, + disabled: true, + placeholder: 'Example Placeholder', + context: null, + secureTextEntry: false, + onSubmit: expect.any(Function), + autoFocus: true + }) + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \t \r \n String \n \r \t' + ) + ).toEqual('Example\n\nString') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \t \t \t \t String \n \r \t' + ) + ).toEqual('Example \t \t \t \t String') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \r\n String \n \r \t' + ) + ).toEqual('Example\nString') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \r \n String \n \r \t' + ) + ).toEqual('Example\n\nString') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \n\n String \n \r \t' + ) + ).toEqual('Example\n\nString') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \n\n\n String \n \r \t' + ) + ).toEqual('Example\n\nString') + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \n \n \n String \n \r \t' + ) + ).toEqual('Example\n\nString') + + expect(rendered.type.inputComponent.tryParse('', null)).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse(' \n \r \t ', null) + ).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('', null)).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse(' \n \r \t ', null) + ).toBeUndefined() + expect(rendered.type.inputComponent.tryParse('Example String', null)).toEqual( + 'Example String' + ) + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \t \r \n String \n \r \t', + null + ) + ).toEqual('Example\n\nString') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \t \t \t \t String \n \r \t', + null + ) + ).toEqual('Example \t \t \t \t String') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \r\n String \n \r \t', + null + ) + ).toEqual('Example\nString') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \r \n String \n \r \t', + null + ) + ).toEqual('Example\n\nString') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \n\n String \n \r \t', + null + ) + ).toEqual('Example\n\nString') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \n\n\n String \n \r \t', + null + ) + ).toEqual('Example\n\nString') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \n \n \n String \n \r \t', + null + ) + ).toEqual('Example\n\nString') + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createRequiredTextInputComponent/index.tsx b/react-native/components/createRequiredTextInputComponent/index.tsx index 6e9d8c7e..82a20de7 100644 --- a/react-native/components/createRequiredTextInputComponent/index.tsx +++ b/react-native/components/createRequiredTextInputComponent/index.tsx @@ -57,11 +57,10 @@ export const createRequiredTextInputComponent = ( 'default', autoCapitalize, false, - false, 'left' ) - const RequiredTextInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, unique }) => ( + const RequiredTextInput: React.FunctionComponent = ({ value, onChange, disabled, placeholder, unique, autoFocus }) => ( { /* No-op. */ }} + autoFocus={autoFocus} /> ) diff --git a/react-native/components/createRequiredTextInputComponent/unit.tsx b/react-native/components/createRequiredTextInputComponent/unit.tsx index b3e8c025..a802cc36 100644 --- a/react-native/components/createRequiredTextInputComponent/unit.tsx +++ b/react-native/components/createRequiredTextInputComponent/unit.tsx @@ -96,6 +96,7 @@ test('renders as expected without bounds', () => { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -107,7 +108,6 @@ test('renders as expected without bounds', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false, autoCapitalize: 'sentences' } @@ -122,7 +122,8 @@ test('renders as expected without bounds', () => { placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect( @@ -268,6 +269,7 @@ test('renders as expected with a minimum length', () => { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -279,7 +281,6 @@ test('renders as expected with a minimum length', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false, autoCapitalize: 'sentences' } @@ -294,7 +295,8 @@ test('renders as expected with a minimum length', () => { placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect( @@ -474,6 +476,7 @@ test('renders as expected with a maximum length', () => { disabled placeholder="Example Placeholder" unique={['Example Unique A', 'Example Unique B', 'Example Unique C']} + autoFocus={false} /> ) @@ -485,7 +488,6 @@ test('renders as expected with a maximum length', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: false, keepFocusOnSubmit: false, autoCapitalize: 'sentences' } @@ -500,7 +502,8 @@ test('renders as expected with a maximum length', () => { placeholder: 'Example Placeholder', context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect( @@ -680,6 +683,7 @@ test('passes down an empty array when unique is undefined', () => { disabled placeholder="Example Placeholder" unique={undefined} + autoFocus={false} /> ) @@ -692,7 +696,8 @@ test('passes down an empty array when unique is undefined', () => { placeholder: 'Example Placeholder', context: [], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(onChange).not.toHaveBeenCalled() @@ -787,6 +792,7 @@ test('passes down an empty array when unique is not given', () => { onChange={onChange} disabled placeholder="Example Placeholder" + autoFocus={false} /> ) @@ -799,8 +805,182 @@ test('passes down an empty array when unique is not given', () => { placeholder: 'Example Placeholder', context: [], secureTextEntry: false, - onSubmit: expect.any(Function) + onSubmit: expect.any(Function), + autoFocus: false }) expect(onChange).not.toHaveBeenCalled() }) + +test('renders as expected with auto focus', () => { + const controlStyle: ControlStyle = { + fontFamily: 'Example Font Family', + fontSize: 37, + paddingVertical: 12, + paddingHorizontal: 29, + blurredValid: { + textColor: '#FFEE00', + placeholderColor: '#E7AA32', + backgroundColor: '#32AE12', + radius: 5, + border: { + width: 4, + color: '#FF00FF' + }, + iconColor: '#43AE21' + }, + blurredInvalid: { + textColor: '#99FE88', + placeholderColor: '#CACA3A', + backgroundColor: '#259284', + radius: 10, + border: { + width: 6, + color: '#9A9A8E' + }, + iconColor: '#985E00' + }, + focusedValid: { + textColor: '#55EA13', + placeholderColor: '#273346', + backgroundColor: '#CABA99', + radius: 3, + border: { + width: 5, + color: '#646464' + }, + iconColor: '#789521' + }, + focusedInvalid: { + textColor: '#ABAADE', + placeholderColor: '#47ADAD', + backgroundColor: '#32AA88', + radius: 47, + border: { + width: 12, + color: '#98ADAA' + }, + iconColor: '#449438' + }, + disabledValid: { + textColor: '#AE2195', + placeholderColor: '#FFAAEE', + backgroundColor: '#772728', + radius: 100, + border: { + width: 14, + color: '#5E5E5E' + }, + iconColor: '#ADAADA' + }, + disabledInvalid: { + textColor: '#340297', + placeholderColor: '#233832', + backgroundColor: '#938837', + radius: 2, + border: { + width: 19, + color: '#573829' + }, + iconColor: '#709709' + } + } + const onChange = jest.fn() + const Component = createRequiredTextInputComponent( + controlStyle, + Example Left Icon, + Example Right Icon, + null, + null, + 'sentences' + ) + + const rendered = unwrapRenderedFunctionComponent( + + ) + + expect(rendered.type).toBeAFunctionWithTheStaticProperties({ + inputComponent: { + stringify: expect.any(Function), + tryParse: expect.any(Function), + controlStyle, + multiLine: false, + autoComplete: 'off', + keyboardType: 'default', + keepFocusOnSubmit: false, + autoCapitalize: 'sentences' + } + }) + + expect(rendered.props).toEqual({ + leftIcon: Example Left Icon, + rightIcon: Example Right Icon, + value: 'Example String', + onChange, + disabled: true, + placeholder: 'Example Placeholder', + context: ['Example Unique A', 'Example Unique B', 'Example Unique C'], + secureTextEntry: false, + onSubmit: expect.any(Function), + autoFocus: true + }) + + expect( + rendered.type.inputComponent.stringify( + ' \n \r \t Example \t \r \n String \n \r \t' + ) + ).toEqual('Example String') + + expect( + rendered.type.inputComponent.tryParse('', [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ]) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse(' \n \r \t ', [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ]) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Unique \t \r \n B \n \r \t', + [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ] + ) + ).toBeUndefined() + expect( + rendered.type.inputComponent.tryParse('Example String', [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ]) + ).toEqual('Example String') + expect( + rendered.type.inputComponent.tryParse( + ' \n \r \t Example \t \r \n String \n \r \t', + [ + ' \t \r \n Unique \t \t \n A \n \r \t ', + ' \t \r \n Unique \t \t \n B \n \r \t ', + ' \t \r \n Unique \t \t \n C \n \r \t ' + ] + ) + ).toEqual('Example String') + + rendered.props.onSubmit() + + expect(onChange).not.toHaveBeenCalled() +}) diff --git a/react-native/components/createSearchableMultiSelectComponent/createSearchableMultiSelectChildrenComponent/index.tsx b/react-native/components/createSearchableMultiSelectComponent/createSearchableMultiSelectChildrenComponent/index.tsx index 5a1fb591..996e4df2 100644 --- a/react-native/components/createSearchableMultiSelectComponent/createSearchableMultiSelectChildrenComponent/index.tsx +++ b/react-native/components/createSearchableMultiSelectComponent/createSearchableMultiSelectChildrenComponent/index.tsx @@ -73,7 +73,6 @@ export const createSearchableMultiSelectChildrenComponent = < 'default', 'sentences', true, - true, 'left' ) @@ -203,6 +202,7 @@ export const createSearchableMultiSelectChildrenComponent = < }} secureTextEntry={false} disabled={false} + autoFocus={true} placeholder={placeholder} onSubmit={(parsed) => { const normalizedParsed = normalize(parsed) diff --git a/react-native/components/createSearchableMultiSelectComponent/createSearchableMultiSelectChildrenComponent/unit.tsx b/react-native/components/createSearchableMultiSelectComponent/createSearchableMultiSelectChildrenComponent/unit.tsx index 52c5bbfa..ceed90d8 100644 --- a/react-native/components/createSearchableMultiSelectComponent/createSearchableMultiSelectChildrenComponent/unit.tsx +++ b/react-native/components/createSearchableMultiSelectComponent/createSearchableMultiSelectChildrenComponent/unit.tsx @@ -198,7 +198,8 @@ test('renders as expected without a filter', async () => { disabled: false, placeholder: 'Example Placeholder', onSubmit: expect.any(Function), - context: null + context: null, + autoFocus: true } }) ] @@ -376,7 +377,6 @@ test('renders as expected without a filter', async () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: true, keepFocusOnSubmit: true } }) @@ -576,7 +576,8 @@ test('filters the list down to only those matching the user\'s input', async () disabled: false, placeholder: 'Example Placeholder', onSubmit: expect.any(Function), - context: null + context: null, + autoFocus: true } }) ] @@ -1584,7 +1585,8 @@ test('renders as expected without horizontal padding', () => { disabled: false, placeholder: 'Example Placeholder', onSubmit: expect.any(Function), - context: null + context: null, + autoFocus: true } }) ] @@ -1759,7 +1761,6 @@ test('renders as expected without horizontal padding', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: true, keepFocusOnSubmit: true } }) @@ -1968,7 +1969,8 @@ test('renders as expected without vertical padding', () => { disabled: false, placeholder: 'Example Placeholder', onSubmit: expect.any(Function), - context: null + context: null, + autoFocus: true } }) ] @@ -2143,7 +2145,6 @@ test('renders as expected without vertical padding', () => { multiLine: false, autoComplete: 'off', keyboardType: 'default', - autoFocus: true, keepFocusOnSubmit: true } }) diff --git a/react-native/components/createSearchableMultiSelectComponent/index.tsx b/react-native/components/createSearchableMultiSelectComponent/index.tsx index 1991736e..bcc7e023 100644 --- a/react-native/components/createSearchableMultiSelectComponent/index.tsx +++ b/react-native/components/createSearchableMultiSelectComponent/index.tsx @@ -43,7 +43,7 @@ export function createSearchableMultiSelectComponent< return ( ) diff --git a/react-native/components/createSearchableSelectComponent/createSearchableSelectChildrenComponent/unit.tsx b/react-native/components/createSearchableSelectComponent/createSearchableSelectChildrenComponent/unit.tsx index 7ac2c658..3639a034 100644 --- a/react-native/components/createSearchableSelectComponent/createSearchableSelectChildrenComponent/unit.tsx +++ b/react-native/components/createSearchableSelectComponent/createSearchableSelectChildrenComponent/unit.tsx @@ -170,7 +170,8 @@ test('renders as expected with an absent selected value', () => { disabled: false, placeholder: 'Example Placeholder', onSubmit: expect.any(Function), - context: null + context: null, + autoFocus: true } }) ] @@ -292,8 +293,7 @@ test('renders as expected with an absent selected value', () => { }, multiLine: false, autoComplete: 'off', - keyboardType: 'default', - autoFocus: true + keyboardType: 'default' } }) @@ -482,7 +482,8 @@ test('renders as expected with a present selected value', () => { disabled: false, placeholder: 'Example Option B Label', onSubmit: expect.any(Function), - context: null + context: null, + autoFocus: true } }) ] @@ -632,8 +633,7 @@ test('renders as expected with a present selected value', () => { }, multiLine: false, autoComplete: 'off', - keyboardType: 'default', - autoFocus: true + keyboardType: 'default' } }) @@ -823,7 +823,8 @@ test('renders as expected when matches are found for user input', async () => { disabled: false, placeholder: 'Example Option B Label', onSubmit: expect.any(Function), - context: null + context: null, + autoFocus: true } }) ] @@ -993,7 +994,8 @@ test('renders as expected when matches are not found for user input', async () = disabled: false, placeholder: 'Example Option B Label', onSubmit: expect.any(Function), - context: null + context: null, + autoFocus: true } }) ] @@ -1667,7 +1669,8 @@ test('renders as expected when horizontal padding is not present', () => { disabled: false, placeholder: 'Example Option B Label', onSubmit: expect.any(Function), - context: null + context: null, + autoFocus: true } }) ] @@ -1815,8 +1818,7 @@ test('renders as expected when horizontal padding is not present', () => { }, multiLine: false, autoComplete: 'off', - keyboardType: 'default', - autoFocus: true + keyboardType: 'default' } }) @@ -2003,7 +2005,8 @@ test('renders as expected when vertical padding is not present', () => { disabled: false, placeholder: 'Example Option B Label', onSubmit: expect.any(Function), - context: null + context: null, + autoFocus: true } }) ] @@ -2151,8 +2154,7 @@ test('renders as expected when vertical padding is not present', () => { }, multiLine: false, autoComplete: 'off', - keyboardType: 'default', - autoFocus: true + keyboardType: 'default' } }) diff --git a/react-native/components/createSearchableSelectComponent/index.tsx b/react-native/components/createSearchableSelectComponent/index.tsx index 17a82c74..82c35800 100644 --- a/react-native/components/createSearchableSelectComponent/index.tsx +++ b/react-native/components/createSearchableSelectComponent/index.tsx @@ -41,7 +41,7 @@ export function createSearchableSelectComponent< return ( { * When true, it will not be possible to select an option. It will otherwise * be possible to do so. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean /** * Text to be shown on the button when no value has been selected. diff --git a/react-native/types/NullableEmailInputProps/index.tsx b/react-native/types/NullableEmailInputProps/index.tsx index b1b5b2f8..65583f03 100644 --- a/react-native/types/NullableEmailInputProps/index.tsx +++ b/react-native/types/NullableEmailInputProps/index.tsx @@ -19,7 +19,13 @@ export interface NullableEmailInputProps { * When true, the text box is rendered semi-transparently and does not accept * focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/NullableEmailInputProps/readme.md b/react-native/types/NullableEmailInputProps/readme.md index 550dfcd6..856fa269 100644 --- a/react-native/types/NullableEmailInputProps/readme.md +++ b/react-native/types/NullableEmailInputProps/readme.md @@ -13,6 +13,7 @@ const example: NullableEmailInputProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered", unique: [`Not`, `In`, `This`, `List`], }; diff --git a/react-native/types/NullableFloatInputProps/index.tsx b/react-native/types/NullableFloatInputProps/index.tsx index f9ad87e0..7bfe252a 100644 --- a/react-native/types/NullableFloatInputProps/index.tsx +++ b/react-native/types/NullableFloatInputProps/index.tsx @@ -19,7 +19,13 @@ export interface NullableFloatInputProps { * When true, the text box is rendered semi-transparently and does not accept * focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/NullableFloatInputProps/readme.md b/react-native/types/NullableFloatInputProps/readme.md index 6ce91f7e..0a9650ef 100644 --- a/react-native/types/NullableFloatInputProps/readme.md +++ b/react-native/types/NullableFloatInputProps/readme.md @@ -13,6 +13,7 @@ const example: NullableFloatInputProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered", }; ``` diff --git a/react-native/types/NullableIntegerInputProps/index.tsx b/react-native/types/NullableIntegerInputProps/index.tsx index 9a3445af..0036f706 100644 --- a/react-native/types/NullableIntegerInputProps/index.tsx +++ b/react-native/types/NullableIntegerInputProps/index.tsx @@ -19,7 +19,13 @@ export interface NullableIntegerInputProps { * When true, the text box is rendered semi-transparently and does not accept * focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/NullableIntegerInputProps/readme.md b/react-native/types/NullableIntegerInputProps/readme.md index cd9179d5..1a853e2a 100644 --- a/react-native/types/NullableIntegerInputProps/readme.md +++ b/react-native/types/NullableIntegerInputProps/readme.md @@ -13,6 +13,7 @@ const example: NullableIntegerInputProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered", }; ``` diff --git a/react-native/types/NullablePasswordInputProps/index.tsx b/react-native/types/NullablePasswordInputProps/index.tsx index f0b21d96..a7da3ce4 100644 --- a/react-native/types/NullablePasswordInputProps/index.tsx +++ b/react-native/types/NullablePasswordInputProps/index.tsx @@ -19,7 +19,13 @@ export interface NullablePasswordInputProps { * When true, the password box is rendered semi-transparently and does not * accept focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/NullablePasswordInputProps/readme.md b/react-native/types/NullablePasswordInputProps/readme.md index e0254210..bea406f8 100644 --- a/react-native/types/NullablePasswordInputProps/readme.md +++ b/react-native/types/NullablePasswordInputProps/readme.md @@ -13,6 +13,7 @@ const example: NullablePasswordInputProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered.", match: "Must match this when non-null.", }; diff --git a/react-native/types/NullableTextAreaProps/index.tsx b/react-native/types/NullableTextAreaProps/index.tsx index 79676a4b..e1d6c7e2 100644 --- a/react-native/types/NullableTextAreaProps/index.tsx +++ b/react-native/types/NullableTextAreaProps/index.tsx @@ -19,7 +19,13 @@ export interface NullableTextAreaProps { * When true, the text box is rendered semi-transparently and does not accept * focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/NullableTextAreaProps/readme.md b/react-native/types/NullableTextAreaProps/readme.md index e8842c66..876625ba 100644 --- a/react-native/types/NullableTextAreaProps/readme.md +++ b/react-native/types/NullableTextAreaProps/readme.md @@ -13,6 +13,7 @@ const example: NullableTextAreaProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered", }; ``` diff --git a/react-native/types/NullableTextInputProps/index.tsx b/react-native/types/NullableTextInputProps/index.tsx index ffccfe70..b86172de 100644 --- a/react-native/types/NullableTextInputProps/index.tsx +++ b/react-native/types/NullableTextInputProps/index.tsx @@ -19,7 +19,13 @@ export interface NullableTextInputProps { * When true, the text box is rendered semi-transparently and does not accept * focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/NullableTextInputProps/readme.md b/react-native/types/NullableTextInputProps/readme.md index 76ea0654..675e6597 100644 --- a/react-native/types/NullableTextInputProps/readme.md +++ b/react-native/types/NullableTextInputProps/readme.md @@ -13,6 +13,7 @@ const example: NullableTextInputProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered", unique: [`Not`, `In`, `This`, `List`], }; diff --git a/react-native/types/RequiredEmailInputProps/index.tsx b/react-native/types/RequiredEmailInputProps/index.tsx index 66da6011..6129bb79 100644 --- a/react-native/types/RequiredEmailInputProps/index.tsx +++ b/react-native/types/RequiredEmailInputProps/index.tsx @@ -19,7 +19,13 @@ export interface RequiredEmailInputProps { * When true, the text box is rendered semi-transparently and does not accept * focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/RequiredEmailInputProps/readme.md b/react-native/types/RequiredEmailInputProps/readme.md index 1def698b..5524597b 100644 --- a/react-native/types/RequiredEmailInputProps/readme.md +++ b/react-native/types/RequiredEmailInputProps/readme.md @@ -13,6 +13,7 @@ const example: RequiredEmailInputProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered", unique: [`Not`, `In`, `This`, `List`], }; diff --git a/react-native/types/RequiredFloatInputProps/index.tsx b/react-native/types/RequiredFloatInputProps/index.tsx index 6f778e25..837b1c99 100644 --- a/react-native/types/RequiredFloatInputProps/index.tsx +++ b/react-native/types/RequiredFloatInputProps/index.tsx @@ -19,7 +19,13 @@ export interface RequiredFloatInputProps { * When true, the text box is rendered semi-transparently and does not accept * focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/RequiredFloatInputProps/readme.md b/react-native/types/RequiredFloatInputProps/readme.md index fa732393..7c421f65 100644 --- a/react-native/types/RequiredFloatInputProps/readme.md +++ b/react-native/types/RequiredFloatInputProps/readme.md @@ -13,6 +13,7 @@ const example: RequiredIntegerInputProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered", }; ``` diff --git a/react-native/types/RequiredIntegerInputProps/index.tsx b/react-native/types/RequiredIntegerInputProps/index.tsx index 85f50c79..9ce16966 100644 --- a/react-native/types/RequiredIntegerInputProps/index.tsx +++ b/react-native/types/RequiredIntegerInputProps/index.tsx @@ -19,7 +19,13 @@ export interface RequiredIntegerInputProps { * When true, the text box is rendered semi-transparently and does not accept * focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/RequiredIntegerInputProps/readme.md b/react-native/types/RequiredIntegerInputProps/readme.md index a4ca7095..df214ac9 100644 --- a/react-native/types/RequiredIntegerInputProps/readme.md +++ b/react-native/types/RequiredIntegerInputProps/readme.md @@ -13,6 +13,7 @@ const example: RequiredIntegerInputProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered", }; ``` diff --git a/react-native/types/RequiredPasswordInputProps/index.tsx b/react-native/types/RequiredPasswordInputProps/index.tsx index 01b7a98f..ac8509ef 100644 --- a/react-native/types/RequiredPasswordInputProps/index.tsx +++ b/react-native/types/RequiredPasswordInputProps/index.tsx @@ -19,7 +19,13 @@ export interface RequiredPasswordInputProps { * When true, the password box is rendered semi-transparently and does not * accept focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/RequiredPasswordInputProps/readme.md b/react-native/types/RequiredPasswordInputProps/readme.md index 67f64450..656c0e49 100644 --- a/react-native/types/RequiredPasswordInputProps/readme.md +++ b/react-native/types/RequiredPasswordInputProps/readme.md @@ -13,6 +13,7 @@ const example: RequiredPasswordInputProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered.", match: "Must match this when non-null.", }; diff --git a/react-native/types/RequiredTextAreaProps/index.tsx b/react-native/types/RequiredTextAreaProps/index.tsx index cffe4407..00607084 100644 --- a/react-native/types/RequiredTextAreaProps/index.tsx +++ b/react-native/types/RequiredTextAreaProps/index.tsx @@ -19,7 +19,13 @@ export interface RequiredTextAreaProps { * When true, the text box is rendered semi-transparently and does not accept * focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/RequiredTextAreaProps/readme.md b/react-native/types/RequiredTextAreaProps/readme.md index 24b346c9..c3756685 100644 --- a/react-native/types/RequiredTextAreaProps/readme.md +++ b/react-native/types/RequiredTextAreaProps/readme.md @@ -13,6 +13,7 @@ const example: RequiredTextAreaProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered", }; ``` diff --git a/react-native/types/RequiredTextInputProps/index.tsx b/react-native/types/RequiredTextInputProps/index.tsx index f6d079aa..8d509e1a 100644 --- a/react-native/types/RequiredTextInputProps/index.tsx +++ b/react-native/types/RequiredTextInputProps/index.tsx @@ -19,7 +19,13 @@ export interface RequiredTextInputProps { * When true, the text box is rendered semi-transparently and does not accept * focus or input. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean + + /** + * When true, the text input will steal focus on mount. It will otherwise + * wait for the user to interact with it. + */ + readonly autoFocus: boolean /** * Text to be shown when no value has been entered. diff --git a/react-native/types/RequiredTextInputProps/readme.md b/react-native/types/RequiredTextInputProps/readme.md index 5402e8c5..07a5556d 100644 --- a/react-native/types/RequiredTextInputProps/readme.md +++ b/react-native/types/RequiredTextInputProps/readme.md @@ -13,6 +13,7 @@ const example: RequiredTextInputProps = { console.log(`Value: ${value}, complete: ${complete ? "Yes" : "No"}`); }} disabled: false, + autoFocus: true, placeholder: "Shown when no text has been entered", unique: [`Not`, `In`, `This`, `List`], }; diff --git a/react-native/types/SearchableMultiSelectProps/index.tsx b/react-native/types/SearchableMultiSelectProps/index.tsx index ee8dcf66..0e24b279 100644 --- a/react-native/types/SearchableMultiSelectProps/index.tsx +++ b/react-native/types/SearchableMultiSelectProps/index.tsx @@ -10,7 +10,7 @@ export type SearchableMultiSelectProps = React.PropsWithChildren<{ * When true, it will not be possible to select an option. It will otherwise * be possible to do so. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean /** * Text to be shown on the button when no value has been selected. diff --git a/react-native/types/SearchableSelectProps/index.tsx b/react-native/types/SearchableSelectProps/index.tsx index 26c72bfb..1677c369 100644 --- a/react-native/types/SearchableSelectProps/index.tsx +++ b/react-native/types/SearchableSelectProps/index.tsx @@ -10,7 +10,7 @@ export type SearchableSelectProps = React.PropsWithChildren<{ * When true, it will not be possible to select an option. It will otherwise * be possible to do so. */ - readonly disabled?: undefined | boolean + readonly disabled: boolean /** * Text to be shown on the button when no value has been selected.