Skip to content

Commit

Permalink
feat: add anchor component
Browse files Browse the repository at this point in the history
  • Loading branch information
dominik-stumpf committed Jul 9, 2024
1 parent a525c4b commit 53c2028
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
68 changes: 68 additions & 0 deletions src/v2/components/ui/Anchor.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import type { Meta, StoryObj } from "@storybook/react"
import { Anchor } from "./Anchor"

const meta: Meta<typeof Anchor> = {
title: "Design system/Anchor",
component: Anchor,
}

export default meta

type Story = StoryObj<typeof Anchor>

export const Default: Story = {
args: {
children: "Default",
href: "#",
variant: "default",
},
argTypes: {
variant: {
control: {
disable: true,
},
},
showExternal: {
type: "boolean",
control: "boolean",
},
asChild: {
control: {
disable: true,
},
},
},
}

export const Muted: Story = {
args: {
...Default.args,
variant: "muted",
children: "Muted",
},
argTypes: {
...Default.argTypes,
},
}

export const Highlighted: Story = {
args: {
...Default.args,
variant: "highlighted",
children: "Highlighted",
},
argTypes: {
...Default.argTypes,
},
}

export const Silent: Story = {
args: {
...Default.args,
variant: "silent",
children: "Silent",
},
argTypes: {
...Default.argTypes,
},
}
65 changes: 65 additions & 0 deletions src/v2/components/ui/Anchor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import * as React from "react"

import { cn } from "@/lib/utils"
import Link from "next/link"
import { ArrowSquareOut } from "@phosphor-icons/react/dist/ssr/ArrowSquareOut"

const anchorVariants = cva(
"underline-offset-4 focus-visible:ring-ring focus-visible:ring-4 outline-none",
{
variants: {
variant: {
default: "text-foreground hover:underline",
highlighted: "text-anchor-foreground hover:underline",
muted: "text-muted-foreground font-semibold hover:underline",
silent: "",
},
},
defaultVariants: {
variant: "default",
},
}
)

export interface AnchorProps
extends React.ComponentProps<typeof Link>,
VariantProps<typeof anchorVariants> {
asChild?: boolean
showExternal?: boolean
}

const Anchor = React.forwardRef<HTMLAnchorElement, AnchorProps>(
(
{
className,
variant,
asChild = false,
showExternal = false,
children,
...props
},
ref
) => {
const Comp = asChild ? Slot : Link

return (
<Comp
className={cn(
anchorVariants({ variant }),
showExternal && "inline-flex items-center gap-1",
className
)}
ref={ref}
{...props}
>
{children}
{showExternal && <ArrowSquareOut />}
</Comp>
)
}
)
Anchor.displayName = "Anchor"

export { Anchor, anchorVariants }

0 comments on commit 53c2028

Please sign in to comment.