From e981a9fa6d7ff61849bea3d3467bd404eff6c373 Mon Sep 17 00:00:00 2001 From: Mrugesh Mohapatra Date: Mon, 6 Oct 2025 12:10:12 +0530 Subject: [PATCH] feat: use standardised callouts --- src/callout/callout.stories.tsx | 12 ++-- src/callout/callout.test.tsx | 118 ++++++++++++++++++++++++++++++-- src/callout/callout.tsx | 35 ++++++++-- src/callout/types.ts | 2 +- 4 files changed, 151 insertions(+), 16 deletions(-) diff --git a/src/callout/callout.stories.tsx b/src/callout/callout.stories.tsx index 157d50bc..638da511 100644 --- a/src/callout/callout.stories.tsx +++ b/src/callout/callout.stories.tsx @@ -9,19 +9,19 @@ const story = { type Story = StoryObj; -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", }, }; @@ -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", }, }; diff --git a/src/callout/callout.test.tsx b/src/callout/callout.test.tsx index 45008093..c72e06b9 100644 --- a/src/callout/callout.test.tsx +++ b/src/callout/callout.test.tsx @@ -5,10 +5,120 @@ import { Callout } from "./callout"; describe("", () => { it("should render children correctly", () => { - render(Hello World); + render(Hello World); expect(screen.getByText("Hello World")).toBeInTheDocument(); }); + + it("should have a vertical bar with border-l-4 class", () => { + const { container } = render( + Test content, + ); + // 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(Tip message); + // 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( + Note message, + ); + // 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( + Warning message, + ); + // 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( + Caution message, + ); + // 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(Tip message); + + expect(screen.getByText("Tip")).toBeInTheDocument(); + }); + + it("should display 'Note' label for note variant", () => { + render(Note message); + + expect(screen.getByText("Note")).toBeInTheDocument(); + }); + + it("should display 'Warning' label for warning variant", () => { + render(Warning message); + + expect(screen.getByText("Warning")).toBeInTheDocument(); + }); + + it("should display 'Caution' label for caution variant", () => { + render(Caution message); + + expect(screen.getByText("Caution")).toBeInTheDocument(); + }); + + it("should render an icon for tip variant", () => { + const { container } = render(Tip message); + // 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( + Note message, + ); + // 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( + Warning message, + ); + // 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( + Caution message, + ); + // eslint-disable-next-line testing-library/no-container, testing-library/no-node-access + const icon = container.querySelector("svg"); + + expect(icon).toBeInTheDocument(); + }); }); // ------------------------------ @@ -16,12 +126,12 @@ describe("", () => { // ------------------------------ // @ts-expect-error - Callout does not accept `role` - + Hello World ; // @ts-expect-error - Callout does not accept `role` - + Hello World ; @@ -31,6 +141,6 @@ describe("", () => { ; // @ts-expect-error - Callout does not accept `role` - + Hello World ; diff --git a/src/callout/callout.tsx b/src/callout/callout.tsx index 0e2af738..1f8a7274 100644 --- a/src/callout/callout.tsx +++ b/src/callout/callout.tsx @@ -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", }; /** @@ -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 (
+
+ + {variantLabels[variant]} +
{children}
); diff --git a/src/callout/types.ts b/src/callout/types.ts index fce4c35c..503af83c 100644 --- a/src/callout/types.ts +++ b/src/callout/types.ts @@ -1,4 +1,4 @@ -type CalloutVariant = "success" | "info" | "warning" | "danger"; +type CalloutVariant = "tip" | "note" | "warning" | "caution"; export interface CalloutProps extends Omit, "role"> {