# Feature DREAM-846 - Make selection and existing context actions in the Work Packages table fully accessible to keyboard and assistive-technology users

Project: Stream Design System
Status: merged
URL: https://community.openproject.org/work_packages/DREAM-846

## Planning

| Attribute | Value |
| --- | --- |
| Date |  |
| Priority | High |
| Target versions | 18.0.0 |
| Sprint |  |
| Backlog bucket |  |
| Votes |  |
| List | a11y report 2026 |
| Roadmap |  |
| Relevance |  |

## OPEN POINTS / FEEDBACK

| ID | Subject | Status | Decision |
| --- | --- | --- | --- |
| DREAM-860 | Decide grid or treegrid semantics for the work package table | needs clarification |  |
| DREAM-936 | Review Shift+Select All shortcut compatibility | decided | Shift+A is not handled |

## Features and Chunks

| ID | Subject | Type | Status | Assignee | Target versions | Spent time |
| --- | --- | --- | --- | --- | --- | --- |
| DREAM-863 | Backfill table collapse and rerender regression coverage | Implementation | closed |  | 18.0.0 |  |
| DREAM-864 | Backfill table interaction-boundary regression coverage | Implementation | closed |  | 18.0.0 |  |
| DREAM-865 | Backfill table lifecycle and configuration regression coverage | Implementation | closed |  | 18.0.0 |  |
| DREAM-866 | Scope table row lookups to their own table | Implementation | closed |  | 18.0.0 |  |
| DREAM-885 | Treegrid semantics (ARIA roles, states and row model) for the work package table | Implementation | closed |  | 18.0.0 |  |
| DREAM-886 | Focus model and cell navigation for the work package table | Implementation | closed |  | 18.0.0 |  |
| DREAM-892 | Introduce a rendered-occurrence ledger for the wp-fast-table | Implementation | closed |  | 18.0.0 |  |
| DREAM-893 | Reconcile table selection with the settled rendered scope | Implementation | closed |  | 18.0.0 |  |
| DREAM-894 | Keyboard selection, context actions and selection feedback in the work package table | Implementation | closed |  | 18.0.0 |  |
| DREAM-895 | Keyboard interaction with cell controls and editors in the work package table | Implementation | closed |  | 18.0.0 |  |
| DREAM-896 | Keyboard parity in embedded work package table consumers | Implementation | closed |  | 18.0.0 |  |
| DREAM-937 | Leave Ctrl/Cmd+Shift+A to the browser in Select All | Implementation | closed |  | 18.0.0 |  |
| DREAM-938 | Accessible row positions and counts in the work package table | Implementation | closed |  | 18.0.0 |  |
| DREAM-941 | Row-position metadata for hierarchy work package tables | Implementation | rejected |  | 18.0.0 |  |
| DREAM-945 | Expose work package row headers in the table | Implementation | closed |  | 18.0.0 |  |
| DREAM-955 | Give work package table controls accessible tooltips instead of title | Implementation | closed |  | 18.0.0 |  |
| DREAM-959 | Clean up the work package table keyboard code | Implementation | closed |  | 18.0.0 |  |

## Bugs and other work packages

| ID | Type | Subject | Status | Assignee | Target versions | Spent time | Module |
| --- | --- | --- | --- | --- | --- | --- | --- |
| DREAM-897 | Task | Screen-reader verification and release readiness for table keyboard access | to be scheduled | Behrokh Satarnejad | 18.0.0 |  |  |
| DREAM-986 | Bug | Column header hover hides the keyboard focus ring of the table header row | confirmed |  | 18.0.0 |  | Modules and project features / Work packages, Frontend components and Primer design system |
| DREAM-977 | Bug | Table cell interaction: focus edge cases deferred from review | confirmed | Alexander Coles | 18.0.0 |  |  |
| DREAM-947 | Documentation | Document new shortcuts in User Guide | specified |  | 18.0.0 |  | Frontend components and Primer design system, Accessibility, Modules and project features / Work packages |
| DREAM-998 | Bug | BCF viewer split view ignores the j/k table shortcuts | new |  | 18.0.0 |  |  |

