{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "quiz",
  "title": "Quiz",
  "description": "Inline concept check with immediate feedback and an xAPI answered statement.",
  "registryDependencies": [
    "https://beadkit.dev/r/learning-core.json"
  ],
  "files": [
    {
      "path": "components/learning/QuizBlock.tsx",
      "content": "\"use client\";\nimport { useState } from \"react\";\nimport { LearningCard } from \"./LearningCard\";\nimport { useTelemetry, type XApiStatement } from \"./xapi\";\n\nexport interface QuizOption {\n  id: string;\n  text: string;\n  valid: boolean;\n  feedback: string;\n}\n\nexport interface QuizBlockProps {\n  activityId: string;\n  prompt: string;\n  options: QuizOption[];\n  onTrackTelemetry?: (statement: XApiStatement) => void;\n}\n\nexport function QuizBlock({ activityId, prompt, options, onTrackTelemetry }: QuizBlockProps) {\n  const [selected, setSelected] = useState<string | null>(null);\n  const [submitted, setSubmitted] = useState(false);\n  const track = useTelemetry(activityId, prompt, onTrackTelemetry);\n\n  const chosen = options.find((o) => o.id === selected);\n\n  const handleSubmit = () => {\n    if (!chosen || submitted) return;\n    setSubmitted(true);\n    track(\"answered\", { response: chosen.id, success: chosen.valid });\n  };\n\n  return (\n    <LearningCard label=\"Concept check\" type=\"quiz\">\n      <p id={`${activityId}-prompt`} className=\"mb-3 text-sm font-semibold\">\n        {prompt}\n      </p>\n      <fieldset\n        role=\"radiogroup\"\n        aria-labelledby={`${activityId}-prompt`}\n        disabled={submitted}\n        className=\"space-y-2\"\n      >\n        {options.map((opt) => {\n          const isSelected = selected === opt.id;\n          return (\n            <label\n              key={opt.id}\n              className={`has-[:focus-visible]:ring-ring block w-full cursor-pointer rounded-lg border p-3 text-left text-xs transition-all has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-offset-1 ${\n                isSelected\n                  ? \"border-primary bg-primary/5 font-medium\"\n                  : \"hover:border-muted-foreground/40\"\n              } ${submitted ? \"cursor-default opacity-80\" : \"\"}`}\n            >\n              <input\n                type=\"radio\"\n                name={`${activityId}-choice`}\n                value={opt.id}\n                checked={isSelected}\n                onChange={() => setSelected(opt.id)}\n                className=\"sr-only\"\n              />\n              <span className=\"text-muted-foreground mr-1.5 font-mono\">{opt.id}.</span>\n              {opt.text}\n            </label>\n          );\n        })}\n      </fieldset>\n      {selected && !submitted && (\n        <button\n          onClick={handleSubmit}\n          className=\"bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:ring-ring mt-3 w-full rounded-lg py-2 text-xs font-medium transition focus-visible:ring-2 focus-visible:ring-offset-1\"\n        >\n          Submit answer\n        </button>\n      )}\n      <div aria-live=\"polite\">\n        {submitted && chosen && (\n          <div\n            className={`mt-3 rounded-lg border p-3 text-xs ${\n              chosen.valid\n                ? \"border-success/30 bg-success/10\"\n                : \"border-destructive/30 bg-destructive/10\"\n            }`}\n          >\n            <span\n              className={`mb-1 block font-bold ${\n                chosen.valid ? \"text-success\" : \"text-destructive\"\n              }`}\n            >\n              {chosen.valid ? \"Correct\" : \"Incorrect\"}\n            </span>\n            {chosen.feedback}\n          </div>\n        )}\n      </div>\n    </LearningCard>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/learning/QuizBlock.tsx"
    }
  ],
  "type": "registry:component"
}
