1
- import React from 'react' ;
1
+ import React , { useState } from 'react' ;
2
2
import { cleanup , render , screen , fireEvent } from '@testing-library/react' ;
3
+ import userEvent from '@testing-library/user-event' ;
3
4
import { Slot , Slottable } from './slot' ;
4
5
import { afterEach , describe , it , beforeEach , vi , expect } from 'vitest' ;
5
6
@@ -139,6 +140,36 @@ describe('given a Button with Slottable', () => {
139
140
} ) ;
140
141
} ) ;
141
142
143
+ describe ( 'given an Input' , ( ) => {
144
+ const handleRef = vi . fn ( ) ;
145
+
146
+ beforeEach ( ( ) => {
147
+ handleRef . mockReset ( ) ;
148
+ } ) ;
149
+
150
+ afterEach ( cleanup ) ;
151
+
152
+ describe ( 'without asChild' , ( ) => {
153
+ it ( 'should only call function refs once' , async ( ) => {
154
+ render ( < Input ref = { handleRef } /> ) ;
155
+ await userEvent . type ( screen . getByRole ( 'textbox' ) , 'foo' ) ;
156
+ expect ( handleRef ) . toHaveBeenCalledTimes ( 1 ) ;
157
+ } ) ;
158
+ } ) ;
159
+
160
+ describe ( 'with asChild' , ( ) => {
161
+ it ( 'should only call function refs once' , async ( ) => {
162
+ render (
163
+ < Input asChild ref = { handleRef } >
164
+ < input />
165
+ </ Input >
166
+ ) ;
167
+ await userEvent . type ( screen . getByRole ( 'textbox' ) , 'foo' ) ;
168
+ expect ( handleRef ) . toHaveBeenCalledTimes ( 1 ) ;
169
+ } ) ;
170
+ } ) ;
171
+ } ) ;
172
+
142
173
type TriggerProps = React . ComponentProps < 'button' > & { as : React . ElementType } ;
143
174
144
175
const Trigger = ( { as : Comp = 'button' , ...props } : TriggerProps ) => < Comp { ...props } /> ;
@@ -160,3 +191,24 @@ const Button = React.forwardRef<
160
191
</ Comp >
161
192
) ;
162
193
} ) ;
194
+
195
+ const Input = React . forwardRef <
196
+ React . ElementRef < 'input' > ,
197
+ React . ComponentProps < 'input' > & {
198
+ asChild ?: boolean ;
199
+ }
200
+ > ( ( { asChild, children, ...props } , forwardedRef ) => {
201
+ const Comp = asChild ? Slot : 'input' ;
202
+ const [ value , setValue ] = useState ( '' ) ;
203
+
204
+ return (
205
+ < Comp
206
+ { ...props }
207
+ onChange = { ( event ) => setValue ( event . target . value ) }
208
+ ref = { forwardedRef }
209
+ value = { value }
210
+ >
211
+ { children }
212
+ </ Comp >
213
+ ) ;
214
+ } ) ;
0 commit comments