From e4211c60c25ac75f08e39b787684c34aa9f9d633 Mon Sep 17 00:00:00 2001 From: Sokolovskii Ivan Date: Mon, 15 Dec 2025 12:51:31 +0300 Subject: [PATCH 1/3] =?UTF-8?q?fix(input):=20=D0=B8=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=BE=D0=B3?= =?UTF-8?q?=D0=B8=D0=BA=D0=B8=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=8F=20=D0=B2=D0=B2=D0=BE=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=BE=D0=B4=D0=BD=D0=BE=D1=80=D0=B0=D0=B7=D0=BE=D0=B2=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Input/InputOtp/InputOtp.stories.ts | 18 - .../Input/InputOtp/InputOtp.stories.tsx | 38 + src/components/Input/InputOtp/InputOtp.tsx | 17 +- .../InputOtp/__tests__/InputOtp.test.tsx | 16 +- .../__snapshots__/InputOtp.test.tsx.snap | 11734 +++++++++++++++- src/components/Input/index.ts | 1 + 6 files changed, 11348 insertions(+), 476 deletions(-) delete mode 100644 src/components/Input/InputOtp/InputOtp.stories.ts create mode 100644 src/components/Input/InputOtp/InputOtp.stories.tsx diff --git a/src/components/Input/InputOtp/InputOtp.stories.ts b/src/components/Input/InputOtp/InputOtp.stories.ts deleted file mode 100644 index 94fd7cf..0000000 --- a/src/components/Input/InputOtp/InputOtp.stories.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react' - -import { InputOtp } from './InputOtp' - -const meta: Meta = { - title: 'Form/InputOtp', - component: InputOtp, - args: { disabled: false, error: false, length: 4 }, - argTypes: { onComplete: { action: 'onComplete' } }, -} - -export default meta - -type Story = StoryObj - -const InputOtpStory: Story = {} - -export { InputOtpStory as InputOtp } diff --git a/src/components/Input/InputOtp/InputOtp.stories.tsx b/src/components/Input/InputOtp/InputOtp.stories.tsx new file mode 100644 index 0000000..c4cbcf2 --- /dev/null +++ b/src/components/Input/InputOtp/InputOtp.stories.tsx @@ -0,0 +1,38 @@ +import { useArgs } from '@storybook/preview-api' +import type { Meta, StoryObj } from '@storybook/react' + +import { useCallback, useEffect, useState } from 'react' + +import { InputOtp } from './InputOtp' + +const meta: Meta = { + title: 'Form/InputOtp', + component: InputOtp, + args: { disabled: false, error: false, length: 4, value: '' }, + render: (args) => { + const [, updateArgs] = useArgs() + const [value, setValue] = useState(args.value) + + const onChange = useCallback( + (nextValue: string) => { + setValue(nextValue) + updateArgs({ value: nextValue }) + }, + [updateArgs] + ) + + useEffect(() => { + setValue(args.value) + }, [args.value]) + + return + }, +} + +export default meta + +type Story = StoryObj + +const InputOtpStory: Story = {} + +export { InputOtpStory as InputOtp } diff --git a/src/components/Input/InputOtp/InputOtp.tsx b/src/components/Input/InputOtp/InputOtp.tsx index f62dd15..ba2caca 100644 --- a/src/components/Input/InputOtp/InputOtp.tsx +++ b/src/components/Input/InputOtp/InputOtp.tsx @@ -15,8 +15,8 @@ import { InputOtpItem } from './InputOtpItem' export interface InputOtpProps extends Omit< TextInputProps, - | 'value' | 'onChangeText' + | 'onChange' | 'onFocus' | 'onBlur' | 'ref' @@ -25,7 +25,7 @@ export interface InputOtpProps >, Pick { length: number - onComplete?: (value: string) => void + onChange: (value: string) => void disabled?: boolean error?: boolean } @@ -33,15 +33,15 @@ export interface InputOtpProps export const InputOtp = memo( ({ length, - onComplete, + onChange, disabled = false, error = false, testOnly_pressed, testID, + value = '', ...rest }) => { const styles = useStyles() - const [value, setValue] = useState('') const [isFocused, setIsFocused] = useState(false) const inputRef = useRef(null) @@ -53,14 +53,9 @@ export const InputOtp = memo( const handleChange = useCallback( (text: string) => { const sanitizedText = text.replace(/[^0-9]/g, '') - setValue(sanitizedText) - - if (sanitizedText.length === length) { - onComplete?.(sanitizedText) - inputRef.current?.blur() - } + onChange(sanitizedText) }, - [length, onComplete] + [onChange] ) const handleFocus = useCallback(() => { diff --git a/src/components/Input/InputOtp/__tests__/InputOtp.test.tsx b/src/components/Input/InputOtp/__tests__/InputOtp.test.tsx index 3b023b5..32342d9 100644 --- a/src/components/Input/InputOtp/__tests__/InputOtp.test.tsx +++ b/src/components/Input/InputOtp/__tests__/InputOtp.test.tsx @@ -7,6 +7,8 @@ describe('InputOtp component tests', () => { disabled: [true, false], error: [true, false], testOnly_pressed: [true, false], + value: [undefined, '5', '55'], + onChange: [jest.fn()], length: [2, 4, 8], }) @@ -20,19 +22,25 @@ describe('InputOtp component tests', () => { ) test('Handle input', async () => { - const mockedOnComplete = jest.fn() + const mockedOnChange = jest.fn() const { getByTestId } = render( - + ) const hiddenInput = getByTestId('InputOtpHiddenInput') + expect(mockedOnChange).not.toHaveBeenCalled() + fireEvent.changeText(hiddenInput, '55') - expect(mockedOnComplete).not.toHaveBeenCalled() + expect(mockedOnChange).toHaveBeenCalledWith('55') fireEvent.changeText(hiddenInput, '5543') - expect(mockedOnComplete).toHaveBeenCalledWith('5543') + expect(mockedOnChange).toHaveBeenCalledWith('5543') + + fireEvent.changeText(hiddenInput, '55 ') + + expect(mockedOnChange).toHaveBeenCalledWith('55') }) }) diff --git a/src/components/Input/InputOtp/__tests__/__snapshots__/InputOtp.test.tsx.snap b/src/components/Input/InputOtp/__tests__/__snapshots__/InputOtp.test.tsx.snap index 7a1c09e..7590ddc 100644 --- a/src/components/Input/InputOtp/__tests__/__snapshots__/InputOtp.test.tsx.snap +++ b/src/components/Input/InputOtp/__tests__/__snapshots__/InputOtp.test.tsx.snap @@ -124,7 +124,7 @@ exports[`InputOtp component tests length - 2, error - false, disabled - false, p `; -exports[`InputOtp component tests length - 2, error - false, disabled - false, pressed - true 1`] = ` +exports[`InputOtp component tests length - 2, error - false, disabled - false, pressed - false 2`] = ` + > + 5 + `; -exports[`InputOtp component tests length - 2, error - false, disabled - true, pressed - false 1`] = ` +exports[`InputOtp component tests length - 2, error - false, disabled - false, pressed - false 3`] = ` @@ -325,7 +320,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr } } testID="undefinedItem" - /> + > + 5 + @@ -359,7 +353,9 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr } } testID="undefinedItem" - /> + > + 5 + `; -exports[`InputOtp component tests length - 2, error - false, disabled - true, pressed - true 1`] = ` +exports[`InputOtp component tests length - 2, error - false, disabled - false, pressed - true 1`] = ` @@ -476,10 +469,7 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr { "borderColor": "#1dc831", }, - { - "mixBlendMode": "luminosity", - "opacity": 0.6, - }, + false, ] } > @@ -516,7 +506,7 @@ exports[`InputOtp component tests length - 2, error - false, disabled - true, pr `; -exports[`InputOtp component tests length - 2, error - true, disabled - false, pressed - false 1`] = ` +exports[`InputOtp component tests length - 2, error - false, disabled - false, pressed - true 2`] = ` @@ -588,7 +578,9 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr } } testID="undefinedItem" - /> + > + 5 + @@ -639,12 +631,12 @@ exports[`InputOtp component tests length - 2, error - true, disabled - false, pr } } testID="undefinedHiddenInput" - value="" + value="5" /> `; -exports[`InputOtp component tests length - 2, error - true, disabled - false, pressed - true 1`] = ` +exports[`InputOtp component tests length - 2, error - false, disabled - false, pressed - true 3`] = ` + > + 5 + + > + 5 + `; -exports[`InputOtp component tests length - 2, error - true, disabled - true, pressed - false 1`] = ` +exports[`InputOtp component tests length - 2, error - false, disabled - true, pressed - false 1`] = ` `; -exports[`InputOtp component tests length - 2, error - true, disabled - true, pressed - true 1`] = ` +exports[`InputOtp component tests length - 2, error - false, disabled - true, pressed - false 2`] = ` + > + 5 + `; -exports[`InputOtp component tests length - 4, error - false, disabled - false, pressed - false 1`] = ` +exports[`InputOtp component tests length - 2, error - false, disabled - true, pressed - false 3`] = ` - - - @@ -1149,7 +1103,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p } } testID="undefinedItem" - /> + > + 5 + - - - @@ -1211,12 +1139,14 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p } } testID="undefinedItem" - /> + > + 5 + `; -exports[`InputOtp component tests length - 4, error - false, disabled - false, pressed - true 1`] = ` +exports[`InputOtp component tests length - 2, error - false, disabled - true, pressed - true 1`] = ` @@ -1325,7 +1258,10 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p { "borderColor": "#1dc831", }, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -1341,6 +1277,68 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p testID="undefinedItem" /> + + + +`; + +exports[`InputOtp component tests length - 2, error - false, disabled - true, pressed - true 2`] = ` + + @@ -1372,7 +1373,9 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p } } testID="undefinedItem" - /> + > + 5 + @@ -1410,7 +1416,7 @@ exports[`InputOtp component tests length - 4, error - false, disabled - false, p `; -exports[`InputOtp component tests length - 4, error - false, disabled - true, pressed - false 1`] = ` +exports[`InputOtp component tests length - 2, error - false, disabled - true, pressed - true 3`] = ` + + 5 + + + + + 5 + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - false, pressed - false 1`] = ` + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - false, pressed - false 2`] = ` + + + + + 5 + + + + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - false, pressed - false 3`] = ` + + + + + 5 + + + + + 5 + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - false, pressed - true 1`] = ` + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - false, pressed - true 2`] = ` + + + + + 5 + + + + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - false, pressed - true 3`] = ` + + + + + 5 + + + + + 5 + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - true, pressed - false 1`] = ` + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - true, pressed - false 2`] = ` + + + + + 5 + + + + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - true, pressed - false 3`] = ` + + + + + 5 + + + + + 5 + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - true, pressed - true 1`] = ` + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - true, pressed - true 2`] = ` + + + + + 5 + + + + + + + + +`; + +exports[`InputOtp component tests length - 2, error - true, disabled - true, pressed - true 3`] = ` + + + + + 5 + + + + + 5 + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - false, pressed - false 1`] = ` + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - false, pressed - false 2`] = ` + + + + + 5 + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - false, pressed - false 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - false, pressed - true 1`] = ` + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - false, pressed - true 2`] = ` + + + + + 5 + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - false, pressed - true 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - true, pressed - false 1`] = ` + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - true, pressed - false 2`] = ` + + + + + 5 + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - true, pressed - false 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - true, pressed - true 1`] = ` + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - true, pressed - true 2`] = ` + + + + + 5 + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - false, disabled - true, pressed - true 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - false, pressed - false 1`] = ` + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - false, pressed - false 2`] = ` + + + + + 5 + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - false, pressed - false 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - false, pressed - true 1`] = ` + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - false, pressed - true 2`] = ` + + + + + 5 + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - false, pressed - true 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - true, pressed - false 1`] = ` + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - true, pressed - false 2`] = ` + + + + + 5 + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - true, pressed - false 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - true, pressed - true 1`] = ` + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - true, pressed - true 2`] = ` + + + + + 5 + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 4, error - true, disabled - true, pressed - true 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - false, pressed - false 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - false, pressed - false 2`] = ` + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - false, pressed - false 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - false, pressed - true 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - false, pressed - true 2`] = ` + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - false, pressed - true 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - true, pressed - false 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - true, pressed - false 2`] = ` + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - true, pressed - false 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - true, pressed - true 1`] = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - true, pressed - true 2`] = ` + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - false, disabled - true, pressed - true 3`] = ` + + + + + 5 + + + + + 5 + + + + + + + + + + + + + + + + + + + + + +`; + +exports[`InputOtp component tests length - 8, error - true, disabled - false, pressed - false 1`] = ` + + + + + + + + + + + @@ -1550,12 +12210,44 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr "paddingHorizontal": 10.5, "paddingVertical": 0, }, + { + "borderColor": "#db3424", + }, false, false, + ] + } + > + + + @@ -1584,12 +12276,44 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr "paddingHorizontal": 10.5, "paddingVertical": 0, }, + { + "borderColor": "#db3424", + }, false, false, + ] + } + > + + + @@ -1608,7 +12332,7 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr `; -exports[`InputOtp component tests length - 4, error - false, disabled - true, pressed - true 1`] = ` +exports[`InputOtp component tests length - 8, error - true, disabled - false, pressed - false 2`] = ` + + 5 + + + + + + @@ -1716,14 +12505,44 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr "paddingHorizontal": 10.5, "paddingVertical": 0, }, + { + "borderColor": "#db3424", + }, false, + false, + ] + } + > + + + @@ -1752,14 +12571,44 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr "paddingHorizontal": 10.5, "paddingVertical": 0, }, + { + "borderColor": "#db3424", + }, false, + false, + ] + } + > + + + @@ -1788,14 +12637,11 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr "paddingHorizontal": 10.5, "paddingVertical": 0, }, - false, - { - "borderColor": "#1dc831", - }, { - "mixBlendMode": "luminosity", - "opacity": 0.6, + "borderColor": "#db3424", }, + false, + false, ] } > @@ -1814,7 +12660,7 @@ exports[`InputOtp component tests length - 4, error - false, disabled - true, pr `; -exports[`InputOtp component tests length - 4, error - true, disabled - false, pressed - false 1`] = ` +exports[`InputOtp component tests length - 8, error - true, disabled - false, pressed - false 3`] = ` + > + 5 + + > + 5 + - - - -`; - -exports[`InputOtp component tests length - 4, error - true, disabled - false, pressed - true 1`] = ` - - `; -exports[`InputOtp component tests length - 4, error - true, disabled - true, pressed - false 1`] = ` +exports[`InputOtp component tests length - 8, error - true, disabled - false, pressed - true 1`] = ` @@ -2321,11 +13100,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre { "borderColor": "#db3424", }, - false, { - "mixBlendMode": "luminosity", - "opacity": 0.6, + "borderColor": "#1dc831", }, + false, ] } > @@ -2357,11 +13135,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre { "borderColor": "#db3424", }, - false, { - "mixBlendMode": "luminosity", - "opacity": 0.6, + "borderColor": "#1dc831", }, + false, ] } > @@ -2393,11 +13170,10 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre { "borderColor": "#db3424", }, - false, { - "mixBlendMode": "luminosity", - "opacity": 0.6, + "borderColor": "#1dc831", }, + false, ] } > @@ -2413,68 +13189,6 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre testID="undefinedItem" /> - - - -`; - -exports[`InputOtp component tests length - 4, error - true, disabled - true, pressed - true 1`] = ` - - @@ -2532,10 +13243,7 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre { "borderColor": "#1dc831", }, - { - "mixBlendMode": "luminosity", - "opacity": 0.6, - }, + false, ] } > @@ -2570,10 +13278,7 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre { "borderColor": "#1dc831", }, - { - "mixBlendMode": "luminosity", - "opacity": 0.6, - }, + false, ] } > @@ -2608,10 +13313,7 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre { "borderColor": "#1dc831", }, - { - "mixBlendMode": "luminosity", - "opacity": 0.6, - }, + false, ] } > @@ -2630,7 +13332,7 @@ exports[`InputOtp component tests length - 4, error - true, disabled - true, pre `; -exports[`InputOtp component tests length - 8, error - false, disabled - false, pressed - false 1`] = ` +exports[`InputOtp component tests length - 8, error - true, disabled - false, pressed - true 2`] = ` + > + 5 + `; -exports[`InputOtp component tests length - 8, error - false, disabled - false, pressed - true 1`] = ` +exports[`InputOtp component tests length - 8, error - true, disabled - false, pressed - true 3`] = ` + > + 5 + + > + 5 + `; -exports[`InputOtp component tests length - 8, error - false, disabled - true, pressed - false 1`] = ` +exports[`InputOtp component tests length - 8, error - true, disabled - true, pressed - false 1`] = ` `; -exports[`InputOtp component tests length - 8, error - false, disabled - true, pressed - true 1`] = ` +exports[`InputOtp component tests length - 8, error - true, disabled - true, pressed - false 2`] = ` + > + 5 + `; -exports[`InputOtp component tests length - 8, error - true, disabled - false, pressed - false 1`] = ` +exports[`InputOtp component tests length - 8, error - true, disabled - true, pressed - false 3`] = ` @@ -4040,7 +14817,9 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr } } testID="undefinedItem" - /> + > + 5 + @@ -4073,7 +14855,9 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr } } testID="undefinedItem" - /> + > + 5 + @@ -4125,7 +14912,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr "borderColor": "#db3424", }, false, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4158,7 +14948,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr "borderColor": "#db3424", }, false, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4191,7 +14984,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr "borderColor": "#db3424", }, false, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4224,7 +15020,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr "borderColor": "#db3424", }, false, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4257,7 +15056,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr "borderColor": "#db3424", }, false, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4289,18 +15091,18 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr } } testID="undefinedHiddenInput" - value="" + value="55" /> `; -exports[`InputOtp component tests length - 8, error - true, disabled - false, pressed - true 1`] = ` +exports[`InputOtp component tests length - 8, error - true, disabled - true, pressed - true 1`] = ` @@ -4389,7 +15194,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr { "borderColor": "#1dc831", }, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4424,7 +15232,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr { "borderColor": "#1dc831", }, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4459,7 +15270,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr { "borderColor": "#1dc831", }, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4494,7 +15308,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr { "borderColor": "#1dc831", }, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4529,7 +15346,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr { "borderColor": "#1dc831", }, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4564,7 +15384,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr { "borderColor": "#1dc831", }, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4599,7 +15422,10 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr { "borderColor": "#1dc831", }, - false, + { + "mixBlendMode": "luminosity", + "opacity": 0.6, + }, ] } > @@ -4636,7 +15462,7 @@ exports[`InputOtp component tests length - 8, error - true, disabled - false, pr `; -exports[`InputOtp component tests length - 8, error - true, disabled - true, pressed - false 1`] = ` +exports[`InputOtp component tests length - 8, error - true, disabled - true, pressed - true 2`] = ` + > + 5 + `; -exports[`InputOtp component tests length - 8, error - true, disabled - true, pressed - true 1`] = ` +exports[`InputOtp component tests length - 8, error - true, disabled - true, pressed - true 3`] = ` + > + 5 + + > + 5 + `; diff --git a/src/components/Input/index.ts b/src/components/Input/index.ts index de401d6..0616675 100644 --- a/src/components/Input/index.ts +++ b/src/components/Input/index.ts @@ -3,3 +3,4 @@ export { InputText } from './InputText' export { FloatLabel } from './FloatLabel' export { InputSwitch } from './InputSwitch' export type { InputTextBaseProps } from './InputTextBase/types' +export { InputOtp } from './InputOtp/InputOtp' From 4b6ee439d5ea2292cd81b16d8922894325fe4f30 Mon Sep 17 00:00:00 2001 From: Sokolovskii Ivan Date: Mon, 15 Dec 2025 12:58:01 +0300 Subject: [PATCH 2/3] =?UTF-8?q?fix(input):=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D1=81=D0=BE=D0=B1=D1=8B=D1=82?= =?UTF-8?q?=D0=B8=D1=8F=20onFocus=20=D0=B8=20onBlur=20=D0=B2=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=B5=20=D0=B2=D0=B2=D0=BE=D0=B4=D0=B0=20=D0=BE?= =?UTF-8?q?=D0=B4=D0=BD=D0=BE=D1=80=D0=B0=D0=B7=D0=BE=D0=B2=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Input/InputOtp/InputOtp.tsx | 32 +++++++++++++--------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/components/Input/InputOtp/InputOtp.tsx b/src/components/Input/InputOtp/InputOtp.tsx index ba2caca..3ced897 100644 --- a/src/components/Input/InputOtp/InputOtp.tsx +++ b/src/components/Input/InputOtp/InputOtp.tsx @@ -6,6 +6,8 @@ import { TextInput, type TextInputProps, type PressableProps, + type TextInputFocusEventData, + type NativeSyntheticEvent, } from 'react-native' import { makeStyles } from '../../../utils/makeStyles' @@ -15,13 +17,7 @@ import { InputOtpItem } from './InputOtpItem' export interface InputOtpProps extends Omit< TextInputProps, - | 'onChangeText' - | 'onChange' - | 'onFocus' - | 'onBlur' - | 'ref' - | 'keyboardType' - | 'style' + 'onChangeText' | 'onChange' | 'ref' | 'keyboardType' | 'style' >, Pick { length: number @@ -39,6 +35,8 @@ export const InputOtp = memo( testOnly_pressed, testID, value = '', + onFocus, + onBlur, ...rest }) => { const styles = useStyles() @@ -58,13 +56,21 @@ export const InputOtp = memo( [onChange] ) - const handleFocus = useCallback(() => { - setIsFocused(true) - }, []) + const handleFocus = useCallback( + (e: NativeSyntheticEvent) => { + setIsFocused(true) + onFocus?.(e) + }, + [onFocus] + ) - const handleBlur = useCallback(() => { - setIsFocused(false) - }, []) + const handleBlur = useCallback( + (e: NativeSyntheticEvent) => { + setIsFocused(false) + onBlur?.(e) + }, + [onBlur] + ) const activeIndex = useMemo( () => Math.min(value.length, length - 1), From 6097a5eca96967e39af3a5b673505e4447b0b10f Mon Sep 17 00:00:00 2001 From: Sokolovskii Ivan Date: Mon, 15 Dec 2025 13:03:24 +0300 Subject: [PATCH 3/3] =?UTF-8?q?fix(input):=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D1=80=D0=BE=D0=B1=D1=80=D0=BE?= =?UTF-8?q?=D1=81=20ref=20=D0=BA=20=D0=BF=D0=BE=D0=BB=D1=8E=20=D0=B2=D0=B2?= =?UTF-8?q?=D0=BE=D0=B4=D0=B0=20=D0=BE=D0=B4=D0=BD=D0=BE=D1=80=D0=B0=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE=20=D0=BA=D0=BE=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Input/InputOtp/InputOtp.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/Input/InputOtp/InputOtp.tsx b/src/components/Input/InputOtp/InputOtp.tsx index 3ced897..1e5f7ae 100644 --- a/src/components/Input/InputOtp/InputOtp.tsx +++ b/src/components/Input/InputOtp/InputOtp.tsx @@ -1,4 +1,12 @@ -import { memo, useCallback, useMemo, useRef, useState } from 'react' +import { + memo, + useCallback, + useImperativeHandle, + useMemo, + useRef, + useState, + type Ref, +} from 'react' import { Pressable, @@ -24,6 +32,7 @@ export interface InputOtpProps onChange: (value: string) => void disabled?: boolean error?: boolean + inputRef?: Ref } export const InputOtp = memo( @@ -33,6 +42,7 @@ export const InputOtp = memo( disabled = false, error = false, testOnly_pressed, + inputRef: propsInputRef, testID, value = '', onFocus, @@ -44,6 +54,8 @@ export const InputOtp = memo( const inputRef = useRef(null) + useImperativeHandle(propsInputRef, () => inputRef.current as TextInput) + const handlePress = useCallback(() => { inputRef.current?.focus() }, [])