Skip to content

Prior study: ui primitives taxonomy — enumerate and normalize the certain set #28

Description

@k08200

Premise (decide first)

From team discussion, ui splits into two systems:

  • use uhura::ui; — unstyled primitives, essentially html. Behavior-purposeful, things anyone can agree on (button).
  • Styled kits as separate opt-in modules (use uhura::shadcnui; as an example). Styled/opinionated components (attachment) are effectively themes, not primitives — attachment appears nowhere in the checked catalog today.

Proposed constraint that keeps this safe: a kit composes and skins primitives but cannot introduce new checked elements — aria, event payloads, and determinism stay in the core, and normalization happens once instead of per kit. Kits mirror onto primitives, so they are not a one-day job; the one-day scope below is primitives only.

Scope fence: this issue stays at the primitive vocabulary layer. The reusable presentation / component contract is #27's "UI composition" question; the kit constraint above touches that boundary and should be decided consistently with it.

Enumeration (the current checked vocabulary, ui_catalog/elements.rs)

element content interactive events (payload) html counterpart
button children yes press (Unit) <button>
input void yes input (TextField), change (BoundaryNumberField) <input>
textfield void yes change (TextField), submit (Unit) <input>
text children no span/p
view children no div
scroll children yes near-end (Unit) overflow div
img void no <img>
video void yes <video>
icon void no — (convention)
region children yes activate, activate-double (Unit) section + button semantics
progress children no <progress>
fieldset children no <fieldset>
pager children yes page-change (Unit) none
Link children yes follow (Unit) <a>
Surface children no dialog-ish, spec gap

Decisions this study should make

  1. input vs textfield overlap. Two input-shaped primitives coexist with different event contracts (typed input/change vs change + submit). One should be canonical, or the split needs a stated rule.
  2. pager. The only interactive element with no html counterpart (scroll snap is a CSS mechanic, not an element). Its page-change payload is Unit — a machine learns that the page changed, never which — and it owns an indicator. Certain set, or does it wait with the compositions (carousel = pager + button, Prior study: Uhura element and widget candidate landscape #19 / docs(studies): carousel and pager candidate study #25)?
  3. Conditional display. <match> (the svg <switch> role) was proposed instead of tabs. Worth enumerating as a candidate; the element name collides with the core match expression keyword, so the markup/expression namespace question needs a call.
  4. Event payload rule. Payload kinds already exist (Unit, TextField, BoundaryNumberField). When is Unit enough (notify) and when must an event carry a value? pager is the current outlier.
  5. Aria ownership. Realizations live in the renderer today (pager → role=group, region → role=button). Is the aria mapping part of the primitive's contract (kits may not override), or renderer discretion?

Out of scope: surfaces/modality. That contract is explicitly undecided in #27, and the play comment-modal misplacement comes from the same gap — it deserves its own track rather than a corner of this one.

Deliverable

One page: primitive × {name + required attributes, event payload, aria realization, static preview pose} — direct input for the ui sub-specification.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions