{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "action-bar",
  "title": "Action bar",
  "description": "A slide-up action bar for bulk operations on selected items.",
  "dependencies": [
    "@mdi/js"
  ],
  "registryDependencies": [
    "https://blok.sitecore.com/r/theme.json",
    "https://blok.sitecore.com/r/button.json",
    "https://blok.sitecore.com/r/tooltip.json",
    "https://blok.sitecore.com/r/checkbox.json",
    "https://blok.sitecore.com/r/dropdown-menu.json",
    "https://blok.sitecore.com/r/label.json"
  ],
  "files": [
    {
      "path": "src/components/ui/action-bar.tsx",
      "content": "\"use client\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { Icon } from \"@/lib/icon\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  mdiArchiveOutline,\n  mdiClose,\n  mdiCloudOffOutline,\n  mdiCloudUploadOutline,\n  mdiContentCopy,\n  mdiDotsHorizontal,\n  mdiTrashCanOutline,\n} from \"@mdi/js\";\nimport type { ComponentProps } from \"react\";\n\nexport interface ActionBarButton {\n  label: string;\n  icon?: string;\n  onClick?: () => void;\n  variant?: \"default\" | \"outline\" | \"ghost\";\n  colorScheme?: \"primary\" | \"neutral\" | \"success\" | \"danger\";\n  ariaLabel?: string;\n}\n\nexport interface ActionBarMenuItem {\n  label: string;\n  icon?: string;\n  onClick?: () => void;\n  variant?: \"default\" | \"destructive\";\n}\n\nexport interface ActionBarProps {\n  isOpen?: boolean;\n  onOpenChange?: (open: boolean) => void;\n  selectedCount?: number;\n  onCancel?: () => void;\n\n  onPublish?: () => void;\n  onUnpublish?: () => void;\n  onDuplicate?: () => void;\n  onArchive?: () => void;\n  onDelete?: () => void;\n\n  buttons?: ActionBarButton[];\n  menuItems?: ActionBarMenuItem[];\n  className?: string;\n  align?: \"left\" | \"center\" | \"right\";\n}\n\nexport function ActionBar({\n  isOpen = false,\n  onOpenChange,\n  selectedCount = 0,\n  onCancel,\n\n  onPublish,\n  onUnpublish,\n  onDuplicate,\n  onArchive,\n  onDelete,\n\n  buttons,\n  menuItems,\n  className,\n  align = \"center\",\n  ...props\n}: ActionBarProps & ComponentProps<\"div\">) {\n  const handleCancel = () => {\n    onOpenChange?.(false);\n    onCancel?.();\n  };\n\n  const alignClasses = {\n    left: \"ml-4\",\n    center: \"mx-auto\",\n    right: \"mr-4 ml-auto\",\n  };\n\n  // Default buttons if not provided via array\n  const defaultButtons: ActionBarButton[] = buttons || [\n    {\n      label: \"Publish\",\n      icon: mdiCloudUploadOutline,\n      onClick: onPublish,\n      variant: \"outline\",\n      colorScheme: \"neutral\",\n    },\n    {\n      label: \"Unpublish\",\n      icon: mdiCloudOffOutline,\n      onClick: onUnpublish,\n      variant: \"outline\",\n      colorScheme: \"neutral\",\n    },\n    {\n      label: \"Duplicate\",\n      icon: mdiContentCopy,\n      onClick: onDuplicate,\n      variant: \"default\",\n      colorScheme: \"primary\",\n    },\n  ];\n\n  // Default menu items if not provided via array\n  const defaultMenuItems: ActionBarMenuItem[] = menuItems || [\n    {\n      label: \"Archive\",\n      icon: mdiArchiveOutline,\n      onClick: onArchive,\n      variant: \"default\",\n    },\n    {\n      label: \"Delete\",\n      icon: mdiTrashCanOutline,\n      onClick: onDelete,\n      variant: \"destructive\",\n    },\n  ];\n\n  return (\n    <div\n      className={cn(\n        \"fixed bottom-0 left-0 right-0 z-50 px-4 pb-4 transition-transform duration-300 ease-in-out\",\n        isOpen ? \"translate-y-0\" : \"translate-y-full\",\n        className,\n      )}\n      {...props}\n    >\n      <div\n        className={cn(\n          \"flex items-center justify-between gap-4 border-t border-border bg-background rounded-lg shadow-lg px-4 py-3 max-w-2xl w-full\",\n          alignClasses[align],\n        )}\n      >\n        <div className=\"flex items-center gap-4\">\n          <Tooltip>\n            <TooltipTrigger asChild>\n              <Button\n                variant=\"ghost\"\n                size=\"icon\"\n                onClick={handleCancel}\n                aria-label=\"Cancel\"\n                className=\"hover:bg-neutral-bg\"\n              >\n                <Icon path={mdiClose} size={1} />\n              </Button>\n            </TooltipTrigger>\n            <TooltipContent>Cancel</TooltipContent>\n          </Tooltip>\n\n          <span className=\"font-semibold text-neutral-fg\">\n            {selectedCount} selected\n          </span>\n        </div>\n\n        <div className=\"flex items-center gap-2 ml-auto\">\n          {/* Desktop buttons */}\n          <div className=\"hidden sm:flex items-center gap-2\">\n            {defaultButtons.map((button, index) => (\n              <Button\n                key={index}\n                variant={button.variant || \"outline\"}\n                colorScheme={button.colorScheme || \"neutral\"}\n                onClick={button.onClick}\n              >\n                {button.icon && <Icon path={button.icon} size={1} />}\n                {button.label}\n              </Button>\n            ))}\n          </div>\n\n          {/* Mobile icon buttons */}\n          <div className=\"flex sm:hidden items-center gap-2\">\n            {defaultButtons.map((button, index) => (\n              <Tooltip key={index}>\n                <TooltipTrigger asChild>\n                  <Button\n                    variant=\"ghost\"\n                    size=\"icon\"\n                    onClick={button.onClick}\n                    className=\"text-foreground hover:bg-neutral-bg\"\n                    aria-label={button.ariaLabel || button.label}\n                  >\n                    {button.icon && <Icon path={button.icon} size={1} />}\n                  </Button>\n                </TooltipTrigger>\n                <TooltipContent>{button.label}</TooltipContent>\n              </Tooltip>\n            ))}\n          </div>\n\n          {/* More menu */}\n          {defaultMenuItems.length > 0 && (\n            <DropdownMenu>\n              <Tooltip>\n                <TooltipTrigger asChild>\n                  <DropdownMenuTrigger asChild>\n                    <Button\n                      variant=\"ghost\"\n                      size=\"icon\"\n                      className=\"hover:bg-neutral-bg\"\n                      aria-label=\"More\"\n                    >\n                      <Icon path={mdiDotsHorizontal} size={1} />\n                    </Button>\n                  </DropdownMenuTrigger>\n                </TooltipTrigger>\n                <TooltipContent>More</TooltipContent>\n              </Tooltip>\n              <DropdownMenuContent align=\"start\">\n                <DropdownMenuGroup className=\"*:data-[slot=dropdown-menu-item]:[&>svg]:text-muted-foreground\">\n                  {defaultMenuItems.map((item, index) => (\n                    <DropdownMenuItem\n                      key={index}\n                      variant={item.variant || \"default\"}\n                      onClick={item.onClick}\n                    >\n                      {item.icon && <Icon path={item.icon} size={1.5} />}\n                      {item.label}\n                    </DropdownMenuItem>\n                  ))}\n                </DropdownMenuGroup>\n              </DropdownMenuContent>\n            </DropdownMenu>\n          )}\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:ui"
    },
    {
      "path": "src/lib/icon.tsx",
      "content": "import type { SVGProps } from \"react\";\n\ntype IconProps = SVGProps<SVGSVGElement> & {\n  path: string;\n  title?: string;\n  size?: number | string;\n  className?: string;\n  fill?: string;\n};\n\nexport function Icon({\n  path,\n  title,\n  size = 1,\n  className,\n  fill = \"currentColor\",\n  ...rest\n}: IconProps) {\n  return (\n    <svg\n      transform={`scale(${size})`}\n      viewBox=\"0 0 24 24\"\n      aria-label={title}\n      className={className}\n      {...rest}\n    >\n      {title ? <title>{title}</title> : null}\n      <path d={path} fill={fill} />\n    </svg>\n  );\n}\n",
      "type": "registry:lib"
    }
  ],
  "type": "registry:ui"
}