Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@
"authLoginTitle": "Log in",
"authPlaceholderEmail": "Email",
"authPlaceholderPassword": "Password",
"passwordToggleBtn": "Password is shown",
"authPostedResend": "Resend to {email}",
"authPostedResendAction": "No email showing up?",
"authPostedResendDetail": "Check your email inbox and follow the instructions.",
Expand Down
2 changes: 2 additions & 0 deletions src/script/auth/component/AccountForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@
placeholder={t('accountForm.passwordPlaceholder')}
pattern={ValidationUtil.getNewPasswordPattern(Config.getConfig().NEW_PASSWORD_MINIMUM_LENGTH)}
data-uie-name="enter-password"
togglePasswordBtnLabel={t('passwordToggleBtn')}

Check failure on line 251 in src/script/auth/component/AccountForm.tsx

View workflow job for this annotation

GitHub Actions / test

Type '{ label: string; name: string; id: string; onChange: (event: ChangeEvent<HTMLInputElement>) => void; ref: MutableRefObject<HTMLInputElement>; ... 7 more ...; togglePasswordBtnLabel: string; }' is not assignable to type 'IntrinsicAttributes & { css?: Interpolation<Theme>; } & Omit<InputProps<HTMLInputElement>, "ref"> & RefAttributes<...>'.
/>
<Text muted css={styles.passwordInfo(!!validationErrors.length)} data-uie-name="element-password-help">
{t('accountForm.passwordHelp', {minPasswordLength: String(Config.getConfig().NEW_PASSWORD_MINIMUM_LENGTH)})}
Expand All @@ -269,6 +270,7 @@
placeholder={t('accountForm.confirmPasswordPlaceholder')}
pattern={`^${registrationData.password?.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`}
data-uie-name="enter-confirm-password"
togglePasswordBtnLabel={t('passwordToggleBtn')}

Check failure on line 273 in src/script/auth/component/AccountForm.tsx

View workflow job for this annotation

GitHub Actions / test

Type '{ label: string; name: string; id: string; onChange: (event: ChangeEvent<HTMLInputElement>) => void; ref: MutableRefObject<HTMLInputElement>; ... 6 more ...; togglePasswordBtnLabel: string; }' is not assignable to type 'IntrinsicAttributes & { css?: Interpolation<Theme>; } & Omit<InputProps<HTMLInputElement>, "ref"> & RefAttributes<...>'.
/>

<Exception errors={[authError, ...validationErrors]} />
Expand Down
12 changes: 7 additions & 5 deletions src/script/auth/component/BackButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ export const BackButton = () => {
const navigate = useNavigate();

return (
<ArrowIcon
<button
type="button"
onClick={() => navigate(-1)}
direction="left"
data-uie-name="go-index"
aria-label={t('createPersonalAccount.goBack')}
color={COLOR.TEXT}
/>
data-uie-name="go-index"
css={{background: 'none', border: 'none', cursor: 'pointer'}}
>
<ArrowIcon direction="left" aria-hidden="true" focusable="false" color={COLOR.TEXT} />
</button>
);
};
1 change: 1 addition & 0 deletions src/script/auth/component/ClientItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@
placeholder={t('clientItem.passwordPlaceholder')}
required
type="password"
togglePasswordBtnLabel={t('passwordToggleBtn')}

Check failure on line 314 in src/script/auth/component/ClientItem.tsx

View workflow job for this annotation

GitHub Actions / test

Type '{ autoFocus: true; id: string; autoComplete: string; "data-uie-name": string; ref: MutableRefObject<HTMLInputElement>; name: string; label: string; onChange: (event: ChangeEvent<...>) => void; ... 5 more ...; value: string; }' is not assignable to type 'IntrinsicAttributes & { css?: Interpolation<Theme>; } & Omit<InputProps<HTMLInputElement>, "ref"> & RefAttributes<...>'.
value={password}
/>
</FlexBox>
Expand Down
1 change: 1 addition & 0 deletions src/script/auth/component/JoinGuestLinkPasswordModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
id="guest_link_join_password"
className="modal__input"
type="password"
togglePasswordBtnLabel={t('passwordToggleBtn')}

