Skip to content

Commit

Permalink
Merge branch 'feat/yossi/new-modal-building-blocks-7359960492' into f…
Browse files Browse the repository at this point in the history
…eat/yossi/modalcontent-component-to-render-scrollable-content-inside-a-7360624571
  • Loading branch information
YossiSaadi authored Sep 11, 2024
2 parents 1b33be4 + 77ddf05 commit dd3bdab
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.header {
width: 100%;
align-self: flex-start;

.title {
width: 100%;
}

.descriptionIcon {
flex-shrink: 0;
margin-inline-end: var(--spacing-xs);
color: var(--icon-color);
}
}
52 changes: 52 additions & 0 deletions packages/core/src/components/ModalNew/ModalHeader/ModalHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { forwardRef } from "react";
import cx from "classnames";
import { getTestId } from "../../../tests/test-ids-utils";
import { ComponentDefaultTestId } from "../../../tests/constants";
import styles from "./ModalHeader.module.scss";
import { ModalHeaderProps } from "./ModalHeader.types";
import Flex from "../../Flex/Flex";
import Heading from "../../Heading/Heading";
import Text from "../../Text/Text";
import Icon from "../../Icon/Icon";

const ModalHeader = forwardRef(
(
{ title, description, descriptionIcon, className, id, "data-testid": dataTestId }: ModalHeaderProps,
ref: React.ForwardedRef<HTMLDivElement>
) => {
return (
<Flex
gap={Flex.gaps.XS}
direction={Flex.directions.COLUMN}
align={Flex.align.START}
ref={ref}
className={cx(styles.header, className)}
id={id}
data-testid={dataTestId || getTestId(ComponentDefaultTestId.MODAL_NEXT_HEADER, id)}
>
<Heading type={Heading.types.H2} weight={Heading.weights.MEDIUM} maxLines={2} className={styles.title}>
{title}
</Heading>
{description && (
<Flex>
{descriptionIcon && (
<Icon
icon={typeof descriptionIcon === "object" ? descriptionIcon.name : descriptionIcon}
className={cx(styles.descriptionIcon, typeof descriptionIcon === "object" && descriptionIcon.className)}
/>
)}
{typeof description === "string" ? (
<Text element="span" type={Text.types.TEXT1}>
{description}
</Text>
) : (
description
)}
</Flex>
)}
</Flex>
);
}
);

export default ModalHeader;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from "react";
import { SubIcon, VibeComponentProps } from "../../../types";

interface WithoutDescription {
description?: never;
descriptionIcon?: never;
}

interface WithDescription {
description: string | React.ReactNode;
descriptionIcon?:
| SubIcon
| {
name: SubIcon;
className?: string;
};
}

export type ModalHeaderProps = { title: string } & (WithoutDescription | WithDescription) & VibeComponentProps;
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from "react";
import { render } from "@testing-library/react";
import ModalHeader from "../ModalHeader";
import { Text as TextIcon } from "../../../Icon/Icons";

describe("ModalHeader", () => {
const title = "Test Modal Header";
const simpleDescription = "This is a description";
const descriptionIcon = TextIcon;

it("renders the title correctly", () => {
const { getByText } = render(<ModalHeader title={title} />);

expect(getByText(title)).toBeInTheDocument();
});

it("renders the description correctly", () => {
const { getByText } = render(<ModalHeader title={title} description={simpleDescription} />);

expect(getByText(simpleDescription)).toBeInTheDocument();
});

it("renders the description icon when provided", () => {
const { getByText, getByTestId } = render(
<ModalHeader title={title} description={simpleDescription} descriptionIcon={descriptionIcon} />
);

expect(getByText(simpleDescription)).toBeInTheDocument();
expect(getByTestId("icon")).toBeInTheDocument();
});

it("renders custom description node", () => {
const customDescription = <span data-testid="custom-description">Custom description content</span>;

const { getByTestId } = render(<ModalHeader title={title} description={customDescription} />);

expect(getByTestId("custom-description")).toBeInTheDocument();
});

it("does not render description when not provided", () => {
const { queryByText } = render(<ModalHeader title={title} />);

expect(queryByText(simpleDescription)).not.toBeInTheDocument();
});

it("renders with description icon when descriptionIcon is an object", () => {
const descriptionIconObject = {
name: TextIcon,
className: "with-custom-icon-class"
};

const { getByTestId } = render(
<ModalHeader title={title} description={simpleDescription} descriptionIcon={descriptionIconObject} />
);

const icon = getByTestId("icon");
expect(icon).toHaveClass(descriptionIconObject.className);
});
});
1 change: 1 addition & 0 deletions packages/core/src/tests/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export enum ComponentDefaultTestId {
MODAL_CONTENT = "modal-content",
MODAL_HEADER = "modal-header",
MODAL_FOOTER_BUTTONS = "modal-footer-buttons",
MODAL_NEXT_HEADER = "modal-header",
MODAL_NEXT_CONTENT = "modal-content",
FORMATTED_NUMBER = "formatted-number",
HIDDEN_TEXT = "hidden-text",
Expand Down

0 comments on commit dd3bdab

Please sign in to comment.