@intility/bifrost-react
Version:
React library for Intility's design system, Bifrost.
133 lines (131 loc) • 4.61 kB
JavaScript
"use client";
import { faAngleRight } from "@fortawesome/free-solid-svg-icons/faAngleRight";
import { faCircleCheck } from "@fortawesome/free-solid-svg-icons/faCircleCheck";
import { faCircleExclamation } from "@fortawesome/free-solid-svg-icons/faCircleExclamation";
import { faCircleInfo } from "@fortawesome/free-solid-svg-icons/faCircleInfo";
import { faTriangleExclamation } from "@fortawesome/free-solid-svg-icons/faTriangleExclamation";
import { faXmark } from "@fortawesome/free-solid-svg-icons/faXmark";
import classNames from "classnames";
import { forwardRef, useState } from "react";
import useLocale from "../../hooks/useLocale.js";
import accessibleOnClick from "../../utils/accessibleOnClick.js";
import Icon from "../Icon/Icon.js";
import SlideDown from "../SlideDown/SlideDown.js";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const statusBarStateClass = {
default: "bfc-theme-bg",
neutral: "bfc-neutral-bg",
brand: "bfc-brand-bg",
chill: "bfc-chill-bg",
attn: "bfc-attn-bg",
success: "bfc-success-bg",
warning: "bfc-warning-bg",
alert: "bfc-alert-bg"
};
const messageStateClass = {
default: "bfc-theme-fade-bg",
neutral: "bfc-neutral-fade-bg",
brand: "bfc-brand-fade-bg",
chill: "bfc-chill-fade-bg",
attn: "bfc-attn-fade-bg",
success: "bfc-success-fade-bg",
warning: "bfc-warning-fade-bg",
alert: "bfc-alert-fade-bg"
};
/**
* Display a highlighted message
*
* @see https://bifrost.intility.com/react/message
*
* @example
* <Message>Text</Message>
* <Message state="warning">Yellow box</Message>
*
* @example
* <Message expandable header="Header text will be the clickable button">
* Content inside will be toggleable
* </Message>
*/
const Message = /*#__PURE__*/forwardRef(({
children,
className,
style,
header,
state = "default",
icon,
noIcon,
statusBar = false,
noPadding,
onClose,
expandable = false,
isOpen,
onHeaderClick,
eager = false,
radius = "m",
...props
}, ref) => {
const [active, setActive] = useState(isOpen ?? false);
const controlled = isOpen !== undefined && onHeaderClick !== undefined;
const locale = useLocale();
const handleClick = () => {
if (onHeaderClick) onHeaderClick();
setActive(!active);
};
if (!icon && !noIcon) {
icon = state === "success" ? faCircleCheck : state === "warning" ? faCircleExclamation : state === "alert" ? faTriangleExclamation : faCircleInfo;
}
const expandMode = (expandable || controlled) && header;
const bgColorClass = statusBar ? statusBarStateClass[state] ?? statusBarStateClass.default : messageStateClass[state] ?? messageStateClass.default;
return /*#__PURE__*/_jsxs("div", {
...props,
className: classNames("bf-message bf-break-word", className, {
[bgColorClass]: !expandMode,
"bf-message-only-header": header && !children || statusBar && !header,
"bf-message-expandable": expandable || controlled,
"bf-message-expandable-active": controlled ? isOpen : active
}),
style: {
["--bf-message-radius"]: typeof radius === "string" && radius !== "m" && `var(--bf-radius-${radius})`,
...style
},
ref: ref,
children: [onClose && /*#__PURE__*/_jsx("button", {
type: "button",
"aria-label": locale.closeMessage,
className: "bf-message-close",
onClick: onClose,
children: /*#__PURE__*/_jsx(Icon, {
icon: faXmark
})
}), (header || statusBar && children) && /*#__PURE__*/_jsxs("header", {
className: classNames("bf-message-header", {
[bgColorClass]: expandMode
}),
...(expandMode && accessibleOnClick(props, () => handleClick())),
children: [expandMode && /*#__PURE__*/_jsx("div", {
className: "bf-message-expandable-icon",
children: /*#__PURE__*/_jsx(Icon, {
icon: faAngleRight
})
}), icon && /*#__PURE__*/_jsx(Icon, {
icon: icon,
className: "bf-message-icon"
}), header || statusBar && children]
}), expandMode ? /*#__PURE__*/_jsx(SlideDown, {
open: controlled ? isOpen : active,
"data-testid": "bf-message-expandable-content",
eager: eager,
children: /*#__PURE__*/_jsx("div", {
className: classNames("bf-message-expandable-content", {
"bf-success": state === "success",
"bf-warning": state === "warning",
"bf-alert": state === "alert",
"bf-nopadding": noPadding
}),
children: children
})
}) : (!statusBar || statusBar && header) && children]
});
});
Message.displayName = "Message";
export default Message;