140Curriculum builder
The course's structure, editable: section blocks with in-place titles and mono lesson-count meta, lesson rows with grip, index, type badge, duration and hover-revealed actions, and the dashed add rows. The learner curriculum is this, read-only.
Use it for
- Building and reordering a course's sections and lessons
- The grip button reorders with ArrowUp/ArrowDown — keyboard first, drag layered on by the app
Not for
- Displaying a curriculum to learners — CurriculumList is the read-only twin
One section
01
What is an org?
video
12:04
02
Lightning navigation
video
14:31
markup
<div class="ns-builder" style="inline-size:100%">
<section class="ns-builder__section">
<header class="ns-builder__head">
<span class="ns-builder__index">01</span>
<input class="ns-builder__title" value="Getting around" aria-label="Section 1 title">
<span class="ns-builder__meta">2 lessons · 26 min</span>
</header>
<div class="ns-builder__row">
<button type="button" class="ns-builder__grip" aria-label="Reorder What is an org?"><i class="ph ph-dots-six-vertical" aria-hidden="true"></i></button>
<span class="ns-builder__index">01</span>
<span class="ns-builder__name">What is an org?</span>
<span class="ns-builder__type">video</span>
<span class="ns-builder__dur">12:04</span>
<span class="ns-builder__rowactions">
<button type="button" class="ns-btn ns-btn--quiet ns-btn--sm ns-btn--icon" aria-label="Edit"><i class="ph ph-pencil-simple" aria-hidden="true"></i></button>
<button type="button" class="ns-btn ns-btn--quiet ns-btn--sm ns-btn--icon" aria-label="Remove"><i class="ph ph-x" aria-hidden="true"></i></button>
</span>
</div>
<div class="ns-builder__row">
<button type="button" class="ns-builder__grip" aria-label="Reorder Lightning navigation"><i class="ph ph-dots-six-vertical" aria-hidden="true"></i></button>
<span class="ns-builder__index">02</span>
<span class="ns-builder__name">Lightning navigation</span>
<span class="ns-builder__type">video</span>
<span class="ns-builder__dur">14:31</span>
<span class="ns-builder__rowactions">
<button type="button" class="ns-btn ns-btn--quiet ns-btn--sm ns-btn--icon" aria-label="Edit"><i class="ph ph-pencil-simple" aria-hidden="true"></i></button>
<button type="button" class="ns-btn ns-btn--quiet ns-btn--sm ns-btn--icon" aria-label="Remove"><i class="ph ph-x" aria-hidden="true"></i></button>
</span>
</div>
<button type="button" class="ns-builder__add"><i class="ph ph-plus" aria-hidden="true"></i> Add lesson</button>
</section>
<button type="button" class="ns-builder__add"><i class="ph ph-plus" aria-hidden="true"></i> Add section</button>
</div>Accessibility contract
- Every grip and row action is a labelled button
- The section title is an input with an explicit aria-label
- Row actions appear on hover AND focus-within — keyboard users get them too