@@ -282,6 +282,86 @@ it('does not pass TextField-only props through to TextInput', () => {
282282 expect ( input . props . prefixProps ) . toBeUndefined ( ) ;
283283 expect ( input . props . suffix ) . toBeUndefined ( ) ;
284284 expect ( input . props . suffixProps ) . toBeUndefined ( ) ;
285+ expect ( input . props . counter ) . toBeUndefined ( ) ;
286+ expect ( input . props . counterProps ) . toBeUndefined ( ) ;
287+ } ) ;
288+
289+ it ( 'shows a character counter when counter is true and maxLength is set (filled)' , ( ) => {
290+ const { getByText, queryByText } = render (
291+ < TextField
292+ label = "Bio"
293+ value = "hello"
294+ onChangeText = { ( ) => { } }
295+ counter
296+ maxLength = { 100 }
297+ />
298+ ) ;
299+
300+ expect ( getByText ( '5/100' ) ) . toBeTruthy ( ) ;
301+ expect ( queryByText ( '0/100' ) ) . toBeNull ( ) ;
302+ } ) ;
303+
304+ it ( 'shows a character counter when counter is true and maxLength is set (outlined)' , ( ) => {
305+ const { getByText } = render (
306+ < TextField
307+ variant = "outlined"
308+ label = "Bio"
309+ value = ""
310+ onChangeText = { ( ) => { } }
311+ counter
312+ maxLength = { 50 }
313+ />
314+ ) ;
315+
316+ expect ( getByText ( '0/50' ) ) . toBeTruthy ( ) ;
317+ } ) ;
318+
319+ it ( 'updates the character counter when the value changes' , ( ) => {
320+ const { getByText, rerender } = render (
321+ < TextField
322+ label = "Bio"
323+ value = "a"
324+ onChangeText = { ( ) => { } }
325+ counter
326+ maxLength = { 10 }
327+ />
328+ ) ;
329+
330+ expect ( getByText ( '1/10' ) ) . toBeTruthy ( ) ;
331+
332+ rerender (
333+ < TextField
334+ label = "Bio"
335+ value = "abcd"
336+ onChangeText = { ( ) => { } }
337+ counter
338+ maxLength = { 10 }
339+ />
340+ ) ;
341+
342+ expect ( getByText ( '4/10' ) ) . toBeTruthy ( ) ;
343+ } ) ;
344+
345+ it ( 'does not show a character counter when counter is false' , ( ) => {
346+ const { queryByText } = render (
347+ < TextField
348+ label = "Bio"
349+ value = "hello"
350+ onChangeText = { ( ) => { } }
351+ maxLength = { 100 }
352+ />
353+ ) ;
354+
355+ expect ( queryByText ( '5/100' ) ) . toBeNull ( ) ;
356+ } ) ;
357+
358+ it ( 'does not show a character counter when maxLength is missing' , ( ) => {
359+ const { queryByText } = render (
360+ < TextField label = "Bio" value = "hello" onChangeText = { ( ) => { } } counter />
361+ ) ;
362+
363+ expect ( queryByText ( '5/100' ) ) . toBeNull ( ) ;
364+ expect ( queryByText ( / \/ / ) ) . toBeNull ( ) ;
285365} ) ;
286366
287367it ( 'invokes onFocus and onBlur on the TextInput' , ( ) => {
@@ -419,6 +499,39 @@ it('applies supportingTextProps to the supporting Text', () => {
419499 expect ( getByTestId ( 'supporting-text' ) . props . children ) . toBe ( 'Hint' ) ;
420500} ) ;
421501
502+ it ( 'applies counterProps to the counter Text' , ( ) => {
503+ const { getByTestId } = render (
504+ < TextField
505+ label = "Bio"
506+ value = "hi"
507+ onChangeText = { ( ) => { } }
508+ counter
509+ maxLength = { 80 }
510+ counterProps = { { testID : 'counter-text' } }
511+ />
512+ ) ;
513+
514+ expect ( getByTestId ( 'counter-text' ) . props . children ) . toBe ( '2/80' ) ;
515+ } ) ;
516+
517+ it ( 'does not apply supportingTextProps style to the counter Text' , ( ) => {
518+ const { getByTestId } = render (
519+ < TextField
520+ label = "Bio"
521+ value = "x"
522+ onChangeText = { ( ) => { } }
523+ counter
524+ maxLength = { 10 }
525+ supportingTextProps = { { style : { fontSize : 9 } } }
526+ counterProps = { { testID : 'counter-text' } }
527+ />
528+ ) ;
529+
530+ expect (
531+ StyleSheet . flatten ( getByTestId ( 'counter-text' ) . props . style ) . fontSize
532+ ) . not . toBe ( 9 ) ;
533+ } ) ;
534+
422535it ( 'applies RTL text alignment and writing direction to the TextInput (filled)' , ( ) => {
423536 I18nManager . isRTL = true ;
424537
0 commit comments