From 1c8ac3d247a18cecd8d1152cd21a3ee34e2b38a7 Mon Sep 17 00:00:00 2001 From: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Date: Wed, 10 Sep 2025 00:15:37 +0530 Subject: [PATCH] [WEB-4737] dev: propel pill component (#7743) * dev: pill component added to propel * dev: pill story added * chore: propel config updated * chore: code refactor --- packages/propel/package.json | 1 + packages/propel/src/pill/index.ts | 2 + packages/propel/src/pill/pill.stories.tsx | 143 ++++++++++++++++++++++ packages/propel/src/pill/pill.tsx | 72 +++++++++++ packages/propel/tsdown.config.ts | 1 + 5 files changed, 219 insertions(+) create mode 100644 packages/propel/src/pill/index.ts create mode 100644 packages/propel/src/pill/pill.stories.tsx create mode 100644 packages/propel/src/pill/pill.tsx diff --git a/packages/propel/package.json b/packages/propel/package.json index b08b2a12e..9de16d76e 100644 --- a/packages/propel/package.json +++ b/packages/propel/package.json @@ -29,6 +29,7 @@ "./emoji-icon-picker": "./dist/emoji-icon-picker/index.js", "./icons": "./dist/icons/index.js", "./menu": "./dist/menu/index.js", + "./pill": "./dist/pill/index.js", "./popover": "./dist/popover/index.js", "./scrollarea": "./dist/scrollarea/index.js", "./skeleton": "./dist/skeleton/index.js", diff --git a/packages/propel/src/pill/index.ts b/packages/propel/src/pill/index.ts new file mode 100644 index 000000000..9b9f4c84e --- /dev/null +++ b/packages/propel/src/pill/index.ts @@ -0,0 +1,2 @@ +export { Pill } from "./pill"; +export type { PillProps } from "./pill"; diff --git a/packages/propel/src/pill/pill.stories.tsx b/packages/propel/src/pill/pill.stories.tsx new file mode 100644 index 000000000..7072bdb72 --- /dev/null +++ b/packages/propel/src/pill/pill.stories.tsx @@ -0,0 +1,143 @@ +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { Pill, EPillVariant, EPillSize } from "./pill"; + +const meta: Meta = { + title: "Components/Pill", + component: Pill, + parameters: { + layout: "centered", + }, + tags: ["autodocs"], + argTypes: { + variant: { + control: "select", + options: Object.values(EPillVariant), + }, + size: { + control: "select", + options: Object.values(EPillSize), + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + children: "Default", + }, +}; + +export const Primary: Story = { + args: { + variant: EPillVariant.PRIMARY, + children: "Primary", + }, +}; + +export const Success: Story = { + args: { + variant: EPillVariant.SUCCESS, + children: "Success", + }, +}; + +export const Warning: Story = { + args: { + variant: EPillVariant.WARNING, + children: "Warning", + }, +}; + +export const Error: Story = { + args: { + variant: EPillVariant.ERROR, + children: "Error", + }, +}; + +export const Info: Story = { + args: { + variant: EPillVariant.INFO, + children: "Info", + }, +}; + +export const Small: Story = { + args: { + size: EPillSize.SM, + children: "Small", + }, +}; + +export const Medium: Story = { + args: { + size: EPillSize.MD, + children: "Medium", + }, +}; + +export const Large: Story = { + args: { + size: EPillSize.LG, + children: "Large", + }, +}; + +export const AllVariants: Story = { + render: () => ( +
+
+ Default + Primary + Success + Warning + Error + Info +
+
+ ), +}; + +export const AllSizes: Story = { + render: () => ( +
+
+ Small + Medium + Large +
+
+ ), +}; + +export const WithNumbers: Story = { + render: () => ( +
+
+ 3 + 12 + 99+ + ! +
+
+ ), +}; + +export const StatusExamples: Story = { + render: () => ( +
+
+

Task Status

+
+ Draft + In Progress + In Review + Completed + Blocked +
+
+
+ ), +}; diff --git a/packages/propel/src/pill/pill.tsx b/packages/propel/src/pill/pill.tsx new file mode 100644 index 000000000..dbbf60d8d --- /dev/null +++ b/packages/propel/src/pill/pill.tsx @@ -0,0 +1,72 @@ +import * as React from "react"; +import { cn } from "../utils"; + +export enum EPillVariant { + DEFAULT = "default", + PRIMARY = "primary", + SUCCESS = "success", + WARNING = "warning", + ERROR = "error", + INFO = "info", +} + +export enum EPillSize { + SM = "sm", + MD = "md", + LG = "lg", +} + +export type TPillVariant = + | EPillVariant.DEFAULT + | EPillVariant.PRIMARY + | EPillVariant.SUCCESS + | EPillVariant.WARNING + | EPillVariant.ERROR + | EPillVariant.INFO; +export type TPillSize = EPillSize.SM | EPillSize.MD | EPillSize.LG; + +export interface PillProps extends React.HTMLAttributes { + variant?: TPillVariant; + size?: TPillSize; + className?: string; + children: React.ReactNode; +} + +const pillVariants = { + [EPillVariant.DEFAULT]: "bg-custom-background-90 text-custom-text-200 border border-custom-border-200", + [EPillVariant.PRIMARY]: "bg-custom-primary-100/10 text-custom-primary-100 border border-custom-primary-100/20", + [EPillVariant.SUCCESS]: "bg-green-50 text-green-700 border border-green-200", + [EPillVariant.WARNING]: "bg-amber-50 text-amber-700 border border-amber-200", + [EPillVariant.ERROR]: "bg-red-50 text-red-700 border border-red-200", + [EPillVariant.INFO]: "bg-blue-50 text-blue-700 border border-blue-200", +}; + +const pillSizes = { + [EPillSize.SM]: "px-2 py-0.5 text-xs", + [EPillSize.MD]: "px-2.5 py-1 text-sm", + [EPillSize.LG]: "px-3 py-1.5 text-base", +}; + +const Pill = React.forwardRef( + ({ variant = EPillVariant.DEFAULT, size = EPillSize.MD, className, children, ...props }, ref) => ( + + {children} + + ) +); + +Pill.displayName = "Pill"; + +export { Pill }; diff --git a/packages/propel/tsdown.config.ts b/packages/propel/tsdown.config.ts index 7309c2cba..71d201641 100644 --- a/packages/propel/tsdown.config.ts +++ b/packages/propel/tsdown.config.ts @@ -15,6 +15,7 @@ export default defineConfig({ "src/emoji-icon-picker/index.ts", "src/icons/index.ts", "src/menu/index.ts", + "src/pill/index.ts", "src/popover/index.ts", "src/scrollarea/index.ts", "src/skeleton/index.ts",