DOM annotations

The four data-uidex* attributes and the rules for applying them.

Four attributes. All use kebab-case ids. DOM attributes are the sole surface for multi-per-file kinds (elements, regions, widget roots).

Only these four data-uidex* attributes are recognised. Other data-uidex-* attributes are ignored (no warning — this lets teams use adjacent attributes for their own tooling without collision).

data-uidex — every interactive element

uidex scan --audit flags unannotated <button>, <a>, <input>, <select>, <textarea> as INFO diagnostics. Rename carefully — ids are referenced by flow tests.

data-uidex-region — structural regions

HTML5 landmarks (<header>, <nav>, <main>, <aside>, <footer>, role="region") auto-register as regions. Only add data-uidex-region on non-semantic <div> wrappers you want in the registry:

data-uidex-widget — composite behavioural units

Place on the root of a self-contained UI unit with internal state (video player, date picker, rich text editor). The DOM attribute is the runtime boundary; acceptance criteria live on the export const uidex at the component definition.

Widget id duplication rule. The id must appear in both places — on data-uidex-widget="..." at the DOM root (runtime boundary) and on export const uidex = { widget: "..." } (scan-time metadata). The scanner cross-validates: a mismatch or one-sided presence is an error.

Child data-uidex elements are automatically composed onto the widget (via DOM nesting at scan time).

data-uidex-primitive — reusable component definitions

Any .tsx under src/components/ui/** is auto-promoted to a primitive (name = kebab of filename). Add data-uidex-primitive="name" only to opt-in a reusable component that lives outside the convention directory.