{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "button",
  "type": "registry:ui",
  "title": "Button",
  "description": "دکمه",
  "registryDependencies": [
    "https://kashi.sepantapouya.com/r/cx.json",
    "https://kashi.sepantapouya.com/r/kashi-provider.json",
    "https://kashi.sepantapouya.com/r/utils.json"
  ],
  "files": [
    {
      "path": "registry/kashi/Button.tsx",
      "type": "registry:ui",
      "target": "components/kashi/Button.tsx",
      "content": "\"use client\";\n\nimport { forwardRef, type ButtonHTMLAttributes, type ElementType, type MouseEvent, type ReactNode } from \"react\";\nimport { cx } from \"./cx\";\nimport { isDev } from \"./utils\";\nimport { useKashi } from \"./KashiProvider\";\n\nexport type ButtonVariant = \"primary\" | \"secondary\" | \"tertiary\" | \"link\" | \"danger\" | \"danger-secondary\";\nexport type ButtonSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"type\"> {\n  /** @default \"secondary\" */\n  variant?: ButtonVariant;\n  /** @default \"md\" */\n  size?: ButtonSize;\n  /** «pill» کاملاً گرد، «square» گوشهٔ کم @default \"default\" */\n  shape?: \"default\" | \"pill\" | \"square\";\n  /** نمایش اسپینر؛ دکمه فوکوس‌پذیر می‌ماند ولی کلیک نمی‌گیرد */\n  loading?: boolean;\n  /** متنی که صفحه‌خوان هنگام بارگذاری می‌خواند @default \"در حال بارگذاری\" */\n  loadingLabel?: string;\n  /** دکمهٔ تمام‌عرض */\n  block?: boolean;\n  /** دکمهٔ مربعی فقط‌آیکون — حتماً aria-label بدهید */\n  iconOnly?: boolean;\n  /** آیکون ابتدای متن (در RTL سمت راست) */\n  iconStart?: ReactNode;\n  /** آیکون انتهای متن (در RTL سمت چپ) */\n  iconEnd?: ReactNode;\n  /** با href به‌صورت لینک (<a>) رندر می‌شود */\n  href?: string;\n  target?: string;\n  rel?: string;\n  /** عنصر یا کامپوننت دلخواه، مثل Link در Next.js: as={Link} */\n  as?: ElementType;\n  type?: \"button\" | \"submit\" | \"reset\";\n  /** بقیهٔ props برای کامپوننت as، مثل prefetch */\n  [key: `data-${string}`]: unknown;\n}\n\nexport const Button = forwardRef<HTMLElement, ButtonProps>(function Button(\n  {\n    variant = \"secondary\", size = \"md\", shape = \"default\", loading = false, loadingLabel,\n    block = false, iconOnly = false, iconStart, iconEnd, disabled, type = \"button\", href, as, className, children, onClick, ...rest\n  },\n  ref,\n) {\n  const { messages: M } = useKashi();\n  loadingLabel ??= M.common.loading;\n  if (isDev() && iconOnly && !rest[\"aria-label\"] && !rest[\"aria-labelledby\"]) {\n    console.warn(\"[kashi] <Button iconOnly> بدون aria-label برای صفحه‌خوان‌ها بی‌نام است.\");\n  }\n\n  const Tag: ElementType = as ?? (href ? \"a\" : \"button\");\n  const isNativeButton = Tag === \"button\";\n  const inactive = loading || (!isNativeButton && disabled);\n\n  const handleClick = (e: MouseEvent<HTMLButtonElement>) => {\n    if (inactive) {\n      e.preventDefault();\n      return;\n    }\n    onClick?.(e);\n  };\n\n  return (\n    <Tag\n      ref={ref}\n      {...(isNativeButton ? { type, disabled } : { href: inactive ? undefined : href, role: href ? undefined : \"button\" })}\n      // در حالت loading از disabled بومی استفاده نمی‌کنیم تا فوکوس کیبورد از دست نرود\n      aria-disabled={inactive || undefined}\n      aria-busy={loading || undefined}\n      onClick={handleClick}\n      data-variant={variant}\n      data-size={size}\n      className={cx(\n        \"k-btn\",\n        `k-btn--${variant}`,\n        size !== \"md\" && `k-btn--${size}`,\n        shape !== \"default\" && `k-btn--${shape}`,\n        block && \"k-btn--block\",\n        iconOnly && \"k-btn--icon\",\n        className,\n      )}\n      {...rest}\n    >\n      {iconStart}\n      {children}\n      {iconEnd}\n      {loading && <span className=\"k-sr-only\" role=\"status\">{loadingLabel}</span>}\n    </Tag>\n  );\n});\n"
    }
  ]
}