{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "bubble",
  "title": "Bubble",
  "description": "A chat message bubble for conversational interfaces.",
  "dependencies": [
    "@base-ui/react@^1.6.0",
    "class-variance-authority@^0.7.1"
  ],
  "registryDependencies": [
    "@nx-ui/utils"
  ],
  "files": [
    {
      "path": "components/ui/bubble.tsx",
      "content": "import * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction BubbleGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"bubble-group\"\n      className={cn(\"flex min-w-0 flex-col gap-2\", className)}\n      {...props}\n    />\n  )\n}\n\nconst bubbleVariants = cva(\n  \"group/bubble relative flex w-fit max-w-[80%] min-w-0 flex-col gap-1 group-data-[align=end]/message:self-end data-[align=end]:self-end data-[variant=ghost]:max-w-full\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"*:data-[slot=bubble-content]:bg-primary *:data-[slot=bubble-content]:text-primary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-primary/80\",\n        secondary:\n          \"*:data-[slot=bubble-content]:bg-bg-tertiary *:data-[slot=bubble-content]:text-secondary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--color-bg-tertiary),var(--foreground)_5%)]\",\n        muted:\n          \"*:data-[slot=bubble-content]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--muted),var(--foreground)_5%)]\",\n        tinted:\n          \"*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)]\",\n        outline:\n          \"*:data-[slot=bubble-content]:border-border *:data-[slot=bubble-content]:bg-background [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30\",\n        ghost:\n          \"border-none *:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50\",\n        destructive:\n          \"*:data-[slot=bubble-content]:bg-destructive/10 *:data-[slot=bubble-content]:text-destructive dark:*:data-[slot=bubble-content]:bg-destructive/20 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/20 dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/30\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Bubble({\n  variant = \"default\",\n  align = \"start\",\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> &\n  VariantProps<typeof bubbleVariants> & {\n    align?: \"start\" | \"end\"\n  }) {\n  return (\n    <div\n      data-slot=\"bubble\"\n      data-variant={variant}\n      data-align={align}\n      className={cn(bubbleVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction BubbleContent({\n  className,\n  render,\n  ...props\n}: useRender.ComponentProps<\"div\">) {\n  return useRender({\n    defaultTagName: \"div\",\n    props: mergeProps<\"div\">(\n      {\n        className: cn(\n          \"w-fit max-w-full min-w-0 overflow-hidden rounded-xl border border-transparent px-3 py-2 text-sm leading-relaxed wrap-break-word group-data-[align=end]/bubble:self-end group-data-[align=end]/bubble:rounded-tr-none group-data-[align=start]/bubble:rounded-tl-none [button]:text-left [button,a]:transition-colors [button,a]:outline-none [button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-4 [button,a]:focus-visible:ring-ring/25\",\n          className\n        ),\n      },\n      props\n    ),\n    render,\n    state: {\n      slot: \"bubble-content\",\n    },\n  })\n}\n\nconst bubbleReactionsVariants = cva(\n  \"absolute z-10 flex w-fit shrink-0 items-center justify-center gap-1 rounded-full bg-muted px-1.5 py-0.5 text-sm ring-3 ring-card has-[button]:p-0\",\n  {\n    variants: {\n      side: {\n        top: \"top-0 -translate-y-3/4\",\n        bottom: \"bottom-0 translate-y-3/4\",\n      },\n      align: {\n        start: \"left-3\",\n        end: \"right-3\",\n      },\n    },\n    defaultVariants: {\n      side: \"bottom\",\n      align: \"end\",\n    },\n  }\n)\n\nfunction BubbleReactions({\n  side = \"bottom\",\n  align = \"end\",\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  align?: \"start\" | \"end\"\n  side?: \"top\" | \"bottom\"\n}) {\n  return (\n    <div\n      data-slot=\"bubble-reactions\"\n      data-align={align}\n      data-side={side}\n      className={cn(bubbleReactionsVariants({ side, align }), className)}\n      {...props}\n    />\n  )\n}\n\nexport { BubbleGroup, Bubble, BubbleContent, BubbleReactions }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}