Files
ThreadNet-Web/packages/shared-components/src/composer/Banner/Banner.tsx
T
ZackandGitHub e8701f5a06 Shared Components Restructure, Cherry Picked | Core (#32914)
* refactor(shared-components): move core primitives under core

* refactor(shared-components): restore i18n strings path

* fix(shared-components): repair typedoc story imports

* fix(shared-components): align newer imports with core paths

* test(shared-components): add core visual baselines

* refactor(shared-components): move virtualized list to core root
2026-03-27 19:58:56 +00:00

93 lines
2.6 KiB
TypeScript

/*
* Copyright (c) 2025 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
import classNames from "classnames";
import React, {
type MouseEventHandler,
type ReactElement,
type ReactNode,
type PropsWithChildren,
useMemo,
type HTMLAttributes,
} from "react";
import { Button } from "@vector-im/compound-web";
import CheckCircleIcon from "@vector-im/compound-design-tokens/assets/web/icons/check-circle";
import ErrorIcon from "@vector-im/compound-design-tokens/assets/web/icons/error";
import InfoIcon from "@vector-im/compound-design-tokens/assets/web/icons/info";
import styles from "./Banner.module.css";
import { _t } from "../../core/i18n/i18n";
interface BannerProps {
/**
* The type of the status banner.
*/
type?: "success" | "info" | "critical";
/**
* The banner avatar.
*/
avatar?: React.ReactNode;
/**
* Actions presented to the user in the right-hand side of the banner alongside the dismiss button.
*/
actions?: ReactNode;
/**
* Called when the user presses the "dismiss" button.
*/
onClose?: MouseEventHandler<HTMLButtonElement>;
}
/**
* A banner component used for displaying user-facing information above the message composer.
*
* @example
* ```tsx
* <Banner onClose={onCloseHandler} />
* ```
*/
export function Banner({
type,
children,
avatar,
className,
actions,
onClose,
...props
}: PropsWithChildren<BannerProps & HTMLAttributes<HTMLDivElement>>): ReactElement {
const classes = classNames(styles.banner, className);
const icon = useMemo((): ReactElement => {
switch (type) {
case "critical":
return <ErrorIcon fontSize={24} />;
case "info":
return <InfoIcon fontSize={24} />;
case "success":
return <CheckCircleIcon fontSize={24} />;
default:
return <InfoIcon fontSize={24} />;
}
}, [type]);
return (
<div {...props} className={classes} data-type={type}>
<div className={styles.icon}>{avatar ?? icon}</div>
<div className={styles.content}>{children}</div>
<div className={styles.actions}>
{actions}
{onClose && (
<Button kind="secondary" size="sm" onClick={onClose}>
{_t("action|dismiss")}
</Button>
)}
</div>
</div>
);
}