Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 6 additions & 6 deletions src/callout/callout.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ const story = {

type Story = StoryObj<typeof Callout>;

export const Success: Story = {
export const Tip: Story = {
args: {
children:
"Eaque non tempore porro quod voluptates rerum ipsam. Consequatur ea voluptate quo tempora autem quod. Voluptatem perspiciatis non mollitia. Dicta non necessitatibus laboriosam est aut cum eos et. Animi pariatur aliquid sint ipsum nam occaecati nisi sit.",
variant: "success",
variant: "tip",
},
};

export const Info: Story = {
export const Note: Story = {
args: {
children:
"Eaque non tempore porro quod voluptates rerum ipsam. Consequatur ea voluptate quo tempora autem quod. Voluptatem perspiciatis non mollitia. Dicta non necessitatibus laboriosam est aut cum eos et. Animi pariatur aliquid sint ipsum nam occaecati nisi sit.",
variant: "info",
variant: "note",
},
};

Expand All @@ -33,11 +33,11 @@ export const Warning: Story = {
},
};

export const Danger: Story = {
export const Caution: Story = {
args: {
children:
"Eaque non tempore porro quod voluptates rerum ipsam. Consequatur ea voluptate quo tempora autem quod. Voluptatem perspiciatis non mollitia. Dicta non necessitatibus laboriosam est aut cum eos et. Animi pariatur aliquid sint ipsum nam occaecati nisi sit.",
variant: "danger",
variant: "caution",
},
};

Expand Down
118 changes: 114 additions & 4 deletions src/callout/callout.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,133 @@ import { Callout } from "./callout";

describe("<Callout />", () => {
it("should render children correctly", () => {
render(<Callout variant="info">Hello World</Callout>);
render(<Callout variant="note">Hello World</Callout>);

expect(screen.getByText("Hello World")).toBeInTheDocument();
});

it("should have a vertical bar with border-l-4 class", () => {
const { container } = render(
<Callout variant="note">Test content</Callout>,
);
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const callout = container.querySelector("div");

expect(callout).toHaveClass("border-l-4");
});

it("should apply tip variant border color", () => {
const { container } = render(<Callout variant="tip">Tip message</Callout>);
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const callout = container.querySelector("div");

expect(callout).toHaveClass("border-l-green-700");
});

it("should apply note variant border color", () => {
const { container } = render(
<Callout variant="note">Note message</Callout>,
);
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const callout = container.querySelector("div");

expect(callout).toHaveClass("border-l-blue-700");
});

it("should apply warning variant border color", () => {
const { container } = render(
<Callout variant="warning">Warning message</Callout>,
);
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const callout = container.querySelector("div");

expect(callout).toHaveClass("border-l-yellow-700");
});

it("should apply caution variant border color", () => {
const { container } = render(
<Callout variant="caution">Caution message</Callout>,
);
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const callout = container.querySelector("div");

expect(callout).toHaveClass("border-l-red-700");
});

it("should display 'Tip' label for tip variant", () => {
render(<Callout variant="tip">Tip message</Callout>);

expect(screen.getByText("Tip")).toBeInTheDocument();
});

it("should display 'Note' label for note variant", () => {
render(<Callout variant="note">Note message</Callout>);

expect(screen.getByText("Note")).toBeInTheDocument();
});

it("should display 'Warning' label for warning variant", () => {
render(<Callout variant="warning">Warning message</Callout>);

expect(screen.getByText("Warning")).toBeInTheDocument();
});

it("should display 'Caution' label for caution variant", () => {
render(<Callout variant="caution">Caution message</Callout>);

expect(screen.getByText("Caution")).toBeInTheDocument();
});

it("should render an icon for tip variant", () => {
const { container } = render(<Callout variant="tip">Tip message</Callout>);
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const icon = container.querySelector("svg");

expect(icon).toBeInTheDocument();
});

it("should render an icon for note variant", () => {
const { container } = render(
<Callout variant="note">Note message</Callout>,
);
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const icon = container.querySelector("svg");

expect(icon).toBeInTheDocument();
});

it("should render an icon for warning variant", () => {
const { container } = render(
<Callout variant="warning">Warning message</Callout>,
);
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const icon = container.querySelector("svg");

expect(icon).toBeInTheDocument();
});

it("should render an icon for caution variant", () => {
const { container } = render(
<Callout variant="caution">Caution message</Callout>,
);
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const icon = container.querySelector("svg");

expect(icon).toBeInTheDocument();
});
});

// ------------------------------
// Type tests
// ------------------------------

// @ts-expect-error - Callout does not accept `role`
<Callout variant="success" role="alert">
<Callout variant="tip" role="alert">
Hello World
</Callout>;

// @ts-expect-error - Callout does not accept `role`
<Callout variant="info" role="alert">
<Callout variant="note" role="alert">
Hello World
</Callout>;

Expand All @@ -31,6 +141,6 @@ describe("<Callout />", () => {
</Callout>;

// @ts-expect-error - Callout does not accept `role`
<Callout variant="danger" role="alert">
<Callout variant="caution" role="alert">
Hello World
</Callout>;
35 changes: 30 additions & 5 deletions src/callout/callout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faCircleCheck,
faCircleInfo,
faTriangleExclamation,
faCircleExclamation,
} from "@fortawesome/free-solid-svg-icons";
import { CalloutProps } from "./types";

const variantClasses = {
success: "text-green-800 bg-green-50 border-green-700",
info: "text-blue-800 bg-blue-50 border-blue-700",
warning: "text-yellow-800 bg-yellow-50 border-yellow-700",
danger: "text-red-900 bg-red-50 border-red-700",
tip: "text-green-800 bg-green-50 border-l-green-700",
note: "text-blue-800 bg-blue-50 border-l-blue-700",
warning: "text-yellow-800 bg-yellow-50 border-l-yellow-700",
caution: "text-red-900 bg-red-50 border-l-red-700",
};

const variantIcons = {
tip: faCircleCheck,
note: faCircleInfo,
warning: faTriangleExclamation,
caution: faCircleExclamation,
};

const variantLabels = {
tip: "Tip",
note: "Note",
warning: "Warning",
caution: "Caution",
};

/**
Expand All @@ -22,13 +43,17 @@ export const Callout = ({
const variantClass = variantClasses[variant];

const classes = [
"p-4 mb-6 border border-solid border-1 break-words",
"p-4 mb-6 border-l-4 break-words",
variantClass,
className,
].join(" ");

return (
<div className={classes} {...others}>
<div className="flex items-start mb-2">
<FontAwesomeIcon icon={variantIcons[variant]} className="me-2 mt-1" />
<strong>{variantLabels[variant]}</strong>
</div>
{children}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/callout/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type CalloutVariant = "success" | "info" | "warning" | "danger";
type CalloutVariant = "tip" | "note" | "warning" | "caution";

export interface CalloutProps
extends Omit<React.HTMLAttributes<HTMLDivElement>, "role"> {
Expand Down