diff options
author | stanislavh <stanislav.honcharov@sonarsource.com> | 2024-11-28 17:13:02 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-11-29 20:03:06 +0000 |
commit | 7bfb85fef959d5f1cf12f08c88dc9d8025aba6f3 (patch) | |
tree | 7e8214860e449a6e9006a5d387cdadbd31943e15 /server/sonar-web/src | |
parent | 0e670b6152c075f8ada586e5202ce8b89d59a0ab (diff) | |
download | sonarqube-7bfb85fef959d5f1cf12f08c88dc9d8025aba6f3.tar.gz sonarqube-7bfb85fef959d5f1cf12f08c88dc9d8025aba6f3.zip |
SONAR-22289 Fix a11y issues on project key page
Diffstat (limited to 'server/sonar-web/src')
-rw-r--r-- | server/sonar-web/src/main/js/apps/projectKey/ProjectKeyApp.tsx | 7 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx | 163 |
2 files changed, 90 insertions, 80 deletions
diff --git a/server/sonar-web/src/main/js/apps/projectKey/ProjectKeyApp.tsx b/server/sonar-web/src/main/js/apps/projectKey/ProjectKeyApp.tsx index 5e941b47821..3a790292b68 100644 --- a/server/sonar-web/src/main/js/apps/projectKey/ProjectKeyApp.tsx +++ b/server/sonar-web/src/main/js/apps/projectKey/ProjectKeyApp.tsx @@ -18,8 +18,9 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { Heading } from '@sonarsource/echoes-react'; import { Helmet } from 'react-helmet-async'; -import { LargeCenteredLayout, PageContentFontWrapper, Title } from '~design-system'; +import { LargeCenteredLayout, PageContentFontWrapper } from '~design-system'; import { withRouter } from '~sonar-aligned/components/hoc/withRouter'; import { Router } from '~sonar-aligned/types/router'; import { changeKey } from '../../api/components'; @@ -47,7 +48,9 @@ function ProjectKeyApp({ component, router }: Props) { <Helmet defer={false} title={translate('update_key.page')} /> <PageContentFontWrapper className="sw-my-8 sw-typo-default"> <header className="sw-mt-8 sw-mb-4"> - <Title className="sw-mb-4">{translate('update_key.page')}</Title> + <Heading as="h1" className="sw-mb-4"> + {translate('update_key.page')} + </Heading> <div className="sw-mb-2">{translate('update_key.page.description')}</div> </header> <UpdateForm component={component} onKeyChange={handleChangeKey} /> diff --git a/server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx b/server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx index a9337558cc5..7d82b428ff7 100644 --- a/server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx +++ b/server/sonar-web/src/main/js/apps/projectKey/UpdateForm.tsx @@ -18,17 +18,11 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { Button, ButtonVariety, ModalAlert, Text } from '@sonarsource/echoes-react'; import * as React from 'react'; -import { - ButtonPrimary, - ButtonSecondary, - FlagMessage, - FormField, - InputField, - Note, -} from '~design-system'; -import ConfirmButton from '../../components/controls/ConfirmButton'; -import { translate, translateWithParameters } from '../../helpers/l10n'; +import { useIntl } from 'react-intl'; +import { FlagMessage, FormField, InputField } from '~design-system'; +import { translate } from '../../helpers/l10n'; import { validateProjectKey } from '../../helpers/projects'; import { ProjectKeyValidationResult } from '../../types/component'; import { Component } from '../../types/types'; @@ -38,8 +32,8 @@ export interface UpdateFormProps { onKeyChange: (newKey: string) => Promise<void>; } -export default function UpdateForm(props: UpdateFormProps) { - const { component } = props; +export default function UpdateForm({ component, onKeyChange }: Readonly<UpdateFormProps>) { + const intl = useIntl(); const [newKey, setNewKey] = React.useState(component.key); const hasChanged = newKey !== component.key; @@ -57,76 +51,89 @@ export default function UpdateForm(props: UpdateFormProps) { ); return ( - <ConfirmButton - confirmButtonText={translate('update_verb')} - confirmData={newKey} - modalBody={ - <> - {translateWithParameters('update_key.are_you_sure_to_change_key', component.name)} - <div className="sw-mt-2"> - {translate('update_key.old_key')} - {': '} - <strong className="sw-typo-lg-semibold">{component.key}</strong> - </div> - <div className="sw-mt-2"> - {translate('update_key.new_key')} - {': '} - <strong className="sw-typo-lg-semibold">{newKey}</strong> - </div> - </> - } - modalHeader={translate('update_key.page')} - onConfirm={props.onKeyChange} - > - {({ onFormSubmit }) => ( - <form onSubmit={onFormSubmit}> - <FormField label={translate('update_key.new_key')} required> - <InputField - id="project-key" - name="update_key.new_key" - required - isInvalid={hasChanged && error !== undefined} - isValid={hasChanged && error === undefined} - autoFocus - onChange={onInputChange} - value={newKey} - type="text" - /> + <form onSubmit={(e) => e.preventDefault()}> + <FormField htmlFor="project-key-input" label={translate('update_key.new_key')} required> + <InputField + id="project-key-input" + name="update_key.new_key" + required + aria-invalid={hasChanged && error !== undefined} + aria-describedby="project-key-input-error project-key-input-hint" + isInvalid={hasChanged && error !== undefined} + isValid={hasChanged && error === undefined} + autoFocus + onChange={onInputChange} + value={newKey} + type="text" + /> - {error && ( - <FlagMessage className="sw-mt-2 sw-w-abs-400" variant="error"> - {error} - </FlagMessage> - )} + <output> + {Boolean(error) && ( + <FlagMessage + id="project-key-input-error" + className="sw-mt-2 sw-w-abs-400" + variant="error" + > + {error} + </FlagMessage> + )} + </output> - <Note className="sw-mt-2 sw-max-w-1/2"> - {translate('onboarding.create_project.project_key.description')} - </Note> - </FormField> + <Text isSubdued className="sw-mt-2 sw-max-w-1/2"> + <span id="project-key-input-hint"> + {translate('onboarding.create_project.project_key.description')} + </span> + </Text> + </FormField> - <div className="sw-mt-2"> - <ButtonPrimary - disabled={!hasChanged || error !== undefined} - id="update-key-submit" - type="submit" - > + <div className="sw-mt-2"> + <ModalAlert + primaryButton={ + <Button variety={ButtonVariety.Primary} onClick={() => onKeyChange(newKey)}> {translate('update_verb')} - </ButtonPrimary> + </Button> + } + title={translate('update_key.page')} + description={intl.formatMessage( + { id: 'update_key.are_you_sure_to_change_key' }, + { '0': component.name }, + )} + content={ + <> + <span> + {translate('update_key.old_key')}: + <strong className="sw-typo-lg-semibold">{component.key}</strong> + </span> + <div className="sw-mt-2"> + {translate('update_key.new_key')}: + <strong className="sw-typo-lg-semibold">{newKey}</strong> + </div> + </> + } + > + <Button + variety={ButtonVariety.Primary} + isDisabled={!hasChanged || error !== undefined} + id="update-key-submit" + type="submit" + > + {translate('update_verb')} + </Button> + </ModalAlert> - <ButtonSecondary - className="sw-ml-2" - disabled={!hasChanged} - id="update-key-reset" - onClick={() => { - setNewKey(component.key); - }} - type="reset" - > - {translate('reset_verb')} - </ButtonSecondary> - </div> - </form> - )} - </ConfirmButton> + <Button + variety={ButtonVariety.Default} + className="sw-ml-2" + isDisabled={!hasChanged} + id="update-key-reset" + onClick={() => { + setNewKey(component.key); + }} + type="reset" + > + {translate('reset_verb')} + </Button> + </div> + </form> ); } |