{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dialog",
  "type": "registry:ui",
  "title": "Dialog",
  "description": "دیالوگ",
  "registryDependencies": [
    "https://kashi.sepantapouya.com/r/cx.json",
    "https://kashi.sepantapouya.com/r/icons.json",
    "https://kashi.sepantapouya.com/r/kashi-provider.json"
  ],
  "files": [
    {
      "path": "registry/kashi/Dialog.tsx",
      "type": "registry:ui",
      "target": "components/kashi/Dialog.tsx",
      "content": "\"use client\";\n\nimport { useEffect, useId, useRef, type ReactNode } from \"react\";\nimport { cx } from \"./cx\";\nimport { CloseIcon } from \"./icons\";\nimport { useKashi } from \"./KashiProvider\";\n\nexport interface DialogProps {\n  open: boolean;\n  onOpenChange: (open: boolean) => void;\n  title: ReactNode;\n  description?: ReactNode;\n  /** آیکون شاخص بالای عنوان */\n  icon?: ReactNode;\n  /** «danger» برای تأیید عملیات مخرب */\n  tone?: \"default\" | \"danger\";\n  /** @default \"md\" */\n  size?: \"sm\" | \"md\" | \"lg\" | \"full\";\n  /** «center» پنجرهٔ وسط، «start»/«end» کشوی کناری، «bottom» برگهٔ پایین (مناسب گوشی) @default \"center\" */\n  placement?: \"center\" | \"start\" | \"end\" | \"bottom\";\n  /** دکمه‌های پایین پنجره */\n  footer?: ReactNode;\n  /** بستن با کلیک روی پس‌زمینه @default true */\n  dismissible?: boolean;\n  /** @default \"بستن\" */\n  closeLabel?: string;\n  className?: string;\n  children?: ReactNode;\n}\n\n/**\n * پنجرهٔ گفتگو روی <dialog> بومی با showModal:\n * فوکوس داخل پنجره می‌ماند، Esc می‌بندد، بقیهٔ صفحه از دسترس صفحه‌خوان خارج می‌شود\n * و پس از بستن، فوکوس به عنصری که پنجره را باز کرده برمی‌گردد.\n */\nexport function Dialog({\n  open, onOpenChange, title, description, icon, tone = \"default\", size = \"md\", footer, dismissible = true,\n  closeLabel, placement = \"center\", className, children,\n}: DialogProps) {\n  const { messages: M } = useKashi();\n  closeLabel ??= M.common.close;\n  const ref = useRef<HTMLDialogElement>(null);\n  const opener = useRef<Element | null>(null);\n  const id = useId();\n\n  useEffect(() => {\n    const d = ref.current;\n    if (!d) return;\n    if (open && !d.open) {\n      opener.current = document.activeElement;\n      d.showModal();\n    } else if (!open && d.open) {\n      d.close();\n    }\n  }, [open]);\n\n  return (\n    <dialog\n      ref={ref}\n      data-placement={placement}\n      className={cx(\"k-dialog\", size !== \"md\" && `k-dialog--${size}`, placement !== \"center\" && `k-dialog--${placement}`, tone === \"danger\" && \"k-dialog--danger\", className)}\n      aria-labelledby={`${id}-title`}\n      aria-describedby={description ? `${id}-desc` : undefined}\n      onClose={() => {\n        onOpenChange(false);\n        (opener.current as HTMLElement | null)?.focus?.();\n      }}\n      onCancel={(e) => {\n        // Esc: بستن از طریق state تا والد همگام بماند\n        e.preventDefault();\n        onOpenChange(false);\n      }}\n      onClick={(e) => {\n        // کلیک روی خود <dialog> یعنی کلیک روی پس‌زمینه\n        if (dismissible && e.target === ref.current) onOpenChange(false);\n      }}\n    >\n      <div className=\"k-dialog__header\">\n        {icon && <span className=\"k-dialog__icon\" aria-hidden=\"true\">{icon}</span>}\n        <div className=\"k-dialog__heading\">\n          <h2 className=\"k-dialog__title\" id={`${id}-title`}>{title}</h2>\n          {description && <p className=\"k-dialog__description\" id={`${id}-desc`}>{description}</p>}\n        </div>\n        <button type=\"button\" className=\"k-btn k-btn--tertiary k-btn--icon k-btn--sm k-dialog__close\" aria-label={closeLabel} onClick={() => onOpenChange(false)}>\n          <CloseIcon />\n        </button>\n      </div>\n      {children && <div className=\"k-dialog__body\">{children}</div>}\n      {footer && <div className=\"k-dialog__footer\">{footer}</div>}\n    </dialog>\n  );\n}\n"
    }
  ]
}