# Result

The end of a task as one plate: a lens sunk into it with one lamp lit, a verdict, one sentence and what to do next. Green when it worked, amber when it worked with something to check, red when it did not. The verdict is a sentence that says which, so the lamp is only a second sign. When a result appears, focus moves to its verdict, so a keyboard user is where the news is and a screen reader says it.

Kit part · Free · https://tactileui.dev/parts/result

- Element: `<section class="tui-result" role="status">`
- Needs: `kit.css` and `kit.mjs` ([how to install the kit](https://tactileui.dev/docs/installation#the-kit))
- Covers: Result, Task complete
- Categories: Empty states
- Finishes: Aluminium, Graphite, Oak, Walnut, Porcelain, Black, Daylight, Night, Paper, Phosphor, E-paper, AMOLED
- Volumes: Tactile, Quiet

## Variants

### Success · green lamp

```html
<section class="tui-result" data-result="success" role="status" aria-labelledby="rs18" style="width:min(100%,360px)"><div class="tui-result__lens"><span class="tui-lamp" data-on aria-hidden="true"></span></div><h2 class="tui-result__title" id="rs18" tabindex="-1">Payment received</h2><p class="tui-result__text">Your receipt is on its way to your inbox.</p><div class="tui-result__next"><button class="tui-key tui-key--primary" type="button" data-result-next>View the order</button><button class="tui-key tui-key--flat" type="button">Back to shop</button></div></section>
```

### Warning · amber lamp

```html
<section class="tui-result" data-result="warning" role="status" aria-labelledby="rs19" style="width:min(100%,360px)"><div class="tui-result__lens"><span class="tui-lamp" data-lamp="amber" data-on aria-hidden="true"></span></div><h2 class="tui-result__title" id="rs19" tabindex="-1">Imported, with 3 rows skipped</h2><p class="tui-result__text">The other 212 customers are in. The skipped rows have no email address.</p><div class="tui-result__next"><button class="tui-key tui-key--primary" type="button" data-result-next>Review the 3 rows</button><button class="tui-key tui-key--flat" type="button">Done</button></div></section>
```

### Failure · red lamp, role="alert"

```html
<section class="tui-result" data-result="failure" role="alert" aria-labelledby="rs20" style="width:min(100%,360px)"><div class="tui-result__lens"><span class="tui-lamp" data-lamp="red" data-on aria-hidden="true"></span></div><h2 class="tui-result__title" id="rs20" tabindex="-1">The import did not run</h2><p class="tui-result__text">The file is not a spreadsheet Lode can read. Nothing was changed.</p><div class="tui-result__next"><button class="tui-key tui-key--primary" type="button" data-result-next>Choose another file</button><button class="tui-key tui-key--flat" type="button">Cancel</button></div></section>
```

### With small print

```html
<section class="tui-result" data-result="success" role="status" aria-labelledby="rs21" style="width:min(100%,360px)"><div class="tui-result__lens"><span class="tui-lamp" data-on aria-hidden="true"></span></div><h2 class="tui-result__title" id="rs21" tabindex="-1">Payment received</h2><p class="tui-result__text">Your receipt is on its way to your inbox.</p><p class="tui-result__detail">Order 1042 · 6 October, 14:02</p><div class="tui-result__next"><button class="tui-key tui-key--primary" type="button" data-result-next>View the order</button><button class="tui-key tui-key--flat" type="button">Back to shop</button></div></section>
```

### One key only

```html
<section class="tui-result" data-result="success" role="status" aria-labelledby="rs22" style="width:min(100%,360px)"><div class="tui-result__lens"><span class="tui-lamp" data-on aria-hidden="true"></span></div><h2 class="tui-result__title" id="rs22" tabindex="-1">Payment received</h2><p class="tui-result__text">Your receipt is on its way to your inbox.</p><div class="tui-result__next"><button class="tui-key tui-key--primary" type="button" data-result-next>View the order</button></div></section>
```

### Beside the words · .tui-result--row

```html
<section class="tui-result tui-result--row" data-result="warning" role="status" aria-labelledby="rs23" style="width:min(100%,520px)"><div class="tui-result__lens"><span class="tui-lamp" data-lamp="amber" data-on aria-hidden="true"></span></div><h2 class="tui-result__title" id="rs23" tabindex="-1">Imported, with 3 rows skipped</h2><p class="tui-result__text">The other 212 customers are in. The skipped rows have no email address.</p><div class="tui-result__next"><button class="tui-key tui-key--primary" type="button" data-result-next>Review the 3 rows</button><button class="tui-key tui-key--flat" type="button">Done</button></div></section>
```

## Every state

- Success
- Warning
- Failure
- Verdict focused

Hover, pressed and focus are forced with `.is-hover`, `.is-down` and `.is-focus`; checked and disabled are real.

## API

| Name | Kind | Values | What it does |
| - | - | - | - |
| section.tui-result[data-result][role][aria-labelledby] | element | success · warning · failure | The plate. role="status" for success and warning, role="alert" for failure, named by its verdict. |
| .tui-result__lens > .tui-lamp[data-on] | element | green · amber · red | The lens: a round bezel sunk into the plate with one lamp lit in it, hidden from a screen reader. data-lamp is amber or red; green needs none. |
| h2.tui-result__title[tabindex="-1"] | element | the verdict | One short sentence that says how it went (“Payment received”). Focus lands here, so tabindex="-1" is in the markup. |
| .tui-result__text | class | on | One sentence: what it means and what was or was not changed. |
| .tui-result__detail | class | optional, on | Small print: an order number, a time. |
| .tui-result__next | class | the keys | What to do next: one key that matters (the contrast key), and perhaps one flat key. |
| --row | modifier | tui-result--row | The lens beside the words, for a wide and short place; it folds back to a column on a phone. |
| data-no-focus | attribute | on the plate | Stops the plate taking the focus when it appears, for a result shown for reference. |
| showResult(result) | function | needs kit.mjs | Unhides the plate and focuses its verdict. |
| focusResult(result) | function | needs kit.mjs | Focuses the verdict. |
| resultRole(kind) · resultLamp(kind) | function | pure | The ARIA role and the lamp colour for a kind. |

## Markup

```html
<!-- success and warning are role="status"; a failure is role="alert". -->
<section class="tui-result" data-result="success" role="status" aria-labelledby="done">
  <div class="tui-result__lens"><span class="tui-lamp" data-on aria-hidden="true"></span></div>
  <h2 class="tui-result__title" id="done" tabindex="-1">Payment received</h2>
  <p class="tui-result__text">Your receipt is on its way to your inbox.</p>
  <div class="tui-result__next">
    <a class="tui-key tui-key--primary" href="/orders/1042">View the order</a>
    <a class="tui-key tui-key--flat" href="/shop">Back to shop</a>
  </div>
</section>

<!-- Amber: data-lamp="amber" with data-result="warning". Red: data-lamp="red" with data-result="failure" and role="alert". -->
```

```js
import { showResult } from '/kit/kit.mjs';

// A result added to the page, or one that loses its hidden attribute, takes the focus on its own.
host.append(resultElement);

// Or say so yourself:
showResult(document.querySelector('.tui-result'));   // unhides it, focuses the verdict
```

The demo on the page:

```html
<div class="tui-panel" style="width:min(100%,540px);display:grid;gap:16px;text-align:left"><div class="tui-panel__head" style="margin-bottom:0"><span class="tui-label">Customers · Northwind</span></div><div data-rs-host>
  <form class="tui-panel__form" data-rs-form style="display:grid;gap:16px" onsubmit="return false">
    <div class="tui-field"><label class="tui-label" for="rs-file">Spreadsheet</label><input class="tui-input" id="rs-file" value="customers-october.csv" readonly></div>
    <div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap"><span class="tui-label" id="rs-l">Pretend it</span>
      <div class="tui-seg" role="radiogroup" aria-labelledby="rs-l" data-rs-kind><label><input type="radio" name="rs-kind" value="success" checked><span>Worked</span></label><label><input type="radio" name="rs-kind" value="warning"><span>Had a snag</span></label><label><input type="radio" name="rs-kind" value="failure"><span>Failed</span></label></div></div>
    <div><button class="tui-key tui-key--primary" type="button" data-rs-run>Run import</button></div>
  </form>
  <div data-rs-out style="display:grid;gap:16px;justify-items:center" hidden></div>
</div></div>
```

## Usage notes

Pick an outcome and press Run import. The form goes, the result takes its place and focus moves to the verdict: press Tab to reach the keys. Start again brings the form back.

## Accessibility

- Focus moves to the verdict when a result appears: one that is added to the page after it has loaded, or that loses its `hidden`. The verdict has `tabindex="-1"`, so it takes focus from a script but is not a stop of its own, and a screen reader says it at once.
- Success and warning are `role="status"`, read politely. A failure is `role="alert"`, because the person has to know. The plate is named by its verdict with `aria-labelledby`.
- The verdict says how it went in words (“Imported, with 3 rows skipped”), never “Done” alone. The lamp is hidden from a screen reader and the amber and red lamps are never the only sign.
- The next step is a real key in the reading order straight after the sentence, so Tab from the verdict reaches it. The contrast key is the one that matters; the other key is flat.
- Nothing moves; the lamp does not blink. Keys are 44px on a phone, the plate is as wide as its container and never scrolls sideways, and the verdict’s focus ring is 2px.

## How it’s built

The raised plate and bead-blast of a panel, with the recess the kit uses for a well cut into it as a round bezel, and the kit’s lamp enlarged to sit in the middle of it, so every finish draws the lamp as it draws any lamp. The words are the empty state’s: a lead-sized bold title and a sentence in the secondary ink, balanced so they never leave a single word on a line. The focus rule is a small observer in `result.mjs` that waits for the page to finish loading, then focuses the verdict of any plate that arrives or is unhidden.

## Rules

Finish a task with a verdict, one sentence and the one thing to do next, and put the focus where the news is.

The full rules are in `result.rules.md` in the brain, which ships with the Kit.

## Related parts

- [Empty state](https://tactileui.dev/parts/empty-state): What a view shows before it has anything: an empty tray with the outline of what goes in it printed on its floor, one sentence and one key.
- [Alert](https://tactileui.dev/parts/alert): A message let into the surface, with an annunciator: a small lit legend (Note, Done, Check, Fault) beside the words that say what happened.
- [Key](https://tactileui.dev/parts/key): Every button, and every link that acts like one: a cap on a skirt that drops below the plate when pressed.
