Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Update toast styles to match Figma (#12833)
Browse files Browse the repository at this point in the history
* Warn users on unsupported browsers before they lack features

Signed-off-by: Michael Telatynski <[email protected]>

* Update Learn more link

Signed-off-by: Michael Telatynski <[email protected]>

* Iterate

Signed-off-by: Michael Telatynski <[email protected]>

* Iterate

Signed-off-by: Michael Telatynski <[email protected]>

* Update toast styles to match Figma

Signed-off-by: Michael Telatynski <[email protected]>

* Remove test code

Signed-off-by: Michael Telatynski <[email protected]>

* update tests

Signed-off-by: Michael Telatynski <[email protected]>

* Update tests

Signed-off-by: Michael Telatynski <[email protected]>

* Update snapshots

---------

Signed-off-by: Michael Telatynski <[email protected]>
  • Loading branch information
t3chguy authored Jul 30, 2024
1 parent a189758 commit b0392b8
Show file tree
Hide file tree
Showing 29 changed files with 156 additions and 114 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"@sentry/browser": "^8.0.0",
"@testing-library/react-hooks": "^8.0.1",
"@vector-im/compound-design-tokens": "^1.6.1",
"@vector-im/compound-web": "^5.4.0",
"@vector-im/compound-web": "^5.5.0",
"@zxcvbn-ts/core": "^3.0.4",
"@zxcvbn-ts/language-common": "^3.0.4",
"@zxcvbn-ts/language-en": "^3.0.2",
Expand Down
4 changes: 2 additions & 2 deletions playwright/pages/toasts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class Toasts {
*/
public async acceptToast(expectedTitle: string): Promise<void> {
const toast = await this.getToast(expectedTitle);
await toast.locator(".mx_Toast_buttons .mx_AccessibleButton_kind_primary").click();
await toast.locator('.mx_Toast_buttons button[data-kind="primary"]').click();
}

/**
Expand All @@ -55,6 +55,6 @@ export class Toasts {
*/
public async rejectToast(expectedTitle: string): Promise<void> {
const toast = await this.getToast(expectedTitle);
await toast.locator(".mx_Toast_buttons .mx_AccessibleButton_kind_danger_outline").click();
await toast.locator('.mx_Toast_buttons button[data-kind="secondary"]').click();
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 1 addition & 4 deletions res/css/structures/_ToastContainer.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,14 @@ limitations under the License.
overflow: hidden;
text-overflow: ellipsis;
margin: 4px 0 11px 0;
color: $secondary-content;
font: var(--cpd-font-body-sm-regular);

a {
text-decoration: none;
}
}

.mx_Toast_detail {
color: $secondary-content;
}

.mx_Toast_deviceID {
font-size: $font-10px;
}
Expand Down
10 changes: 6 additions & 4 deletions src/SupportedBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
import { logger } from "matrix-js-sdk/src/logger";
import browserlist from "browserslist";
import electronToChromium from "electron-to-chromium/versions";
import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out";

import { DeviceType, parseUserAgent } from "./utils/device/parseUserAgent";
import ToastStore from "./stores/ToastStore";
Expand Down Expand Up @@ -112,10 +113,11 @@ export function checkBrowserSupport(): void {
title: _t("unsupported_browser|title", { brand }),
props: {
description: _t("unsupported_browser|description", { brand }),
acceptLabel: _t("action|learn_more"),
onAccept: onLearnMoreClick,
rejectLabel: _t("action|dismiss"),
onReject: onDismissClick,
secondaryLabel: _t("action|learn_more"),
SecondaryIcon: PopOutIcon,
onSecondaryClick: onLearnMoreClick,
primaryLabel: _t("action|dismiss"),
onPrimaryClick: onDismissClick,
},
component: GenericToast,
priority: 40,
Expand Down
4 changes: 2 additions & 2 deletions src/components/structures/MatrixChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1390,8 +1390,8 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
title: userNotice.title,
props: {
description: <Linkify>{userNotice.description}</Linkify>,
acceptLabel: _t("action|ok"),
onAccept: () => {
primaryLabel: _t("action|ok"),
onPrimaryClick: () => {
ToastStore.sharedInstance().dismissToast(key);
localStorage.setItem(key, "1");
},
Expand Down
5 changes: 4 additions & 1 deletion src/components/structures/ToastContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.

import * as React from "react";
import classNames from "classnames";
import { Text } from "@vector-im/compound-web";

import ToastStore, { IToast } from "../../stores/ToastStore";

Expand Down Expand Up @@ -78,7 +79,9 @@ export default class ToastContainer extends React.Component<{}, IState> {
if (title) {
titleElement = (
<div className="mx_Toast_title">
<h2>{title}</h2>
<Text size="lg" weight="semibold" as="h2">
{title}
</Text>
<span className="mx_Toast_title_countIndicator">{countIndicator}</span>
</div>
);
Expand Down
12 changes: 6 additions & 6 deletions src/components/views/toasts/GenericExpiringToast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ const SECOND = 1000;

const GenericExpiringToast: React.FC<IProps> = ({
description,
acceptLabel,
primaryLabel,
dismissLabel,
onAccept,
onPrimaryClick,
onDismiss,
toastKey,
numSeconds,
Expand All @@ -52,10 +52,10 @@ const GenericExpiringToast: React.FC<IProps> = ({
return (
<GenericToast
description={description}
acceptLabel={acceptLabel}
onAccept={onAccept}
rejectLabel={rejectLabel}
onReject={onReject}
primaryLabel={primaryLabel}
onPrimaryClick={onPrimaryClick}
secondaryLabel={rejectLabel}
onSecondaryClick={onReject}
/>
);
};
Expand Down
50 changes: 33 additions & 17 deletions src/components/views/toasts/GenericToast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,37 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import React, { ReactNode } from "react";
import React, { ComponentType, ReactNode } from "react";
import { Button } from "@vector-im/compound-web";

import AccessibleButton from "../elements/AccessibleButton";
import { XOR } from "../../../@types/common";

export interface IProps {
description: ReactNode;
detail?: ReactNode;
acceptLabel: string;
primaryLabel: string;
PrimaryIcon?: ComponentType<React.SVGAttributes<SVGElement>>;

onAccept(): void;
onPrimaryClick(): void;
}

interface IPropsExtended extends IProps {
rejectLabel: string;
onReject(): void;
secondaryLabel: string;
SecondaryIcon?: ComponentType<React.SVGAttributes<SVGElement>>;
destructive?: "primary" | "secondary";
onSecondaryClick(): void;
}

const GenericToast: React.FC<XOR<IPropsExtended, IProps>> = ({
description,
detail,
acceptLabel,
rejectLabel,
onAccept,
onReject,
primaryLabel,
PrimaryIcon,
secondaryLabel,
SecondaryIcon,
destructive,
onPrimaryClick,
onSecondaryClick,
}) => {
const detailContent = detail ? <div className="mx_Toast_detail">{detail}</div> : null;

Expand All @@ -49,14 +55,24 @@ const GenericToast: React.FC<XOR<IPropsExtended, IProps>> = ({
{detailContent}
</div>
<div className="mx_Toast_buttons" aria-live="off">
{onReject && rejectLabel && (
<AccessibleButton kind="danger_outline" onClick={onReject}>
{rejectLabel}
</AccessibleButton>
{onSecondaryClick && secondaryLabel && (
<Button
onClick={onSecondaryClick}
kind={destructive === "secondary" ? "destructive" : "secondary"}
Icon={SecondaryIcon}
size="sm"
>
{secondaryLabel}
</Button>
)}
<AccessibleButton onClick={onAccept} kind="primary">
{acceptLabel}
</AccessibleButton>
<Button
onClick={onPrimaryClick}
kind={destructive === "primary" ? "destructive" : "primary"}
Icon={PrimaryIcon}
size="sm"
>
{primaryLabel}
</Button>
</div>
</div>
);
Expand Down
8 changes: 4 additions & 4 deletions src/components/views/toasts/VerificationRequestToast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,14 @@ export default class VerificationRequestToast extends React.PureComponent<IProps
<GenericToast
description={description}
detail={detail}
acceptLabel={
primaryLabel={
request.isSelfVerification || !request.roomId
? _t("encryption|verification|request_toast_accept")
: _t("encryption|verification|request_toast_accept_user")
}
onAccept={this.accept}
rejectLabel={declineLabel}
onReject={this.cancel}
onPrimaryClick={this.accept}
secondaryLabel={declineLabel}
onSecondaryClick={this.cancel}
/>
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/stores/LifecycleStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ async function checkServerVersions(): Promise<void> {
version: MINIMUM_MATRIX_VERSION,
brand: SdkConfig.get().brand,
}),
acceptLabel: _t("action|ok"),
onAccept: () => {
primaryLabel: _t("action|ok"),
onPrimaryClick: () => {
ToastStore.sharedInstance().dismissToast(toastKey);
},
},
Expand Down
16 changes: 8 additions & 8 deletions src/toasts/AnalyticsToast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ export const showToast = (): void => {
// them to opt in again.
props = {
description: _t("analytics|consent_migration"),
acceptLabel: _t("analytics|accept_button"),
onAccept,
rejectLabel: _t("action|learn_more"),
onReject: onLearnMorePreviouslyOptedIn,
primaryLabel: _t("analytics|accept_button"),
onPrimaryClick: onAccept,
secondaryLabel: _t("action|learn_more"),
onSecondaryClick: onLearnMorePreviouslyOptedIn,
};
} else if (legacyAnalyticsOptIn === null || legacyAnalyticsOptIn === undefined) {
// The user had no analytics setting previously set, so we just need to prompt to opt-in, rather than
Expand All @@ -102,10 +102,10 @@ export const showToast = (): void => {
);
props = {
description: _t("analytics|learn_more", {}, { LearnMoreLink: learnMoreLink }),
acceptLabel: _t("action|yes"),
onAccept,
rejectLabel: _t("action|no"),
onReject,
primaryLabel: _t("action|yes"),
onPrimaryClick: onAccept,
secondaryLabel: _t("action|no"),
onSecondaryClick: onReject,
};
} else {
// false
Expand Down
8 changes: 4 additions & 4 deletions src/toasts/BulkUnverifiedSessionsToast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ export const showToast = (deviceIds: Set<string>): void => {
icon: "verification_warning",
props: {
description: _t("encryption|verification|unverified_sessions_toast_description"),
acceptLabel: _t("action|review"),
onAccept,
rejectLabel: _t("encryption|verification|unverified_sessions_toast_reject"),
onReject,
primaryLabel: _t("action|review"),
onPrimaryClick: onAccept,
secondaryLabel: _t("encryption|verification|unverified_sessions_toast_reject"),
onSecondaryClick: onReject,
},
component: GenericToast,
priority: 50,
Expand Down
8 changes: 4 additions & 4 deletions src/toasts/DesktopNotificationsToast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ export const showToast = (fromMessageSend: boolean): void => {
: _t("notifications|enable_prompt_toast_title"),
props: {
description: _t("notifications|enable_prompt_toast_description"),
acceptLabel: _t("action|enable"),
onAccept,
rejectLabel: _t("action|dismiss"),
onReject,
primaryLabel: _t("action|enable"),
onPrimaryClick: onAccept,
secondaryLabel: _t("action|dismiss"),
onSecondaryClick: onReject,
},
component: GenericToast,
priority: 30,
Expand Down
8 changes: 4 additions & 4 deletions src/toasts/MobileGuideToast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ export const showToast = (): void => {
title: _t("mobile_guide|toast_title"),
props: {
description: _t("mobile_guide|toast_description", { brand }),
acceptLabel: _t("mobile_guide|toast_accept"),
onAccept,
rejectLabel: _t("action|dismiss"),
onReject,
primaryLabel: _t("mobile_guide|toast_accept"),
onPrimaryClick: onAccept,
secondaryLabel: _t("action|dismiss"),
onSecondaryClick: onReject,
},
component: GenericToast,
priority: 99,
Expand Down
4 changes: 2 additions & 2 deletions src/toasts/ServerLimitToast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ export const showToast = (
{errorText} {contactText}
</React.Fragment>
),
acceptLabel: _t("action|ok"),
onAccept: () => {
primaryLabel: _t("action|ok"),
onPrimaryClick: () => {
hideToast();
if (onHideToast) onHideToast();
},
Expand Down
9 changes: 5 additions & 4 deletions src/toasts/SetupEncryptionToast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,11 @@ export const showToast = (kind: Kind): void => {
icon: getIcon(kind),
props: {
description: getDescription(kind),
acceptLabel: getSetupCaption(kind),
onAccept,
rejectLabel: _t("encryption|verification|unverified_sessions_toast_reject"),
onReject,
primaryLabel: getSetupCaption(kind),
onPrimaryClick: onAccept,
secondaryLabel: _t("encryption|verification|unverified_sessions_toast_reject"),
onSecondaryClick: onReject,
destructive: "secondary",
},
component: GenericToast,
priority: kind === Kind.VERIFY_THIS_SESSION ? 95 : 40,
Expand Down
9 changes: 5 additions & 4 deletions src/toasts/UnverifiedSessionToast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,11 @@ export const showToast = async (deviceId: string): Promise<void> => {
props: {
description: device.display_name,
detail: <DeviceMetaData device={extendedDevice} />,
acceptLabel: _t("encryption|verification|unverified_session_toast_accept"),
onAccept,
rejectLabel: _t("action|no"),
onReject,
primaryLabel: _t("encryption|verification|unverified_session_toast_accept"),
onPrimaryClick: onAccept,
secondaryLabel: _t("action|no"),
onSecondaryClick: onReject,
destructive: "secondary",
},
component: GenericToast,
priority: 80,
Expand Down
8 changes: 4 additions & 4 deletions src/toasts/UpdateToast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ export const showToast = (version: string, newVersion: string, releaseNotes?: st
title: _t("update|toast_title", { brand }),
props: {
description: _t("update|toast_description", { brand }),
acceptLabel,
onAccept,
rejectLabel: _t("action|dismiss"),
onReject,
primaryLabel: acceptLabel,
onPrimaryClick: onAccept,
secondaryLabel: _t("action|dismiss"),
onSecondaryClick: onReject,
},
component: GenericToast,
priority: 20,
Expand Down
8 changes: 4 additions & 4 deletions test/components/views/toasts/GenericToast-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import GenericToast from "../../../../src/components/views/toasts/GenericToast";

const renderGenericToast = (props: Partial<ComponentProps<typeof GenericToast>> = {}): RenderResult => {
const propsWithDefaults = {
acceptLabel: "Accept",
primaryLabel: "Accept",
description: <div>Description</div>,
onAccept: () => {},
onReject: () => {},
rejectLabel: "Reject",
onPrimaryClick: () => {},
onSecondaryClick: () => {},
secondaryLabel: "Reject",
...props,
};

Expand Down
Loading

0 comments on commit b0392b8

Please sign in to comment.