## Technical Details

| Attribute | Value |
| --- | --- |
| Module | Frontend components and Primer design system, Modules and project features / Work packages |
| Feature Flag |  |
| Requires doc change | Yes |
| Enterprise plan | Community (COM) |

## Details

| Attribute | Value |
| --- | --- |
| Pull preview |  |
| Mockups |  |
| Accessibility | Yes |

## People

| Attribute | Value |
| --- | --- |
| Assignee |  |
| Accountable |  |
| Product manager |  |
| Developers | OP Dev Dream Team |
| Designer |  |
| Ordered by |  |
| Signed off by |  |
| Interest by |  |

## Estimates and progress

| Attribute | Value |
| --- | --- |
| PD (min) |  |
| PD (max) |  |
| Work |  |
| Labor costs |  |

## Description

**As** a keyboard or screen-reader user working in the work package table  
**I want to** move through rows and cells, select one or several work packages, and open their context actions without a pointer  
**so that** I can do bulk work (move, copy, change status, delete) in the table the same way pointer users can, with the same selection rules as Backlogs.

### Background

Backlogs multi-selection in <mention class="mention" data-id="AGILE-181" data-type="work_package" data-text="#AGILE-181">#AGILE-181</mention> establishes shared pointer and keyboard anchor/range rules. <mention class="mention" data-id="AGILE-423" data-type="work_package" data-text="#AGILE-423">#AGILE-423</mention> and <mention class="mention" data-id="AGILE-424" data-type="work_package" data-text="#AGILE-424">#AGILE-424</mention> track follow-up work for VoiceOver operability and accessible feedback. <mention class="mention" data-id="OP-20196" data-type="work_package" data-text="#OP-20196">#OP-20196</mention>, <mention class="mention" data-id="OP-20382" data-type="work_package" data-text="#OP-20382">#OP-20382</mention> and <mention class="mention" data-id="OP-20383" data-type="work_package" data-text="#OP-20383">#OP-20383</mention> provide the foundations for adopting the same model in the work package table and Angular card view: a test harness, one shared gesture service, and pointer range selection aligned with Backlogs on the shared `BatchSelection` model. DREAM-846 builds on these foundations and coordinates with the accessibility follow-ups.

