sveltelean
Versionv0.2.0 GitHub

Policy

  • Native semantics first. Where a native element provides the widget model, the primitive uses it and adds no role. Where it does not (tabs, menu), the contract follows the WAI-ARIA Authoring Practices for that pattern.
  • Correctness before bytes. A change that saves bytes and breaks keyboard navigation, screen reader semantics, focus restoration, disabled behavior, RTL, IME composition or native text editing is invalid. The priority order is correctness, accessibility, developer experience, performance, then bundle size.
  • Tests check behavior, not only attributes: that ArrowRight moves focus, that Home focuses the first tab, that manual activation does not switch the panel, that a disabled trigger is skipped, that nested content does not break routing.
  • Authored ids. Every ARIA relationship uses ids the author wrote, so server-rendered markup is correct before hydration and the same on both sides.
  • Automated checks are necessary and insufficient. axe and keyboard tests are not screen-reader testing, and the site says which of the two it has.

The contract

Every primitive ships a contract.md. The sections below are read from the tabs contract when this site is built; every contract has the same structure, so a missing section is visible as a gap in the file, not as a claim on this page.

  1. Required semantics
  2. Required parts
  3. Options
  4. Keyboard interaction
  5. Focus rules
  6. Disabled behavior
  7. Orientation
  8. RTL
  9. ARIA relationships
  10. Events
  11. Platform features and Baseline
  12. SSR expectations
  13. JS-disabled behavior
  14. Runtime budget
  15. Test cases

The contracts: accordion, alert, alert-dialog, autocomplete, avatar, badge, breadcrumb, button, button-group, calendar, card, carousel, checkbox, color-field, combobox, context-menu, date-field, date-picker, descriptions, dialog, disclosure, drawer, empty, field, file-drop, file-field, hover-card, input, kbd, listbox, menu, menubar, meter, number-field, otp-field, pagination, popover, progress, radio-group, range-slider, rating, scroll-area, segmented, select, separator, skeleton, slider, spinner, splitter, steps, switch, tabs, tag, timeline, toast, toggle, toggle-group, toolbar, tooltip, tree. Native primitives use the same file to document the platform features they rely on, their Baseline status and the fallback (Browser support).

Focus and portal policy

There is no universal focus manager; each primitive has a specific focus contract. Dialog uses the native modal focus behavior: showModal() moves focus in, Tab stays inside because the rest of the document is inert, closing returns focus to the invoker. Tabs use a roving tabindex. Menu focuses the first enabled item on open and returns focus to the invoker on close. The combobox keeps DOM focus in the input and exposes the active option through aria-activedescendant.

There is no portal primitive, no overlay manager and no z-index context: modal dialogs and popovers participate in the browser's top layer. Positioning follows one priority: the implicit anchor relationship of the invoker, then CSS anchor positioning, then the CSS fallback placement. No JavaScript positioning engine is imported by default.

Regression budget

Bundle size is not the only regression the repository blocks. For every interactive primitive the contract's test cases are the checklist; a pull request that changes a behavior runs them in a real browser, and the size budgets are checked in the same gate. A byte saved is never an argument against a failing keyboard test.

Test layers

LayerWhat it provesWhere
Contract testsTier, routed events, registration module and native base of every primitivepackages/primitives/tests/registry.test.ts
Algorithm testsNext and previous enabled item, Home and End, RTL, typeahead matchingpackages/core/tests, packages/primitives/tests/tabs.test.ts, menu.test.ts
Browser interaction testsFocus, dialog, popover, top layer and anchor positioning in a real browserapps/playground/tests/primitives/native.spec.ts, tabs.spec.ts, menu.spec.ts
Keyboard contract testsArrow keys, Home and End, activation modes, disabled skipping, Escape and focus returnapps/playground/tests/primitives/tabs.spec.ts, menu.spec.ts, table/table.spec.ts
JavaScript-disabled testsThe native contracts with page JavaScript offapps/playground/tests/primitives/native.spec.ts
SSR testsServer HTML with authored state and ids; hydration changes nothingapps/playground/tests/ssr.spec.ts, packages/*/tests/ssr.test.ts
Automated accessibility scansNo serious or critical axe violation on every page and on open dialog, popover and menu statesapps/playground/tests/primitives/a11y.spec.ts, apps/docs/tests/routes.spec.ts
Production bundle testsThe shipping invariants against real production outputfixtures/*, apps/playground/tests/bundle.spec.ts

Browser tests run with Playwright, never with a DOM simulation, for anything that involves focus, the top layer or anchor positioning; the unit tests under happy-dom cover the algorithmic part and shim the Popover API where a test needs it.

Test matrix

The status per area and browser as recorded in the claim registry and the audit of 2026-09-27. "Tested in Chromium" means Google Chrome locally and Playwright's Chromium in CI; "not run" means no run has been recorded (the Firefox and WebKit projects run in the nightly workflow; pull-request CI skips them); "not done" means no session has been performed or recorded.

AreaChromiumFirefoxWebKitScreen reader
Keyboardtested in Chromiumnot runnot runnot done
Focustested in Chromiumnot runnot runnot done
axe scantested in Chromiumnot runnot runn/a
RTLtested in Chromium (tabs)not runnot runnot done
Without JavaScripttested in Chromiumnot runnot runn/a
Reduced motionstylesheet rule; no browser testnot runnot runn/a
Forced colorsstylesheet rule; no browser testnot runnot runn/a
Screen reader smokenot donenot donenot donenot done

Recorded Firefox and WebKit runs are a stage 2 requirement and a recorded screen-reader session per primitive (VoiceOver with Safari, NVDA with Chrome or Firefox) a stage 3 requirement in docs/release.md. Until they exist the site says "axe and keyboard tests", not "screen-reader tested", and no cross-browser statement is made.

What is not claimed

  • Screen-reader behavior, in any browser.
  • Behavior in Firefox or WebKit.
  • IME composition handling: no primitive with a text input exists yet.
  • Anything about a Tier 2 primitive: none exists.

Source