X-06 · Composites · App components
All elements · Editor on the Composites page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve Editor
Approving as
Lexical rich-text chrome: a Field-like frame with a formatting Toolbar, a content surface with typographic defaults and a status footer.
The specimen below is copied from
editor.html, which shows it inside the app
shell, by bun scripts/design-pages/build-composite-pages.mjs — edit that file, not this
one; --check fails when they drift.
Documents that are not plain rich text open in qf-office, the QEditor host wrapper, as a
standalone dialog.qf-overlay[data-window] window rather than in this surface. The editor
runs in an iframe (qf-office__embed) and draws its own ribbon, canvas and status bar (office mockups); the window header is its title bar, with the app glyph, the file name and the save state. See
DocumentViewer for the full
qf-office axis table and
OverlaySystem for the window contract
(data-window, data-snap, data-ds-open-window).
| Axis | Values |
|---|---|
.qf-editor · __toolbar · __surface ·
__placeholder · __footer
|
regions |
[data-mention] |
inline mention token |
.qf-office[data-kind] · [data-mode] · [data-state] |
the QEditor host wrapper — documented under DocumentViewer |
Assessment notes
Visited the property with @Alex Kim on 14 Aug. The kitchen ceiling shows water staining consistent with the tenant's report; see photo set 3.
- Source: upstairs bathroom, failed seal
- Estimated repair:
£4,250
Recommend approval subject to a second quote.
Guidance
When to use
- Use it for rich-text property values and notes, such as an assessment summary with headings, lists, links and mentions.
- Use it when users need a formatting toolbar, a save status and a word count around the text.
- Use it when users mention colleagues inline with
@tokens. -
Use
qf-officein a window instead when the file is a document, spreadsheet, presentation or PDF rather than plain rich text.
When to consider something else
- Use a multi-line TextField when the value is plain text with no formatting. See TextField.
- Use DocumentViewer to open office files and PDFs in the QEditor host window. See DocumentViewer.
- Use a CommentThread for short threaded replies rather than a formatted body. See CommentThread.
- Use a Ribbon only inside office editors; the rich-text editor uses a single Toolbar. See Ribbon.
Usability
- Keep the toolbar to the formats the content needs: block type, bold, italic, underline, code, lists, quote, link, table, image, undo.
- Show the save state and a word count in
.qf-editor__footer. -
Show
.qf-editor__placeholdertext only while the surface is empty, and keep a separate visible label for the field. - Render mentions as
[data-mention]tokens with the person's full name. -
Open office files in
qf-officeas a window; the window header carries the file name and save state.
- Do not use the rich-text editor for whole office documents.
- Do not rely on toolbar icons alone; every icon button has an accessible name and tooltip.
- Do not show pressed formats only by color; use
aria-pressed.
Accessibility
Keyboard
| Keys | Action |
|---|---|
| Tab | Moves into the toolbar, then to the editing surface; Tab inside the surface must not be captured unless the binding provides an escape such as Escape then Tab. |
| Arrow Left / Arrow Right | The binding must move between toolbar buttons with arrow keys and keep one tab stop for the toolbar (roving tabindex). |
| Ctrl+B / Ctrl+I / Ctrl+U |
The binding must apply bold, italic and underline in the surface (Cmd on Mac) and keep the
toolbar's aria-pressed in sync.
|
| Ctrl+Z | The binding must undo the last change, matching the Undo button. |
| Alt+F10 | The binding should move focus from the surface to the toolbar; Escape returns to the surface. |
Roles and names
-
The toolbar is
role="toolbar"; the binding must give it anaria-labelsuch asFormatting. -
Format buttons are icon-only with
aria-label; toggles (Bold, Italic, Underline, Code) carryaria-pressed. - The block-type select has
aria-label="Block type". -
The surface is
contenteditable; the binding must addrole="textbox",aria-multiline="true"and a name viaaria-labelledbyto the field label. -
Office files run in an
<iframe class="qf-office__embed">whosetitlenames the editor and file; the iframe content owns its own semantics.
Focus
- After a toolbar command, return focus to the surface at the caret.
- The link and image commands must return focus to the surface when their dialogs close.
- Closing an office window returns focus to the file row that opened it; key presses inside the iframe stay with the editor, so the window's Close button must remain reachable.
Other requirements
-
Save state in the footer and in
.qf-office__savemust be announced politely when it changes to saved, offline or error (4.1.3). - Mention tokens must not rely on color alone; the
@and name are text (1.4.1). - Toolbar buttons are small ghost buttons; confirm 24 by 24 CSS pixels (2.5.8).
- Content typed in the surface must reflow at 320 CSS pixels; tables inside may scroll (1.4.10).
Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.
Accessibility tests
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| Area | Automated | A person checks |
|---|---|---|
| General | Passed | Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme. |
| Zoom | Passed | At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping. |
| Keyboard | Passed | Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (5 rows) |
| Screen reader | Passed | With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (5 items) |
Approving. When the checklist passes on the checked run, record it with
bun run a11y:approve -- editor --by "Your name" and commit
a11y/approvals.json with the rebuilt pages.
All test status
Package
Consumers link one stylesheet, css/classic/index.css, which includes every element. The
files below are where this element is defined.
Latest updates
No recorded changes yet.