Skip to content
ssntl/ui

Notice

A dismissible message with a full-size close button and concentric corners.

Your domain is live

ssntl.app now points to your store. It can take a few minutes to reach everyone.

Installation

$ pnpm dlx shadcn@latest add @ssntl/notice

Usage

tsx
import { Notice, NoticeClose, NoticeDescription, NoticeTitle } from "@/components/ui/notice"

<Notice>
  <NoticeTitle>Your domain is live</NoticeTitle>
  <NoticeDescription>It can take a few minutes to reach everyone.</NoticeDescription>
  <NoticeClose label="Dismiss" onClick={dismiss} />
</Notice>
  • Concentric: the 48px close button sits 8px from the corner of a 32px card, so both curves share a center.
  • The text keeps 64px clear at the end, so it never runs under the close button.
  • Add role="status" only when the notice appears in response to something; static notices need no role.

Code

components/ui/notice.tsx
import * as React from "react"

import { cn } from "@/lib/utils"
import { CloseButton } from "@/registry/ssntl/ui/close-button"

// A dismissible message on a card surface. Concentric: the close button
// (48px, radius 24) sits 8px from the corner, so the notice takes 24 + 8 = 32
// (rounded-lg) and both curves share a center. The text keeps clear of it,
// and 20px on top puts the title's first line on the button's center (32px).
function Notice({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="notice"
      className={cn(
        "relative grid gap-1 rounded-lg bg-card p-6 pe-16 pt-5 text-left shadow-float",
        className
      )}
      {...props}
    />
  )
}

function NoticeTitle({ className, ...props }: React.ComponentProps<"p">) {
  return (
    <p
      data-slot="notice-title"
      className={cn("text-heading", className)}
      {...props}
    />
  )
}

function NoticeDescription({ className, ...props }: React.ComponentProps<"p">) {
  return (
    <p
      data-slot="notice-description"
      className={cn("text-body text-muted-foreground", className)}
      {...props}
    />
  )
}

function NoticeClose({
  className,
  ...props
}: React.ComponentProps<typeof CloseButton>) {
  return (
    <CloseButton className={cn("absolute end-2 top-2", className)} {...props} />
  )
}

export { Notice, NoticeClose, NoticeDescription, NoticeTitle }