# Sync status

A small legend that says whether your work is safe: Saving, Saved or Offline, with a lamp that matches (amber and blinking while it saves, green when it has, red when it cannot). The words are the state and the lamp only agrees with them. It is a polite status region, so changing its words is what a screen reader hears.

Kit part · Free · https://tactileui.dev/parts/sync-status

- Element: `<span class="tui-sync" role="status" data-state>`
- Needs: `kit.css` only, no script ([how to install the kit](https://tactileui.dev/docs/installation#the-kit))
- Categories: Badges & tags
- Finishes: Aluminium, Graphite, Oak, Walnut, Porcelain, Black, Daylight, Night, Paper, Phosphor, E-paper, AMOLED
- Volumes: Tactile, Quiet

## Variants

### Saving · amber, blinking

```html
<span class="tui-sync" role="status" data-state="saving"><span class="tui-lamp" data-on aria-hidden="true"></span><span class="tui-sync__text">Saving…</span> <span class="tui-sync__detail"></span></span>
```

### Saved · green

```html
<span class="tui-sync" role="status" data-state="saved"><span class="tui-lamp" data-on aria-hidden="true"></span><span class="tui-sync__text">Saved</span> <span class="tui-sync__detail"></span></span>
```

### Offline · red

```html
<span class="tui-sync" role="status" data-state="offline"><span class="tui-lamp" data-on aria-hidden="true"></span><span class="tui-sync__text">Offline</span> <span class="tui-sync__detail"></span></span>
```

### With small print

```html
<div style="display:grid;gap:8px"><span class="tui-sync" role="status" data-state="saved"><span class="tui-lamp" data-on aria-hidden="true"></span><span class="tui-sync__text">Saved</span> <span class="tui-sync__detail">2 min ago</span></span><span class="tui-sync" role="status" data-state="offline"><span class="tui-lamp" data-on aria-hidden="true"></span><span class="tui-sync__text">Offline</span> <span class="tui-sync__detail">changes kept on this device</span></span></div>
```

### In the head of a panel

```html
<div class="tui-panel" style="width:min(100%,340px)"><div class="tui-panel__head" style="margin-bottom:0"><span class="tui-label">Settings</span><span class="tui-sync" role="status" data-state="saved"><span class="tui-lamp" data-on aria-hidden="true"></span><span class="tui-sync__text">Saved</span> <span class="tui-sync__detail"></span></span></div></div>
```

## Every state

- Saving
- Saved
- Offline

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 |
| - | - | - | - |
| span.tui-sync[role="status"][data-state] | element | saving · saved · offline | The legend. data-state sets the lamp’s colour and, for saving, its blink. A polite status region. |
| .tui-lamp[data-on][aria-hidden="true"] | element | the kit’s lamp | The lamp. Do not set data-lamp: the legend gives it its colour from data-state. |
| .tui-sync__text · .tui-sync__detail | element | the words · small print | The state in one word, and anything more after it: “2 min ago”, “changes kept on this device”. |
| syncText(state) | function | pure | The words for a state: “Saving…”, “Saved”, “Offline”. |
| setSync(el, state, detail?) | function | needs kit.mjs | Changes data-state and the words together, and does nothing if neither has changed, so the same words are not said twice. |

## Markup

```html
<span class="tui-sync" role="status" data-state="saved">
  <span class="tui-lamp" data-on aria-hidden="true"></span>
  <span class="tui-sync__text">Saved</span>
  <span class="tui-sync__detail">2 min ago</span>
</span>

<!-- Change data-state to "saving" or "offline" and the words with it. -->
```

```js
import { setSync, syncText } from '/kit/kit.mjs';

const legend = document.querySelector('.tui-sync');
setSync(legend, 'saving');                     // lamp amber and blinking, "Saving…"
await save();
setSync(legend, 'saved', 'just now');          // lamp green, "Saved just now"
setSync(legend, 'offline', 'changes kept on this device');

syncText('offline');                            // 'Offline'
```

The demo on the page:

```html
<div class="tui-panel" style="width:min(100%,460px);display:grid;gap:16px;text-align:left"><div class="tui-panel__head" style="margin-bottom:0"><span class="tui-label">Quarterly letter · Draft</span></div><div style="display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap"><span class="tui-label">Draft</span><span class="tui-sync" role="status" data-state="saved" data-sy><span class="tui-lamp" data-on aria-hidden="true"></span><span class="tui-sync__text">Saved</span> <span class="tui-sync__detail">just now</span></span></div>
  <div class="tui-field"><label class="tui-label" for="sy-body">Letter</label><textarea class="tui-textarea" id="sy-body" rows="4" data-sy-body>Dear Dana, thank you for the site visit on Monday.</textarea></div>
  <div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap"><span class="tui-label" id="sy-l">Connection</span>
    <div class="tui-seg" role="radiogroup" aria-labelledby="sy-l" data-sy-conn><label><input type="radio" name="sy-conn" value="online" checked><span>Online</span></label><label><input type="radio" name="sy-conn" value="offline"><span>Offline</span></label></div></div></div>
```

## Usage notes

Type in the box: the legend says Saving while you type and Saved a moment after you stop. Switch the connection to Offline and it says so as soon as you type, and goes back to Saved when you are online again. A screen reader says each change without moving the focus.

## Accessibility

- It is `role="status"`, a polite live region, so a screen reader says “Saving…”, then “Saved”, as the words change, without moving the focus or interrupting what it is reading.
- The state is the word. The lamp is hidden from a screen reader and agrees with the words; amber, green and red are never the only sign, and the three words differ in their first letter and length.
- The blink while it saves is the kit’s lamp blink, 1.2 seconds a step; it stops under reduced motion and the lamp stays lit amber.
- Say Saved only when the work is kept, and Offline as soon as it cannot be. The words are the primary ink and the small print the secondary, both above 4.5:1 on the plate.
- It is not a control and takes no focus; on a phone it is the same size and sits in the line of the thing it describes.

## How it’s built

The status line the kit already has, with its lamp, drawn as a legend whose colour comes from one attribute. The lamp is the kit’s own, so every finish draws it as it draws any lamp, and the blink for saving is the lamp’s own blink. The words are changed by the page, and the script does no more than change the attribute and the words together.

## Rules

Tell someone their work is being kept: three words and a lamp in the head of a document or the foot of a form.

The full rules are in `sync-status.rules.md` in the brain, which ships with the Kit.

## Related parts

- [Status](https://tactileui.dev/parts/status): A lamp with words: the state line in tables, panel heads and lists. The words carry the meaning; the lamp is the glance.
- [Lamp](https://tactileui.dev/parts/lamp): The only colour in the kit: a lamp that is on. Green is on, amber is waiting, red is recording or failing, blue is linked, white is standing by. Always next to words.
- [Toast](https://tactileui.dev/parts/toast): A confirmation after an action: a small plate with a lamp and one factual sentence, read out politely, gone in 3.6 seconds.
- [Spinner](https://tactileui.dev/parts/spinner): A ring of eight lamps lit in turn, a chase round a dial: each lamp is a dim cap with its light laid over it, and the light fades as the chase passes on, leaving a short tail. Only the light’s opacity moves. Amber, the lamp for work in hand. Under reduced motion it holds still on one lit lamp at the top, and the words still say it is busy.
