11import React from 'react' ;
22import { useTranslation } from 'react-i18next' ;
3-
43import { Spacer } from '@freecodecamp/ui' ;
4+
55import { parseBlanks } from '../fill-in-the-blank/parse-blanks' ;
66import PrismFormatted from '../components/prism-formatted' ;
77import { FillInTheBlank } from '../../../redux/prop-types' ;
@@ -26,18 +26,22 @@ function FillInTheBlanks({
2626} : FillInTheBlankProps ) : JSX . Element {
2727 const { t } = useTranslation ( ) ;
2828
29- const addInputClass = ( index : number ) : string => {
30- if ( answersCorrect [ index ] === true ) return 'green-underline' ;
31- if ( answersCorrect [ index ] === false ) return 'red-underline' ;
32- return '' ;
29+ const getInputClass = ( index : number ) : string => {
30+ let cls = 'fill-in-the-blank-input' ;
31+
32+ if ( answersCorrect [ index ] === false ) {
33+ cls += ' incorrect-blank-answer' ;
34+ }
35+
36+ return cls ;
3337 } ;
3438
3539 const paragraphs = parseBlanks ( sentence ) ;
3640 const blankAnswers = blanks . map ( b => b . answer ) ;
3741
3842 return (
3943 < >
40- < ChallengeHeading heading = { t ( 'learn.fill-in-the-blank' ) } />
44+ < ChallengeHeading heading = { t ( 'learn.fill-in-the-blank.heading ' ) } />
4145 < Spacer size = 'xs' />
4246 < div className = 'fill-in-the-blank-wrap' >
4347 { paragraphs . map ( ( p , i ) => {
@@ -47,36 +51,49 @@ function FillInTheBlanks({
4751 < p key = { i } >
4852 { p . map ( ( node , j ) => {
4953 const { type, value } = node ;
50- if ( type === 'text' ) return value ;
51- if ( type === 'blank' )
54+ if ( type === 'text' ) {
55+ return value ;
56+ }
57+
58+ // If a blank is answered correctly, render the answer as part of the sentence.
59+ if ( type === 'blank' && answersCorrect [ value ] === true ) {
5260 return (
53- < input
54- key = { j }
55- type = 'text'
56- maxLength = { blankAnswers [ value ] . length + 3 }
57- className = { `fill-in-the-blank-input ${ addInputClass (
58- value
59- ) } `}
60- onChange = { handleInputChange }
61- data-index = { node . value }
62- size = { blankAnswers [ value ] . length }
63- aria-label = { t ( 'learn.blank' ) }
64- />
61+ < span key = { j } className = 'correct-blank-answer' >
62+ { blankAnswers [ value ] }
63+ </ span >
6564 ) ;
65+ }
66+
67+ return (
68+ < input
69+ key = { j }
70+ type = 'text'
71+ maxLength = { blankAnswers [ value ] . length + 3 }
72+ className = { getInputClass ( value ) }
73+ onChange = { handleInputChange }
74+ data-index = { node . value }
75+ size = { blankAnswers [ value ] . length }
76+ autoComplete = 'off'
77+ aria-label = { t ( 'learn.fill-in-the-blank.blank' ) }
78+ { ...( answersCorrect [ value ] === false
79+ ? { 'aria-invalid' : 'true' }
80+ : { } ) }
81+ />
82+ ) ;
6683 } ) }
6784 </ p >
6885 ) ;
6986 } ) }
7087 </ div >
7188 < Spacer size = 'm' />
72- { showFeedback && feedback && (
73- < >
74- < PrismFormatted text = { feedback } / >
75- < Spacer size = 'm' / >
76- < />
77- ) }
78- < div className = 'text-center' >
79- { showWrong && < span > { t ( 'learn.wrong-answer' ) } </ span > }
89+ < div aria-live = 'polite' >
90+ { showWrong && (
91+ < div className = 'text-center' >
92+ < span > { t ( 'learn.wrong-answer' ) } </ span >
93+ < Spacer size = 'm' />
94+ </ div >
95+ ) }
96+ { showFeedback && feedback && < PrismFormatted text = { feedback } / >}
8097 </ div >
8198 </ >
8299 ) ;
0 commit comments