DocsPlatform

Command

A searchable command palette. The machine does the filtering and the grouping, and value, open state and query are three separate bindings, so you can drive any one of them without disturbing the others. All four layers share the one behaviour contract.

Live machine

The shipped commandMachine with two fixture groups, open by default. SET_QUERY filters the flat item list the highlight indexes into.

command · live via createService

query: “

Actions

Navigate

States · walked from the machine

openclosed

Transitions from here · click to send

Context

{
  "open": true,
  "query": "",
  "highlightedIndex": 0,
  "filteredGroups": [
    {
      "heading": "Actions",
      "items": [
        {
          "label": "Deploy to production",
          "value": "deploy"
        },
        {
          "label": "Roll back release",
          "value": "rollback"
        }
      ]
    },
    {
      "heading": "Navigate",
      "items": [
        {
          "label": "Open dashboard",
          "value": "dashboard"
        },
        {
          "label": "Open deployment log",
          "value": "log"
        }
      ]
    }
  ],
  "flatItems": [
    {
      "label": "Deploy to production",
      "value": "deploy"
    },
    {
      "label": "Roll back release",
      "value": "rollback"
    },
    {
      "label": "Open dashboard",
      "value": "dashboard"
    },
    {
      "label": "Open deployment log",
      "value": "log"
    }
  ],
  "modes": {
    "value": "uncontrolled",
    "open": "uncontrolled",
    "query": "uncontrolled"
  }
}

Log · newest first

No events yet — use the component above or send a transition.

The layers

Machine is pure state with no DOM. Headless maps that state to framework-native anatomy and ARIA. Styled keeps the existing Grassroot visual recipe while delegating behaviour. Vanilla mounts the same headless contract without a framework.

Behaviour contract

The machine owns query filtering, group pruning, active-row navigation, and serialisable focus/announcement commands. Adapters translate DOM events and render machine snapshots. Not one of them keeps a second reducer or re-filters the collection behind your back.

  • Controlled bindings emit serialisable change requests, and only adopt the parent's state once it comes back in through input.
  • Uncontrolled bindings commit straight to machine state, and still emit the same request object, so a consumer can watch either way.
  • Keyboard, pointer, focus, dismissal, and accessibility behaviour are shared across vanilla, React, Vue, Solid, Svelte, and Angular.

Evidence

The authoritative source files are:

  • packages/ui-machines/src/command/index.ts
  • packages/ui-headless/core/src/command/command.spec.md
  • packages/ui-headless/core/src/command/vanilla.ts
  • packages/ui-headless/browser-contract/command.contract.ts, the shared browser assertions.
  • Each framework package has a matching browser/command.spec.ts contract entry.