-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Pill): introducing Pill component (#363)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced new color tokens for UI elements, enhancing visual cues for information, success, warning, and error states. - Added the `Pill` component to the UI library, enabling the display of release stage information in a visually appealing pill format. - **Documentation** - Updated documentation to include the `Pill` component, showcasing its use alongside existing components. - **Tests** - Implemented test coverage for the `Pill` component to ensure reliable rendering across various states and properties. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Loading branch information
Showing
9 changed files
with
239 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import type { Story } from "@ladle/react"; | ||
import { Pill } from "@versini/ui-components"; | ||
|
||
export default { | ||
title: "Components/Pill", | ||
meta: { | ||
importName: "Pill", | ||
}, | ||
}; | ||
|
||
export const Basic: Story<any> = (args) => { | ||
return ( | ||
<div className="flex flex-wrap gap-2"> | ||
<Pill label="this is a pill" {...args} /> | ||
</div> | ||
); | ||
}; | ||
Basic.args = { | ||
description: "", | ||
}; | ||
Basic.argTypes = { | ||
variant: { | ||
options: ["error", "information", "success", "warning"], | ||
control: { type: "radio" }, | ||
defaultValue: "information", | ||
}, | ||
}; | ||
|
||
export const HardCoded: Story<any> = () => { | ||
return ( | ||
<div className="flex flex-wrap gap-2"> | ||
<Pill label="warning" variant="warning" /> | ||
<Pill label="success" variant="success" /> | ||
<Pill label="info" variant="information" /> | ||
<Pill label="error" variant="error" /> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { PillProps } from "./PillTypes"; | ||
import { getPillClasses } from "./utilities"; | ||
|
||
export const Pill = ({ | ||
label, | ||
className, | ||
variant = "information", | ||
description, | ||
spacing, | ||
}: PillProps) => { | ||
const pillClassName = getPillClasses({ | ||
label, | ||
className, | ||
variant, | ||
spacing, | ||
}); | ||
return ( | ||
<div role="text" className={pillClassName}> | ||
{description && <span className="sr-only">{description}</span>} | ||
<span>{label}</span> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { SpacingProps } from "@versini/ui-private/dist/utilities"; | ||
|
||
export type PillProps = { | ||
/** | ||
* Content of the Pill. | ||
*/ | ||
label: string; | ||
/** | ||
* CSS class(es) to add to the main component wrapper. | ||
*/ | ||
className?: string; | ||
/** | ||
* Hidden label adjacent to the pill text to provide added | ||
* context for screen reader users, ideally no more | ||
* than 2-3 words. | ||
*/ | ||
description?: string; | ||
/** | ||
* Theme of the Pill. | ||
* @default "information" | ||
*/ | ||
variant?: "information" | "warning" | "error" | "success"; | ||
} & SpacingProps; |
82 changes: 82 additions & 0 deletions
82
packages/ui-components/src/components/Pill/__tests__/Pill.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { render, screen } from "@testing-library/react"; | ||
|
||
import { expectToHaveClasses } from "../../../common/__tests__/helpers"; | ||
import { PILL_CLASSNAME } from "../../../common/constants"; | ||
import { Pill } from "../.."; | ||
|
||
describe("Pill (exceptions)", () => { | ||
it("should be able to require/import from root", () => { | ||
expect(Pill).toBeDefined(); | ||
}); | ||
}); | ||
|
||
describe("Pill modifiers", () => { | ||
it("should render a default pill", async () => { | ||
render(<Pill label="hello" />); | ||
const pill = await screen.findByRole("text"); | ||
expectToHaveClasses(pill, [ | ||
PILL_CLASSNAME, | ||
"px-2", | ||
"py-0.5", | ||
"text-xs", | ||
"bg-surface-information", | ||
"text-copy-information", | ||
"border-border-information", | ||
]); | ||
}); | ||
|
||
it("should render a pill with variant warning", async () => { | ||
render(<Pill label="hello" variant="warning" />); | ||
const pill = await screen.findByRole("text"); | ||
expectToHaveClasses(pill, [ | ||
PILL_CLASSNAME, | ||
"px-2", | ||
"py-0.5", | ||
"text-xs", | ||
"bg-surface-warning", | ||
"text-copy-warning", | ||
"border-border-warning", | ||
]); | ||
}); | ||
|
||
it("should render a pill with variant success", async () => { | ||
render(<Pill label="hello" variant="success" />); | ||
const pill = await screen.findByRole("text"); | ||
expectToHaveClasses(pill, [ | ||
PILL_CLASSNAME, | ||
"px-2", | ||
"py-0.5", | ||
"text-xs", | ||
"bg-surface-success", | ||
"text-copy-success", | ||
"border-border-success", | ||
]); | ||
}); | ||
|
||
it("should render a pill with variant error", async () => { | ||
render(<Pill label="hello" variant="error" />); | ||
const pill = await screen.findByRole("text"); | ||
expectToHaveClasses(pill, [ | ||
PILL_CLASSNAME, | ||
"px-2", | ||
"py-0.5", | ||
"text-xs", | ||
"bg-surface-error", | ||
"text-copy-error", | ||
"border-border-error", | ||
]); | ||
}); | ||
|
||
it("should render a pill with a custom class", async () => { | ||
render(<Pill label="hello" className="custom-class" />); | ||
const pill = await screen.findByRole("text"); | ||
expectToHaveClasses(pill, [PILL_CLASSNAME, "custom-class"]); | ||
}); | ||
|
||
it("should render a pill with a description", async () => { | ||
render(<Pill label="hello" description="this is a description" />); | ||
await screen.findByRole("text"); | ||
const description = await screen.findByText("this is a description"); | ||
expect(description.className).toContain("sr-only"); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { getSpacing } from "@versini/ui-private/dist/utilities"; | ||
import clsx from "clsx"; | ||
|
||
import { PILL_CLASSNAME } from "../../common/constants"; | ||
import type { PillProps } from "./PillTypes"; | ||
|
||
const getPillBorderClasses = ({ variant }: { variant?: string }) => { | ||
return clsx("rounded-sm border", { | ||
"border-border-information": variant === "information", | ||
"border-border-warning": variant === "warning", | ||
"border-border-success": variant === "success", | ||
"border-border-error": variant === "error", | ||
}); | ||
}; | ||
|
||
const getPillCopyClasses = ({ variant }: { variant?: string }) => { | ||
return clsx("not-prose", { | ||
"text-copy-information": variant === "information", | ||
"text-copy-warning": variant === "warning", | ||
"text-copy-success": variant === "success", | ||
"text-copy-error": variant === "error", | ||
}); | ||
}; | ||
|
||
const getPillBackgroundClasses = ({ variant }: { variant?: string }) => { | ||
return clsx({ | ||
"bg-surface-information": variant === "information", | ||
"bg-surface-warning": variant === "warning", | ||
"bg-surface-success": variant === "success", | ||
"bg-surface-error": variant === "error", | ||
}); | ||
}; | ||
|
||
export const getPillClasses = (props: PillProps) => { | ||
const { className, spacing, variant } = props; | ||
|
||
return clsx( | ||
PILL_CLASSNAME, | ||
"px-2 py-0.5 text-xs", | ||
getSpacing(spacing), | ||
getPillBorderClasses({ variant }), | ||
getPillCopyClasses({ variant }), | ||
getPillBackgroundClasses(props), | ||
className, | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters