diff --git a/src/components/badges/BadgeCounter.tsx b/src/components/badges/BadgeCounter.tsx index ec2bc2ba2..282145f9b 100644 --- a/src/components/badges/BadgeCounter.tsx +++ b/src/components/badges/BadgeCounter.tsx @@ -19,27 +19,37 @@ */ import styled from '@emotion/styled'; -import { forwardRef } from 'react'; +import { Ref } from 'react'; import { cssVar } from '~utils/design-tokens'; +export enum BadgeCounterVariety { + Accent = 'accent', + Default = 'default', +} + export interface BadgeCounterProps { className?: string; + ref?: Ref; /** * Specifies the content of the BadgeCounter. * Type string is possible, to allow for use cases like `23+` */ value: number | string; + /** + * Specifies the visual style of the BadgeCounter. Must match `BadgeCounterVariety`. + * @defaultValue `BadgeCounterVariety.Default`. + */ + variety?: `${BadgeCounterVariety}`; } -export const BadgeCounter = forwardRef( - ({ value, ...otherProps }, ref) => { - return ( - - {value} - - ); - }, -); +export function BadgeCounter(props: Readonly) { + const { value, variety = BadgeCounterVariety.Default, ...restProps } = props; + return ( + + {value} + + ); +} BadgeCounter.displayName = 'BadgeCounter'; @@ -53,9 +63,20 @@ const BadgeCounterStyled = styled.span` padding: ${cssVar('dimension-space-0')} ${cssVar('dimension-space-50')}; font: ${cssVar('typography-text-small-semi-bold')}; - color: ${cssVar('color-text-default')}; + color: var(--badge-counter-color); text-align: center; - background-color: ${cssVar('color-background-neutral-bolder-default')}; + background-color: var(--badge-counter-background-color); `; BadgeCounterStyled.displayName = 'BadgeCounterStyled'; + +const BADGE_COUNTER_VARIETY_STYLES = { + [BadgeCounterVariety.Default]: { + '--badge-counter-color': cssVar('color-text-default'), + '--badge-counter-background-color': cssVar('color-background-neutral-bolder-default'), + }, + [BadgeCounterVariety.Accent]: { + '--badge-counter-color': cssVar('color-text-on-color'), + '--badge-counter-background-color': cssVar('color-background-accent-default'), + }, +}; diff --git a/src/components/badges/__tests__/BadgeCounter-test.tsx b/src/components/badges/__tests__/BadgeCounter-test.tsx index 2d4ee974b..aca32cb66 100644 --- a/src/components/badges/__tests__/BadgeCounter-test.tsx +++ b/src/components/badges/__tests__/BadgeCounter-test.tsx @@ -18,13 +18,25 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { render, screen } from '@testing-library/react'; -import { BadgeCounter } from '../BadgeCounter'; +import { screen } from '@testing-library/react'; +import { render } from '~common/helpers/test-utils'; +import { BadgeCounter, BadgeCounterProps, BadgeCounterVariety } from '../BadgeCounter'; -describe('RatingBadge', () => { - it('renders as expected', () => { - render(); +describe('BadgeCounter', () => { + it.each(Object.values(BadgeCounterVariety))('renders with the %s variety', async (variety) => { + const { container } = renderBadgeCounter({ value: 3, variety }); - expect(screen.getByText('7')).toBeInTheDocument(); + expect(screen.getByText('3')).toBeInTheDocument(); + await expect(container).toHaveNoA11yViolations(); + }); + + it('accepts a string value', () => { + renderBadgeCounter({ value: '23+' }); + + expect(screen.getByText('23+')).toBeInTheDocument(); }); }); + +function renderBadgeCounter(props: BadgeCounterProps) { + return render(); +} diff --git a/src/components/badges/index.ts b/src/components/badges/index.ts index 23e340bc5..84fa00bc5 100644 --- a/src/components/badges/index.ts +++ b/src/components/badges/index.ts @@ -19,7 +19,7 @@ */ export { Badge, BadgeSize, BadgeVariety } from './Badge'; -export { BadgeCounter } from './BadgeCounter'; +export { BadgeCounter, BadgeCounterVariety } from './BadgeCounter'; export { BadgeSeverity, BadgeSeverityLevel, BadgeSeverityVariety } from './BadgeSeverity'; export { RatingBadge, RatingBadgeRating, RatingBadgeSize } from './RatingBadge'; export { RatingBadgeButton } from './RatingBadgeButton'; diff --git a/stories/badges/BadgeCounter-stories.tsx b/stories/badges/BadgeCounter-stories.tsx index 5e6949b81..76c417d27 100644 --- a/stories/badges/BadgeCounter-stories.tsx +++ b/stories/badges/BadgeCounter-stories.tsx @@ -19,13 +19,20 @@ */ import type { Meta, StoryObj } from '@storybook/react-vite'; -import { BadgeCounter } from '../../src'; +import { BadgeCounter, BadgeCounterVariety } from '../../src'; import { basicWrapperDecorator } from '../helpers/BasicWrapper'; const meta: Meta = { component: BadgeCounter, decorators: [basicWrapperDecorator], + argTypes: { + variety: { + control: { type: 'select' }, + options: Object.values(BadgeCounterVariety), + }, + }, + parameters: { controls: { exclude: ['className'] }, }, @@ -47,3 +54,15 @@ export const Default: Story = { ), }; + +export const Accent: Story = { + args: { + value: 42, + variety: BadgeCounterVariety.Accent, + }, + render: (args) => ( + + + + ), +};