{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "card-task-tailwind",
  "type": "registry:item",
  "title": "Card Task (Tailwind)",
  "description": "A task card component with badges, avatars, and action menu.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "https://roiui.com/r/alert-dialog-tailwind.json",
    "https://roiui.com/r/avatar-tailwind.json",
    "https://roiui.com/r/badge-tailwind.json",
    "https://roiui.com/r/button-tailwind.json",
    "https://roiui.com/r/card-tailwind.json",
    "https://roiui.com/r/combobox-tailwind.json",
    "https://roiui.com/r/dialog-tailwind.json",
    "https://roiui.com/r/dropdown-menu-tailwind.json",
    "https://roiui.com/r/tooltip-tailwind.json"
  ],
  "files": [
    {
      "path": "registry/brook/tailwind/blocks/card-task/components/card-task.tsx",
      "content": "import { Calendar, ListTodo, MessageCircleMore, MoreHorizontal, Trash, UserPlus, Users } from \"lucide-react\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/registry/brook/tailwind/ui/avatar\";\nimport { Badge } from \"@/registry/brook/tailwind/ui/badge\";\nimport { Button } from \"@/registry/brook/tailwind/ui/button\";\nimport {\n  Card,\n  CardAction,\n  CardContent,\n  CardDescription,\n  CardFooter,\n  CardHeader,\n  CardTitle,\n} from \"@/registry/brook/tailwind/ui/card\";\nimport {\n  DropdownMenu,\n  DropdownMenuItem,\n  DropdownMenuPopup,\n  DropdownMenuPortal,\n  DropdownMenuPositioner,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from \"@/registry/brook/tailwind/ui/dropdown-menu\";\nimport {\n  Tooltip,\n  TooltipArrow,\n  TooltipPopup,\n  TooltipPortal,\n  TooltipPositioner,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/registry/brook/tailwind/ui/tooltip\";\n\nexport type User = {\n  value: string;\n  label: string;\n  email: string;\n  avatar: string;\n};\n\ntype TaskCardProps = {\n  title: string;\n  description: string;\n  tags: Array<{\n    label: string;\n    variant?: \"default\" | \"destructive\";\n  }>;\n  collaborators: User[];\n  stats: {\n    comments: number;\n    subtasks: string;\n  };\n  dueDate: {\n    label: string;\n    variant?: \"default\" | \"warning\";\n  };\n  onAddCollaborator?: () => void;\n  onDeleteTask?: () => void;\n};\n\nfunction AvatarGroup({ users, maxDisplay = 3 }: { users: User[]; maxDisplay?: number }) {\n  const displayUsers = users.slice(0, maxDisplay);\n  const remainingCount = users.length - maxDisplay;\n\n  return (\n    <TooltipProvider>\n      <div className=\"flex items-center\">\n        {displayUsers.map((user, index) => (\n          <Tooltip key={user.value}>\n            <TooltipTrigger\n              render={\n                <div className={index > 0 ? \"-ml-1.5\" : \"\"}>\n                  <Avatar className=\"h-6 w-6 border-2 border-[var(--card)]\">\n                    <AvatarImage alt={`profile image for ${user.label}`} src={user.avatar} />\n                    <AvatarFallback>\n                      {user.label\n                        ?.split(\" \")\n                        .map((n: string) => n[0])\n                        .join(\"\") || \"??\"}\n                    </AvatarFallback>\n                  </Avatar>\n                </div>\n              }\n            />\n            <TooltipPortal>\n              <TooltipPositioner>\n                <TooltipPopup>\n                  <TooltipArrow />\n                  {user.label}\n                </TooltipPopup>\n              </TooltipPositioner>\n            </TooltipPortal>\n          </Tooltip>\n        ))}\n        {remainingCount > 0 && (\n          <div className=\"-ml-1.5 flex h-6 w-6 items-center justify-center rounded-full border-2 border-[var(--card)] bg-[var(--muted)] font-semibold text-[0.625rem] text-[var(--muted-foreground)]\">\n            +{remainingCount}\n          </div>\n        )}\n      </div>\n    </TooltipProvider>\n  );\n}\n\nfunction TaskCardDropdownMenu({\n  onAddCollaborator,\n  onDeleteTask,\n}: {\n  onAddCollaborator?: () => void;\n  onDeleteTask?: () => void;\n}) {\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger\n        render={(props) => (\n          <Button {...props} aria-label=\"Task options\" size=\"icon\" variant=\"ghost\">\n            <MoreHorizontal\n              aria-hidden=\"true\"\n              className=\"text-[oklch(from_var(--muted-foreground)_l_c_h_/_0.8)]\"\n              size=\"16\"\n            />\n          </Button>\n        )}\n      />\n      <DropdownMenuPortal>\n        <DropdownMenuPositioner sideOffset={8}>\n          <DropdownMenuPopup className=\"min-w-[160px]\" render={<ul />}>\n            <div className=\"h-1 w-full\" />\n            <DropdownMenuItem icon={<UserPlus size=\"14\" />} onClick={onAddCollaborator} render={<li />}>\n              Add collaborator\n            </DropdownMenuItem>\n            <DropdownMenuItem icon={<Calendar size=\"14\" />} render={<li />}>\n              Change due date\n            </DropdownMenuItem>\n            <DropdownMenuSeparator />\n            <DropdownMenuItem icon={<Trash size=\"14\" />} onClick={onDeleteTask} render={<li />} variant=\"destructive\">\n              Delete task\n            </DropdownMenuItem>\n            <div className=\"h-1 w-full\" />\n          </DropdownMenuPopup>\n        </DropdownMenuPositioner>\n      </DropdownMenuPortal>\n    </DropdownMenu>\n  );\n}\n\nexport function CardTask({\n  title,\n  description,\n  tags,\n  collaborators,\n  stats,\n  dueDate,\n  onAddCollaborator,\n  onDeleteTask,\n}: TaskCardProps) {\n  return (\n    <Card className=\"!gap-4 !p-4 w-full max-w-[300px] xl:min-h-auto\">\n      <CardHeader>\n        <CardTitle className=\"!text-base\">{title}</CardTitle>\n        <CardDescription>{description}</CardDescription>\n        <CardAction>\n          <TaskCardDropdownMenu onAddCollaborator={onAddCollaborator} onDeleteTask={onDeleteTask} />\n        </CardAction>\n      </CardHeader>\n      <CardContent>\n        <div className=\"flex w-full items-center justify-between\">\n          <div className=\"flex items-center gap-2\">\n            {tags.map((tag) => (\n              <Badge key={tag.label} size=\"sm\" variant={tag.variant}>\n                <span>{tag.label}</span>\n              </Badge>\n            ))}\n          </div>\n          <AvatarGroup users={collaborators} />\n        </div>\n      </CardContent>\n\n      <CardFooter className=\"mt-0 mb-0 flex flex-col gap-[0.65rem]\">\n        <div className=\"-mx-4 w-[calc(100%+32px)] py-[5px]\">\n          <div className=\"h-px w-full border-[oklch(from_var(--border)_l_c_h_/_0.6)] border-b-[0.5px]\" />\n        </div>\n        <div className=\"flex w-full justify-between text-[oklch(from_var(--muted-foreground)_l_c_h_/_0.6)] text-xs\">\n          <div className=\"flex items-center gap-3\">\n            <div\n              aria-label={`${collaborators.length} collaborators`}\n              className=\"flex h-[27px] items-center justify-center gap-1 rounded-xl border-[0.5px] border-[oklch(from_var(--border)_l_c_h_/_0.2)] bg-[var(--mix-card-33-bg)] px-2 py-1 transition-all duration-150 hover:border-[var(--border)] hover:bg-[var(--mix-card-50-bg)]\"\n              role=\"group\"\n            >\n              <Users aria-hidden=\"true\" size=\"14\" />\n              <span>{collaborators.length}</span>\n            </div>\n            <div\n              aria-label={`${stats.comments} comments`}\n              className=\"flex h-[27px] items-center justify-center gap-1 rounded-xl border-[0.5px] border-[oklch(from_var(--border)_l_c_h_/_0.2)] bg-[var(--mix-card-33-bg)] px-2 py-1 transition-all duration-150 hover:border-[var(--border)] hover:bg-[var(--mix-card-50-bg)]\"\n              role=\"group\"\n            >\n              <MessageCircleMore aria-hidden=\"true\" size=\"14\" />\n              <span>{stats.comments}</span>\n            </div>\n            <div\n              aria-label={`${stats.subtasks} subtasks`}\n              className=\"flex h-[27px] items-center justify-center gap-1 rounded-xl border-[0.5px] border-[oklch(from_var(--border)_l_c_h_/_0.2)] bg-[var(--mix-card-33-bg)] px-2 py-1 transition-all duration-150 hover:border-[var(--border)] hover:bg-[var(--mix-card-50-bg)]\"\n              role=\"group\"\n            >\n              <ListTodo aria-hidden=\"true\" size=\"14\" />\n              <span>{stats.subtasks}</span>\n            </div>\n          </div>\n          <div\n            aria-label={`Due ${dueDate.label}`}\n            className=\"flex h-[27px] items-center justify-center gap-1 rounded-xl border-[0.5px] border-[oklch(from_var(--border)_l_c_h_/_0.2)] bg-[var(--mix-card-33-bg)] px-2 py-1 transition-all duration-150 hover:border-[var(--border)] hover:bg-[var(--mix-card-50-bg)]\"\n            role=\"group\"\n          >\n            <Calendar aria-hidden=\"true\" size=\"14\" />\n            <span className={dueDate.variant === \"warning\" ? \"text-[var(--warning-foreground)]\" : undefined}>\n              {dueDate.label}\n            </span>\n          </div>\n        </div>\n      </CardFooter>\n    </Card>\n  );\n}\n",
      "type": "registry:file",
      "target": "~/components/blocks/card-task/card-task.tsx"
    }
  ]
}