# Border Button Corner 1 - Corner L

> Classic L-shaped bracket on each corner.

A shadcn/ui block from the [@shadcnblocks](https://shadcnblocks.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/shadcnblocks/border-button-border-button-corner-1).

- Page, with a live preview: https://shadcn.exchange/r/shadcnblocks/border-button-border-button-corner-1
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/shadcnblocks/border-button-border-button-corner-1-light-b52b493fce2bbe12.png
- Registry item: https://shadcnblocks.com/r/border-button-border-button-corner-1.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://shadcnblocks.com/r/border-button-border-button-corner-1.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `cn`
- Registry items: `button`

## Files

### `example/border-button/border-button-corner-1.tsx`

```tsx
import { BorderButton } from "@/components/shadcnblocks/border-button";

export const title = "Corner L";

const Example = () => (
  <BorderButton corners="l" variant="outline">
    Corner L
  </BorderButton>
);

export default Example;
```

### `components/shadcnblocks/border-button.tsx`

```tsx
import { cn } from "cn";

import { Button } from "@/components/ui/button";

export type BorderCornerStyle = "l" | "plus" | "square" | "double" | "dot";

const cornerPlacements: Array<{ className: string }> = [
  { className: "absolute -bottom-px -left-px" },
  { className: "absolute -bottom-px -right-px scale-x-[-1]" },
  { className: "absolute -top-px -left-px scale-y-[-1]" },
  { className: "absolute -top-px -right-px scale-[-1]" },
];

export const BorderButton = ({
  children,
  variant = "outline",
  corners = "l",
  className,
}: {
  children: React.ReactNode;
  variant?:
    | "outline"
    | "default"
    | "destructive"
    | "secondary"
    | "ghost"
    | "link";
  corners?: BorderCornerStyle;
  className?: string;
}) => {
  return (
    <Button
      variant={variant}
      className={cn(
        className,
        "relative overflow-visible rounded-none px-4! shadow-none",
      )}
    >
      {children}
      {cornerPlacements.map((placement) => (
        <CornerArt
          key={placement.className}
          style={corners}
          className={placement.className}
        />
      ))}
    </Button>
  );
};

const overflowVisibleStyles: Partial<Record<BorderCornerStyle, boolean>> = {
  plus: true,
  double: true,
  dot: true,
};

const CornerArt = ({
  style,
  className,
}: {
  style: BorderCornerStyle;
  className?: string;
}) => {
  return (
    <svg
      viewBox="0 0 12 12"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      overflow={overflowVisibleStyles[style] ? "visible" : undefined}
      aria-hidden
      className={cn("pointer-events-none size-3", className)}
    >
      {cornerPaths[style]}
    </svg>
  );
};

const stroke = {
  stroke: "currentColor",
  strokeWidth: 1,
  strokeLinecap: "square" as const,
};

const cornerPaths: Record<BorderCornerStyle, React.ReactNode> = {
  l: (
    <>
      <path d="M0 0V12" {...stroke} />
      <path d="M0 12H12" {...stroke} />
    </>
  ),
  plus: (
    <>
      <path d="M-6 12 H6" {...stroke} />
      <path d="M0 6 V18" {...stroke} />
    </>
  ),
  square: <rect x="0" y="8" width="4" height="4" {...stroke} />,
  double: (
    <>
      <path d="M0 0 V12" {...stroke} />
      <path d="M0 12 H12" {...stroke} />
      <path d="M-2 2 V14" {...stroke} />
      <path d="M-2 14 H10" {...stroke} />
    </>
  ),
  dot: (
    <>
      <circle cx="0" cy="12" r="1.25" fill="currentColor" />
      <path d="M-4.5 12 H0" {...stroke} />
      <path d="M0 12 V16.5" {...stroke} />
    </>
  ),
};
```