Check failure on line 86 in src/script/auth/component/JoinGuestLinkPasswordModal.tsx

View workflow job for this annotation

GitHub Actions / test

Type '{ error: Element; "data-uie-name": string; name: string; required: true; placeholder: string; label: string; id: string; className: string; type: string; togglePasswordBtnLabel: string; autoComplete: string; value: string; onChange: (event: FormEvent<...>) => void; }' is not assignable to type 'IntrinsicAttributes & { css?: Interpolation<Theme>; } & Omit<InputProps<HTMLInputElement>, "ref"> & RefAttributes<...>'.
autoComplete="off"
value={passwordValue}
onChange={event => setPasswordValue(event.currentTarget.value)}
Expand Down
1 change: 1 addition & 0 deletions src/script/auth/component/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
pattern={'.{1,1024}'}
required
data-uie-name="enter-password"
togglePasswordBtnLabel={t('passwordToggleBtn')}

Check failure on line 143 in src/script/auth/component/LoginForm.tsx

View workflow job for this annotation

GitHub Actions / test

Type '{ id: string; name: string; onChange: (event: ChangeEvent<HTMLInputElement>) => void; ref: MutableRefObject<HTMLInputElement>; ... 8 more ...; togglePasswordBtnLabel: string; }' is not assignable to type 'IntrinsicAttributes & { css?: Interpolation<Theme>; } & Omit<InputProps<HTMLInputElement>, "ref"> & RefAttributes<...>'.
/>

