Use Compound buttons in auth screens (#32562)
* Use Compound buttons in auth screens Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Simplify Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Replace brandClass with testid Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Fix tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update screenshots Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Replace OIDC native Continue buttons too Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Fix contrast issues on legacy sso buttons Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Tidy css Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update test Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 984 KiB After Width: | Height: | Size: 981 KiB |
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.0 MiB |
@@ -7,19 +7,9 @@ Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
.mx_Login_submit {
|
||||
@mixin mx_DialogButton;
|
||||
font-size: 15px;
|
||||
font-weight: var(--cpd-font-weight-semibold);
|
||||
width: 100%;
|
||||
margin-top: 24px;
|
||||
margin-bottom: 24px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mx_Login_submit:disabled {
|
||||
opacity: 0.3;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.mx_Login_loader {
|
||||
|
||||
@@ -148,7 +148,6 @@ Please see LICENSE files in the repository root for full details.
|
||||
}
|
||||
|
||||
.mx_Login_submit {
|
||||
font-weight: var(--cpd-font-weight-semibold);
|
||||
margin: 0 0 $spacing-16;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,55 +11,33 @@ Please see LICENSE files in the repository root for full details.
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
||||
.mx_SSOButtons_row {
|
||||
& + .mx_SSOButtons_row {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.mx_SSOButtons_row + .mx_SSOButtons_row {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.mx_SSOButton {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: 7px 32px;
|
||||
text-align: center;
|
||||
border-radius: 8px;
|
||||
display: inline-block;
|
||||
font: var(--cpd-font-body-md-semibold);
|
||||
border: 1px solid $input-border-color;
|
||||
color: $primary-content;
|
||||
|
||||
> img {
|
||||
svg,
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
object-fit: contain;
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
top: 4px;
|
||||
color: var(--cpd-color-icon-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.mx_SSOButton:hover {
|
||||
background-color: $panel-actions;
|
||||
}
|
||||
|
||||
.mx_SSOButton_default {
|
||||
color: $accent;
|
||||
background-color: $button-secondary-bg-color;
|
||||
border-color: $accent;
|
||||
}
|
||||
.mx_SSOButton_default.mx_SSOButton_primary {
|
||||
color: $button-primary-fg-color;
|
||||
background-color: $accent;
|
||||
}
|
||||
|
||||
.mx_SSOButton_mini {
|
||||
box-sizing: border-box;
|
||||
width: 50px; /* 48px + 1px border on all sides */
|
||||
height: 50px; /* 48px + 1px border on all sides */
|
||||
min-width: 50px; /* prevent crushing by the flexbox */
|
||||
padding: 12px;
|
||||
|
||||
> img {
|
||||
left: 12px;
|
||||
top: 12px;
|
||||
svg,
|
||||
img {
|
||||
/* 30px parent, 24px self */
|
||||
padding: 3px;
|
||||
position: unset;
|
||||
}
|
||||
|
||||
& + .mx_SSOButton_mini {
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20.8421 7.10595C19.9703 5.6121 18.7876 4.42942 17.2939 3.55764C15.8 2.68581 14.169 2.25001 12.3999 2.25001C10.6311 2.25001 8.9996 2.68594 7.50597 3.55764C6.01212 4.42938 4.82953 5.6121 3.95765 7.10595C3.08592 8.59976 2.65002 10.231 2.65002 11.9997C2.65002 14.1242 3.26987 16.0346 4.50987 17.7315C5.74973 19.4284 7.35145 20.6027 9.3149 21.2543C9.54345 21.2967 9.71264 21.2669 9.82265 21.1656C9.9327 21.0641 9.98766 20.937 9.98766 20.7848C9.98766 20.7595 9.98548 20.531 9.98126 20.0993C9.9769 19.6676 9.97485 19.291 9.97485 18.9696L9.68285 19.0202C9.49667 19.0543 9.26181 19.0687 8.97826 19.0646C8.69484 19.0607 8.40061 19.031 8.09598 18.9757C7.79121 18.921 7.50775 18.7941 7.24536 18.5952C6.98311 18.3963 6.79693 18.1359 6.68688 17.8145L6.55993 17.5224C6.47531 17.3279 6.3421 17.1119 6.1601 16.875C5.97811 16.638 5.79406 16.4773 5.60789 16.3927L5.519 16.329C5.45978 16.2868 5.40482 16.2358 5.35399 16.1766C5.30321 16.1174 5.2652 16.0582 5.23981 15.9988C5.21437 15.9395 5.23545 15.8908 5.30326 15.8526C5.37107 15.8144 5.49361 15.7959 5.67143 15.7959L5.92524 15.8338C6.09451 15.8677 6.3039 15.9691 6.55366 16.1384C6.80329 16.3077 7.0085 16.5277 7.16933 16.7984C7.36408 17.1455 7.59873 17.4099 7.87392 17.5919C8.14889 17.7739 8.42613 17.8648 8.70537 17.8648C8.98461 17.8648 9.22579 17.8436 9.429 17.8015C9.63198 17.7592 9.82243 17.6955 10.0002 17.611C10.0764 17.0437 10.2838 16.6079 10.6222 16.3033C10.1399 16.2526 9.70619 16.1762 9.32099 16.0747C8.93601 15.9731 8.53818 15.8081 8.12777 15.5794C7.71714 15.3509 7.37649 15.0673 7.10574 14.7289C6.83495 14.3904 6.61271 13.9459 6.43934 13.3959C6.26588 12.8457 6.17913 12.211 6.17913 11.4916C6.17913 10.4674 6.51351 9.59578 7.18213 8.87633C6.86892 8.10629 6.89849 7.24304 7.27093 6.28668C7.51638 6.21043 7.88037 6.26765 8.36273 6.45801C8.84517 6.64845 9.1984 6.8116 9.42277 6.94686C9.64714 7.08208 9.82692 7.19666 9.96236 7.2896C10.7496 7.06963 11.562 6.95962 12.3998 6.95962C13.2377 6.95962 14.0503 7.06963 14.8376 7.2896L15.32 6.98505C15.6498 6.78185 16.0394 6.59563 16.4877 6.42635C16.9363 6.25716 17.2793 6.21056 17.5164 6.28682C17.8971 7.24322 17.931 8.10642 17.6177 8.87647C18.2863 9.59591 18.6208 10.4677 18.6208 11.4918C18.6208 12.2111 18.5337 12.8478 18.3605 13.4023C18.1871 13.9568 17.963 14.4008 17.688 14.7353C17.4127 15.0697 17.0699 15.3511 16.6595 15.5795C16.249 15.808 15.851 15.973 15.466 16.0747C15.0809 16.1763 14.6472 16.2527 14.1648 16.3035C14.6048 16.6842 14.8248 17.2851 14.8248 18.106V20.7845C14.8248 20.9367 14.8777 21.0637 14.9836 21.1652C15.0894 21.2665 15.2565 21.2964 15.485 21.2539C17.4487 20.6024 19.0505 19.4281 20.2903 17.7311C21.53 16.0343 22.15 14.1238 22.15 11.9993C22.1496 10.2309 21.7135 8.59976 20.8421 7.10595Z" fill="black"/>
|
||||
<path d="M20.8421 7.10595C19.9703 5.6121 18.7876 4.42942 17.2939 3.55764C15.8 2.68581 14.169 2.25001 12.3999 2.25001C10.6311 2.25001 8.9996 2.68594 7.50597 3.55764C6.01212 4.42938 4.82953 5.6121 3.95765 7.10595C3.08592 8.59976 2.65002 10.231 2.65002 11.9997C2.65002 14.1242 3.26987 16.0346 4.50987 17.7315C5.74973 19.4284 7.35145 20.6027 9.3149 21.2543C9.54345 21.2967 9.71264 21.2669 9.82265 21.1656C9.9327 21.0641 9.98766 20.937 9.98766 20.7848C9.98766 20.7595 9.98548 20.531 9.98126 20.0993C9.9769 19.6676 9.97485 19.291 9.97485 18.9696L9.68285 19.0202C9.49667 19.0543 9.26181 19.0687 8.97826 19.0646C8.69484 19.0607 8.40061 19.031 8.09598 18.9757C7.79121 18.921 7.50775 18.7941 7.24536 18.5952C6.98311 18.3963 6.79693 18.1359 6.68688 17.8145L6.55993 17.5224C6.47531 17.3279 6.3421 17.1119 6.1601 16.875C5.97811 16.638 5.79406 16.4773 5.60789 16.3927L5.519 16.329C5.45978 16.2868 5.40482 16.2358 5.35399 16.1766C5.30321 16.1174 5.2652 16.0582 5.23981 15.9988C5.21437 15.9395 5.23545 15.8908 5.30326 15.8526C5.37107 15.8144 5.49361 15.7959 5.67143 15.7959L5.92524 15.8338C6.09451 15.8677 6.3039 15.9691 6.55366 16.1384C6.80329 16.3077 7.0085 16.5277 7.16933 16.7984C7.36408 17.1455 7.59873 17.4099 7.87392 17.5919C8.14889 17.7739 8.42613 17.8648 8.70537 17.8648C8.98461 17.8648 9.22579 17.8436 9.429 17.8015C9.63198 17.7592 9.82243 17.6955 10.0002 17.611C10.0764 17.0437 10.2838 16.6079 10.6222 16.3033C10.1399 16.2526 9.70619 16.1762 9.32099 16.0747C8.93601 15.9731 8.53818 15.8081 8.12777 15.5794C7.71714 15.3509 7.37649 15.0673 7.10574 14.7289C6.83495 14.3904 6.61271 13.9459 6.43934 13.3959C6.26588 12.8457 6.17913 12.211 6.17913 11.4916C6.17913 10.4674 6.51351 9.59578 7.18213 8.87633C6.86892 8.10629 6.89849 7.24304 7.27093 6.28668C7.51638 6.21043 7.88037 6.26765 8.36273 6.45801C8.84517 6.64845 9.1984 6.8116 9.42277 6.94686C9.64714 7.08208 9.82692 7.19666 9.96236 7.2896C10.7496 7.06963 11.562 6.95962 12.3998 6.95962C13.2377 6.95962 14.0503 7.06963 14.8376 7.2896L15.32 6.98505C15.6498 6.78185 16.0394 6.59563 16.4877 6.42635C16.9363 6.25716 17.2793 6.21056 17.5164 6.28682C17.8971 7.24322 17.931 8.10642 17.6177 8.87647C18.2863 9.59591 18.6208 10.4677 18.6208 11.4918C18.6208 12.2111 18.5337 12.8478 18.3605 13.4023C18.1871 13.9568 17.963 14.4008 17.688 14.7353C17.4127 15.0697 17.0699 15.3511 16.6595 15.5795C16.249 15.808 15.851 15.973 15.466 16.0747C15.0809 16.1763 14.6472 16.2527 14.1648 16.3035C14.6048 16.6842 14.8248 17.2851 14.8248 18.106V20.7845C14.8248 20.9367 14.8777 21.0637 14.9836 21.1652C15.0894 21.2665 15.2565 21.2964 15.485 21.2539C17.4487 20.6024 19.0505 19.4281 20.2903 17.7311C21.53 16.0343 22.15 14.1238 22.15 11.9993C22.1496 10.2309 21.7135 8.59976 20.8421 7.10595Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
@@ -12,6 +12,7 @@ import React, { type JSX, type ReactNode } from "react";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { sleep } from "matrix-js-sdk/src/utils";
|
||||
import { LockSolidIcon, CheckIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
import { Button } from "@vector-im/compound-web";
|
||||
|
||||
import { _t, _td } from "../../../languageHandler";
|
||||
import Modal from "../../../Modal";
|
||||
@@ -417,9 +418,9 @@ export default class ForgotPassword extends React.Component<Props, State> {
|
||||
</StyledCheckbox>
|
||||
</div>
|
||||
{this.state.errorText && <ErrorMessage message={this.state.errorText} />}
|
||||
<button type="submit" className="mx_Login_submit">
|
||||
<Button type="submit" className="mx_Login_submit" size="sm">
|
||||
{submitButtonChild}
|
||||
</button>
|
||||
</Button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</>
|
||||
@@ -432,12 +433,9 @@ export default class ForgotPassword extends React.Component<Props, State> {
|
||||
<CheckIcon className="mx_Icon mx_Icon_32 mx_Icon_accent" />
|
||||
<h1>{_t("auth|reset_password|reset_successful")}</h1>
|
||||
{this.state.logoutDevices ? <p>{_t("auth|reset_password|devices_logout_success")}</p> : null}
|
||||
<input
|
||||
className="mx_Login_submit"
|
||||
type="button"
|
||||
onClick={this.props.onComplete}
|
||||
value={_t("auth|reset_password|return_to_login")}
|
||||
/>
|
||||
<Button className="mx_Login_submit" size="sm" type="button" onClick={this.props.onComplete}>
|
||||
{_t("auth|reset_password|return_to_login")}
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import React, { type JSX, type ReactNode } from "react";
|
||||
import classNames from "classnames";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { type SSOFlow, SSOAction } from "matrix-js-sdk/src/matrix";
|
||||
import { Button } from "@vector-im/compound-web";
|
||||
|
||||
import { _t, UserFriendlyError } from "../../../languageHandler";
|
||||
import Login, { type ClientLoginFlow, type OidcNativeFlow } from "../../../Login";
|
||||
@@ -439,9 +440,10 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
|
||||
private renderOidcNativeStep = (): React.ReactNode => {
|
||||
const flow = this.state.flows!.find((flow) => flow.type === "oidcNativeFlow")! as OidcNativeFlow;
|
||||
return (
|
||||
<AccessibleButton
|
||||
<Button
|
||||
className="mx_Login_fullWidthButton"
|
||||
kind="primary"
|
||||
size="sm"
|
||||
onClick={async () => {
|
||||
await startOidcLogin(
|
||||
this.props.serverConfig.delegatedAuthentication!,
|
||||
@@ -452,7 +454,7 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
|
||||
}}
|
||||
>
|
||||
{_t("action|continue")}
|
||||
</AccessibleButton>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
import React, { type JSX, Fragment, type ReactNode } from "react";
|
||||
import classNames from "classnames";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { Button } from "@vector-im/compound-web";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { adminContactStrings, messageForResourceLimitError, resourceLimitStrings } from "../../../utils/ErrorUtils";
|
||||
@@ -546,9 +547,10 @@ export default class Registration extends React.Component<IProps, IState> {
|
||||
);
|
||||
} else if (this.state.matrixClient && this.state.oidcNativeFlow) {
|
||||
return (
|
||||
<AccessibleButton
|
||||
<Button
|
||||
className="mx_Login_fullWidthButton"
|
||||
kind="primary"
|
||||
size="sm"
|
||||
onClick={async () => {
|
||||
await startOidcLogin(
|
||||
this.props.serverConfig.delegatedAuthentication!,
|
||||
@@ -560,7 +562,7 @@ export default class Registration extends React.Component<IProps, IState> {
|
||||
}}
|
||||
>
|
||||
{_t("action|continue")}
|
||||
</AccessibleButton>
|
||||
</Button>
|
||||
);
|
||||
} else if (this.state.matrixClient && this.state.flows.length) {
|
||||
let ssoSection: JSX.Element | undefined;
|
||||
|
||||
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React, { type ReactNode } from "react";
|
||||
import { Tooltip } from "@vector-im/compound-web";
|
||||
import { Button, Tooltip } from "@vector-im/compound-web";
|
||||
import { RestartIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import AccessibleButton from "../../../views/elements/AccessibleButton";
|
||||
@@ -55,7 +55,9 @@ export const CheckEmail: React.FC<CheckEmailProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
{errorText && <ErrorMessage message={errorText} />}
|
||||
<input onClick={onSubmitForm} type="button" className="mx_Login_submit" value={_t("action|next")} />
|
||||
<Button onClick={onSubmitForm} type="button" className="mx_Login_submit" size="sm">
|
||||
{_t("action|next")}
|
||||
</Button>
|
||||
<div className="mx_AuthBody_did-not-receive">
|
||||
<span className="mx_VerifyEMailDialog_text-light">{_t("auth|check_email_resend_prompt")}</span>
|
||||
<Tooltip description={_t("auth|check_email_resend_tooltip")} placement="top" open={tooltipVisible}>
|
||||
|
||||
@@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import React, { type ReactNode, useRef } from "react";
|
||||
import { EmailSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
import { Button } from "@vector-im/compound-web";
|
||||
|
||||
import { _t, _td } from "../../../../languageHandler";
|
||||
import EmailField from "../../../views/auth/EmailField";
|
||||
@@ -74,9 +75,9 @@ export const EnterEmail: React.FC<EnterEmailProps> = ({
|
||||
/>
|
||||
</div>
|
||||
{errorText && <ErrorMessage message={errorText} />}
|
||||
<button type="submit" className="mx_Login_submit">
|
||||
<Button type="submit" className="mx_Login_submit" size="sm">
|
||||
{submitButtonChild}
|
||||
</button>
|
||||
</Button>
|
||||
<div className="mx_AuthBody_button-container">
|
||||
<AccessibleButton
|
||||
className="mx_AuthBody_sign-in-instead-button"
|
||||
|
||||
@@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import React, { type JSX, type SyntheticEvent } from "react";
|
||||
import classNames from "classnames";
|
||||
import { Button } from "@vector-im/compound-web";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import SdkConfig from "../../../SdkConfig";
|
||||
@@ -433,12 +434,9 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
||||
/>
|
||||
{forgotPasswordJsx}
|
||||
{!this.props.busy && (
|
||||
<input
|
||||
className="mx_Login_submit"
|
||||
type="submit"
|
||||
value={_t("action|sign_in")}
|
||||
disabled={this.props.disableSubmit}
|
||||
/>
|
||||
<Button className="mx_Login_submit" size="sm" type="submit" disabled={this.props.disableSubmit}>
|
||||
{_t("action|sign_in")}
|
||||
</Button>
|
||||
)}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -10,6 +10,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import React, { type JSX, type BaseSyntheticEvent, type ComponentProps, type ReactNode } from "react";
|
||||
import { type MatrixClient, MatrixError } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { Button } from "@vector-im/compound-web";
|
||||
|
||||
import * as Email from "../../../email";
|
||||
import { looksValid as phoneNumberLooksValid, type PhoneNumberCountryDefinition } from "../../../phonenumber";
|
||||
@@ -548,12 +549,9 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
||||
|
||||
public render(): ReactNode {
|
||||
const registerButton = (
|
||||
<input
|
||||
className="mx_Login_submit"
|
||||
type="submit"
|
||||
value={_t("action|register")}
|
||||
disabled={!this.props.canSubmit}
|
||||
/>
|
||||
<Button className="mx_Login_submit" size="sm" type="submit" disabled={!this.props.canSubmit}>
|
||||
{_t("action|register")}
|
||||
</Button>
|
||||
);
|
||||
|
||||
let emailHelperText: JSX.Element | undefined;
|
||||
|
||||
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React, { type JSX } from "react";
|
||||
import React, { type ComponentProps, type JSX } from "react";
|
||||
import { chunk } from "lodash";
|
||||
import classNames from "classnames";
|
||||
import {
|
||||
@@ -18,12 +18,18 @@ import {
|
||||
DELEGATED_OIDC_COMPATIBILITY,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { type Signup } from "@matrix-org/analytics-events/types/typescript/Signup";
|
||||
import { Button, Tooltip } from "@vector-im/compound-web";
|
||||
import { MacIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import PlatformPeg from "../../../PlatformPeg";
|
||||
import AccessibleButton from "./AccessibleButton";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { mediaFromMxc } from "../../../customisations/Media";
|
||||
import { PosthogAnalytics } from "../../../PosthogAnalytics";
|
||||
import { Icon as FacebookIcon } from "../../../../res/img/element-icons/brands/facebook.svg";
|
||||
import { Icon as GithubIcon } from "../../../../res/img/element-icons/brands/github.svg";
|
||||
import { Icon as GitlabIcon } from "../../../../res/img/element-icons/brands/gitlab.svg";
|
||||
import { Icon as GoogleIcon } from "../../../../res/img/element-icons/brands/google.svg";
|
||||
import { Icon as TwitterIcon } from "../../../../res/img/element-icons/brands/twitter.svg";
|
||||
|
||||
interface ISSOButtonProps extends IProps {
|
||||
idp?: IIdentityProvider;
|
||||
@@ -31,24 +37,22 @@ interface ISSOButtonProps extends IProps {
|
||||
action?: SSOAction;
|
||||
}
|
||||
|
||||
const getIcon = (brand: IdentityProviderBrand | string): string | null => {
|
||||
const getIcon = (brand: IdentityProviderBrand | string): typeof FacebookIcon | null => {
|
||||
switch (brand) {
|
||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
case IdentityProviderBrand.Apple:
|
||||
return require("@vector-im/compound-design-tokens/icons/mac.svg").default;
|
||||
return MacIcon;
|
||||
case IdentityProviderBrand.Facebook:
|
||||
return require(`../../../../res/img/element-icons/brands/facebook.svg`).default;
|
||||
return FacebookIcon;
|
||||
case IdentityProviderBrand.Github:
|
||||
return require(`../../../../res/img/element-icons/brands/github.svg`).default;
|
||||
return GithubIcon;
|
||||
case IdentityProviderBrand.Gitlab:
|
||||
return require(`../../../../res/img/element-icons/brands/gitlab.svg`).default;
|
||||
return GitlabIcon;
|
||||
case IdentityProviderBrand.Google:
|
||||
return require(`../../../../res/img/element-icons/brands/google.svg`).default;
|
||||
return GoogleIcon;
|
||||
case IdentityProviderBrand.Twitter:
|
||||
return require(`../../../../res/img/element-icons/brands/twitter.svg`).default;
|
||||
return TwitterIcon;
|
||||
default:
|
||||
return null;
|
||||
/* eslint-enable @typescript-eslint/no-require-imports */
|
||||
}
|
||||
};
|
||||
|
||||
@@ -78,10 +82,10 @@ const SSOButton: React.FC<ISSOButtonProps> = ({
|
||||
fragmentAfterLogin,
|
||||
idp,
|
||||
primary,
|
||||
mini,
|
||||
mini: iconOnly,
|
||||
action,
|
||||
flow,
|
||||
...props
|
||||
disabled,
|
||||
}) => {
|
||||
let label: string;
|
||||
if (idp) {
|
||||
@@ -98,43 +102,43 @@ const SSOButton: React.FC<ISSOButtonProps> = ({
|
||||
PlatformPeg.get()?.startSingleSignOn(matrixClient, loginType, fragmentAfterLogin, idp?.id, action);
|
||||
};
|
||||
|
||||
const commonProps: Partial<ComponentProps<typeof Button>> & Record<`data-${string}`, string> = {
|
||||
iconOnly,
|
||||
className: classNames("mx_SSOButton", {
|
||||
mx_SSOButton_mini: iconOnly,
|
||||
}),
|
||||
onClick,
|
||||
kind: primary ? "primary" : "secondary",
|
||||
disabled,
|
||||
};
|
||||
|
||||
let icon: JSX.Element | undefined;
|
||||
let brandClass: string | undefined;
|
||||
const brandIcon = idp?.brand ? getIcon(idp.brand) : null;
|
||||
if (idp?.brand && brandIcon) {
|
||||
const BrandIcon = idp?.brand ? getIcon(idp.brand) : null;
|
||||
if (idp?.brand && BrandIcon) {
|
||||
const brandName = idp.brand.split(".").pop();
|
||||
brandClass = `mx_SSOButton_brand_${brandName}`;
|
||||
icon = <img src={brandIcon} height="24" width="24" alt={brandName} />;
|
||||
icon = <BrandIcon aria-label={brandName} />;
|
||||
commonProps["data-testid"] = `idp-${idp.id}`;
|
||||
} else if (typeof idp?.icon === "string" && idp.icon.startsWith("mxc://")) {
|
||||
const src = mediaFromMxc(idp.icon, matrixClient).getSquareThumbnailHttp(24) ?? undefined;
|
||||
icon = <img src={src} height="24" width="24" alt={idp.name} />;
|
||||
icon = <img src={src} alt={idp.name} />;
|
||||
}
|
||||
|
||||
const brandPart = brandClass ? { [brandClass]: brandClass } : undefined;
|
||||
const classes = classNames(
|
||||
"mx_SSOButton",
|
||||
{
|
||||
mx_SSOButton_mini: mini,
|
||||
mx_SSOButton_default: !idp,
|
||||
mx_SSOButton_primary: primary,
|
||||
},
|
||||
brandPart,
|
||||
);
|
||||
|
||||
if (mini) {
|
||||
// TODO fallback icon
|
||||
// TODO fallback icon
|
||||
if (iconOnly) {
|
||||
return (
|
||||
<AccessibleButton {...props} title={label} className={classes} onClick={onClick}>
|
||||
{icon}
|
||||
</AccessibleButton>
|
||||
<Tooltip label={label}>
|
||||
<Button {...commonProps} size="lg">
|
||||
{icon}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<AccessibleButton {...props} className={classes} onClick={onClick}>
|
||||
<Button {...commonProps} size="sm">
|
||||
{icon}
|
||||
{label}
|
||||
</AccessibleButton>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1269,7 +1269,7 @@ describe("<MatrixChat />", () => {
|
||||
fireEvent.change(screen.getByLabelText("Password"), { target: { value: password } });
|
||||
|
||||
// sign in button is an input
|
||||
fireEvent.click(screen.getByDisplayValue("Sign in"));
|
||||
fireEvent.click(screen.getByRole("button", { name: "Sign in" }));
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -281,13 +281,13 @@ describe("Login", function () {
|
||||
],
|
||||
});
|
||||
|
||||
const { container } = getComponent();
|
||||
const { container, getByTestId } = getComponent();
|
||||
await waitForElementToBeRemoved(() => screen.queryAllByLabelText("Loading…"));
|
||||
|
||||
for (const idp of idpsWithIcons) {
|
||||
const ssoButton = container.querySelector(`.mx_SSOButton.mx_SSOButton_brand_${idp.brand}`);
|
||||
const ssoButton = getByTestId(`idp-${idp.id}`);
|
||||
expect(ssoButton).toBeTruthy();
|
||||
expect(ssoButton?.querySelector(`img[alt="${idp.brand}"]`)).toBeTruthy();
|
||||
expect(ssoButton.childNodes[0]).toHaveAccessibleName(idp.brand);
|
||||
}
|
||||
|
||||
const ssoButtons = container.querySelectorAll(".mx_SSOButton");
|
||||
|
||||