TBX Docs
Exercises

Common patterns

Shared API across all exercises

All built-in exercises share this API. Type-specific props (entries, grids, variants) are documented on each catalogue page.

Layout

Every exercise wraps ExerciseLayout. Pass these to override the default header from the book language:

PropTypeDescription
titleReactNodeHeading shown next to the type icon
descriptionReactNodeSupporting text under the title. Omit for the language default; pass null or false to hide it
infoReactNodeHint shown in an info popover
iconLucideIcon | ReactNodeReplaces the default type icon
<YesNo
  title="True or false"
  description="Answer every statement."
  info="Use what you read on this page."
  entries={[
    { text: "The sky is blue.", answer: true },
  ]}
/>

<YesNo description={null} entries={entries} />

Inline formatting

Display strings (titles, descriptions, info, labels, entry text, clues) accept CommonMark emphasis. Markers are parsed at render time into <em> and <strong>; they are not HTML.

MarkerResult
*italic* or _italic_italic
**bold** or __bold__bold
***both***bold italic

Interior underscores stay literal (snake_case). Unmatched markers and HTML tags (<b>) show as text. For anything richer (images, links, custom markup), pass a ReactNode instead.

True or false
Decide if each statement is accurate.
  • The mitochondria is the powerhouse of the cell.
    Answer for: The mitochondria is the powerhouse of the cell.
  • Water boils at 100°C at sea_level.
    Answer for: Water boils at 100°C at sea_level.
<YesNo
  title="True or **false**"
  description="Decide if each statement is *accurate*."
  entries={[
    { text: "The **mitochondria** is the *powerhouse* of the cell.", answer: true },
    { text: "Water boils at 100°C at sea_level.", answer: true },
  ]}
/>

Do not put emphasis markers in answers, crossword or word-search solutions, grid letters, or MarkWords paragraphs ([word] tokens). Inline blank values (typed answers, dropdown values, drag chips used for matching) are compared as plain strings.

Custom exercises can use the same helper:

import { formatInlineText } from '@bside-tech/tbx-ui';

<span>{formatInlineText(label)}</span>

Labels

Optional overrides for button text, results display, and validator metadata. Supported keys vary by component:

  • YesNo: true, false (Yes/No buttons), check, reset, results
  • Crosswords: across, down for direction labels
  • GroupItems: Group ids from entries for zone headings; items for the common pool
  • InlineDragAndDrop: items for the choice-bank heading
  • Others: check, reset, results (e.g. "correct" in "X / Y correct")

checkOn

  • "manual" (default) — Shows Check/Reset buttons. User validates when ready.
  • "auto" — Validates as soon as answers are provided. No Check button.

Check callbacks

Run arbitrary code when a check succeeds or fails — play a sound, show a notification, log analytics, and so on.

import { toast } from '@heroui/react';

<YesNo
  entries={entries}
  onSuccess={() => toast('Well done', { variant: 'success' })}
  onFailure={() => toast('Try again', { variant: 'danger' })}
/>
PropTypeDescription
onSuccess() => voidCalled when the exercise is checked and all answers are correct
onFailure() => voidCalled when the exercise is checked and at least one answer is wrong

Callbacks fire once per check(), after the overall result is computed. They do not fire on reset, or while the student is still editing (isCorrect is null).

They apply to both checkOn: "manual" and "auto". With "auto", onFailure can run on every answer change — prefer onSuccess, or debounce, if that would be noisy.

FindWords has no Check button. onSuccess runs when the last word is found. onFailure runs when a committed selection matches no remaining word (re-selecting an already found word does nothing).

The same options exist on the exercise hooks (usePickMultiExercise, useFillBlanksExercise, and the others), so custom exercises get the same behaviour.

For page-wide defaults and worked examples (sound, notification, analytics), see Exercise feedback.

ExerciseFeedback

Wrap exercises in <ExerciseFeedback> to set default callbacks once. Per-exercise onSuccess / onFailure override the defaults.

import { ExerciseFeedback, YesNo, PickOne } from '@bside-tech/tbx-ui/components';

<ExerciseFeedback
  onSuccess={playSuccess}
  onFailure={playFail}
>
  <YesNo entries={yesNoEntries} />
  <PickOne entries={pickOneEntries} />
</ExerciseFeedback>

classNames

Object to customize CSS classes for styling individual parts. Each component documents its supported keys (e.g. root, list, item, buttons, checkButton, resetButton, result).

ExerciseGroup integration

All exercises integrate with ExerciseGroup and ExerciseResults for grouped scoring. Wrap multiple exercises in <ExerciseGroup> to get aggregated correct / total counts.

On this page