Skip to content

Single Tab stop toolbars, chat slots, and controllable DataTableCore state - #368

Merged
woksin merged 10 commits into
mainfrom
feature/release-4210
Sep 29, 2026
Merged

woksin merged 10 commits into
mainfrom
feature/release-4210

Conversation

@woksin

@woksin woksin commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Toolbars can offer a single Tab stop, chat hosts can add their own content to messages and the sidebar header, and DataTableCore can have its sort, filter and search state controlled by the host.

Added

  • ToolbarFocusMode.SingleTabStop for Toolbar and ActionMenubar implements the WAI-ARIA toolbar pattern. The toolbar's own tools share one Tab stop, which starts at the first available tool, moves with the arrow keys and returns to the last focused tool. When that tool is disabled, hidden or removed, the Tab stop moves to the next available tool. Controls you add yourself, widgets such as inputs, tools rendered outside the toolbar's markup (for example through a portal), and tools with an explicit tab index keep their own Tab stop. Arrows remains the default until the next major release. (Make toolbars a single Tab stop by default in the next major #353)
  • ChatConversation.renderMessageExtra renders your content under a message body, for example reactions or a notice that a reply failed. ChatSidebar forwards it. (Chat family: no reactions, no failed-reply banner, no ChatSidebar header slot #194)
  • ChatSidebar.renderHeaderActions renders your content between the sidebar title and its close button, and receives the open topic. Neither slot adds markup when you leave it unset. (Chat family: no reactions, no failed-reply banner, no ChatSidebar header slot #194)
  • DataTableCore accepts sort with onSortChange, filters (reported through the existing onFilter), and globalFilter with onGlobalFilterChange, so the host can own that state. When a value is left undefined, the table keeps managing it as before. Set rowProcessing={DataTableRowProcessing.None} to render rows exactly as given when the source has already filtered and sorted them. DataTableSort, DataTableSortDirection and DataTableRowProcessing are exported from @cratis/components/DataTables. (Server mode for query-bound tables: complete-result filtering and sorting before paging #178)

Closes #353, closes #194. Refs #178.

Components-owned tools read their tab index from a toolbar context, so React stays
the only writer of the attribute. The toolbar keeps the active tool in state and
moves it when the tool becomes unavailable. Consumer controls, widgets, and tools
with an explicit tab index keep their own Tab stop. Refs #353.
ChatConversation.renderMessageExtra renders host content under a message body,
for reactions or a failed-reply notice, and ChatSidebar forwards it. The sidebar's
renderHeaderActions renders content between the title and the close button and
receives the open topic. Neither adds markup when unused.
Tools subscribe to the active tool through a stable store, so a focus change
re-renders only the two tools whose tab index changes. Registration changes and
relevant mutations schedule one batched check, so a tool that opts out, is disabled,
or is removed inside its own wrapper hands the Tab stop to the next tool. Adds
wrapper, folder, onFocus, and StrictMode specs and a Toolbar play story.
sort with onSortChange, filters with onFilter, and globalFilter with
onGlobalFilterChange are controllable; undefined keeps today's internal state.
rowProcessing=None renders rows as given when the source already filtered and
sorted them. First step of #178; server mode for the bound tables follows the
Arc fixes.
A tool rendered through a portal or under a nested role=toolbar registered
with the toolbar but could never become active, so it stayed at -1. Such
tools now keep their native Tab stop. A ResizeObserver catches hiding by
stylesheet alone, reconcile checks only the active tool on most renders,
and the docs state that an explicit tabIndex of -1 leaves arrow navigation.
…he documented contracts

A tooltip wrapper builds a new merged ref each render, so React detaches and
re-attaches the same element. Removal now waits for a microtask and a
re-attach of the same element costs nothing. New specs cover ActionMenubar in
SingleTabStop mode and DataTableCore's search and column filter callbacks
through the UI in controlled mode.
@woksin woksin added the minor label Sep 29, 2026
@woksin woksin self-assigned this Sep 29, 2026
@woksin
woksin merged commit b0e00d8 into main Sep 29, 2026
50 of 51 checks passed
@woksin
woksin deleted the feature/release-4210 branch September 29, 2026 07:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make toolbars a single Tab stop by default in the next major Chat family: no reactions, no failed-reply banner, no ChatSidebar header slot

1 participant