Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-298Done

5.4.8 `MultiSelectPicker` primitive + Labels & Components rail cards (chips, create-row, caps; the Epic-6-reusable control)

Estimate: 35m · Depends on: 5.4.2, 5.4.3, 5.4.6

The issue-view assignment UI. Two pieces, per the 5.4.6 design:

components/ui/MultiSelectPicker — the generic chip-input primitive the design specifies (value chips + remove ×, type-to-filter input, anchored aria-multiselectable listbox on the OptionRow vocabulary, full keyboard model incl. Backspace-removes-last, optional create-row via an onCreate prop, optional per-value cap, optional per-value tint — chip colour + the option-row swatch dot). PURE + typed-generic (options in, selection out — no fetching), component-tested in isolation, documented for Epic-6 facet reuse. This is the ONE new primitive the story earns (rung-2: nothing multi-select exists; designed in 5.4.6 — not improvised).

Rail cards (in CoreFieldsPanel/siblings, the FieldCard grammar): Labels — the picker with onCreate wired to the folksonomy (typed no-spaces/cap errors inline), options from the bounded searchLabels autocomplete (debounced), chips from the detail read, tinted by the deterministic name-hash (FNV-1a over nameLower mod 6 → the six --el-tint-* pastels, --el-text-strong text — the Story 5.4 label-colour deviation; the pure helper lives beside the picker for Epic-6 reuse); Components — the picker without create (options = listComponents, the empty-project state with the admin link). Both persist via server actions → the 5.4.2/5.4.3 services → router.refresh() (the rail pattern); viewer renders read-only chips. Strings via next-intl.

Acceptance criteria

  • MultiSelectPicker matches the 5.4.6 design (every keyboard/visual state), is axe-clean standalone, pure, and component-tested (toggle/create/cap/Backspace paths); no fetching inside.
  • The Labels card round-trips create/add/remove with the inline 422s; autocomplete is debounced + bounded; case-insensitive match surfaces the existing casing; the same label renders the same hash tint everywhere (deterministic — unit-tested).
  • The Components card assigns/unassigns from the project taxonomy; empty-project + read-only states match the design.
  • Token tiers only; the detail-route axe sweep stays clean; integration tests over both cards; coverage ≥90%.

Context refs

  • design/work-items/labels-components-watch.mock.html + notes (5.4.6) — THE authority
  • 5.4.2/5.4.3 services + routes; CoreFieldsPanel FieldCard + the rail action pattern
  • IssueFilterBar OptionRow + Combobox internals (the listbox/a11y vocabulary to reuse)
  • The i18n threading pattern (en byte-identical)