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-268Done

5.1.4 Mention capability in `MarkdownEditor` + mention-chip rendering in `MarkdownView` (tiptap Mention + `mention:` token round-trip)

Estimate: 30m · Depends on: 5.1.3, 5.1.2

The editor-level mention capability — built into the SHARED MarkdownEditor primitive (2.3.5) so comments (5.1.5) AND the existing description fields (create modal, edit form) gain mentions in one place — the Jira-faithful scope (mentions work in description too). Design-gated UI: carries 5.1.3 in dependsOn (the popup + chip are designed there) and 5.1.2 (the token format + candidate scoping are the service's contract).

Editor side. Add @tiptap/extension-mention (suggestion plugin) to MarkdownEditor: typing @ opens the caret-anchored member listbox from the 5.1.3 design (Combobox option-row vocabulary — Avatar · name · email; filter-as-you-type; ↑/↓/Enter/Esc; aria-activedescendant — the a11y bar the shipped Combobox sets). Candidates come from a mentionCandidates prop the host surface supplies (the detail/comment surfaces pass the issue-scoped viewable members from 5.1.2's candidate read; the primitive itself stays data-source-agnostic and mention support is OFF when the prop is absent — existing consumers are untouched until wired). The mention node serializes to the durable Markdown token [@Display Name](mention:<userId>) via the tiptap-markdown serializer, and parses back on load (round-trip stable — editing a body with mentions preserves them).

Render side. MarkdownView / lib/markdown/render.tsx: allow the mention: protocol through rehype-sanitize (extend the schema's allowed protocols — the default strips unknown schemes) and map mention links to a user chip (the 5.1.3 treatment: accent tint bg + --el-text-strong, finding #35 AA) instead of a navigable anchor. Unknown/stale user ids degrade to plain text of the display name — never a broken link.

Acceptance criteria

  • MarkdownEditor accepts an optional mentionCandidates source; with it, @ opens the designed picker (keyboard-complete, axe-clean) and inserts a mention that serializes to [@Name](mention:<userId>) and round-trips through load→edit→getMarkdown() unchanged; without it, behaviour is byte-identical to today (existing tests untouched).
  • MarkdownView renders mention tokens as the designed chip (no navigation), sanitize still strips every other non-allowlisted protocol (no XSS regression — test javascript: stays dead), and a stale id degrades to plain text.
  • No raw --color-*/Tier-0 utilities; chip + popup colour through --el-*, shape through element tokens (adding tokens per the growth pattern if 5.1.3's notes call for them).
  • Component tests: serialization round-trip, the sanitize allowlist, the picker's keyboard path; pnpm test:coverage holds the gate.

Context refs

  • design/work-items/comments.mock.html + design-notes (5.1.3) — the popup + chip design
  • components/ui/MarkdownEditor.tsx (2.3.5 — tiptap v3 + tiptap-markdown, html: false), lib/markdown/render.tsx + rehype-sanitize schema
  • lib/mentions/parse.ts + the candidate read (5.1.2) — the token format + scoping contract the editor must match
  • components/ui/Combobox.tsx — the option-row + aria-activedescendant vocabulary the popup mirrors