Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Refactor Dialog sub-components to be functional components #7180

Merged
merged 2 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 17 additions & 19 deletions packages/core/src/components/dialog/dialogBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
import classNames from "classnames";
import * as React from "react";

import { AbstractPureComponent, Classes } from "../../common";
import type { Props } from "../../common/props";
import { Classes, DISPLAYNAME_PREFIX } from "../../common";
import type { HTMLDivProps, Props } from "../../common/props";

export interface DialogBodyProps extends Props {
export interface DialogBodyProps extends Props, HTMLDivProps {
/** Dialog body contents. */
children?: React.ReactNode;

Expand All @@ -37,20 +37,18 @@ export interface DialogBodyProps extends Props {
*
* @see https://blueprintjs.com/docs/#core/components/dialog.dialog-body-props
*/
export class DialogBody extends AbstractPureComponent<DialogBodyProps> {
public static defaultProps: DialogBodyProps = {
useOverflowScrollContainer: true,
};
export const DialogBody: React.FC<DialogBodyProps> = props => {
const { children, className, useOverflowScrollContainer, ...htmlProps } = props;
return (
<div
{...htmlProps}
className={classNames(Classes.DIALOG_BODY, className, {
[Classes.DIALOG_BODY_SCROLL_CONTAINER]: useOverflowScrollContainer,
})}
>
{children}
</div>
);
};

public render() {
return (
<div
className={classNames(Classes.DIALOG_BODY, this.props.className, {
[Classes.DIALOG_BODY_SCROLL_CONTAINER]: this.props.useOverflowScrollContainer,
})}
>
{this.props.children}
</div>
);
}
}
DialogBody.displayName = `${DISPLAYNAME_PREFIX}.DialogBody`;
60 changes: 23 additions & 37 deletions packages/core/src/components/dialog/dialogFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@
import classNames from "classnames";
import * as React from "react";

import { AbstractPureComponent, Classes } from "../../common";
import type { Props } from "../../common/props";

export interface DialogFooterProps extends Props {
/** Child contents are rendered on the left side of the footer. */
children?: React.ReactNode;
import { Classes, DISPLAYNAME_PREFIX } from "../../common";
import type { HTMLDivProps, Props } from "../../common/props";

export interface DialogFooterProps extends Props, HTMLDivProps {
/** Dialog actions (typically buttons) are rendered on the right side of the footer. */
actions?: React.ReactNode;

/** Child contents are rendered on the left side of the footer. */
children?: React.ReactNode;

/**
* Use a "minimal" appearance for the footer, simply applying an HTML role and
* some visual padding. This is useful for small dialogs, and should not be used
Expand All @@ -52,35 +52,21 @@ export interface DialogFooterProps extends Props {
*
* @see https://blueprintjs.com/docs/#core/components/dialog.dialog-footer-props
*/
export class DialogFooter extends AbstractPureComponent<DialogFooterProps> {
public static defaultProps: DialogFooterProps = {
minimal: false,
};

public render() {
return (
<div
className={classNames(Classes.DIALOG_FOOTER, this.props.className, {
[Classes.DIALOG_FOOTER_FIXED]: !this.props.minimal,
})}
>
{this.renderMainSection()}
{this.maybeRenderActionsSection()}
</div>
);
}
export const DialogFooter: React.FC<DialogFooterProps> = props => {
const { actions, children, className, minimal = false, ...htmlProps } = props;
return (
<div
{...htmlProps}
className={classNames(Classes.DIALOG_FOOTER, className, {
[Classes.DIALOG_FOOTER_FIXED]: !minimal,
})}
>
{/* Render the main footer section (left aligned). */}
ggdouglas marked this conversation as resolved.
Show resolved Hide resolved
<div className={Classes.DIALOG_FOOTER_MAIN_SECTION}>{children}</div>
{/* Optionally render the footer actions (right aligned). */}
{actions != null && <div className={Classes.DIALOG_FOOTER_ACTIONS}>{actions}</div>}
</div>
);
};

/** Render the main footer section (left aligned). */
private renderMainSection() {
return <div className={Classes.DIALOG_FOOTER_MAIN_SECTION}>{this.props.children}</div>;
}

/** Optionally render the footer actions (right aligned). */
private maybeRenderActionsSection() {
const { actions } = this.props;
if (actions == null) {
return undefined;
}
return <div className={Classes.DIALOG_FOOTER_ACTIONS}>{actions}</div>;
}
}
DialogFooter.displayName = `${DISPLAYNAME_PREFIX}.DialogFooter`;
27 changes: 13 additions & 14 deletions packages/core/src/components/dialog/dialogStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import classNames from "classnames";
import * as React from "react";

import { AbstractPureComponent, Classes } from "../../common";
import { Classes } from "../../common";
import { DISPLAYNAME_PREFIX, type HTMLDivProps, type Props } from "../../common/props";

import type { DialogStepButtonProps } from "./dialogStepButton";
Expand Down Expand Up @@ -56,22 +56,21 @@ export interface DialogStepProps extends Props, Omit<HTMLDivProps, "id" | "title
nextButtonProps?: DialogStepButtonProps;
}

/* istanbul ignore next */
/**
* Dialog step component.
*
* @see https://blueprintjs.com/docs/#core/components/dialog.dialogstep
*/
export class DialogStep extends AbstractPureComponent<DialogStepProps> {
public static displayName = `${DISPLAYNAME_PREFIX}.DialogStep`;
export const DialogStep: React.FC<DialogStepProps> = props => {
const { className, id, title, ...htmlProps } = props;

// this component is never rendered directly; see MultistepDialog#renderDialogStepPanel()
/* istanbul ignore next */
public render() {
const { className } = this.props;
return (
<div className={Classes.DIALOG_STEP_CONTAINER} role="tab">
<div className={classNames(Classes.DIALOG_STEP, className)} />
</div>
);
}
}
// this component is never rendered directly; see MultistepDialog#renderDialogStep()
return (
<div {...htmlProps} className={Classes.DIALOG_STEP_CONTAINER} role="tab">
<div className={classNames(Classes.DIALOG_STEP, className)} />
</div>
);
};

DialogStep.displayName = `${DISPLAYNAME_PREFIX}.DialogStep`;