Skip to content

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.

Move to archive

The project stays searchable and can be restored at any time.

Archiving hides it from the sidebar for everyone on the team.

Move to archive

The project stays searchable and can be restored at any time.

Archiving hides it from the sidebar for everyone on the team.

<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.

Design Engineering Research

Twelve open 12

Nothing archived this quarter.

Design Engineering Research

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>