Showcase
Four surfaces built out of root and nothing else - no framework, no CSS classes, no runtime dependency. Each one is live on this page in both color schemes, and the markup under it is the markup running above it: there is no third version of these examples anywhere.
Everything here is flagged Ready for Dev, and these four compositions are what the finished components make - which is a more honest thing to show than a mock-up of the ones that are not. How many are finished is counted on the home page, from the packages themselves; a figure written into this sentence would be wrong the first time one of them is promoted.
A form, composed
Six field types, one composition. Every control is a native element that has been taught to behave: the
label, the box, the hint, the required marker and the invalid state come from one decorator in
@root/core, so a text field, a select, a date picker and a switch line up without anything here
saying how.
The date picker is the platform's own - the user agent draws it, localises it and does the parsing. The
action is inert on this page, which is why it is a type="button".
<form data-part="demo-form">
<input is="root-input" type="text" data-label="Project name" placeholder="Quarterly report" required />
<select is="root-select" data-label="Visibility">
<option value="team">Team</option>
<option value="private">Private</option>
<option value="public">Public</option>
</select>
<input is="root-date-picker" data-label="Due date" value="2026-09-30" />
<input is="root-number" type="number" data-label="Seats" value="8" min="1" max="50" />
<textarea is="root-textarea" data-label="Description" data-hint="Plain text is fine." rows="3"></textarea>
<input is="root-switch" type="checkbox" data-label="Notify the team" />
<button is="root-button" type="button" data-variant="primary" data-color="default">Create project</button>
</form>
A table that sorts, and pages
The table is a <table>. It sorts on the columns marked sortable, selects
rows through
aria-selected, and the paginator beside it is a <nav> of buttons that knows
which page it is on. Neither one holds the data: sorting is the component's, paging is the page's, and what
a real application puts in the rows is its own business.
| Name | Role | Projects |
|---|---|---|
| Ada Lovelace | Owner | 12 |
| Grace Hopper | Editor | 7 |
| Alan Turing | Editor | 9 |
| Katherine Johnson | Reader | 3 |
| Name | Role | Projects |
|---|---|---|
| Ada Lovelace | Owner | 12 |
| Grace Hopper | Editor | 7 |
| Alan Turing | Editor | 9 |
| Katherine Johnson | Reader | 3 |
<table is="root-data-table" selectable alternate>
<thead>
<tr>
<th sortable scope="col">Name</th>
<th sortable scope="col">Role</th>
<th sortable scope="col">Projects</th>
</tr>
</thead>
<tbody>
<tr aria-selected="true"><td>Ada Lovelace</td><td>Owner</td><td>12</td></tr>
<tr><td>Grace Hopper</td><td>Editor</td><td>7</td></tr>
<tr><td>Alan Turing</td><td>Editor</td><td>9</td></tr>
<tr><td>Katherine Johnson</td><td>Reader</td><td>3</td></tr>
</tbody>
</table>
<nav is="root-paginator" aria-label="Team, by page" current="1" total="3">
<button is="root-button" type="button" data-color="default" previous>Previous</button>
<button is="root-button" type="button" data-color="default" data-page="1">1</button>
<button is="root-button" type="button" data-color="default" data-page="2">2</button>
<button is="root-button" type="button" data-color="default" data-page="3">3</button>
<button is="root-button" type="button" data-color="default" next>Next</button>
</nav>
An overlay the platform opens
The close control says "Close" rather than carrying an ✕. That started as a constraint -
root-icon
was not flagged Ready for Dev and everything on this page is - and it outlived the constraint: Icon is
finished now, and a word still beats a glyph on the one control in a dialog that a reader has to find in a
hurry.
The dialog is a <dialog>, and what opens it is the platform's own command attributes -
command
and commandfor on a button, with no script in the page. Focus, the backdrop, the top layer,
Escape and the return focus are all the browser's, which is why none of that is code anybody
here had to write or keep working.
data-size="small"
is 600px, and it is the step this dialog wants: a confirmation is a sentence and two buttons, and the
default 900px gave it a line long enough to read twice.
<button is="root-button" type="button" data-variant="primary" data-color="default" command="show-modal" commandfor="showcase-dialog">
Archive project
</button>
<dialog is="root-dialog" data-size="small" id="showcase-dialog" aria-labelledby="showcase-dialog-title">
<header>
<h2 id="showcase-dialog-title">Move to archive</h2>
<button is="root-button" type="button" data-variant="tertiary" data-color="neutral" command="close" commandfor="showcase-dialog">Close</button>
<p>The project stays searchable and can be restored at any time.</p>
</header>
<div data-part="content">
<p>Archiving hides it from the sidebar for everyone on the team.</p>
</div>
<footer>
<div data-part="actions">
<button is="root-button" type="button" data-variant="secondary" data-color="default" command="close" commandfor="showcase-dialog">Cancel</button>
<button is="root-button" type="button" data-variant="primary" data-color="default" command="close" commandfor="showcase-dialog">Archive</button>
</div>
</footer>
</dialog>
Views, filters and a count
Tabs that move with the arrow keys, a row of filters where the shape carries the state rather than the color
- a selected filter is primary, an unselected one is secondary, which reads for
someone who cannot tell the two colors apart - and a badge carrying a number nobody has to look up.
Twelve open 12
Nothing archived this quarter.
Twelve open 12
Nothing archived this quarter.
<section is="root-tabs" aria-label="Project views">
<nav role="tablist">
<button type="button" role="tab" aria-selected="true">Active</button>
<button type="button" role="tab">Archived</button>
</nav>
<section role="tabpanel">
<span data-part="tags" role="group" aria-label="Filters">
<span is="root-tag" data-variant="primary" data-color="default" tabindex="0">Design</span>
<span is="root-tag" data-variant="secondary" data-color="default" tabindex="0">Engineering</span>
<span is="root-tag" data-variant="secondary" data-color="default" tabindex="0">Research</span>
</span>
<p>Twelve open <span is="root-badge" data-color="success">12</span></p>
</section>
<section role="tabpanel">
<p>Nothing archived this quarter.</p>
</section>
</section>