{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "changelog-entry",
  "title": "Changelog Entry",
  "description": "A release entry with date, version, categories, and linked changes.",
  "dependencies": [
    "class-variance-authority",
    "lucide-react"
  ],
  "registryDependencies": [
    "badge",
    "https://uaiblocks.dev/r/uai-theme.json",
    "https://uaiblocks.dev/r/uai-utils.json"
  ],
  "files": [
    {
      "path": "src/registry/uai/components/changelog-entry.tsx",
      "content": "import { cva } from \"class-variance-authority\";\nimport { ArrowUpRight } from \"lucide-react\";\nimport { type ComponentProps, createContext, useContext, useId } from \"react\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { cn } from \"@/lib/uai-utils\";\n\nexport const CHANGELOG_ENTRY_VARIANTS = [\"timeline\", \"card\", \"compact\"] as const;\nexport type ChangelogEntryVariant = (typeof CHANGELOG_ENTRY_VARIANTS)[number];\nexport type ChangelogEntryCategoryTone = \"added\" | \"improved\" | \"fixed\" | \"removed\" | \"security\";\nexport type ChangelogEntryProps = ComponentProps<\"article\"> & { variant?: ChangelogEntryVariant };\ntype EntryContext = { id: string; variant: ChangelogEntryVariant };\nconst Context = createContext<EntryContext | null>(null);\nfunction useEntry(part: string) {\n  const context = useContext(Context);\n  if (!context) throw new Error(`${part} must be used within ChangelogEntry`);\n  return context;\n}\nconst toneClasses: Record<ChangelogEntryCategoryTone, string> = {\n  added: \"bg-success/14 text-success-ink\",\n  improved:\n    \"bg-[color-mix(in_oklab,color-mix(in_oklab,var(--primary)_62%,var(--foreground))_14%,transparent)] text-primary-ink\",\n  fixed: \"bg-warning/14 text-warning-ink\",\n  removed: \"bg-muted-foreground/14 text-muted-foreground\",\n  security: \"bg-destructive/14 text-destructive-ink\",\n};\n\nconst changelogEntryVariants = cva(\n  \"flex min-w-0 flex-wrap text-[13px]/[18px] text-foreground [&_li]:marker:text-subtle-foreground\",\n  {\n    variants: {\n      variant: {\n        timeline: \"flex-row gap-x-6 gap-y-2 rounded-[14px] border-0 bg-transparent p-0\",\n        card: \"flex-col gap-3 rounded-[14px] border bg-card p-[18px] text-card-foreground\",\n        compact: \"flex-col gap-2 rounded-xl border bg-card p-3 text-card-foreground\",\n      },\n    },\n  },\n);\n\nexport function ChangelogEntry({\n  variant = \"timeline\",\n  className,\n  children,\n  ...props\n}: ChangelogEntryProps) {\n  const id = useId();\n  return (\n    <Context.Provider value={{ id, variant }}>\n      <article\n        aria-labelledby={`${id}-title`}\n        data-slot=\"changelog-entry\"\n        className={cn(changelogEntryVariants({ variant }), className)}\n        {...props}\n        data-variant={variant}\n      >\n        {children}\n      </article>\n    </Context.Provider>\n  );\n}\n\nexport function ChangelogEntryHeader({ className, ...props }: ComponentProps<\"div\">) {\n  const { variant } = useEntry(\"ChangelogEntryHeader\");\n  return (\n    <div\n      data-slot=\"changelog-entry-header\"\n      className={cn(\n        \"flex min-w-0 flex-wrap\",\n        variant === \"timeline\"\n          ? \"flex-[0_0_128px] flex-col items-start gap-1\"\n          : \"flex-row items-center gap-2\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function ChangelogEntryVersion({ className, ...props }: ComponentProps<\"span\">) {\n  const { variant } = useEntry(\"ChangelogEntryVersion\");\n  return (\n    <Badge\n      variant=\"secondary\"\n      data-slot=\"changelog-entry-version\"\n      className={cn(\n        \"gap-0 rounded-md border-0 bg-muted px-1.75 py-0 font-mono text-[11.5px] font-medium text-foreground tabular-nums\",\n        variant === \"compact\" ? \"h-5\" : \"h-5.5\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function ChangelogEntryDate({\n  className,\n  ...props\n}: ComponentProps<\"time\"> & { dateTime: string }) {\n  useEntry(\"ChangelogEntryDate\");\n  return (\n    <time\n      data-slot=\"changelog-entry-date\"\n      className={cn(\"text-[12px] text-subtle-foreground tabular-nums\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function ChangelogEntryContent({ className, ...props }: ComponentProps<\"div\">) {\n  const { variant } = useEntry(\"ChangelogEntryContent\");\n  return (\n    <div\n      data-slot=\"changelog-entry-content\"\n      className={cn(\n        \"grid min-w-0\",\n        variant === \"compact\" ? \"gap-2\" : \"gap-3\",\n        variant === \"timeline\" ? \"flex-[1_1_320px] border-s ps-6\" : \"border-s-0 ps-0\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function ChangelogEntryTitle({\n  level = 3,\n  className,\n  ...props\n}: ComponentProps<\"h3\"> & { level?: 2 | 3 | 4 }) {\n  const { id, variant } = useEntry(\"ChangelogEntryTitle\");\n  const Heading = `h${level}` as \"h3\";\n  return (\n    <Heading\n      data-slot=\"changelog-entry-title\"\n      className={cn(\n        \"m-0 tracking-[-0.01em] text-balance\",\n        variant === \"compact\" ? \"text-sm/5 font-medium\" : \"text-[15px]/[22px] font-medium\",\n        className,\n      )}\n      {...props}\n      id={`${id}-title`}\n    />\n  );\n}\n\nexport function ChangelogEntryCategories({\n  \"aria-label\": label = \"Categories\",\n  className,\n  ...props\n}: ComponentProps<\"ul\">) {\n  useEntry(\"ChangelogEntryCategories\");\n  return (\n    <ul\n      aria-label={label}\n      data-slot=\"changelog-entry-categories\"\n      className={cn(\"m-0 flex list-none flex-wrap gap-1.5 p-0\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function ChangelogEntryCategory({\n  tone = \"improved\",\n  className,\n  children,\n  ...props\n}: ComponentProps<\"li\"> & { tone?: ChangelogEntryCategoryTone }) {\n  useEntry(\"ChangelogEntryCategory\");\n  return (\n    <Badge\n      asChild\n      variant=\"secondary\"\n      className={cn(\n        \"h-5 rounded-full border-0 px-2 py-0 text-[11.5px]/4 font-medium\",\n        toneClasses[tone],\n        className,\n      )}\n    >\n      <li data-slot=\"changelog-entry-category\" {...props} data-tone={tone}>\n        {children}\n      </li>\n    </Badge>\n  );\n}\n\nexport function ChangelogEntryBody({ className, ...props }: ComponentProps<\"div\">) {\n  useEntry(\"ChangelogEntryBody\");\n  return (\n    <div\n      data-slot=\"changelog-entry-body\"\n      className={cn(\"leading-[19px] text-pretty text-muted-foreground\", className)}\n      {...props}\n    />\n  );\n}\n\nexport function ChangelogEntryChanges({ className, ...props }: ComponentProps<\"ul\">) {\n  const { variant } = useEntry(\"ChangelogEntryChanges\");\n  return (\n    <ul\n      data-slot=\"changelog-entry-changes\"\n      className={cn(\n        \"m-0 grid list-disc ps-4.5\",\n        variant === \"compact\" ? \"gap-1\" : \"gap-1.5\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function ChangelogEntryChange({\n  href,\n  className,\n  children,\n  ...props\n}: ComponentProps<\"li\"> & { href?: string }) {\n  useEntry(\"ChangelogEntryChange\");\n  return (\n    <li\n      data-slot=\"changelog-entry-change\"\n      className={cn(\"ps-0.5 text-pretty\", className)}\n      {...props}\n    >\n      {href ? (\n        <a\n          href={href}\n          className=\"group/link text-foreground underline decoration-border-strong underline-offset-3 transition-[text-decoration-color] duration-120 ease-[ease-out] hover:decoration-current focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-ring motion-reduce:transition-none\"\n        >\n          {children}\n          <ArrowUpRight\n            size={12}\n            strokeWidth={2}\n            aria-hidden=\"true\"\n            className=\"ms-0.5 inline-block align-[-1px] text-subtle-foreground [transition:translate_140ms_var(--ease-out-quint),color_120ms_ease-out] group-hover/link:translate-x-px group-hover/link:-translate-y-px group-hover/link:text-foreground motion-reduce:transition-none size-3\"\n          />\n        </a>\n      ) : (\n        children\n      )}\n    </li>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/uai/changelog-entry.tsx"
    }
  ],
  "categories": [
    "content",
    "changelog"
  ],
  "type": "registry:ui"
}