Skip to content

Commit

Permalink
[core] feat(MultistepDialog): Improve appearance without title (#4969)
Browse files Browse the repository at this point in the history
  • Loading branch information
mud authored Oct 19, 2021
1 parent a27d668 commit ca8c284
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 3 deletions.
18 changes: 18 additions & 0 deletions packages/core/src/components/dialog/_multistep-dialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ $step-radius: $pt-border-radius * 2 !default;

.#{$ns}-multistep-dialog-panels {
display: flex;

// If title doesn't exist, this element will be the first child and top
// borders needs to be rounded.
&:first-child {
.#{$ns}-dialog-step-container:first-child {
border-radius: $dialog-border-radius 0 0 0;
}

.#{$ns}-multistep-dialog-right-panel {
border-top-right-radius: $dialog-border-radius;
}
}
}

.#{$ns}-multistep-dialog-left-panel {
Expand Down Expand Up @@ -40,12 +52,18 @@ $step-radius: $pt-border-radius * 2 !default;
background-color: $white;
border-radius: 0 0 $dialog-border-radius 0;
border-top: 1px solid $pt-divider-black;
display: flex;
justify-content: space-between;
padding: 10px;

.#{$ns}-dark & {
background: $dark-gray4;
border-top: 1px solid $pt-dark-divider-black;
}

.#{$ns}-dialog-footer-actions {
flex-grow: 1;
}
}

.#{$ns}-dialog-step-container {
Expand Down
30 changes: 29 additions & 1 deletion packages/core/src/components/dialog/multistepDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ export interface IMultistepDialogProps extends DialogProps {
*/
backButtonProps?: DialogStepButtonProps;

/**
* Props for the close button that appears in the footer when there is no
* title.
*/
closeButtonProps?: Partial<ButtonProps>;

/**
* Props for the button to display on the final step.
*/
Expand Down Expand Up @@ -62,6 +68,15 @@ export interface IMultistepDialogProps extends DialogProps {
*/
resetOnClose?: boolean;

/**
* Whether the footer close button is shown. The button will only appear if
* `isCloseButtonShown` is `true`. The close button in the dialog title will
* not be shown when this is `true`.
*
* @default false
*/
showCloseButtonInFooter?: boolean;

/**
* A 0 indexed initial step to start off on, to start in the middle of the dialog, for example.
* If the provided index exceeds the number of steps, it defaults to the last step.
Expand All @@ -87,13 +102,20 @@ export class MultistepDialog extends AbstractPureComponent2<MultistepDialogProps
canOutsideClickClose: true,
isOpen: false,
resetOnClose: true,
showCloseButtonInFooter: false,
};

public state: IMultistepDialogState = this.getInitialIndexFromProps(this.props);

public render() {
const { showCloseButtonInFooter, isCloseButtonShown, ...otherProps } = this.props;

// Only one close button should be displayed. If the footer close button
// is shown, we need to ensure the dialog close button is not displayed.
const isCloseButtonVisible = !showCloseButtonInFooter && isCloseButtonShown;

return (
<Dialog {...this.props} style={this.getDialogStyle()}>
<Dialog isCloseButtonShown={isCloseButtonVisible} {...otherProps} style={this.getDialogStyle()}>
<div className={Classes.MULTISTEP_DIALOG_PANELS}>
{this.renderLeftPanel()}
{this.maybeRenderRightPanel()}
Expand Down Expand Up @@ -167,8 +189,14 @@ export class MultistepDialog extends AbstractPureComponent2<MultistepDialogProps
}

private renderFooter() {
const { closeButtonProps, isCloseButtonShown, showCloseButtonInFooter, onClose } = this.props;
const isFooterCloseButtonVisible = showCloseButtonInFooter && isCloseButtonShown;
const maybeCloseButton = !isFooterCloseButtonVisible ? undefined : (
<Button text="Close" onClick={onClose} {...closeButtonProps} />
);
return (
<div className={Classes.MULTISTEP_DIALOG_FOOTER}>
{maybeCloseButton}
<div className={Classes.DIALOG_FOOTER_ACTIONS}>{this.renderButtons()}</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export interface IMultistepDialogExampleState {
canEscapeKeyClose: boolean;
canOutsideClickClose: boolean;
enforceFocus: boolean;
hasTitle: boolean;
isCloseButtonShown: boolean;
showCloseButtonInFooter: boolean;
isOpen: boolean;
usePortal: boolean;
value?: string;
Expand All @@ -55,8 +58,11 @@ export class MultistepDialogExample extends React.PureComponent<
canEscapeKeyClose: true,
canOutsideClickClose: true,
enforceFocus: true,
hasTitle: true,
initialStepIndex: 0,
isCloseButtonShown: true,
isOpen: false,
showCloseButtonInFooter: true,
usePortal: true,
};

Expand All @@ -70,12 +76,21 @@ export class MultistepDialogExample extends React.PureComponent<

private handleOutsideClickChange = handleBooleanChange(val => this.setState({ canOutsideClickClose: val }));

private handleCloseButtonChange = handleBooleanChange(isCloseButtonShown => this.setState({ isCloseButtonShown }));

private handleFooterCloseButtonChange = handleBooleanChange(showCloseButtonInFooter =>
this.setState({ showCloseButtonInFooter }),
);

private handleHasTitleChange = handleBooleanChange(hasTitle => this.setState({ hasTitle }));

public render() {
const finalButtonProps: Partial<ButtonProps> = {
intent: "primary",
onClick: this.handleClose,
text: "Close",
};
const { hasTitle, ...state } = this.state;
return (
<Example options={this.renderOptions()} {...this.props}>
<Button onClick={this.handleOpen}>Show dialog</Button>
Expand All @@ -85,8 +100,8 @@ export class MultistepDialogExample extends React.PureComponent<
onClose={this.handleClose}
nextButtonProps={{ disabled: this.state.value === undefined }}
finalButtonProps={finalButtonProps}
title="Multistep dialog"
{...this.state}
title={hasTitle ? "Multistep dialog" : undefined}
{...state}
>
<DialogStep
id="select"
Expand All @@ -110,7 +125,10 @@ export class MultistepDialogExample extends React.PureComponent<
canEscapeKeyClose,
canOutsideClickClose,
usePortal,
hasTitle,
initialStepIndex,
isCloseButtonShown,
showCloseButtonInFooter,
} = this.state;
return (
<>
Expand All @@ -125,6 +143,17 @@ export class MultistepDialogExample extends React.PureComponent<
label="Click outside to close"
onChange={this.handleOutsideClickChange}
/>
<Switch checked={hasTitle} label="Has title" onChange={this.handleHasTitleChange} />
<Switch
checked={isCloseButtonShown}
label="Show close button"
onChange={this.handleCloseButtonChange}
/>
<Switch
checked={showCloseButtonInFooter}
label="Show footer close button"
onChange={this.handleFooterCloseButtonChange}
/>
<Switch checked={canEscapeKeyClose} label="Escape key to close" onChange={this.handleEscapeKeyChange} />
<Label>Initial step index (0-indexed)</Label>
<NumericInput
Expand Down

1 comment on commit ca8c284

@blueprint-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[core] feat(MultistepDialog): Improve appearance without title (#4969)

Previews: documentation | landing | table | modern colors demo

Please sign in to comment.