Entity reference — accessibility
Covers all three variants: default, mini and removable.
Keyboard
- With
onOpenthe chip (default or mini) is a real<button type="button">withtabIndex 0(measured), so Tab reaches it and Enter or Space opens the record. - Without
onOpenit is not a button and takes no tab stop — a reference that leads nowhere never pretends to. - There is no shortcut and no arrow-key navigation between chips in a row; each is its own stop.
- Mini in prose: a sentence can contain several tab stops. That is correct — each reference is a separate destination — but keep the count per sentence low, because there is no way to skip them.
- Removable: two tab stops per token, the chip (when
onOpenis given) and the ×, in reading order. The × is hidden until:hoveror:focus-within, so tabbing into a token reveals it. Enter or Space on the × removes the token. Focus then lands wherever the browser puts it — the component does not manage this, so a host removing the last token should move focus deliberately.
ARIA
- No explicit role: the chip is a real button, and its accessible name is the visible name text.
- Default: the identity mark is
aria-hidden, so the announcement is the name alone — which is why the name must never be abbreviated to fit. - The record's type is not announced in any variant. In default it is carried only by the mark's shape and colour; mini draws no mark at all. A screen-reader user hears
Brno Tech a.s.without hearing that it is a company; where the kind matters, the surrounding label has to say it (a rail row's key, a field label). In a sentence there is no such label, so for mini this limit weighs more. dateis inside the button, so it becomes part of the name (Schůzka s Brno Tech 26. 8.), which reads correctly.- Removable: the × carries an
aria-labelfromremoveLabel, defaulting toOdebrat {name}(measuredOdebrat Josef Novák). A bareOdebraton every token makes a row of identical unnamed controls — always include the name. The token wrapper has no role. Removal is not announced. - Nothing announces what opening the chip did — the host owns that.
Focus
- The foundation ring from
ds.cssapplies (outline: 2px solid var(--accent); outline-offset: 1px);.eref-chipdoes not switch it off. Focus ring--accent: 4.44:1 light, 3.83:1 dark. - Mini: the ring is drawn around a 19px inline box with 1px of horizontal padding, so it sits very close to the text. It is the only focus signal, because hover does not tint the ground.
- Removable:
.eref-xhas its own:focus-visiblerule inds.css;:focus-withinon the token keeps the × visible for as long as focus is inside. - The dashed underline is a permanent affordance, not a focus indicator — focus is the ring.
Contrast
Computed from packages/ui/src/tokens/tokens.css:
- Default: name
--ink-900on the canvas — well above AA in both themes. - Mini: name
--fg-secondaryat 12px — 3.93:1 light, 6.20:1 dark. Below AA for normal text in the light theme, and this is a link. Hover lifts it to--ink-900, but hover does not reach keyboard or touch users. - The dashed underline is
--border-strongat rest, darkening on hover (--ink-700default,--ink-500mini). As a 1px decoration it is what marks a mini reference at rest — the right fallback, but a thin one. - Removable: the name inherits the chip's tone; the 13px × inherits
currentColorand needs 3:1 as a non-text control — met with the default chip, under AA with mini in the light theme. - The typed tiles of the default chip are solid grounds with white glyphs; they are decorative and
aria-hidden.
Known limits
- The record type reaches only sighted users, and only in default; it is shape and colour, never words.
- Long names are clipped, and the full value survives only in
title— unavailable to touch users and unreliable for screen readers. - The hover tint and the darkened underline are the only rest→hover signal; at 1px they are subtle.
- Mini at rest is under AA in the light theme.
- Removable: the × is invisible until hover or focus, so on touch it appears only after the first tap; removal is silent to assistive technology; focus after removal is left to the browser.
- Nothing announces the result of activating the chip.