QuestionCard
question-cardDisplays textbook questions with type, stem, options, subquestions, media, source, and review status.
Usage
Multiple choice questions
Fractions in the stem and the options are typeset by Formula (KaTeX); source and knowledge points sit in the footer.
<QuestionCard
number="3"
type="single"
difficulty="A group"
stem="As shown in the picture, figures ① and 2 are made up of exactly the same small squares. If the side length of figure ① is 4, then the area of figure ② is expressed as a fraction ( )."
options={[
{ key: "A", text: "\\frac{1}{9}" },
{ key: "B", text: "\\frac{5}{9}" },
{ key: "C", text: "\\frac{16}{9}" },
{ key: "D", text: "\\frac{80}{9}" },
]}
chapter="Chapter 1 Rational Numbers · 1.1.1 Natural Numbers, Fractions and Decimals"
topics={["rational numbers", "fraction"]}
source="Academic Ability Assessment Part 7 · Page 3 · Question 3"
/>Fill in the blanks + quiz
Fill-in-the-blank slots are write-in spaces; questions are listed one by one.
<QuestionCard
number="11"
type="blank"
stem="The profit requirement is positive. A company lost 30,000 yuan last year, which can be recorded as ____ million yuan."
parts={["(1) The number b represented by point B on the number axis is ____.", "(2) The number represented by point P is ____."]}
/>Pending review
The items that cannot be determined automatically will have a warning bar on the left and will never be mixed into the normal questions.
<QuestionCard
number="7"
type="single"
stem="Among the following formulas, the correct one is ( )."
issues={[{ label: "Less than 4 options" }, { label: "Question numbers are not consecutive" }]}
When
actions={<Button size="sm" variant="ghost">Go to proofreading</Button>}
/>When to use
Use QuestionCard anywhere one complete exercise must be reviewed: question banks, paper previews, error books, or grading history. It keeps nine kinds of context together and renders mathematical notation correctly.
Use Choicebox for selectable card options, or Formula for standalone mathematical copy.
Import
import { QuestionCard } from "@hulianui/ui/math"The subpath changed in 0.25.0 (it used to be @hulianui/ui). This component's stem and options are Formula internally, which brings KaTeX with it; keeping it in the main barrel would charge every @hulianui/ui consumer 86KB gzip even when they never typeset any mathematics. Styling needs no action: Formula imports KaTeX's CSS itself.
Props
| Name | Type | Default | Description |
|---|---|---|---|
stem | string | - | Prompt using LaTeX notation and ____ answer blanks, typeset by Formula. |
number | ReactNode | - | Original book question number. |
type | "single" | "multiple" | "judge" | "blank" | "short_answer" | "calculation" | "essay" | - | Question type (closed enum). Drives the tag copy and tone; copy comes from the question.types locale table. |
kind | "choice" | "fill" | "solution" | "judge" | - | Deprecated, use type. Maps choice→single, fill→blank, solution→essay; removed in the next minor. |
typeLabel | ReactNode | - | Overrides the type tag copy. |
kindLabel | ReactNode | - | Deprecated, use typeLabel. |
difficulty | ReactNode | - | Level label, such as Group A, Foundation, or Advanced. |
options | { key, text }[] | - | Choices whose text supports LaTeX notation. The legacy { label, text } shape is still accepted for one minor. |
parts | string[] | - | Subquestions such as (1), (2), and (3). |
figure | { src, alt? } | - | Supporting image. |
resolveFigure | (key: string) => string | - | Resolver for  references in the stem: when provided, figures are split out first and rendered after the text in order; otherwise the stem is passed to Formula unchanged |
figureAlt | (index: number) => string | - | Alt text for figures split out of the stem, e.g. (1) → "Figure 1". The card has no hooks and cannot read the Locale, so the default is Chinese; the QuestionEditor preview passes its own locale's figureAlt, and standalone English usage should pass one. |
answer | QuestionAnswerValue | - | Answer key; see QuestionAnswerValue in @hulianui/ui/math. Rendered only when showAnswer is true. |
analysis | string | - | Explanation, accepts LaTeX. Rendered only when showAnswer is true. |
showAnswer | boolean | false | Renders the answer and explanation block. Keep it off before a student has answered. |
chapter / source | ReactNode | - | Chapter and provenance shown in the footer. |
topics | string[] | - | Topic names rendered as chips. |
issues | { label, tone? }[] | - | Quality flags; non-empty values activate the warning edge. |
actions | ReactNode | - | Upper-right actions. |
compact | boolean | false | Hides subparts and footer for long lists. |
Type tag copy comes from the question.types locale table (Chinese by default; enUS ships English). The figure alt falls back to the locale's question figure label.
Pitfalls
stemandoptions[].textmust remain LaTeX notation. Use"\\frac{3}{8}", not plain"3/8", for a typeset fraction. Wrapping formulas in$…$upstream is better still (the boundary then lives in the data), but unwrapped notation works too, since Formula falls back to bare-notation splitting.issuescommunicates uncertain machine extraction and is not decoration. Always pass known issues so untrusted items remain visibly distinct.- The warning uses a left edge instead of tinting the whole card, preserving prompt contrast.
compactnever truncates the prompt or choices; it only hides subparts and footer context.- `showAnswer` defaults to off; never turn it on in the student view. Rendering the key with the card leaks the answer; practice and homework pages only enable it after the server has returned the grading result.
- `type` is a closed seven-value enum, not free text. Short answer, calculation, and extended response are three different types (short, step-scored, comprehensive proof); do not collapse them into
essay. The old four-valuekindis kept for one more minor only.
Related
Playground
<QuestionCard number="3" type="single" stem={"Convert \\frac{3}{8} into a decimal ( )."} />