import { StoryObj, Meta } from "@storybook/react-vite"; import { within, expect } from "storybook/test"; import { useState } from "react"; import Tag from "./tag"; import type { TagVariant } from "./tag.types"; import "./tag.scss"; const meta: Meta = { title: "FP.React Components/Tag", component: Tag, tags: ["autodocs", "beta"], argTypes: { variant: { control: "select", options: ["alpha", "beta", "stable", "production"] as TagVariant[], description: "Visual variant with predefined color schemes", table: { type: { summary: "TagVariant" }, defaultValue: { summary: "undefined" }, }, }, elm: { control: "radio", options: ["span", "p"], description: "HTML element to render (span for inline, p for block)", table: { type: { summary: "span | p" }, defaultValue: { summary: "span" }, }, }, role: { control: "radio", options: ["note", "status"], description: "ARIA role (note for static, status for dynamic content)", table: { type: { summary: "note | status" }, defaultValue: { summary: "note" }, }, }, children: { control: "text", description: "Content to display inside the tag", }, }, args: { children: "Tag", }, parameters: { docs: { description: { component: `A small inline label component for displaying status, versions, or environment indicators with WCAG 2.1 AA accessibility compliance. ## CSS Variables ### Spacing - \`--tag-padding-inline\`: Horizontal padding (default: 0.7rem / 11.2px) - \`--tag-padding-block\`: Vertical padding (default: 0.2rem / 3.2px) ### Typography - \`--tag-fs\`: Font size (default: 0.8rem / 12.8px) - \`--tag-fw\`: Font weight (default: 500) - \`--tag-color\`: Text color (default: currentColor) ### Appearance - \`--tag-bg\`: Background color (default: lightgray) - \`--tag-radius\`: Border radius (default: 99rem for pill shape, 0.5rem for block) - \`--tag-display\`: Display mode (default: inline-block, block for \`

\`) ### Variant Colors (WCAG AA Compliant) - \`--beta\`: Amber (#fbbf24) - 6.94:1 contrast with black - \`--stable\`: Dark green (#0f7c3e) - 4.56:1 contrast with white - \`--production\`: Dark blue (#1e3a8a) - 8.59:1 contrast with white `, }, }, }, } satisfies Meta; export default meta; type Story = StoryObj; /** * Default tag with no variant styling */ export const Default: Story = { args: { children: "Default Tag", }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); const tag = canvas.getByRole("note"); expect(tag).toBeInTheDocument(); expect(tag.textContent).toBe("Default Tag"); }, }; /** * Alpha variant - for early development stage indicators */ export const Alpha: Story = { args: { variant: "alpha", children: "Alpha", }, parameters: { docs: { description: { story: "Alpha variant with warning colors for early development features.", }, }, }, } as Story; /** * Beta variant - for pre-release version indicators */ export const Beta: Story = { args: { variant: "beta", children: "Beta", }, parameters: { docs: { description: { story: "Beta variant with warning colors for pre-release features.", }, }, }, } as Story; /** * Stable variant - for production-ready release indicators */ export const Stable: Story = { args: { variant: "stable", children: "Stable", }, parameters: { docs: { description: { story: "Stable variant with success colors for production-ready releases.", }, }, }, } as Story; /** * Production variant - for live environment indicators */ export const Production: Story = { args: { variant: "production", children: "Production", }, parameters: { docs: { description: { story: "Production variant with primary colors for live environment indicators.", }, }, }, } as Story; /** * All variants displayed together for comparison */ export const AllVariants: Story = { render: () => (

Default Alpha Beta Stable Production
), parameters: { docs: { description: { story: "Comparison of all available tag variants side by side.", }, }, }, } as Story; /** * Block-level tag using paragraph element */ export const BlockLevelTag: Story = { args: { elm: "p", variant: "beta", children: "Block-level Beta Tag", }, parameters: { docs: { description: { story: "Tag rendered as a block-level paragraph element with modified border radius.", }, }, }, } as Story; /** * Dynamic status tag with role="status" for live updates */ const DynamicStatusComponent = () => { const [status, setStatus] = useState<"Deploying" | "Deployed">("Deploying"); return (
{status}
); }; export const DynamicStatus: Story = { render: () => , parameters: { docs: { description: { story: 'Demonstrates role="status" for dynamic content that announces updates to screen readers.', }, }, }, }; /** * Tag with accessibility label for additional context */ export const WithAriaLabel: Story = { args: { variant: "beta", children: "Beta", "aria-label": "Beta version - feedback welcome", }, parameters: { docs: { description: { story: "Tag with aria-label providing additional context for screen reader users.", }, }, }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); const tag = canvas.getByLabelText("Beta version - feedback welcome"); expect(tag).toBeInTheDocument(); }, }; /** * Tags used inline within text content */ export const InlineUsage: Story = { render: () => (

This feature is currently in{" "} Beta {" "} and will be moved to{" "} Stable {" "} after testing is complete.

), parameters: { docs: { description: { story: "Tags used inline within paragraph text for contextual labeling.", }, }, }, }; /** * Version tags with custom styling */ export const VersionTags: Story = { render: () => (
v0.1.0-alpha v0.9.0-beta v1.0.0 v2.0.0 v2.1.0
), parameters: { docs: { description: { story: "Tags used for version labeling with semantic variants.", }, }, }, }; /** * Custom styled tags with inline styles */ export const CustomStyling: Story = { render: () => (
Custom Red Large Beta Square Tag
), parameters: { docs: { description: { story: "Tags with custom inline styles overriding default CSS custom properties.", }, }, }, }; /** * Accessibility test - keyboard navigation and screen reader support */ export const AccessibilityDemo: Story = { render: () => (
Static Tags (role="note"):
v1.0 Beta
Dynamic Tags (role="status"):
Running Building...
), parameters: { docs: { description: { story: 'Demonstrates proper ARIA role usage: role="note" for static content, role="status" for dynamic updates.', }, }, a11y: { config: { rules: [ { id: "color-contrast", enabled: true, }, ], }, }, }, };