Skip to content

Commit

Permalink
feat(ModalFooterBase): base footer component to be used by different …
Browse files Browse the repository at this point in the history
…modal footers (#2437)
  • Loading branch information
YossiSaadi authored Oct 9, 2024
1 parent 5fdcf4d commit 153d94f
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.footer {
position: relative;
width: 100%;
padding: 20px var(--spacing-large);
flex-shrink: 0;
background-color: var(--primary-background-color);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React, { forwardRef } from "react";
import styles from "./ModalFooterBase.module.scss";
import Button from "../../../Button/Button";
import Flex from "../../../Flex/Flex";
import { ModalFooterBaseProps } from "./ModalFooterBase.types";
import cx from "classnames";

const ModalFooterBase = forwardRef(
(
{ primaryButton, secondaryButton, renderAction, id, className, "data-testid": dataTestId }: ModalFooterBaseProps,
ref: React.ForwardedRef<HTMLDivElement>
) => {
return (
<Flex
ref={ref}
id={id}
justify={Flex.justify.SPACE_BETWEEN}
gap={Flex.gaps.SMALL}
className={cx(styles.footer, className)}
data-testid={dataTestId}
>
<Button onClick={primaryButton.onClick} className={primaryButton.className}>
{primaryButton.text}
</Button>
{secondaryButton && (
<Button kind={Button.kinds.TERTIARY} className={secondaryButton.className} onClick={secondaryButton.onClick}>
{secondaryButton.text}
</Button>
)}
{renderAction}
</Flex>
);
}
);

export default ModalFooterBase;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ButtonProps } from "../../../Button";
import React from "react";
import { VibeComponentProps } from "../../../../types";

export interface ModalFooterActionProps extends Pick<ButtonProps, "onClick" | "className"> {
text: string;
}

export interface ModalFooterBaseProps extends VibeComponentProps {
primaryButton: ModalFooterActionProps;
secondaryButton?: ModalFooterActionProps;
renderAction?: React.ReactNode;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from "react";
import { render, fireEvent } from "@testing-library/react";
import ModalFooterBase from "../ModalFooterBase";

describe("ModalFooterBase", () => {
const primaryButton = {
text: "Save",
onClick: jest.fn()
};

const secondaryButton = {
text: "Cancel",
onClick: jest.fn()
};

it("renders the primary button with the correct text", () => {
const { getByText } = render(<ModalFooterBase primaryButton={primaryButton} />);

const primaryButtonElement = getByText("Save");
expect(primaryButtonElement).toBeInTheDocument();
});

it("does not render more than one child when only supplying primary button", () => {
const { container } = render(<ModalFooterBase primaryButton={primaryButton} />);
expect(container.firstChild.childNodes).toHaveLength(1);
});

it("renders the secondary button with the correct text", () => {
const { getByText } = render(<ModalFooterBase primaryButton={primaryButton} secondaryButton={secondaryButton} />);

const secondaryButtonElement = getByText("Cancel");
expect(secondaryButtonElement).toBeInTheDocument();
});

it("calls the primary button's onClick when clicked", () => {
const { getByText } = render(<ModalFooterBase primaryButton={primaryButton} secondaryButton={secondaryButton} />);

fireEvent.click(getByText("Save"));
expect(primaryButton.onClick).toHaveBeenCalled();
});

it("calls the secondary button's onClick when clicked", () => {
const { getByText } = render(<ModalFooterBase primaryButton={primaryButton} secondaryButton={secondaryButton} />);

fireEvent.click(getByText("Cancel"));
expect(secondaryButton.onClick).toHaveBeenCalled();
});

it("renders the custom action via renderAction", () => {
const customAction = <div data-testid="custom-action">Custom Action</div>;
const { getByTestId } = render(<ModalFooterBase primaryButton={primaryButton} renderAction={customAction} />);

const customActionElement = getByTestId("custom-action");
expect(customActionElement).toBeInTheDocument();
expect(customActionElement).toHaveTextContent("Custom Action");
});
});

0 comments on commit 153d94f

Please sign in to comment.