UNPKG

@octopusdeploy/design-system-components

Version:
143 lines (142 loc) • 7.12 kB
"use strict"; 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, }), };