UNPKG

@octopusdeploy/design-system-components

Version:
183 lines (182 loc) 11.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UpsellDialog = UpsellDialog; 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 Button_1 = require("../Button"); const ErrorSummary_1 = require("../ErrorSummary"); const DialogBase_1 = require("./DialogBase"); const DialogMainPanel_1 = require("./DialogMainPanel"); const DialogStepNavigationFooter_1 = require("./DialogStepNavigationFooter"); const dialogBreakpoints_styles_1 = require("./dialogBreakpoints.styles"); const useDialogSteps_1 = require("./useDialogSteps"); function isMultiStepProps(props) { return "steps" in props && Array.isArray(props.steps); } /** * UpsellDialog – an upsell-styled dialog with a main content panel and side panel. * * The side panel is always visible on desktop (stacks on mobile). The primary action button * uses "loud" importance. For multi-step flows, pass the `steps` prop. * * @remarks Do not implement directly in Octopus Server code. Use Workflows instead. See https://docs.octopushq.com/docs/frontend/workflows */ function UpsellDialog(props) { const { width = "medium", open, onClose, onClosed, title, sidePanel, errors } = props; const multiStep = isMultiStepProps(props); const backButtonDisabled = multiStep ? props.backButtonDisabled : false; const nextButtonDisabled = multiStep ? props.nextButtonDisabled : false; const { currentStepIndex, totalSteps, isFirstStep, isLastStep, isNavigating, goToNext, goToPrevious, reset } = (0, useDialogSteps_1.useDialogSteps)(multiStep ? props.steps.map((s) => ({ onBeforeNext: s.onBeforeNext, onBeforeBack: s.onBeforeBack, onEnter: s.onEnter })) : []); (0, react_1.useEffect)(() => { if (open) { reset(); } }, [open, reset]); // Determine content, progress tracker, and side panel based on single vs multi-step. const currentStep = multiStep ? props.steps[currentStepIndex] : undefined; const content = currentStep ? currentStep.content : props.children; const sidePanelContent = currentStep?.sidePanel ?? sidePanel; const progressTracker = multiStep ? currentStep?.progressTracker : props.progressTracker; const closeDialogButton = (0, jsx_runtime_1.jsx)(Button_1.Button, { importance: "ghost", accessibleName: "Close dialog", onClick: onClose, size: "medium", icon: (0, jsx_runtime_1.jsx)(design_system_icons_1.XmarkIcon, { size: 20 }) }); const actionsEl = multiStep ? ((0, jsx_runtime_1.jsx)(DialogStepNavigationFooter_1.DialogStepNavigationFooter, { totalSteps: totalSteps, currentStepIndex: currentStepIndex, isFirstStep: isFirstStep, isLastStep: isLastStep, isNavigating: isNavigating, primaryImportance: "loud", completeButtonLabel: props.completeButtonLabel, backButtonDisabled: backButtonDisabled, nextButtonDisabled: nextButtonDisabled, onClose: onClose, onBack: () => { void goToPrevious(); }, onNext: () => { void goToNext(); }, onComplete: props.onComplete })) : ((0, jsx_runtime_1.jsxs)("footer", { className: styles.actionsSingleStep, children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { importance: "loud", ...props.primaryAction }), props.secondaryAction && (0, jsx_runtime_1.jsx)(Button_1.Button, { importance: "quiet", ...props.secondaryAction })] })); const sidePanelWidth = (0, dialogBreakpoints_styles_1.toSidePanelWidth)(width); return ((0, jsx_runtime_1.jsx)(DialogBase_1.DialogBase, { open: open, onClose: onClose, onClosed: onClosed, accessibleName: title, autoFocusFirstElement: false, children: (0, jsx_runtime_1.jsx)("div", { className: (0, css_1.cx)(styles.outer, sidePanelWidth ? outerSidePanelOpenStyles[sidePanelWidth] : null), children: (0, jsx_runtime_1.jsxs)("div", { className: (0, css_1.cx)(styles.container, sidePanelWidth ? containerWithSidePanelStyles[sidePanelWidth] : null), children: [(0, jsx_runtime_1.jsx)(DialogMainPanel_1.DialogMainPanel, { isLoading: props.isLoading, width: width, title: title, progressTracker: progressTracker, errorPanel: errors?.map((err, index) => ((0, jsx_runtime_1.jsx)(ErrorSummary_1.ErrorSummary, { error: err }, index))), footer: actionsEl, children: content }), (0, jsx_runtime_1.jsx)("aside", { className: (0, css_1.cx)(styles.sidePanelWrapper, sidePanelWidth ? sidePanelWrapperStyles[sidePanelWidth] : null), children: (0, jsx_runtime_1.jsx)("div", { className: (0, css_1.cx)(styles.sidePanel, sidePanelWidth ? sidePanelStyles[sidePanelWidth] : null), children: (0, jsx_runtime_1.jsx)("div", { className: (0, css_1.cx)(styles.sidePanelContent, sidePanelWidth ? sidePanelContentStyles[sidePanelWidth] : null), children: sidePanelContent }) }) }), (0, jsx_runtime_1.jsx)("div", { className: styles.dismissButtonInSidePanel, children: closeDialogButton })] }) }) })); } const outerSidePanelOpenProps = { borderTopRightRadius: 0, borderBottomRightRadius: 0, transition: `border-top-right-radius 0ms 0ms, border-bottom-right-radius 0ms 0ms`, }; const outerSidePanelOpenStyles = { small: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.small})`]: outerSidePanelOpenProps }), medium: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.medium})`]: outerSidePanelOpenProps }), large: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.large})`]: outerSidePanelOpenProps }), }; const containerWithSidePanelStyles = { small: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.small})`]: { display: "grid", gridTemplateColumns: `${design_system_tokens_1.dialog.mainPanel.width.small} ${design_system_tokens_1.dialog.sidePanel.width}`, }, }), medium: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.medium})`]: { display: "grid", gridTemplateColumns: `${design_system_tokens_1.dialog.mainPanel.width.medium} ${design_system_tokens_1.dialog.sidePanel.width}`, }, }), large: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.large})`]: { display: "grid", gridTemplateColumns: `${design_system_tokens_1.dialog.mainPanel.width.large} ${design_system_tokens_1.dialog.sidePanel.width}`, }, }), }; const sidePanelWrapperResponsiveProps = { display: "flex", minWidth: 0, alignSelf: "stretch", overflow: "hidden", position: "relative", borderBottomRightRadius: design_system_tokens_1.borderRadius.large, borderTopRightRadius: design_system_tokens_1.borderRadius.large, }; const sidePanelWrapperStyles = { small: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.small})`]: sidePanelWrapperResponsiveProps }), medium: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.medium})`]: sidePanelWrapperResponsiveProps }), large: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.large})`]: sidePanelWrapperResponsiveProps }), }; const sidePanelResponsiveProps = { width: design_system_tokens_1.dialog.sidePanel.width, padding: `${design_system_tokens_1.space[72]} ${design_system_tokens_1.space[32]}`, }; const sidePanelStyles = { small: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.small})`]: sidePanelResponsiveProps }), medium: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.medium})`]: sidePanelResponsiveProps }), large: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.large})`]: sidePanelResponsiveProps }), }; const sidePanelContentResponsiveProps = { width: "304px", height: "304px", }; const sidePanelContentStyles = { small: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.small})`]: sidePanelContentResponsiveProps }), medium: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.medium})`]: sidePanelContentResponsiveProps }), large: (0, css_1.css)({ [`@media (min-width: ${dialogBreakpoints_styles_1.dialogSidePanelBreakpoint.large})`]: sidePanelContentResponsiveProps }), }; const styles = { outer: (0, css_1.css)({ overflow: "hidden", borderRadius: design_system_tokens_1.borderRadius.large, maxHeight: design_system_tokens_1.dialog.maxHeight, display: "flex", flexDirection: "column", transition: `border-top-right-radius 0ms 0ms, border-bottom-right-radius 0ms 0ms`, }), container: (0, css_1.css)({ position: "relative", display: "flex", flexDirection: "column-reverse", alignItems: "stretch", flex: 1, minHeight: 0, boxSizing: "border-box", }), dismissButtonInSidePanel: (0, css_1.css)({ position: "absolute", top: design_system_tokens_1.space[16], right: design_system_tokens_1.space[16], zIndex: 1, }), sidePanelWrapper: (0, css_1.css)({ display: "flex", alignSelf: "stretch", position: "relative", background: design_system_tokens_1.themeTokens.color.dialog.background.secondary.upsell, }), sidePanel: (0, css_1.css)({ font: design_system_tokens_1.text.body.regular.large, color: design_system_tokens_1.themeTokens.color.text.primary, display: "flex", flexDirection: "column", alignItems: "center", boxSizing: "border-box", padding: design_system_tokens_1.space[24], position: "relative", zIndex: 0, width: "100%", flex: "0 0 auto", }), /** Currently has custom sizing for the side panel upsell variant content. */ sidePanelContent: (0, css_1.css)({ width: "150px", height: "150px", [`@media (min-width: ${dialogBreakpoints_styles_1.dialogBreakpoints.tablet})`]: { width: "248px", height: "248px", }, "& > img:only-child": { display: "block", width: "100%", height: "auto", borderRadius: design_system_tokens_1.borderRadius.small, //TODO confirm with product growth team. // boxShadow: themeTokens.shadow.extraSmall, }, }), actionsSingleStep: (0, css_1.css)({ flexShrink: 0, display: "flex", flexDirection: "column", gap: design_system_tokens_1.space[8], padding: `${design_system_tokens_1.space[8]} ${design_system_tokens_1.space[24]} ${design_system_tokens_1.space[24]} ${design_system_tokens_1.space[24]}`, alignItems: "stretch", }), };