mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-01-08 21:02:25 -05:00
fix(a11y): accessible name for text inputs on settings page (#52723)
Co-authored-by: Naomi Carrigan <nhcarrigan@gmail.com>
This commit is contained in:
@@ -217,33 +217,36 @@ class AboutSettings extends Component<AboutProps, AboutState> {
|
||||
>
|
||||
<div role='group' aria-label={t('settings.headings.personal-info')}>
|
||||
<FormGroup controlId='about-name'>
|
||||
<ControlLabel>
|
||||
<ControlLabel htmlFor='about-name-input'>
|
||||
<strong>{t('settings.labels.name')}</strong>
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.handleNameChange}
|
||||
type='text'
|
||||
value={name}
|
||||
id='about-name-input'
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup controlId='about-location'>
|
||||
<ControlLabel>
|
||||
<ControlLabel htmlFor='about-location-input'>
|
||||
<strong>{t('settings.labels.location')}</strong>
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.handleLocationChange}
|
||||
type='text'
|
||||
value={location}
|
||||
id='about-location-input'
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup controlId='about-picture'>
|
||||
<ControlLabel>
|
||||
<ControlLabel htmlFor='about-picture-input'>
|
||||
<strong>{t('settings.labels.picture')}</strong>
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.handlePictureChange}
|
||||
type='url'
|
||||
value={picture}
|
||||
id='about-picture-input'
|
||||
/>
|
||||
{!this.state.isPictureUrlValid && (
|
||||
<ShowImageValidationWarning
|
||||
@@ -252,13 +255,14 @@ class AboutSettings extends Component<AboutProps, AboutState> {
|
||||
)}
|
||||
</FormGroup>
|
||||
<FormGroup controlId='about-about'>
|
||||
<ControlLabel>
|
||||
<ControlLabel htmlFor='about-about-input'>
|
||||
<strong>{t('settings.labels.about')}</strong>
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
componentClass='textarea'
|
||||
onChange={this.handleAboutChange}
|
||||
value={about}
|
||||
id='about-about-input'
|
||||
/>
|
||||
</FormGroup>
|
||||
</div>
|
||||
|
||||
@@ -203,13 +203,16 @@ function EmailSettings({
|
||||
controlId='new-email'
|
||||
validationState={newEmailValidation}
|
||||
>
|
||||
<ControlLabel>{t('settings.email.new')}</ControlLabel>
|
||||
<ControlLabel htmlFor='new-email-input'>
|
||||
{t('settings.email.new')}
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
data-cy='email-input'
|
||||
data-playwright-test-label='new-email-input'
|
||||
onChange={createHandleEmailFormChange('newEmail')}
|
||||
type='email'
|
||||
value={newEmail}
|
||||
id='new-email-input'
|
||||
/>
|
||||
{newEmailValidationMessage ? (
|
||||
<HelpBlock data-cy='validation-message'>
|
||||
@@ -221,13 +224,16 @@ function EmailSettings({
|
||||
controlId='confirm-email'
|
||||
validationState={confirmEmailValidation}
|
||||
>
|
||||
<ControlLabel>{t('settings.email.confirm')}</ControlLabel>
|
||||
<ControlLabel htmlFor='confirm-email-input'>
|
||||
{t('settings.email.confirm')}
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
data-cy='confirm-email'
|
||||
data-playwright-test-label='confirm-email-input'
|
||||
onChange={createHandleEmailFormChange('confirmNewEmail')}
|
||||
type='email'
|
||||
value={confirmNewEmail}
|
||||
id='confirm-email-input'
|
||||
/>
|
||||
{confirmEmailValidationMessage ? (
|
||||
<HelpBlock data-cy='validation-message'>
|
||||
|
||||
@@ -211,13 +211,16 @@ class InternetSettings extends Component<InternetProps, InternetState> {
|
||||
controlId='internet-github'
|
||||
validationState={githubProfileValidation}
|
||||
>
|
||||
<ControlLabel>GitHub</ControlLabel>
|
||||
<ControlLabel htmlFor='internet-github-input'>
|
||||
GitHub
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
data-playwright-test-label='internet-github-input'
|
||||
onChange={this.createHandleChange('githubProfile')}
|
||||
placeholder='https://github.com/user-name'
|
||||
type='url'
|
||||
value={githubProfile}
|
||||
id='internet-github-input'
|
||||
/>
|
||||
{this.renderCheck(
|
||||
githubProfile,
|
||||
@@ -230,13 +233,16 @@ class InternetSettings extends Component<InternetProps, InternetState> {
|
||||
controlId='internet-linkedin'
|
||||
validationState={linkedinValidation}
|
||||
>
|
||||
<ControlLabel>LinkedIn</ControlLabel>
|
||||
<ControlLabel htmlFor='internet-linkedin-input'>
|
||||
LinkedIn
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
data-playwright-test-label='internet-linkedin-input'
|
||||
onChange={this.createHandleChange('linkedin')}
|
||||
placeholder='https://www.linkedin.com/in/user-name'
|
||||
type='url'
|
||||
value={linkedin}
|
||||
id='internet-linkedin-input'
|
||||
/>
|
||||
{this.renderCheck(
|
||||
linkedin,
|
||||
@@ -246,16 +252,19 @@ class InternetSettings extends Component<InternetProps, InternetState> {
|
||||
<Info message={linkedinValidationMessage} />
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
controlId='internet-picture'
|
||||
controlId='internet-twitter'
|
||||
validationState={twitterValidation}
|
||||
>
|
||||
<ControlLabel>Twitter</ControlLabel>
|
||||
<ControlLabel htmlFor='internet-twitter-input'>
|
||||
Twitter
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
data-playwright-test-label='internet-twitter-input'
|
||||
onChange={this.createHandleChange('twitter')}
|
||||
placeholder='https://twitter.com/user-name'
|
||||
type='url'
|
||||
value={twitter}
|
||||
id='internet-twitter-input'
|
||||
/>
|
||||
{this.renderCheck(
|
||||
twitter,
|
||||
@@ -268,13 +277,16 @@ class InternetSettings extends Component<InternetProps, InternetState> {
|
||||
controlId='internet-website'
|
||||
validationState={websiteValidation}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.personal')}</ControlLabel>
|
||||
<ControlLabel htmlFor='internet-website-input'>
|
||||
{t('settings.labels.personal')}
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
data-playwright-test-label='internet-website-input'
|
||||
onChange={this.createHandleChange('website')}
|
||||
placeholder='https://example.com'
|
||||
type='url'
|
||||
value={website}
|
||||
id='internet-website-input'
|
||||
/>
|
||||
{this.renderCheck(
|
||||
website,
|
||||
|
||||
@@ -267,13 +267,16 @@ class PortfolioSettings extends Component<PortfolioProps, PortfolioState> {
|
||||
pristine || (!pristine && !title) ? null : titleState
|
||||
}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.title')}</ControlLabel>
|
||||
<ControlLabel htmlFor={`${id}-title-input`}>
|
||||
{t('settings.labels.title')}
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.createOnChangeHandler(id, 'title')}
|
||||
required={true}
|
||||
type='text'
|
||||
value={title}
|
||||
data-cy='portfolio-title'
|
||||
id={`${id}-title-input`}
|
||||
/>
|
||||
{titleMessage ? (
|
||||
<HelpBlock data-cy='validation-message'>{titleMessage}</HelpBlock>
|
||||
@@ -283,13 +286,16 @@ class PortfolioSettings extends Component<PortfolioProps, PortfolioState> {
|
||||
controlId={`${id}-url`}
|
||||
validationState={pristine || (!pristine && !url) ? null : urlState}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.url')}</ControlLabel>
|
||||
<ControlLabel htmlFor={`${id}-url-input`}>
|
||||
{t('settings.labels.url')}
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.createOnChangeHandler(id, 'url')}
|
||||
required={true}
|
||||
type='url'
|
||||
value={url}
|
||||
data-cy='portfolio-url'
|
||||
id={`${id}-url-input`}
|
||||
/>
|
||||
{urlMessage ? (
|
||||
<HelpBlock data-cy='validation-message'>{urlMessage}</HelpBlock>
|
||||
@@ -299,12 +305,15 @@ class PortfolioSettings extends Component<PortfolioProps, PortfolioState> {
|
||||
controlId={`${id}-image`}
|
||||
validationState={pristine ? null : imageState}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.image')}</ControlLabel>
|
||||
<ControlLabel htmlFor={`${id}-image-input`}>
|
||||
{t('settings.labels.image')}
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
onChange={this.createOnChangeHandler(id, 'image')}
|
||||
type='url'
|
||||
value={image}
|
||||
data-cy='portfolio-image'
|
||||
id={`${id}-image-input`}
|
||||
/>
|
||||
{imageMessage ? (
|
||||
<HelpBlock data-cy='validation-message'>{imageMessage}</HelpBlock>
|
||||
@@ -314,12 +323,15 @@ class PortfolioSettings extends Component<PortfolioProps, PortfolioState> {
|
||||
controlId={`${id}-description`}
|
||||
validationState={pristine ? null : descriptionState}
|
||||
>
|
||||
<ControlLabel>{t('settings.labels.description')}</ControlLabel>
|
||||
<ControlLabel htmlFor={`${id}-description-input`}>
|
||||
{t('settings.labels.description')}
|
||||
</ControlLabel>
|
||||
<FormControl
|
||||
componentClass='textarea'
|
||||
onChange={this.createOnChangeHandler(id, 'description')}
|
||||
value={description}
|
||||
data-cy='portfolio-description'
|
||||
id={`${id}-description-input`}
|
||||
/>
|
||||
{descriptionMessage ? (
|
||||
<HelpBlock data-cy='validation-message'>
|
||||
|
||||
@@ -3,7 +3,7 @@ describe('Picture input field', () => {
|
||||
cy.login();
|
||||
cy.visit('/settings');
|
||||
// Setting aliases here
|
||||
cy.get('input#about-picture').as('pictureInput');
|
||||
cy.get('#about-picture-input').as('pictureInput');
|
||||
});
|
||||
|
||||
it('Should be possible to type', () => {
|
||||
|
||||
Reference in New Issue
Block a user