The table is still not operable without a pointer. Today:

  - Every row and every read-only cell is its own Tab stop. There is no arrow-key navigation.

  - There is no keyboard way to toggle a row or to build a range. The only keyboard selection commands are **Ctrl/Cmd+A** (select all) and **Escape** (clear selection, <mention class="mention" data-id="OP-20331" data-type="work_package" data-text="#OP-20331">#OP-20331</mention>).

  - A dedicated keyboard handler supports **Shift+Alt+F10**, and a separate handler accepts `contextmenu` events. Whether platform and assistive-technology commands reliably open and position the menu through that event path needs browser verification.

  - Selection is conveyed only by a CSS class. It is not exposed to assistive technology, and selection changes are not announced.

  - Nothing prunes the selection when the page, filter or sort order changes, so bulk actions can target work packages that are no longer visible.

This feature delivers the user-facing result of that preparation for the work package table only. Card view and Boards are deferred to separate work.

### Target interaction model

The table provides cell navigation and multi-row selection, following the applicable [WAI-ARIA APG grid](https://www.w3.org/WAI/ARIA/apg/patterns/grid/) or [treegrid](https://www.w3.org/WAI/ARIA/apg/patterns/treegrid/) interaction model. <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> decides the role for flat, grouped and hierarchy modes; collapsibility alone does not settle that choice. Cell navigation is the required baseline in every mode. The Open Point decides whether rows are additionally focusable and defines compatible navigation and expansion keys. Selection remains row-based (`aria-multiselectable`, `aria-selected` on selectable rows).

A plain `<table>` cannot expose row selection: `aria-selected` on rows is only meaningful inside a grid or treegrid. Arrow-key navigation on a plain table would also give application-style keys without telling screen readers to pass those keys through. So the role, the focus model and the selection state belong together, and the grid role must not reach users before every cell is reachable from the keyboard.

### Acceptance criteria

#### Grid semantics

  - The results table is exposed as a grid (or treegrid) with an accessible name, column headers, and `aria-multiselectable="true"`. Sortable column headers expose their sort state.

  - Every selectable row exposes `aria-selected` as `true` or `false`. Group headers, sums and the inline-create row are not selectable and carry no selection state.

  - Collapsible group headers and hierarchy parents expose their expanded state. Rows hidden by a collapsed group or parent are hidden from assistive technology as well.

  - Assistive technology receives consistent row counts and positions across pagination. <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> defines the logical row model for each table mode, including headers, group and sum rows, contextual ancestors, expanded relations, repeated work package occurrences, empty/create rows and collapsed rows. Query-result positions must not be presented as accessible row positions where additional rows make them differ; unknown totals must not be fabricated. Where positions cannot be determined (see Proposed accepted gaps), they are withdrawn, not guessed.

  - The timeline stays hidden from assistive technology, as today.

  - Each work package row exposes a programmatic row header identifying the work package. Screen-reader users can determine both the row and column context of a data cell. This covers <mention class="mention" data-id="OP-12741" data-type="work_package" data-text="#OP-12741">#OP-12741</mention>.

#### Moving through the grid

  - <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> defines which row categories participate in keyboard navigation, including group headers, sums, inline-create and empty-state rows, and how their controls are reached. Navigability, selection eligibility and row counting are separate decisions.

  - The grid has one entry in the page Tab sequence. **Tab** enters at the last focused position (the first navigable row initially; <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> decides whether that becomes the header row). From a focused row or cell, **Tab** walks that row's interactive controls in reading order and leaves the grid after the last one; **Shift+Tab** mirrors it (<mention class="mention" data-id="DREAM-895" data-type="work_package" data-text="#DREAM-895">#DREAM-895</mention>). Inside an engaged editor, **Tab** moves between its controls; at either end it parks the editor with its draft and returns focus to that field's origin cell (<mention class="mention" data-id="DREAM-895" data-type="work_package" data-text="#DREAM-895">#DREAM-895</mention>). Explicit **Enter**/**F2** or pointer interaction re-engages the editor.

  - In cell-navigation mode, **Arrow Up/Down** move to the corresponding cell in the previous/next visible row; **Arrow Left/Right** move between cells of the row; **Home/End** move to the first and last cell of the row; **Page Up/Down** move by a visible page of rows. <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> defines boundary-key behavior, including the destination column for **Ctrl/Cmd+Home/End**, for the chosen role. Any additional row-focus mode has explicit bindings rather than inheriting cell-navigation bindings implicitly.

  - Group and hierarchy expansion/collapse is keyboard operable. <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> records the keys for each supported focus mode and resolves conflicts with cell navigation, default cell actions and inline editing.

  - Navigation skips rows hidden by a collapsed group or hierarchy parent. When the focused row becomes hidden because its group or parent collapses, focus moves to that group header or parent.

  - Moving focus alone never changes the selection and never changes the work package shown in the details pane. Keyboard focus, the range anchor, selection membership and the work package open in the details pane remain four distinct things.

#### Working inside cells

  - Editable cells provide keyboard entry into their inline editor. Cancelling or saving returns focus to the originating cell unless the user explicitly requests onward navigation. A validation error keeps the editor open and focused, with the error announced.

  - <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> defines the keys for entering a cell's controls or editor, moving forwards and backwards between controls and editors, and returning to cell navigation. It specifies first/last-control behavior, cells mixing editable content with buttons or links, and whether Enter activates a default action or enters interaction mode. Tab behavior inside controls/editors is distinguished from Tab leaving the grid in navigation mode.

  - Enabled links and buttons inside a cell (ID link, hierarchy toggle, relation count and context-menu button) remain keyboard operable without adding entries to the page Tab sequence in navigation mode. Inner controls can receive focus in interaction mode. Direct keyboard manual sorting remains outside this feature's scope.

  - Selection is unchanged by entering, saving or cancelling an editor.

#### Selecting with the keyboard

  - **Shift+Arrow Up/Down** resize a range from the anchor, with the same preservation, shrinking and reversal rules as Shift-click in <mention class="mention" data-id="OP-20383" data-type="work_package" data-text="#OP-20383">#OP-20383</mention>. Focus moves between visible rows, but the range includes eligible collapsed rows between the anchor and endpoint in the full rendered order.

  - A keyboard command toggles the row containing the focused cell and makes that occurrence the anchor, including when deselected. <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> records the selection binding for cell navigation and any additional row-focus mode, without taking activation or editing keys away from nested controls. Cell navigation does not imply cell selection.

  - **Ctrl/Cmd+A** selects all selectable rows on the current page, including collapsed rows, and anchors the focused row. Table groups do not form separate selection scopes. Inside editors and other nested controls the shortcut keeps its native meaning.

  - **Escape** clears selection only from table navigation when no active interaction consumes it. Menus, dialogs, inline editors, inner-control interaction and timeline relation/follows selection mode retain their cancellation/exit behavior; the same keypress must not also clear the table selection. When selection is empty, the table selection handler does not consume Escape or stop its propagation, so an enclosing dialog or other owning interaction can handle it.

  - Shortcut recognition follows the shared policy from Backlogs: Cmd on Apple platforms, Ctrl elsewhere, Latin and non-Latin layouts, no interference with composition, dead keys or Alt/AltGraph chords.

  - Pointer and keyboard gestures produce the same selection for the same sequence of steps, and can be mixed within one range session.

#### Context actions

  - Where context menus are enabled, **Shift+F10** and the **Menu** (`ContextMenu`) key open the menu for the focused row, anchored to that row. **Shift+Alt+F10** keeps working. Each invocation opens the menu once, including when a native `contextmenu` event accompanies the keyboard path. Verify platform and assistive-technology context-menu commands, including VoiceOver's context-menu command, without assuming they dispatch identical events.

  - If the focused row is part of the selection, the menu acts on the whole selection. If it is not, the selection is replaced by that row first. This matches right-click today.

  - When the menu closes without an action, focus returns to the cell it was opened from. After an action that re-renders the table, focus lands on the same work package if it is still rendered, otherwise on the nearest remaining row, and never on the document body.

#### When rows change

  - The current page's selection scope includes work packages represented by result rows, contextual ancestor rows and expanded relation rows, including eligible collapsed rows. Membership is deduplicated by work-package identity; it is not restricted to IDs returned directly by the query.

  - Whenever the settled selection scope changes, intersect existing membership with the new scope. This includes pagination, filtering, sorting or grouping across pages, hierarchy-mode changes, creation and deletion; these examples are not exhaustive. Newly appearing work packages are not selected by reconciliation alone. Retain a selection if any eligible occurrence remains, even if the work package is present only as a contextual ancestor or relation row. Bulk actions act only on the retained selection. This applies to pointer and keyboard users alike and changes today's selection-retention behavior.

  - A sort change or a re-render that keeps the same work packages in that scope keeps the selection. A transient loading state is not a removal. Collapsing a group or hierarchy parent preserves selections inside it and keeps them included in bulk actions. Collapse alone must not be treated as removal merely because a rendering mode detaches hidden rows from the DOM.

  - The work package open in the details pane is unaffected by pruning.

  - Selection membership and the range anchor are reconciled separately. Another occurrence can retain a work package's membership without replacing a missing anchor occurrence. If the exact anchor occurrence disappears, clear the anchor; the next Shift gesture follows the no-anchor rule from <mention class="mention" data-id="OP-20383" data-type="work_package" data-text="#OP-20383">#OP-20383</mention>. Clearing an anchor does not by itself deselect the work package.

  - Focus follows the same rule as after a context action.

#### Feedback

  - Accessible selection state and necessary announcements are in scope. A persistent visible selection count is separate work to be coordinated with Backlogs; its deferral does not remove accessible feedback about selection size and scope where needed.

  - Accessible state and, where needed, concise announcements communicate the outcome of toggling, range extension/shrinking/reversal, clearing, Select All and membership changes after rerendering. Changes remain understandable when the selected count stays the same or affected rows do not receive focus. Users can determine the resulting selection size and scope without traversing the whole table; count alone is insufficient feedback for same-count membership changes.

  - Select All feedback states the current-page scope and accounts for included collapsed/contextual rows. Coordinate wording and the balance between state and announcements with <mention class="mention" data-id="AGILE-424" data-type="work_package" data-text="#AGILE-424">#AGILE-424</mention>, avoiding redundant speech. Verify actual screen-reader output for repeated gestures, same-count replacements and menu-triggered selection changes. Messages are translatable and plural-aware; no particular spoken phrase or live announcement on every gesture is mandated.

  - The interaction is verified with NVDA (Firefox and Chrome) and VoiceOver (Safari), with the required screen-reader mode documented.

#### Rollout

  - Deliver this feature in OpenProject 18.0.0 without feature flags. The grid role, focus model, selection state and keyboard selection reach users together, after screen-reader verification. Sequence implementation chunks so that no release contains the grid role with unreachable cells, or keyboard selection without exposed state.

  - Target keyboard access to every enabled feature in embedded consumers of the shared work package table. Inventory (<mention class="mention" data-id="DREAM-896" data-type="work_package" data-text="#DREAM-896">#DREAM-896</mention>): global search results, text-editor table macros, dashboard and My page table widgets, the form query groups (children and related work packages) in the split and full view, and the BIM BCF list. The Relations tab is a Rails Turbo frame, not a consumer of the shared table. Context menus stay disabled in every embedded consumer except the BCF list. Preserve disabled features and existing permissions: a consumer with context menus disabled does not gain them through this work. Card rendering remains outside scope.

  - Each embedded table owns its keyboard events, selection and focus. Shortcuts in one table do not act on another table or on surrounding controls.

### Hints for QA

A more detailed QA plan is still under development. In the meantime:

  - Smoke testing to check for any major regressions can begin.

  - The DREAM team will take care of screen-reader testing as part of <mention class="mention" data-id="DREAM-897" data-type="work_package" data-text="#DREAM-897">#DREAM-897</mention>, after the feature freeze on 11 November, on `release/18.0`.

### Technical notes

  - Reuse the framework-independent `BatchSelection` model and the shared shortcut policy in `core-common`, both already consumed by the table after <mention class="mention" data-id="OP-20383" data-type="work_package" data-text="#OP-20383">#OP-20383</mention>. The Stimulus `sortable-lists` selection orchestrator is bound to Stimulus targets and outlets and is not portable; the Angular side needs its own adapter behind `WorkPackageViewSelectionGesturesService`.

  - The focus owner tracks a (row occurrence, column) position from the start, even where a chunk only wires row movement, so cell navigation does not need a second focus model.

  - The table has several `<tbody>` elements and rows built outside Angular templates by the row builders; grid attributes belong in the builders (`single-row-builder.ts` sets today's per-row `tabindex="0"`; `display-field-renderer.ts` sets per-cell `tabindex="0"` and `role="button"` on editable fields).

  - Collapsed group rows stay in `tableRendered` with `hidden: true` (`grouped-rows-builder.ts`). Navigation must filter on that flag; range and Select All eligibility retain existing collapsed-row inclusion, unchanged by <mention class="mention" data-id="OP-20383" data-type="work_package" data-text="#OP-20383">#OP-20383</mention>. Reuse the shared Sortable Lists anchor and range semantics without importing its list boundaries or movement-permission restrictions into the table.

  - `TableEditForm.reset` re-renders the display cell and refocuses it. The focus owner has to adopt the rebuilt cell instead of losing its position.

  - <mention class="mention" data-id="OP-20384" data-type="work_package" data-text="#OP-20384">#OP-20384</mention> owns the shared Angular selection anchor/focus cleanup and remains a separate prerequisite for the focus-model stage. DREAM-846 builds its table keyboard-focus model on that work without absorbing the shared-service cleanup.

  - <mention class="mention" data-id="DREAM-936" data-type="work_package" data-text="#DREAM-936">#DREAM-936</mention> owns the Ctrl/Cmd+Shift+A compatibility decision across the table, cards and Sortable Lists. DREAM-846 follows the shared policy established there; it does not decide or change that policy independently.

  - Related work: <mention class="mention" data-id="DREAM-858" data-type="work_package" data-text="#DREAM-858">#DREAM-858</mention> defines row indices and counts for `OpPrimer::BorderBoxTableComponent`, including pagination offsets, headers, footers and empty states. Coordinate conventions and testing with that work, while <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> resolves the work package table's additional structural/contextual rows. This reference does not make DREAM-858 a prerequisite or imply reuse of its count formula without validation.

  - Coordinate announcement wording with <mention class="mention" data-id="AGILE-424" data-type="work_package" data-text="#AGILE-424">#AGILE-424</mention> so Backlogs and the table speak the same way. Backlogs strings live in the Backlogs module; the table needs its own frontend translation keys. Backlogs cards deliberately do not use listbox or grid roles (<mention class="mention" data-id="73729" data-type="work_package" data-text="#AGILE-181" data-display-id="AGILE-181">\#AGILE-181</mention>); the table differs because it is tabular data.

  - Implementation chunks. These are dependent stages of the OpenProject 18.0.0 delivery, without feature flags, not independent releases:
    
    1.  Role and interaction model: <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> (interim ruling 2026-10-23: `treegrid` with row-first focus in every mode; open items under Open decisions).
    
    2.  Focus model and cell navigation: <mention class="mention" data-id="DREAM-886" data-type="work_package" data-text="#DREAM-886">#DREAM-886</mention> (depends on <mention class="mention" data-id="OP-20384" data-type="work_package" data-text="#OP-20384">#OP-20384</mention>, delivered separately).
    
    3.  Semantics: treegrid roles and states <mention class="mention" data-id="DREAM-885" data-type="work_package" data-text="#DREAM-885">#DREAM-885</mention>; row positions and counts <mention class="mention" data-id="DREAM-938" data-type="work_package" data-text="#DREAM-938">#DREAM-938</mention>; row headers <mention class="mention" data-id="DREAM-945" data-type="work_package" data-text="#DREAM-945">#DREAM-945</mention>. <mention class="mention" data-id="DREAM-942" data-type="work_package" data-text="#DREAM-942">#DREAM-942</mention> (expanded relation and children columns), <mention class="mention" data-id="DREAM-943" data-type="work_package" data-text="#DREAM-943">#DREAM-943</mention> (positions after a drop) and their Open Point <mention class="mention" data-id="DREAM-944" data-type="work_package" data-text="#DREAM-944">#DREAM-944</mention> moved to the follow-up feature <mention class="mention" data-id="DREAM-996" data-type="work_package" data-text="#DREAM-996">#DREAM-996</mention> (target version 18.1.0) on 2026-11-09; see Proposed accepted gaps.
    
    4.  Selection: settled-scope reconciliation <mention class="mention" data-id="DREAM-893" data-type="work_package" data-text="#DREAM-893">#DREAM-893</mention>; keyboard selection, context actions and selection feedback <mention class="mention" data-id="DREAM-894" data-type="work_package" data-text="#DREAM-894">#DREAM-894</mention>.
    
    5.  Cell interaction: editors, controls and the Tab walk <mention class="mention" data-id="DREAM-895" data-type="work_package" data-text="#DREAM-895">#DREAM-895</mention>.
    
    6.  Embedded consumers: <mention class="mention" data-id="DREAM-896" data-type="work_package" data-text="#DREAM-896">#DREAM-896</mention>, which also removes the development-time staging switch.
    
    7.  Accessible tooltips <mention class="mention" data-id="DREAM-955" data-type="work_package" data-text="#DREAM-955">#DREAM-955</mention>; keyboard code cleanup <mention class="mention" data-id="DREAM-959" data-type="work_package" data-text="#DREAM-959">#DREAM-959</mention> (first chunk to descope if the freeze gets tight; it gates nothing).
    
    8.  Screen-reader verification and release readiness <mention class="mention" data-id="DREAM-897" data-type="work_package" data-text="#DREAM-897">#DREAM-897</mention>; user guide for the new shortcuts <mention class="mention" data-id="DREAM-947" data-type="work_package" data-text="#DREAM-947">#DREAM-947</mention>.

### Open decisions

  - **Role and interaction model:** cell navigation is agreed, and the interim plan on <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> (2026-10-23) ships `treegrid` with row-first focus in every mode, to be confirmed or revised on #DREAM-897's screen-reader evidence. <mention class="mention" data-id="DREAM-860" data-type="work_package" data-text="#DREAM-860">#DREAM-860</mention> still owns the sibling set (`aria-posinset`/`aria-setsize`), the initial entry point, focus after sorting from the column menu, and Arrow Left/Right on group header rows. Navigation, semantics and selection still reach users together under the rollout criteria above.

  - **Row positions in expanded relation and children columns:** the 18.1.0 counting model moved with <mention class="mention" data-id="DREAM-944" data-type="work_package" data-text="#DREAM-944">#DREAM-944</mention> to <mention class="mention" data-id="DREAM-996" data-type="work_package" data-text="#DREAM-996">#DREAM-996</mention>. For 18.0.0 this feature withdraws positions in that state; see Proposed accepted gaps.

  - **Escape clearing scope:** <mention class="mention" data-id="DREAM-940" data-type="work_package" data-text="#DREAM-940">#DREAM-940</mention> revisits whether Escape clears the table selection from anywhere on the page or only from the table's navigation surface.

### Permissions and visibility considerations

  - Visible to every user who can see a work package table. Selection itself needs no permission.

  - Context menu entries keep their existing per-work-package permission checks. Unlike Backlogs, selection is not restricted to movable work packages.

  - Read-only cells remain focusable and readable; they do not open an editor.

### Translation considerations

  - An accessible name for the grid and plural-aware selection-feedback strings, covering size/scope, range changes, clearing and reconciliation as established through screen-reader verification with <mention class="mention" data-id="AGILE-424" data-type="work_package" data-text="#AGILE-424">#AGILE-424</mention>.

  - Key terms to align with Backlogs: "selected", "selection cleared", "work package" / "work packages".

### Proposed accepted gaps (18.0.0)

Proposed 2026-10-31 when <mention class="mention" data-id="DREAM-942" data-type="work_package" data-text="#DREAM-942">#DREAM-942</mention> and <mention class="mention" data-id="DREAM-943" data-type="work_package" data-text="#DREAM-943">#DREAM-943</mention> moved to target version 18.1.0; on 2026-11-09 both moved, with <mention class="mention" data-id="DREAM-944" data-type="work_package" data-text="#DREAM-944">#DREAM-944</mention>, to the follow-up feature <mention class="mention" data-id="DREAM-996" data-type="work_package" data-text="#DREAM-996">#DREAM-996</mention>. Accepting a gap for 18.0.0 needs recorded NVDA/VoiceOver results from <mention class="mention" data-id="DREAM-897" data-type="work_package" data-text="#DREAM-897">#DREAM-897</mention> and feature-owner acceptance; neither exists yet. Until then these are proposals, not decisions. The move does not accept them.

  - While a relation or children column is expanded, every `aria-rowindex` / `aria-rowcount` is withdrawn rather than guessed (<mention class="mention" data-id="DREAM-944" data-type="work_package" data-text="#DREAM-944">#DREAM-944</mention> option 3, proposed; closed by <mention class="mention" data-id="DREAM-942" data-type="work_package" data-text="#DREAM-942">#DREAM-942</mention> in <mention class="mention" data-id="DREAM-996" data-type="work_package" data-text="#DREAM-996">#DREAM-996</mention>; <mention class="mention" data-id="DREAM-897" data-type="work_package" data-text="#DREAM-897">#DREAM-897</mention> P7).

  - After a drop in a manually sorted query, positions stay withdrawn until the next load (closed by <mention class="mention" data-id="DREAM-943" data-type="work_package" data-text="#DREAM-943">#DREAM-943</mention> in <mention class="mention" data-id="DREAM-996" data-type="work_package" data-text="#DREAM-996">#DREAM-996</mention>; <mention class="mention" data-id="DREAM-897" data-type="work_package" data-text="#DREAM-897">#DREAM-897</mention> P10).

### Out of scope

  - A persistent visible selection count: unscheduled separate work to coordinate with Backlogs, with no delivery work package assigned. <mention class="mention" data-id="AGILE-424" data-type="work_package" data-text="#AGILE-424">#AGILE-424</mention> remains the coordination point for accessible feedback, not the owner of the visible count. This follow-up does not block DREAM-846.

  - Row positions while a relation or children column is expanded and after a drop in a manually sorted query: follow-up feature <mention class="mention" data-id="DREAM-996" data-type="work_package" data-text="#DREAM-996">#DREAM-996</mention> (target version 18.1.0; <mention class="mention" data-id="DREAM-942" data-type="work_package" data-text="#DREAM-942">#DREAM-942</mention>, <mention class="mention" data-id="DREAM-943" data-type="work_package" data-text="#DREAM-943">#DREAM-943</mention>, <mention class="mention" data-id="DREAM-944" data-type="work_package" data-text="#DREAM-944">#DREAM-944</mention>). 18.0.0 withdraws positions in those states; see Proposed accepted gaps.

  - Angular shell modernization <mention class="mention" data-id="DREAM-939" data-type="work_package" data-text="#DREAM-939">#DREAM-939</mention>: moved to epic <mention class="mention" data-id="DREAM-874" data-type="work_package" data-text="#DREAM-874">#DREAM-874</mention> as Code maintenance on 2026-10-29 to keep this feature at the minimum for the 18.0.0 feature freeze. It does not gate this feature or <mention class="mention" data-id="DREAM-897" data-type="work_package" data-text="#DREAM-897">#DREAM-897</mention>.

  - Table rendering and focus-layer alternatives (TanStack Table, Angular templates or lit-html, `@angular/aria` grid, `@primer/behaviors` focusZone): evaluated under epic <mention class="mention" data-id="DREAM-874" data-type="work_package" data-text="#DREAM-874">#DREAM-874</mention> (<mention class="mention" data-id="DREAM-965" data-type="work_package" data-text="#DREAM-965">#DREAM-965</mention>, <mention class="mention" data-id="DREAM-946" data-type="work_package" data-text="#DREAM-946">#DREAM-946</mention>) and benchmarked on 2026-10-31. Nothing gates this feature or <mention class="mention" data-id="DREAM-897" data-type="work_package" data-text="#DREAM-897">#DREAM-897</mention>; <mention class="mention" data-id="DREAM-959" data-type="work_package" data-text="#DREAM-959">#DREAM-959</mention> continues in place.

  - Separately implemented tables that do not use the shared work package table component.

  - Shared Angular selection anchor/focus cleanup, delivered separately in <mention class="mention" data-id="OP-20384" data-type="work_package" data-text="#OP-20384">#OP-20384</mention>.

  - The cross-view Ctrl/Cmd+Shift+A compatibility decision, taken separately in <mention class="mention" data-id="DREAM-936" data-type="work_package" data-text="#DREAM-936">#DREAM-936</mention> (the shortcut stays with the browser, <mention class="mention" data-id="DREAM-937" data-type="work_package" data-text="#DREAM-937">#DREAM-937</mention>).

  - Keyboard and accessibility changes to Card view and Boards, deferred to separate work.

  - Pointer selection rules covered by <mention class="mention" data-id="OP-20383" data-type="work_package" data-text="#OP-20383">#OP-20383</mention>, except the agreed current-page selection pruning above.

  - Column selection and cell-range selection (**Ctrl+Space**, **Shift+Arrow Left/Right**). Selection is row-based.

  - Batch drag-and-drop of selected rows and keyboard grab-and-drop, including keyboard manual sorting.

  - Selecting work packages beyond the rendered page (cross-page or whole-query select all).

  - Touch and long-press selection.

  - Timeline (Gantt) keyboard interaction.

  - Keyboard access to the table configuration dialog and column header menus beyond keeping them reachable.

  - Changes to Backlogs behavior.

  - Integration of third-party libraries, such as TanStack Table, with the goal of accelerating delivery (this was evaluated during analysis phase)
