{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "filter-bar",
  "title": "Filter Bar",
  "description": "Composable filters, removable chips, result counts, and reset actions.",
  "dependencies": [
    "class-variance-authority",
    "lucide-react"
  ],
  "registryDependencies": [
    "badge",
    "button",
    "https://uaiblocks.dev/r/uai-theme.json",
    "https://uaiblocks.dev/r/uai-utils.json"
  ],
  "files": [
    {
      "path": "src/registry/uai/components/filter-bar.tsx",
      "content": "\"use client\";\n\nimport { cva } from \"class-variance-authority\";\nimport { X } from \"lucide-react\";\nimport { type ComponentProps, createContext, useContext } from \"react\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/uai-utils\";\n\nexport const FILTER_BAR_VARIANTS = [\"toolbar\", \"panel\", \"compact\"] as const;\nexport type FilterBarVariant = (typeof FILTER_BAR_VARIANTS)[number];\nexport type FilterBarProps = ComponentProps<\"div\"> & {\n  variant?: FilterBarVariant;\n  activeCount?: number;\n  onReset?: () => void;\n  disabled?: boolean;\n};\ntype FilterContext = {\n  variant: FilterBarVariant;\n  activeCount: number;\n  onReset?: () => void;\n  disabled: boolean;\n};\nconst Context = createContext<FilterContext | null>(null);\nfunction useFilter() {\n  const context = useContext(Context);\n  if (!context) throw new Error(\"FilterBar children must be used within FilterBar\");\n  return context;\n}\n\nconst filterBarVariants = cva(\"flex min-w-0 flex-wrap border text-foreground\", {\n  variants: {\n    variant: {\n      toolbar:\n        \"flex-row items-center gap-3 rounded-[14px] border-transparent bg-card px-3 py-2.5 text-[13px]/[18px]\",\n      panel: \"flex-col items-stretch gap-3.5 rounded-[14px] bg-card p-4 text-[13px]/[18px]\",\n      compact:\n        \"flex-row items-center gap-2 rounded-xl bg-transparent px-2 py-1.5 text-[12.5px]/[18px]\",\n    },\n  },\n});\n\n// Ghost Button overrides: the neutral hover and pointer-event resets keep hover feedback on\n// enabled controls only and preserve the not-allowed cursor when disabled.\nconst actionButton =\n  \"cursor-pointer border-0 bg-transparent transition-[background-color,color,scale] duration-[120ms,120ms,140ms] ease-[ease-out,ease-out,cubic-bezier(0.23,1,0.32,1)] hover:bg-transparent focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:outline-solid enabled:active:scale-[0.97] disabled:pointer-events-auto disabled:cursor-not-allowed disabled:opacity-45 motion-reduce:transition-none motion-reduce:enabled:active:scale-100 dark:hover:bg-transparent\";\n\nexport function FilterBar({\n  variant = \"toolbar\",\n  activeCount = 0,\n  onReset,\n  disabled = false,\n  className,\n  children,\n  ...props\n}: FilterBarProps) {\n  return (\n    <Context.Provider value={{ variant, activeCount, onReset, disabled }}>\n      <div\n        data-slot=\"filter-bar\"\n        data-variant={variant}\n        className={cn(filterBarVariants({ variant }), className)}\n        {...props}\n      >\n        {children}\n      </div>\n    </Context.Provider>\n  );\n}\nexport function FilterBarControls({ className, ...props }: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"filter-bar-controls\"\n      className={cn(\"flex flex-wrap items-center gap-2\", className)}\n      {...props}\n    />\n  );\n}\nexport function FilterBarChips({ className, ...props }: ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"filter-bar-chips\"\n      className={cn(\"flex flex-wrap items-center gap-1.5\", className)}\n      {...props}\n    />\n  );\n}\nexport function FilterBarChip({\n  children,\n  onRemove,\n  disabled,\n  className,\n  ...props\n}: ComponentProps<\"span\"> & { onRemove: () => void; disabled?: boolean }) {\n  const context = useFilter();\n  return (\n    <Badge\n      variant=\"secondary\"\n      data-slot=\"filter-bar-chip\"\n      className={cn(\n        \"box-border inline-flex min-h-6.5 w-auto max-w-full shrink justify-start items-center gap-0.5 overflow-visible rounded-full border-0 bg-muted py-0 pr-0.75 pl-2.5 text-[12px] font-medium whitespace-normal text-foreground\",\n        \"animate-in fade-in-0 zoom-in-96 duration-180 ease-[cubic-bezier(0.16,1,0.3,1)] motion-reduce:animate-none\",\n        className,\n      )}\n      {...props}\n    >\n      <span className=\"wrap-anywhere\">{children}</span>\n      <Button\n        type=\"button\"\n        variant=\"ghost\"\n        size=\"icon\"\n        disabled={context.disabled || disabled}\n        onClick={onRemove}\n        className={cn(\n          actionButton,\n          \"grid size-5 shrink-0 place-items-center rounded-full p-0 text-subtle-foreground hover:text-subtle-foreground enabled:hover:bg-foreground/10 enabled:hover:text-foreground [&_svg:not([class*='size-'])]:size-3\",\n        )}\n      >\n        <X size={12} className=\"size-3\" strokeWidth={2} aria-hidden=\"true\" />\n        <span className=\"sr-only\">Remove {children} filter</span>\n      </Button>\n    </Badge>\n  );\n}\nexport function FilterBarCount({ children, className, ...props }: ComponentProps<\"span\">) {\n  return (\n    <span\n      role=\"status\"\n      data-slot=\"filter-bar-count\"\n      className={cn(\"text-[12px] text-subtle-foreground tabular-nums\", className)}\n      {...props}\n    >\n      {children}\n    </span>\n  );\n}\nexport function FilterBarReset({\n  children = \"Reset filters\",\n  onClick,\n  className,\n  ...props\n}: ComponentProps<\"button\">) {\n  const context = useFilter();\n  return (\n    <Button\n      data-slot=\"filter-bar-reset\"\n      variant=\"ghost\"\n      className={cn(\n        actionButton,\n        \"h-7 rounded-full px-3 py-0 text-[12.5px] font-medium text-muted-foreground hover:text-muted-foreground enabled:hover:bg-accent enabled:hover:text-foreground has-[>svg]:px-3\",\n        context.variant === \"panel\" ? \"ml-0 self-start\" : \"ml-auto\",\n        className,\n      )}\n      {...props}\n      type=\"button\"\n      disabled={context.disabled || !context.activeCount || props.disabled}\n      onClick={(event) => {\n        onClick?.(event);\n        if (!event.defaultPrevented) context.onReset?.();\n      }}\n    >\n      {children}\n    </Button>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/uai/filter-bar.tsx"
    }
  ],
  "categories": [
    "forms"
  ],
  "type": "registry:ui"
}