{isFetching ? (
Expand Down
25 changes: 25 additions & 0 deletions src/script/auth/component/RouteA11y.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Wire
* Copyright (C) 2025 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

import {useRouteA11y} from '../hooks/useRouteA11y';

export const RouteA11y = () => {

Check failure on line 22 in src/script/auth/component/RouteA11y.tsx

View workflow job for this annotation

GitHub Actions / test

Function expression, which lacks return-type annotation, implicitly has an 'any' return type.
useRouteA11y();
return null;
};
53 changes: 53 additions & 0 deletions src/script/auth/hooks/useRouteA11y.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Wire
* Copyright (C) 2025 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

import {useEffect} from 'react';

import {useLocation} from 'react-router-dom';

export function useRouteA11y() {
const location = useLocation();

useEffect(() => {
const focusTarget =
document.querySelector('[data-page-title]') ||
document.querySelector('main,[role="main"]') ||
document.querySelector('h1');

if (!focusTarget) {
return;
}

// scroll to top on each route change
window.scrollTo({top: 0, left: 0});

const element = focusTarget as HTMLElement;
element.setAttribute('tabindex', '-1');
element.classList.add('sr-only-focus');
element.focus({preventScroll: true});

// remove tabindex after blur
const handleBlur = () => {
element.classList.remove('sr-only-focus');
element.removeAttribute('tabindex');
element.removeEventListener('blur', handleBlur);
};
element.addEventListener('blur', handleBlur);
}, [location.key]);
}
4 changes: 3 additions & 1 deletion src/script/auth/page/CreatePersonalAccount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ export const CreatePersonalAccount = () => {
<div css={styles.backButtonContainer}>
<BackButton />
</div>
<p css={styles.header}>{t('createPersonalAccount.headLine')}</p>
<p css={styles.header} role="heading" aria-level={1} data-page-title tabIndex={-1}>
{t('createPersonalAccount.headLine')}
</p>
<AccountForm onSubmit={onSubmit} />
<p css={styles.footer}>{t('createPersonalAccount.subHeader')}</p>
<a css={styles.teamCreateButton} href={EXTERNAL_ROUTE.WIRE_TEAMS_SIGNUP} target="_blank" rel="noreferrer">
Expand Down
10 changes: 8 additions & 2 deletions src/script/auth/page/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -464,11 +464,17 @@ const LoginComponent = ({
<>
<div>
{isEnterpriseLoginV2Enabled ? (
<div css={{fontWeight: '500', fontSize: '1.5rem', marginBottom: '2rem'}}>
<div
css={{fontWeight: '500', fontSize: '1.5rem', marginBottom: '2rem'}}
role="heading"
aria-level={1}
data-page-title
tabIndex={-1}
>
{t('index.welcome', {brandName: Config.getConfig().BACKEND_NAME})}
</div>
) : (
<Heading level={embedded ? '2' : '1'} center>
<Heading level={embedded ? '2' : '1'} center data-page-title tabIndex={-1}>
{t('login.headline')}
</Heading>
)}
Expand Down
9 changes: 9 additions & 0 deletions src/script/auth/page/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {VerifyEmailCode} from './VerifyEmailCode';
import {VerifyEmailLink} from './VerifyEmailLink';

import {Config} from '../../Config';
import {RouteA11y} from '../component/RouteA11y';
import {mapLanguage, normalizeLanguage} from '../localeConfig';
import {actionRoot as ROOT_ACTIONS} from '../module/action/';
import {bindActionCreators, RootState} from '../module/reducer';
Expand All @@ -73,6 +74,13 @@ const RootComponent: FC<RootProps & ConnectedProps & DispatchProps> = ({
isFetchingSSOSettings,
doGetSSOSettings,
}) => {
useEffect(() => {
const style = document.createElement('style');
style.textContent = `.sr-only-focus:focus, .sr-only-focus:focus-visible { outline: none !important; }`;
document.head.appendChild(style);
return () => style.remove();
}, []);

useEffect(() => {
// Force the hash url to have a initial `/` (see https://stackoverflow.com/a/71864506)
const forceSlashAfterHash = () => {
Expand Down Expand Up @@ -146,6 +154,7 @@ const RootComponent: FC<RootProps & ConnectedProps & DispatchProps> = ({
</ContainerXS>
) : (
<Router>
<RouteA11y />
<Routes>
<Route
path={ROUTE.INDEX}
Expand Down
4 changes: 3 additions & 1 deletion src/script/auth/page/SetAccountType.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ export const SetAccountType = () => {
<FlexBox css={styles.headerIcon}>
<BackButton />
</FlexBox>
<FlexBox css={styles.headerText}>{t('selectAccountTypeHeading')}</FlexBox>
<FlexBox css={styles.headerText} role="heading" aria-level={1} data-page-title tabIndex={-1}>
{t('selectAccountTypeHeading')}
</FlexBox>
</FlexBox>
<FlexBox css={styles.optionWrapper}>
{accountTypeOptions.map((option, index) => (
Expand Down
1 change: 1 addition & 0 deletions src/script/auth/page/SetPassword.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
name="password"
placeholder={t('setPassword.passwordPlaceholder')}
type="password"
togglePasswordBtnLabel={t('passwordToggleBtn')}

Check failure on line 94 in src/script/auth/page/SetPassword.tsx

View workflow job for this annotation

GitHub Actions / test

Type '{ autoComplete: string; name: string; placeholder: string; type: string; togglePasswordBtnLabel: string; markInvalid: boolean; onChange: (event: ChangeEvent<HTMLInputElement>) => void; ... 4 more ...; "data-uie-name": string; }' is not assignable to type 'IntrinsicAttributes & { css?: Interpolation<Theme>; } & Omit<InputProps<HTMLInputElement>, "ref"> & RefAttributes<...>'.
markInvalid={!isValidPassword}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
passwordInput.current.setCustomValidity('');
Expand Down
8 changes: 7 additions & 1 deletion src/script/auth/page/SingleSignOn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,13 @@ const SingleSignOnComponent = ({hasDefaultSSOCode}: Props & ConnectedProps & Dis
<div>
{isEnterpriseLoginV2Enabled ? (
<>
<div css={{fontWeight: '500', fontSize: '1.5rem'}}>
<div
css={{fontWeight: '500', fontSize: '1.5rem'}}
role="heading"
aria-level={1}
data-page-title
tabIndex={-1}
>
{t('index.welcome', {brandName: Config.getConfig().BACKEND_NAME})}
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
id="modal_pswd"
className="modal__input"
type="password"
togglePasswordBtnLabel={t('passwordToggleBtn')}

Check failure on line 78 in src/script/components/Modals/PrimaryModal/GuestLinkPasswordForm/GuestLinkPasswordForm.tsx

View workflow job for this annotation

GitHub Actions / test

Type '{ name: string; "data-uie-name": string; required: true; placeholder: string; label: string; helperText: string; id: string; className: string; type: string; togglePasswordBtnLabel: string; autoComplete: string; ... 5 more ...; error: Element; }' is not assignable to type 'IntrinsicAttributes & { css?: Interpolation<Theme>; } & Omit<InputProps<HTMLInputElement>, "ref"> & RefAttributes<...>'.
autoComplete="off"
value={passwordValue}
ref={passwordValueRef}
Expand All @@ -91,6 +92,7 @@
label={t('modalGuestLinkJoinConfirmLabel')}
className="modal__input"
type="password"
togglePasswordBtnLabel={t('passwordToggleBtn')}

Check failure on line 95 in src/script/components/Modals/PrimaryModal/GuestLinkPasswordForm/GuestLinkPasswordForm.tsx

View workflow job for this annotation

GitHub Actions / test

Type '{ name: string; "data-uie-name": string; required: true; placeholder: string; label: string; className: string; type: string; togglePasswordBtnLabel: string; id: string; autoComplete: string; value: string; onChange: (event: FormEvent<...>) => void; markInvalid: boolean; }' is not assignable to type 'IntrinsicAttributes & { css?: Interpolation<Theme>; } & Omit<InputProps<HTMLInputElement>, "ref"> & RefAttributes<...>'.
id="modal_pswd_confirmation"
autoComplete="off"
value={passwordConfirmationValue}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

import {Input} from '@wireapp/react-ui-kit';

import {t} from 'Util/LocalizerUtil';

interface PasswordAdvancedSecurityFormProps {
onSubmit: (event: FormEvent<HTMLFormElement>) => void;
inputValue: string;
Expand All @@ -45,6 +47,7 @@
<Input
id="modal_pswd_with_rules"
type="password"
togglePasswordBtnLabel={t('passwordToggleBtn')}

Check failure on line 50 in src/script/components/Modals/PrimaryModal/PasswordAdvancedSecurityForm/PasswordAdvancedSecurityForm.tsx

View workflow job for this annotation

GitHub Actions / test

Type '{ id: string; type: string; togglePasswordBtnLabel: string; value: string; placeholder: string; required: true; "data-uie-name": string; markInvalid: boolean; onChange: (event: ChangeEvent<HTMLInputElement>) => void; autoComplete: string; pattern: string; helperText: string; error: ReactElement<...>; }' is not assignable to type 'IntrinsicAttributes & { css?: Interpolation<Theme>; } & Omit<InputProps<HTMLInputElement>, "ref"> & RefAttributes<...>'.
value={inputValue}
placeholder={inputPlaceholder}
required
Expand Down
1 change: 1 addition & 0 deletions src/types/i18n.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ declare module 'I18n/en-US.json' {
'authLoginTitle': `Log in`;
'authPlaceholderEmail': `Email`;
'authPlaceholderPassword': `Password`;
'passwordToggleBtn': `Password is shown`;
'authPostedResend': `Resend to {email}`;
'authPostedResendAction': `No email showing up?`;
'authPostedResendDetail': `Check your email inbox and follow the instructions.`;
Expand Down
Loading