import UI from '#components/ui' import React from 'react' /** * Props for the Badge component * * @property {React.ReactNode} children - Content to display inside the badge (typically numbers or short text) * @property {string} [id] - Optional HTML id attribute for the badge element * @property {React.CSSProperties} [styles] - Inline styles to apply to the badge * @property {string} [classes] - CSS class names to apply to the badge * @property {'rounded'} [variant] - Visual variant of the badge. Use 'rounded' for circular badges (fixed size with ellipsis for overflow) * @property {string} [aria-label] - Accessible label for screen readers. Required for icon-only or number-only badges * @property {'status' | 'note'} [role] - ARIA role for the badge. Defaults to 'status' for dynamic content */ export type BadgeProps = { /** * Content to display inside the badge (typically numbers or short text) */ children?: React.ReactNode /** * Visual variant of the badge * - 'rounded': Circular badge style */ variant?: 'rounded' } & React.ComponentProps /** * Badge - A small label component for displaying status, counts, or notifications * * The Badge component is used to display supplementary information alongside other content, * such as notification counts, status indicators, or labels. It renders as a semantic `` * element with a nested `` required for the component's styling architecture. * * ## Styling Architecture * * The Badge uses a nested structure (`content`) which is required * for the SCSS styling system. The outer `` element provides positioning context, * while the inner `` receives the visual styling (background, padding, border-radius). * * ## Rounded Variant Behavior * * The `rounded` variant creates a perfect circular badge with fixed dimensions (1.5625rem). * Content that exceeds the available space will be truncated with an ellipsis (...). * **Best practice**: Format large numbers yourself (e.g., pass "99+" instead of "999"). * * ## Accessibility Considerations * * - **Semantic HTML**: Uses `` (superscript) element for proper positioning context * - **ARIA Role**: Defaults to `role="status"` for dynamic badges (e.g., unread counts) * - **Accessible Names**: For icon-only or number-only badges, provide an `aria-label` * to give context (e.g., "3 unread messages" instead of just "3") * - **Live Regions**: The `role="status"` makes badges announce updates to screen readers * * @param {BadgeProps} props - Component props * @returns {React.ReactElement} A Badge component * * @example * // Basic badge with notification count *

* Messages * 3 *

* * @example * // Rounded badge variant (perfect circle) *

* Notifications * 99+ *

* * @example * // Status badge with custom styling *

* Active Users * 21 *

* * @example * // ✅ GOOD: Accessible badge with descriptive label and formatted content * 12 * * @example * // ✅ GOOD: Large numbers formatted by developer * 99+ * * @example * // ❌ BAD: Number-only badge without context for screen readers * 12 */ export const Badge = ({ id, styles, classes, children, variant, ...props }: BadgeProps) => { // Build data-badge attribute for variant styling const dataBadge = variant ? variant : undefined return ( {children} ) } Badge.displayName = 'Badge' export default Badge