{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "item-drag",
  "title": "Drag item",
  "description": "Styled item: the Drag set. 5 decorative item variations (HandleItem, GripItem, ReorderItem, GhostItem, RailItem) on the ai2 token system, driven by CSS token transitions and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "lucide-react@^1.23.0"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/item-drag.tsx",
      "content": "\"use client\"\n\nimport type * as React from \"react\"\nimport { ArrowDown, ArrowUp, ChevronRight, GripHorizontal, GripVertical } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Item drag family: 5 list rows carrying the VISUAL AFFORDANCE of reordering.\n   IMPORTANT: there is NO real drag and drop here. No dnd library is wired up and\n   the rows never swap places. This file only offers the visual language that gives\n   the feeling \"this row can be moved\": a handle, grip dots, up/down buttons, a\n   ghost surface, an edge rail. The consumer wires the actual ordering up with their\n   own dnd solution; no broken or half-done drag imitation is performed. The\n   up/down buttons are deliberately no-ops too (the order lives in the consumer's\n   state). Color comes ONLY from tokens; alpha via color-mix. Every export renders\n   with no props too. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst box: Record<StyledSize, string> = {\n  sm: \"gap-2.5 rounded-lg p-2 text-sm\",\n  md: \"gap-3 rounded-lg p-3 text-sm\",\n  lg: \"gap-3.5 rounded-xl p-4 text-base\",\n  xl: \"gap-4 rounded-xl p-5 text-base\",\n}\n\nconst base =\n  \"flex w-full items-center [&_svg]:shrink-0 [&_i]:not-italic [&_i]:leading-none\"\n\nconst titleCls = \"truncate font-medium text-foreground\"\nconst descCls = \"truncate text-muted-foreground text-[0.85em]\"\n\n/* Tutamac: 24px altinda kalan kontrol, gorunmez hit alani ile buyutulur. */\nconst handleCls =\n  \"relative inline-flex size-5 shrink-0 cursor-grab items-center justify-center rounded-md text-muted-foreground outline-none transition-colors duration-(--motion-fast) ease-(--motion-ease) after:absolute after:-inset-1.5 hover:bg-accent hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 active:cursor-grabbing [&_svg]:size-4 [&_i]:text-base\"\n\nconst stepBtn =\n  \"relative inline-flex size-5 shrink-0 items-center justify-center rounded-md text-muted-foreground outline-none transition-colors duration-(--motion-fast) ease-(--motion-ease) after:absolute after:-inset-1.5 hover:bg-accent hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring/50 [&_svg]:size-3.5 [&_i]:text-sm\"\n\ntype Props = React.ComponentProps<\"div\"> & {\n  size?: StyledSize\n  title?: React.ReactNode\n  description?: React.ReactNode\n  trailing?: React.ReactNode\n}\n\nfunction Body({\n  title,\n  description,\n}: {\n  title: React.ReactNode\n  description: React.ReactNode\n}) {\n  return (\n    <div className=\"flex min-w-0 flex-1 flex-col\">\n      <span className={titleCls}>{title}</span>\n      {description ? <span className={descCls}>{description}</span> : null}\n    </div>\n  )\n}\n\n/* Handle: bastaki dikey grip tutamaci (gorsel affordance, gercek surukleme yok). */\nexport function HandleItem({\n  className,\n  size = \"md\",\n  title = \"Overview section\",\n  description = \"Appears first on the page\",\n  trailing,\n  ...props\n}: Props) {\n  return (\n    <div\n      data-slot=\"styled-item\"\n      className={cn(base, box[size], \"border border-border bg-card text-card-foreground\", className)}\n      {...props}\n    >\n      <button type=\"button\" aria-label=\"Drag handle\" className={handleCls}>\n        <GripVertical />\n      </button>\n      <Body title={title} description={description} />\n      {trailing ?? <ChevronRight className=\"size-4 text-muted-foreground\" />}\n    </div>\n  )\n}\n\n/* Grip: the whole row reads as movable - the cursor is grab and a horizontal grip appears on hover. */\nexport function GripItem({\n  className,\n  size = \"md\",\n  title = \"Pricing table\",\n  description = \"Drag the row to reorder\",\n  trailing,\n  ...props\n}: Props) {\n  return (\n    <div\n      data-slot=\"styled-item\"\n      className={cn(\n        base,\n        box[size],\n        \"group cursor-grab border border-border bg-card text-card-foreground transition-colors duration-(--motion-fast) ease-(--motion-ease) hover:bg-accent active:cursor-grabbing\",\n        className\n      )}\n      {...props}\n    >\n      <Body title={title} description={description} />\n      <span\n        aria-hidden=\"true\"\n        className=\"shrink-0 text-muted-foreground opacity-0 transition-opacity duration-(--motion-fast) ease-(--motion-ease) group-hover:opacity-100 [&_svg]:size-4 [&_i]:text-base\"\n      >\n        {trailing ?? <GripHorizontal />}\n      </span>\n    </div>\n  )\n}\n\n/* Reorder: keyboard-accessible up/down buttons. The buttons are deliberately no-ops -\n   the consumer keeps the order in their own state. */\nexport function ReorderItem({\n  className,\n  size = \"md\",\n  title = \"Testimonials\",\n  description = \"Position 3 of 8\",\n  trailing,\n  ...props\n}: Props) {\n  return (\n    <div\n      data-slot=\"styled-item\"\n      className={cn(base, box[size], \"border border-border bg-card text-card-foreground\", className)}\n      {...props}\n    >\n      <Body title={title} description={description} />\n      {trailing ?? (\n        <span className=\"flex shrink-0 items-center gap-1\">\n          <button type=\"button\" aria-label=\"Move up\" className={stepBtn}>\n            <ArrowUp />\n          </button>\n          <button type=\"button\" aria-label=\"Move down\" className={stepBtn}>\n            <ArrowDown />\n          </button>\n        </span>\n      )}\n    </div>\n  )\n}\n\n/* Ghost: a frozen version of the \"how it looks while being moved\" state - a dashed\n   border, a slightly transparent surface, a small tilt. It is used as a\n   placeholder. */\nexport function GhostItem({\n  className,\n  size = \"md\",\n  title = \"FAQ section\",\n  description = \"Drop target preview\",\n  trailing,\n  ...props\n}: Props) {\n  return (\n    <div\n      data-slot=\"styled-item\"\n      className={cn(\n        base,\n        box[size],\n        \"rotate-[-1deg] border border-dashed border-[color-mix(in_oklab,var(--color-brand)_45%,transparent)] bg-[color-mix(in_oklab,var(--color-brand)_6%,transparent)] opacity-80 shadow-lg\",\n        className\n      )}\n      {...props}\n    >\n      <span aria-hidden=\"true\" className=\"shrink-0 text-muted-foreground [&_svg]:size-4\">\n        <GripVertical />\n      </span>\n      <Body title={title} description={description} />\n      {trailing}\n    </div>\n  )\n}\n\n/* Rail: sol kenarda dikey ray + nokta dokusu; tutamac satirin kendisidir. */\nexport function RailItem({\n  className,\n  size = \"md\",\n  title = \"Changelog\",\n  description = \"Grab the left rail\",\n  trailing,\n  ...props\n}: Props) {\n  return (\n    <div\n      data-slot=\"styled-item\"\n      className={cn(\n        base,\n        box[size],\n        \"group relative overflow-hidden border border-border bg-card pl-5 text-card-foreground\",\n        className\n      )}\n      {...props}\n    >\n      <span\n        aria-hidden=\"true\"\n        className=\"absolute inset-y-0 left-0 flex w-4 cursor-grab items-center justify-center bg-[color-mix(in_oklab,var(--color-foreground)_5%,transparent)] text-muted-foreground transition-colors duration-(--motion-fast) ease-(--motion-ease) group-hover:bg-[color-mix(in_oklab,var(--color-brand)_14%,transparent)] group-hover:text-brand [&_svg]:size-3.5\"\n      >\n        <GripVertical />\n      </span>\n      <Body title={title} description={description} />\n      {trailing ?? <ChevronRight className=\"size-4 text-muted-foreground\" />}\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/item-drag.tsx"
    }
  ],
  "categories": [
    "styled",
    "item"
  ],
  "type": "registry:component"
}