CardLesson
A card for displaying individual lessons within a module. It shows a branded cover illustration, a subject label and title, a collection of resource icons (built from icon-only Buttons with optional Badges), a status tag and an action button. Supports a default state for available lessons and a blocked state for locked content with an availability date.
Examples
Completed
Pass status="completed" to CardLessonStatus to show the green completion tag. When CardLessonImage has no src, it falls back to the branded Medway illustration. The icon collection uses CardLessonIcons as a wrapper and CardLessonIcon for each resource.
Preview
Started
Pass status="started" to show the amber in-progress tag.
Preview
No status
A lesson without a status tag. The button right-aligns automatically when it is the only footer child.
Preview
Blocked
Set variant="blocked" and pass a required availableDate string. The cover illustration is dimmed, the footer automatically renders a lock tag with the date, and the button is disabled. Icons are also disabled while the lesson is locked.
Preview
Custom cover image
Pass src to CardLessonImage to replace the default illustration with a real thumbnail.
Preview
Horizontal (list view)
Set orientation="horizontal" to lay the card out as a row — thumbnail on the left, label, title and the icon collection in the middle, status tag and action button on the right. Use it to render lessons inside a list. The same sub-components work in both orientations, including the blocked state.
The layout is responsive: below the lg breakpoint it automatically collapses back to the exact vertical layout (full-width cover, same spacing). Resize the preview to see it switch.
Preview
API
CardLesson structure
| Component | Description | Usage |
|---|---|---|
| CardLesson | Vertical root container with border, rounded corners and variant context | Wraps all sub-components and provides variant state to children |
| CardLessonImage | Full-width 153 px cover area with top/horizontal padding. Falls back to the branded Medway illustration when no src is set. Applies opacity-20 in blocked | Omit src for the default illustration, pass src for a custom thumbnail, or add children for a custom placeholder |
| CardLessonContent | Column wrapper with gap-4 and px-6 pt-4 padding | Wraps CardLessonHeader and CardLessonIcons. Place CardLessonFooter as a sibling after this element |
| CardLessonHeader | Tight stack (no gap) for the label and title block | Wraps CardLessonLabel and CardLessonTitle |
| CardLessonLabel | Small text-xs label above the title. Color adapts to variant | Pass the subject label as children |
| CardLessonTitle | Semibold text-lg title with line-clamp-2 and min-h-14. Color adapts to variant (muted when blocked) | Main heading of the lesson item |
| CardLessonIcons | Wrapping flex row (gap-2.5) for the resource icon collection | Wraps one or more CardLessonIcon elements |
| CardLessonIcon | Non-interactive 40×40 circular indicator (gray-background-soft surface, gray-foreground-muted icon) with an optional Badge. No hover or click behavior | Pass an icon and, optionally, a badge count |
| CardLessonDuration | Duration indicator | Pass the duration string as children, e.g. 35 min |
| CardLessonFooter | Sibling to CardLessonContent. justify-between row with px-6 pb-6 pt-4 padding; auto-injects the lock Tag when blocked | Always include CardLessonButton. Optionally include CardLessonStatus |
| CardLessonStatus | Pre-configured Tag. "completed" renders success-soft with a check icon; "started" renders warning-soft | Place inside CardLessonFooter |
| CardLessonButton | Always variant="regular", size="sm", rounded-full, disabled in blocked. Applies ml-auto via :only-child selector when it is the sole footer child | Pass label text via children. Attach onClick for navigation |
CardLesson
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "blocked" | "default" | Controls the visual state of the entire card and all variant-aware sub-components. |
| orientation | "vertical" | "horizontal" | "vertical" | Card layout. "vertical" stacks cover, content and footer; "horizontal" lays them out as a row (thumbnail left, content middle, action right) for list views, collapsing back to the vertical layout below the lg breakpoint. |
| availableDate | string | - | Required when variant="blocked". Displayed in the footer lock tag (e.g. "05/03"). |
| …props | React.ComponentProps<“div”> | - | All native div props are supported. |
CardLessonImage
| Prop | Type | Default | Description |
|---|---|---|---|
| src | string | - | Image URL. When omitted (and no children are passed), the branded Medway illustration is rendered. |
| alt | string | "" | Alt text for the image element. |
| children | React.ReactNode | - | Rendered inside a custom placeholder when provided (takes precedence over the default illustration). |
| …props | React.ComponentProps<“div”> | - | All native div props are supported. |
CardLessonIcon
| Prop | Type | Default | Description |
|---|---|---|---|
| icon | React.ReactNode | - | Required. The icon rendered inside the icon-only button. |
| badge | number | string | - | Optional count rendered as a gray Badge (navy text) in the top-right corner. Hidden when the value is less than 2 (empty, 0, or 1 — a single item doesn’t need a count). |
| …props | React.ComponentProps<“div”> | - | All native div props are supported. The indicator is non-interactive (no hover or click). |
CardLessonStatus
| Prop | Type | Default | Description |
|---|---|---|---|
| status | "completed" | "started" | - | Required. "completed" renders the success-soft Tag with a check icon; "started" renders the warning-soft Tag without an icon. |
| …props | TagProps | - | All Tag props are supported (excluding variant and icon, which are controlled by status). |
CardLessonButton
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | - | Button label text. Required to define the call-to-action. |
| …props | ButtonProps | - | All Button props are supported. Always variant="regular", size="sm", rounded-full. Automatically disabled in blocked. |