i18n for banner

This commit is contained in:
Half-Shot 2025-12-18 23:09:48 +00:00
parent 7ce4f49cd5
commit c799ee2e38
2 changed files with 23 additions and 17 deletions

View File

@ -12,6 +12,7 @@ import React, {
type ReactNode,
type PropsWithChildren,
useMemo,
HTMLAttributes,
} from "react";
import { Button } from "@vector-im/compound-web";
import CheckCircleIcon from "@vector-im/compound-design-tokens/assets/web/icons/check-circle";
@ -32,8 +33,6 @@ interface BannerProps {
*/
avatar?: React.ReactNode;
className?: string;
/**
* Actions presented to the user in the right-hand side of the banner alongside the dismiss button.
*/
@ -60,19 +59,19 @@ export function Banner({
actions,
onClose,
...props
}: PropsWithChildren<BannerProps>): ReactElement {
}: PropsWithChildren<BannerProps&HTMLAttributes<HTMLDivElement>>): ReactElement {
const classes = classNames(styles.banner, className);
const icon = useMemo(() => {
const icon = useMemo((): ReactElement => {
switch (type) {
case "critical":
return <ErrorIcon fontSize={24} {...props} />;
return <ErrorIcon fontSize={24} />;
case "info":
return <InfoIcon fontSize={24} {...props} />;
return <InfoIcon fontSize={24} />;
case "success":
return <CheckCircleIcon fontSize={24} {...props} />;
return <CheckCircleIcon fontSize={24} />;
default:
return <InfoIcon fontSize={24} {...props} />;
return <InfoIcon fontSize={24} />;
}
}, [type, props]);

View File

@ -5,7 +5,7 @@
* Please see LICENSE files in the repository root for full details.
*/
import React, { useCallback, type JSX } from "react";
import React, { useCallback, useId, type JSX } from "react";
import styles from "./RoomStatusBarView.module.css";
import { useViewModel } from "../../useViewModel";
@ -85,6 +85,7 @@ interface RoomStatusBarViewProps {
export function RoomStatusBarView({ vm }: Readonly<RoomStatusBarViewProps>): JSX.Element {
const { translate: _t } = useI18n();
const { state } = useViewModel(vm);
const bannerTitleId = useId();
const deleteAllClick = useCallback<React.MouseEventHandler<HTMLButtonElement>>(
(ev) => {
@ -117,9 +118,9 @@ export function RoomStatusBarView({ vm }: Readonly<RoomStatusBarViewProps>): JSX
if ("connectionLost" in state) {
return (
<Banner type="critical">
<Banner type="critical" role="status" aria-labelledby={bannerTitleId}>
<div className={styles.container}>
<Text weight="semibold">{_t("room|status_bar|server_connectivity_lost_title")}</Text>
<Text id={bannerTitleId} weight="semibold">{_t("room|status_bar|server_connectivity_lost_title")}</Text>
<Text className={styles.description}>
{_t("room|status_bar|server_connectivity_lost_description")}
</Text>
@ -132,6 +133,8 @@ export function RoomStatusBarView({ vm }: Readonly<RoomStatusBarViewProps>): JSX
return (
<Banner
type="critical"
role="status"
aria-labelledby={bannerTitleId}
actions={
<Button
kind="secondary"
@ -141,12 +144,12 @@ export function RoomStatusBarView({ vm }: Readonly<RoomStatusBarViewProps>): JSX
target="_blank"
rel="noreferrer noopener"
>
View Terms and Conditions
{_t("terms|tac_button")}
</Button>
}
>
<div className={styles.container}>
<Text weight="semibold">{_t("room|status_bar|requires_consent_agreement_title")}</Text>
<Text id={bannerTitleId} weight="semibold">{_t("room|status_bar|requires_consent_agreement_title")}</Text>
</div>
</Banner>
);
@ -162,6 +165,8 @@ export function RoomStatusBarView({ vm }: Readonly<RoomStatusBarViewProps>): JSX
return (
<Banner
type="critical"
role="status"
aria-labelledby={bannerTitleId}
actions={
state.adminContactHref && (
<Button
@ -178,7 +183,7 @@ export function RoomStatusBarView({ vm }: Readonly<RoomStatusBarViewProps>): JSX
}
>
<div className={styles.container}>
<Text weight="semibold">{title}</Text>
<Text id={bannerTitleId} weight="semibold">{title}</Text>
<Text className={styles.description}>
{_t("room|status_bar|exceeded_resource_limit_description")}
</Text>
@ -190,7 +195,9 @@ export function RoomStatusBarView({ vm }: Readonly<RoomStatusBarViewProps>): JSX
if ("isRetryingRoomCreation" in state) {
return (
<Banner
role="status"
type="critical"
aria-labelledby={bannerTitleId}
actions={
<Button
size="sm"
@ -204,7 +211,7 @@ export function RoomStatusBarView({ vm }: Readonly<RoomStatusBarViewProps>): JSX
</Button>
}
>
<Text weight="semibold" className={styles.container}>{_t("room|status_bar|failed_to_create_room_title")}</Text>
<Text id={bannerTitleId} weight="semibold" className={styles.container}>{_t("room|status_bar|failed_to_create_room_title")}</Text>
</Banner>
);
}
@ -240,9 +247,9 @@ export function RoomStatusBarView({ vm }: Readonly<RoomStatusBarViewProps>): JSX
);
return (
<Banner type="critical" actions={actions}>
<Banner role="status" type="critical" actions={actions} aria-labelledby={bannerTitleId}>
<div className={styles.container}>
<Text weight="semibold">{_t("room|status_bar|some_messages_not_sent")}</Text>
<Text id={bannerTitleId} weight="semibold">{_t("room|status_bar|some_messages_not_sent")}</Text>
<Text className={styles.description}>{_t("room|status_bar|select_messages_to_retry")}</Text>
</div>
</Banner>