@octopusdeploy/design-system-components
Version:
The design systems component library.
143 lines (142 loc) • 7.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorSummary = ErrorSummary;
const jsx_runtime_1 = require("react/jsx-runtime");
const css_1 = require("@emotion/css");
const design_system_icons_1 = require("@octopusdeploy/design-system-icons");
const design_system_tokens_1 = require("@octopusdeploy/design-system-tokens");
const react_1 = require("react");
const utils_1 = require("../../utils");
const Link_1 = require("../Link");
function ErrorSummary({ error }) {
return ((0, jsx_runtime_1.jsxs)("div", { className: errorPanelStyles.container, role: "alert", children: [(0, jsx_runtime_1.jsx)("div", { className: errorPanelStyles.iconContainer, children: (0, jsx_runtime_1.jsx)(design_system_icons_1.ExclamationDiamondIcon, { size: 24 }) }), (0, jsx_runtime_1.jsxs)("div", { className: contentContainerStyles, children: [error.message && (0, jsx_runtime_1.jsx)("div", { className: errorPanelStyles.title, children: error.message }), error.details.length > 1 && (0, jsx_runtime_1.jsx)(ErrorsList, { details: error.details }), error.details.length === 1 && (0, jsx_runtime_1.jsx)(DetailDescription, { detail: error.details[0] }), error.help && (0, jsx_runtime_1.jsx)(ErrorHelp, { help: error.help })] })] }));
}
function ErrorHelp({ help }) {
if (help.text) {
return (0, jsx_runtime_1.jsx)(RevealErrorDetails, { details: help.text, link: help.link });
}
if (help.link) {
return ((0, jsx_runtime_1.jsx)(Link_1.ExternalLink, { type: "high-contrast", href: help.link, children: "More info" }));
}
}
function RevealErrorDetails(props) {
const [isOpen, setIsOpen] = (0, react_1.useState)(false);
return ((0, jsx_runtime_1.jsxs)("div", { className: revealErrorDetailsStyles.root, children: [(0, jsx_runtime_1.jsxs)("button", { type: "button", className: revealErrorDetailsStyles.summary, "aria-expanded": isOpen, onClick: () => setIsOpen((prev) => !prev), children: [(0, jsx_runtime_1.jsx)("span", { className: summaryUnderline, children: "View details" }), (0, jsx_runtime_1.jsx)("div", { className: isOpen ? revealErrorDetailsStyles.chevronOpen : revealErrorDetailsStyles.chevron, children: (0, jsx_runtime_1.jsx)(design_system_icons_1.ChevronDownIcon, { size: 16, color: "currentColor" }) })] }), (0, jsx_runtime_1.jsx)("div", { className: isOpen ? revealErrorDetailsStyles.contentGridOpen : revealErrorDetailsStyles.contentGrid, children: (0, jsx_runtime_1.jsx)("div", { className: revealErrorDetailsStyles.details, children: (0, jsx_runtime_1.jsx)(ErrorWithLinkFragment, { text: props.details, link: props.link }) }) })] }));
}
const summaryUnderline = (0, css_1.css)({
textDecoration: "underline",
"&:hover": {
textDecoration: "none",
},
});
const ANIMATION_DURATION = "200ms";
const ANIMATION_EASING = "ease-in-out";
const revealErrorDetailsStyles = {
root: (0, css_1.css)({
display: "flex",
flexDirection: "column",
}),
chevron: (0, css_1.css)({
display: "flex",
transition: `transform ${ANIMATION_DURATION} ${ANIMATION_EASING}`,
}),
chevronOpen: (0, css_1.css)({
display: "flex",
transition: `transform ${ANIMATION_DURATION} ${ANIMATION_EASING}`,
transform: "rotate(180deg)",
}),
summary: (0, css_1.css)({
all: "unset",
cursor: "pointer",
userSelect: "none",
display: "inline-flex",
alignItems: "center",
gap: design_system_tokens_1.space[4],
"&:focus-visible": {
outline: `2px solid ${design_system_tokens_1.themeTokens.color.border.selected}`,
},
}),
contentGrid: (0, css_1.css)({
display: "grid",
gridTemplateRows: "0fr",
overflow: "hidden",
transition: `grid-template-rows ${ANIMATION_DURATION} ${ANIMATION_EASING}`,
}),
contentGridOpen: (0, css_1.css)({
display: "grid",
gridTemplateRows: "1fr",
overflow: "hidden",
transition: `grid-template-rows ${ANIMATION_DURATION} ${ANIMATION_EASING}`,
}),
details: (0, css_1.css)({
lineHeight: design_system_tokens_1.lineHeight.small,
marginTop: design_system_tokens_1.space[4],
overflow: "hidden",
}),
};
function ErrorsList({ details }) {
return ((0, jsx_runtime_1.jsx)("ol", { className: errorPanelStyles.list, children: details.map((detail, index) => ((0, jsx_runtime_1.jsx)(DetailListItem, { detail: detail }, index))) }));
}
function DetailDescription({ detail }) {
const { text, link } = detail;
if (!text) {
return null;
}
return ((0, jsx_runtime_1.jsx)("p", { className: errorPanelStyles.description, children: (0, jsx_runtime_1.jsx)(ErrorWithLinkFragment, { text: text, link: link }) }));
}
function DetailListItem({ detail }) {
if (!detail.text) {
return null;
}
return ((0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsx)(ErrorWithLinkFragment, { text: detail.text, link: detail.link }) }));
}
function ErrorWithLinkFragment({ text, link }) {
const trimmedText = text.trim();
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [trimmedText, link && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [trimmedText.endsWith(".") ? " " : ": ", (0, jsx_runtime_1.jsx)(Link_1.ExternalLink, { type: "high-contrast", href: link, children: "More info" })] }))] }));
}
const contentContainerStyles = (0, css_1.css)({
font: design_system_tokens_1.text.body.regular.medium,
color: design_system_tokens_1.themeTokens.color.callout.text.body,
display: "flex",
flexDirection: "column",
gap: design_system_tokens_1.space[12],
padding: `${design_system_tokens_1.space[2]} 0`,
flex: 1,
});
const errorPanelStyles = {
list: (0, css_1.css)({
...utils_1.resetStyles.list,
display: "flex",
flexDirection: "column",
listStyleType: "revert",
paddingLeft: design_system_tokens_1.space[16],
}),
description: (0, css_1.css)({
...utils_1.resetStyles.paragraph,
margin: 0,
padding: 0,
}),
iconContainer: (0, css_1.css)({
height: "1.5rem",
display: "flex",
alignItems: "center",
justifyContent: "center",
alignSelf: "flex-start",
flexShrink: 0,
color: design_system_tokens_1.themeTokens.color.callout.icon.danger,
}),
container: (0, css_1.css)({
borderRadius: design_system_tokens_1.borderRadius.medium,
display: "flex",
padding: `${design_system_tokens_1.space[12]} ${design_system_tokens_1.space[16]}`,
gap: design_system_tokens_1.space[8],
background: design_system_tokens_1.themeTokens.color.callout.background.danger.default,
}),
title: (0, css_1.css)({
display: "flex",
alignItems: "center",
font: design_system_tokens_1.text.body.bold.medium,
lineHeight: "1.25rem", // This is needed to align to designs while the line height text token changes are not yet merged
color: design_system_tokens_1.themeTokens.color.callout.text.danger,
}),
};