Skip to content

Accessibility, keyboard support and axe auditing

QForm Builder Community 0.1.16 adds a consistent accessibility contract across the catalog, canvas, tree, dialogs and viewing modes.

Keyboard navigation

In the left catalog:

  • Tab focuses an item;
  • Enter or Space adds it to the form;
  • the newly added field then receives focus in the canvas.

In the editing canvas:

  • Tab traverses field overlays;
  • Enter or Space selects the field;
  • Alt + ArrowUp moves the field upward;
  • Alt + ArrowDown moves the field downward.

In the tree:

  • every business node is focusable;
  • Alt + ArrowUp/ArrowDown invokes the same move action as the contextual menu;
  • focus returns to the moved node.

Copy and delete actions are real QBtn controls with accessible names and direct-child QTooltip components.

Click, selection and drag consistency

The canvas uses one interaction session. A simple click selects the field, while a native drag preserves that selection until drop. Post-drag click suppression is tied to the exact source: it neutralizes the browser-generated synthetic click without blocking selection of another field.

Field overlays, contextual actions and step headers are delegated to their dedicated handlers during capture. They never fall through to generic outside-click cleanup, so consuming the dragged source's synthetic click cannot clear another valid selection first.

Keyboard reordering remains independent from pointer drag and keeps its live announcements, focus restoration and Alt + ArrowUp/ArrowDown alternative.

Announcements and focus restoration

The builder contains two visually hidden live regions:

  • a polite region for additions, selections and moves;
  • an assertive region for destructive or high-priority operations.

After closing the Theme Builder, history panel, or import/export dialogs, focus returns to the button that opened the panel.

Custom components nested inside the builder can use the auto-imported composable:

The same composable is available through the public explicit-import subpath:

ts
import { useFormBuilderAccessibility } from '@vevedh/qform-builder-layer/accessibility'
ts
const accessibility = useFormBuilderAccessibility()

accessibility.announce('Configuration applied')
await accessibility.focusField('email')

The composable is safe outside a FormBuilder: its fallback implementation is a no-op.

Readonly and disabled modes

readonly switches the builder to preview and prevents mutations. disabled disables the relevant actions and controls. Both states are covered by the browser accessibility fixture.

Automated audit

The project uses @axe-core/playwright with WCAG A/AA tags through WCAG 2.2 AA.

bash
bun run accessibility:check
bun run e2e:accessibility
bun run release:browser:check

The scenario covers:

  • the editing builder;
  • preview mode;
  • the Theme Builder;
  • import/export dialogs;
  • readonly and disabled modes;
  • keyboard addition and reordering;
  • focus restoration.

An axe violation fails the test and prints the rule identifier, help text, DOM target and failure summary.

Automation limits

An axe audit does not replace human review. Before a release candidate, also verify:

  • reading flow with NVDA or another screen reader;
  • relevance of business labels;
  • tab-order consistency;
  • mouse-free use of complex forms;
  • contrast of host-provided custom themes;
  • 200% zoom and reflow.

Extension contract

A custom element or panel must:

  1. use an appropriate native or Quasar control;
  2. provide an accessible name when visible content is insufficient;
  3. preserve a visible focus indicator;
  4. support Enter and Space when a non-native element behaves as a button;
  5. avoid clickable div elements without role and keyboard support;
  6. restore focus after closing a modal panel;
  7. honor readonly, disabled and prefers-reduced-motion;
  8. add a Playwright scenario whenever a new keyboard workflow is introduced.

QForm Builder — Nuxt 4, Quasar and FormKit layer for dynamic forms.