11/* eslint no-magic-numbers: ["error", { "ignore": [-1] }] */
22
3+ import { validateProps } from '@msinternal/botframework-webchat-react-valibot' ;
34import React , {
45 type ChangeEventHandler ,
56 type FocusEventHandler ,
@@ -9,6 +10,19 @@ import React, {
910 type ReactEventHandler ,
1011 useRef
1112} from 'react' ;
13+ import {
14+ boolean ,
15+ custom ,
16+ type InferInput ,
17+ literal ,
18+ number ,
19+ object ,
20+ optional ,
21+ picklist ,
22+ pipe ,
23+ readonly ,
24+ string
25+ } from 'valibot' ;
1226
1327import useEnterKeyHint from '../hooks/internal/useEnterKeyHint' ;
1428
@@ -30,84 +44,90 @@ import useEnterKeyHint from '../hooks/internal/useEnterKeyHint';
3044// - aria-disabled="true" is the source of truth
3145// - If the widget is contained by a <form>, the developer need to filter out some `onSubmit` event caused by this widget
3246
33- type AccessibleInputTextProps = Readonly < {
34- 'aria-errormessage' ?: string ;
35- className ?: string | undefined ;
36- 'data-id' ?: string | undefined ;
37- 'data-testid' ?: string | undefined ;
38- disabled ?: boolean | undefined ;
39- enterKeyHint ?: string | undefined ;
40- inputMode ?: 'text' | 'none' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search' | undefined ;
41- onChange ?: ChangeEventHandler < HTMLInputElement > | undefined ;
42- onClick ?: MouseEventHandler < HTMLInputElement > | undefined ;
43- onFocus ?: FocusEventHandler < HTMLInputElement > | undefined ;
44- onKeyDown ?: KeyboardEventHandler < HTMLInputElement > | undefined ;
45- onKeyDownCapture ?: KeyboardEventHandler < HTMLInputElement > | undefined ;
46- onKeyPress ?: KeyboardEventHandler < HTMLInputElement > | undefined ;
47- onSelect ?: ReactEventHandler < HTMLInputElement > | undefined ;
48- placeholder ?: string | undefined ;
49- readOnly ?: boolean | undefined ;
50- tabIndex ?: number | undefined ;
51- type : 'text' ;
52- value ?: string | undefined ;
53- } > ;
47+ const AccessibleInputTextPropsSchema = pipe (
48+ object ( {
49+ 'aria-errormessage' : optional ( string ( ) ) ,
50+ 'aria-label' : optional ( string ( ) ) ,
51+ className : optional ( string ( ) ) ,
52+ 'data-id' : optional ( string ( ) ) ,
53+ 'data-testid' : optional ( string ( ) ) ,
54+ disabled : optional ( boolean ( ) ) ,
55+ enterKeyHint : optional ( string ( ) ) ,
56+ inputMode : optional ( picklist ( [ 'decimal' , 'email' , 'none' , 'numeric' , 'search' , 'tel' , 'text' , 'url' ] ) ) ,
57+ onChange : optional ( custom < ChangeEventHandler < HTMLInputElement > > ( value => typeof value === 'function' ) ) ,
58+ onClick : optional ( custom < MouseEventHandler < HTMLInputElement > > ( value => typeof value === 'function' ) ) ,
59+ onFocus : optional ( custom < FocusEventHandler < HTMLInputElement > > ( value => typeof value === 'function' ) ) ,
60+ onKeyDown : optional ( custom < KeyboardEventHandler < HTMLInputElement > > ( value => typeof value === 'function' ) ) ,
61+ onKeyDownCapture : optional ( custom < KeyboardEventHandler < HTMLInputElement > > ( value => typeof value === 'function' ) ) ,
62+ onKeyPress : optional ( custom < KeyboardEventHandler < HTMLInputElement > > ( value => typeof value === 'function' ) ) ,
63+ onSelect : optional ( custom < ReactEventHandler < HTMLInputElement > > ( value => typeof value === 'function' ) ) ,
64+ placeholder : optional ( string ( ) ) ,
65+ readOnly : optional ( boolean ( ) ) ,
66+ tabIndex : optional ( number ( ) ) ,
67+ type : literal ( 'text' ) ,
68+ value : optional ( string ( ) )
69+ } ) ,
70+ readonly ( )
71+ ) ;
5472
55- const AccessibleInputText = forwardRef < HTMLInputElement , AccessibleInputTextProps > (
56- (
57- {
58- 'aria-errormessage' : ariaErrorMessage ,
59- className,
60- 'data-id' : dataId ,
61- 'data-testid' : dataTestId ,
62- disabled,
63- enterKeyHint,
64- onChange,
65- onClick,
66- onFocus,
67- onKeyDown,
68- onKeyDownCapture,
69- onKeyPress,
70- onSelect,
71- placeholder,
72- readOnly,
73- tabIndex,
74- value,
75- ...props
76- } ,
77- forwardedRef
78- ) => {
79- const targetRef = useRef ( ) ;
73+ type AccessibleInputTextProps = InferInput < typeof AccessibleInputTextPropsSchema > ;
8074
81- const ref = forwardedRef || targetRef ;
75+ const AccessibleInputText = forwardRef < HTMLInputElement , AccessibleInputTextProps > ( ( rawProps , forwardedRef ) => {
76+ const {
77+ 'aria-errormessage' : ariaErrorMessage ,
78+ 'aria-label' : ariaLabel ,
79+ className,
80+ 'data-id' : dataId ,
81+ 'data-testid' : dataTestId ,
82+ disabled,
83+ enterKeyHint,
84+ onChange,
85+ onClick,
86+ onFocus,
87+ onKeyDown,
88+ onKeyDownCapture,
89+ onKeyPress,
90+ onSelect,
91+ placeholder,
92+ readOnly,
93+ tabIndex,
94+ value,
95+ ...props
96+ } = validateProps ( AccessibleInputTextPropsSchema , rawProps ) ;
8297
83- useEnterKeyHint ( ref , enterKeyHint ) ;
98+ const targetRef = useRef < HTMLInputElement > ( null ) ;
8499
85- return (
86- < input
87- aria-disabled = { disabled || undefined }
88- aria-errormessage = { ariaErrorMessage }
89- className = { className }
90- data-id = { dataId }
91- data-testid = { dataTestId }
92- onChange = { disabled ? undefined : onChange }
93- onClick = { onClick }
94- onFocus = { disabled ? undefined : onFocus }
95- onKeyDown = { disabled ? undefined : onKeyDown }
96- onKeyDownCapture = { disabled ? undefined : onKeyDownCapture }
97- onKeyPress = { disabled ? undefined : onKeyPress }
98- onSelect = { disabled ? undefined : onSelect }
99- placeholder = { placeholder }
100- readOnly = { readOnly || disabled }
101- ref = { ref }
102- tabIndex = { disabled ? - 1 : tabIndex }
103- value = { value }
104- { ...props }
105- type = "text"
106- />
107- ) ;
108- }
109- ) ;
100+ const ref = forwardedRef || targetRef ;
101+
102+ useEnterKeyHint ( ref , enterKeyHint ) ;
103+
104+ return (
105+ < input
106+ aria-disabled = { disabled || undefined }
107+ aria-errormessage = { ariaErrorMessage }
108+ aria-label = { ariaLabel }
109+ className = { className }
110+ data-id = { dataId }
111+ data-testid = { dataTestId }
112+ onChange = { disabled ? undefined : onChange }
113+ onClick = { onClick }
114+ onFocus = { disabled ? undefined : onFocus }
115+ onKeyDown = { disabled ? undefined : onKeyDown }
116+ onKeyDownCapture = { disabled ? undefined : onKeyDownCapture }
117+ onKeyPress = { disabled ? undefined : onKeyPress }
118+ onSelect = { disabled ? undefined : onSelect }
119+ placeholder = { placeholder }
120+ readOnly = { readOnly || disabled }
121+ ref = { ref }
122+ tabIndex = { disabled ? - 1 : tabIndex }
123+ value = { value }
124+ { ...props }
125+ type = "text"
126+ />
127+ ) ;
128+ } ) ;
110129
111130AccessibleInputText . displayName = 'AccessibleInputText' ;
112131
113132export default AccessibleInputText ;
133+ export { AccessibleInputTextPropsSchema , type AccessibleInputTextProps } ;
0 commit comments