lmscn

Reading Passage

A three-phase reading comprehension component — read, answer, review.

Installation

npx shadcn@latest add https://lmscn.vercel.app/r/reading-passage.json

Required primitives: button, card, badge, progress, scroll-area, separator

npx shadcn@latest add button card badge progress scroll-area separator

Usage

import { ReadingPassage } from "@/components/lms/reading-passage"
import type { ReadingPassageData, ReadingResult } from "@/components/lms/reading-passage"

export function MyReading() {
  return (
    <ReadingPassage
      readingPassageData={{
        title: "The Water Cycle",
        introduction: "Learn how water moves through Earth's systems.",
        readingTimeMinutes: 3,
        hidePassageOnQuestions: false,
        content: `Solar energy drives evaporation, turning liquid water into vapour.
This rises, cools and condenses into clouds, falling as precipitation.`,
        questions: [
          {
            id: "q1",
            type: "single",
            question: "What drives the water cycle?",
            options: [
              { id: "a", label: "The Moon" },
              { id: "b", label: "Solar energy" },
            ],
            correctIds: ["b"],
            explanation: "The sun provides energy to evaporate water.",
          },
        ],
      }}
      onComplete={(result: ReadingResult) => {
        console.log(`${result.score} / ${result.maxScore}`)
      }}
    />
  )
}

Props

ReadingPassageProps

PropTypeRequiredDescription
readingPassageDataReadingPassageDataPassage and questions configuration
onComplete(result: ReadingResult) => voidCalled after the last question is answered
classNamestringAdditional CSS classes

Data shape

ReadingPassageData

FieldTypeDefaultDescription
titlestringPassage title
introductionstringSubtitle / introductory note shown below the title
contentstringThe reading text
contentIsHtmlbooleanfalseRender content as HTML via dangerouslySetInnerHTML
questionsReadingQuestion[]Comprehension questions
readingTimeMinutesnumberEstimated read time shown as a badge
hidePassageOnQuestionsbooleanfalseHide the passage while the learner is answering questions

ReadingQuestion

FieldTypeDescription
idstringUnique identifier
type"single" | "multiple" | "true-false"Selection mode
questionstringThe question text
options{ id: string; label: string }[]Answer options
correctIdsstring[]IDs of the correct option(s)
explanationstringShown in a muted panel after the learner submits

Result

onComplete receives a ReadingResult object:

FieldTypeDescription
answersReadingAnswer[]Per-question answer records
scorenumberNumber of correct answers
maxScorenumberTotal number of questions
percentagenumberRounded score percentage
interface ReadingAnswer {
  questionId: string
  selected: string[]
  correct: boolean
}

Phases

The component moves through three sequential phases:

Reading — the passage is displayed in a scrollable card. An estimated read time badge is shown if readingTimeMinutes is provided. The learner clicks Start Questions to proceed.

Questions — questions are shown one at a time. When hidePassageOnQuestions is false (default), the passage remains visible in a collapsed scroll area above each question card.

Results — shows the overall score and a per-question ✓ / ✗ summary.

HTML content

Set contentIsHtml: true to render rich content with headings, lists, and inline formatting. The content is injected with dangerouslySetInnerHTML inside a prose prose-sm dark:prose-invert wrapper, so standard Tailwind Typography styles apply.

content: `<h2>The Carbon Cycle</h2>
<p>Carbon moves between the atmosphere, oceans, and living organisms...</p>
<ul>
  <li>Photosynthesis fixes atmospheric CO₂ into organic matter.</li>
  <li>Respiration and decomposition return carbon to the atmosphere.</li>
</ul>`,
contentIsHtml: true,

On this page