@octopusdeploy/design-system-components
Version:
The design systems component library.
183 lines (182 loc) • 11.1 kB
JavaScript
;
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",
}),
};