diff --git a/components/Badge/Badge.stories.tsx b/components/Badge/Badge.stories.tsx index 14b2af3e..f78be14c 100644 --- a/components/Badge/Badge.stories.tsx +++ b/components/Badge/Badge.stories.tsx @@ -4,6 +4,7 @@ import { VariantProps } from '../../stitches.config'; import { Badge, COLORS } from './Badge'; import { Flex } from '../Flex'; import { modifyVariantsForStory } from '../../utils/modifyVariantsForStory'; +import { UnstyledLink } from '../Link'; type BadgeVariants = VariantProps; type BadgeProps = BadgeVariants & {}; @@ -85,3 +86,9 @@ const Customize: ComponentStory = (args) => ( Customize ); + +export const BadgeLink: ComponentStory = (args) => ( + + Link + +); diff --git a/components/Badge/Badge.test.tsx b/components/Badge/Badge.test.tsx new file mode 100644 index 00000000..e4cc5314 --- /dev/null +++ b/components/Badge/Badge.test.tsx @@ -0,0 +1,15 @@ +import { Badge } from './Badge'; +import { UnstyledLink } from '../Link'; +import { render } from '@testing-library/react'; + +describe('Badge', () => { + it('should render Badge as link', () => { + const { getByRole } = render( + + Link + + ); + + expect(getByRole('link')).toBeInTheDocument(); + }); +}); diff --git a/components/Badge/Badge.tsx b/components/Badge/Badge.tsx index 2eda2bd8..e1c5a695 100644 --- a/components/Badge/Badge.tsx +++ b/components/Badge/Badge.tsx @@ -1,5 +1,6 @@ -import React, { ComponentProps, createContext } from 'react'; -import { styled, VariantProps, CSS } from '../../stitches.config'; +import React, { ComponentProps, useMemo } from 'react'; +import { styled, VariantProps } from '../../stitches.config'; +import { Slot } from '@radix-ui/react-slot'; export const COLORS = ['gray', 'red', 'blue', 'green', 'neon', 'orange', 'purple'] as const; type COLOR_VALUES = typeof COLORS[number]; @@ -85,7 +86,8 @@ const BADGE_BASE_STYLES = { }, }; -export const StyledSpanBadge = styled('span', BADGE_BASE_STYLES); +const StyledSpanBadge = styled('span', BADGE_BASE_STYLES); +const StyledSpanBadgeSlot = styled(Slot, StyledSpanBadge); const StyledButtonBadge = styled('button', BADGE_BASE_STYLES, { '&:focus-visible': { @@ -106,17 +108,23 @@ const StyledButtonBadge = styled('button', BADGE_BASE_STYLES, { }, }, }); +const StyledButtonBadgeSlot = styled(Slot, StyledButtonBadge); interface BadgeProps extends ComponentProps, - VariantProps {} + VariantProps { + asChild?: boolean; +} export const Badge = React.forwardRef, BadgeProps>( - ({ interactive, ...props }, forwardedRef) => { - return interactive ? ( - - ) : ( - - ); + ({ interactive, asChild, ...props }, forwardedRef) => { + const Component = useMemo(() => { + if (interactive) { + return asChild ? StyledButtonBadgeSlot : StyledButtonBadge; + } + return asChild ? StyledSpanBadgeSlot : StyledSpanBadge; + }, [asChild]); + + return ; } );