Skip to content

feat(parser/renderer): implement badge/pill component with |Label|{.variant} syntax#92

Open
teezeit wants to merge 1 commit intoakonan:mainfrom
teezeit:feat/badge-pills
Open

feat(parser/renderer): implement badge/pill component with |Label|{.variant} syntax#92
teezeit wants to merge 1 commit intoakonan:mainfrom
teezeit:feat/badge-pills

Conversation

@teezeit
Copy link
Copy Markdown
Contributor

@teezeit teezeit commented Apr 21, 2026

Summary

Implements the badge/pill component proposed in the wiremd spec (docs/api/types.md references a BadgeNode that was never wired up). This PR adds the full stack: parser detection, HTML/React/Tailwind renderers, CSS for all 7 styles, tests, and documentation.

Syntax

|Active|
|Active|{.success}
|3|{.warning}
|Failed|{.error}
|New|{.primary}
Status: |Active|{.success}

Variants: success · warning · error · primary · (none = neutral gray)

Why |Label| instead of `Label`{.pill}

The spec proposed backtick-attribute syntax (`Active`{.pill .success}). We evaluated both options and chose |Label| for three reasons:

  1. Backticks are already code in CommonMark. remark tokenises `Active` as an inlineCode node before the wiremd transformer can intercept it. Attaching {.pill} to a backtick span would require forking or patching remark's own tokeniser — fragile and non-standard.

  2. |Label| parses trivially. A single regex (/\|([^|]+)\|(?:\s*\{([^}]*)\})?/) handles detection in any inline context, with no ambiguity against existing wiremd syntax ([buttons], :icons:, [inputs___]).

  3. Visual clarity. In a wireframe source file, |Active|{.success} reads immediately as a distinct inline element. The backtick form looks like inline code, which would confuse readers and conflict with legitimate code spans.

The one trade-off: | is the Markdown table-cell delimiter, so |Label| cannot be used inside a table cell without escaping (\|Label\|). This is documented in the spec and the syntax guide.

Changes

Parser (src/parser/transformer.ts)

  • Detects |Label| and |Label|{.variant} in both plain and rich-content paragraph paths
  • Variant classes (success, warning, error, primary, default) are promoted to props.variant; unrecognised classes remain in props.classes
  • Standalone pill → badge node; mixed with text → paragraph with badge children

Renderers

  • src/renderer/html-renderer.tsrenderBadge()<span class="wmd-badge [wmd-badge-variant]">text</span>
  • src/renderer/react-renderer.ts — same, with className
  • src/renderer/tailwind-renderer.ts — Tailwind utility classes per variant (e.g. bg-green-100 text-green-800)

Styles (src/renderer/styles.ts)

Badge CSS added to all 7 styles, each matching the style's aesthetic:

  • sketch — border + slight rotation
  • clean — soft pastel fills, no border
  • wireframe — grayscale border
  • none — minimal
  • tailwind — full-radius pill, same palette as Tailwind renderer
  • material — chip-style, 16px radius
  • brutal — square corners, thick border, box-shadow

Tests

  • tests/parser.test.ts — 6 badge parsing tests (all variants, mixed text, multiple pills)
  • tests/renderer.test.ts — 5 HTML rendering tests
  • tests/react-renderer.test.ts — 3 React rendering tests
  • tests/tailwind-renderer.test.ts — 5 Tailwind rendering tests

Docs

  • SYNTAX-SPEC-v0.1.md §7.4 — updated from unimplemented backtick spec to |Label| with parser rules and table-cell limitation
  • QUICK-REFERENCE.md — added to component table, disambiguation rules, tips
  • docs/guide/syntax.md — new Badges/Pills section with examples and gotcha

Checklist

  • Tests pass (npm test)
  • TypeScript strict mode (npm run typecheck)
  • Docs updated (SYNTAX-SPEC, QUICK-REFERENCE, guide)
  • Example file added (examples/pills-test.md, pre-rendered for all 7 styles)
  • No changes to unrelated features

Adds inline badges for status labels, counts, and filter chips.
Parser detects |Label| and |Label|{.variant} in both plain and rich-content
paragraphs; renderers (HTML, React, Tailwind) and all 7 CSS styles updated.
Includes 23 new tests and docs updated across SKILL.md, syntax references,
QUICK-REFERENCE.md, SYNTAX-SPEC, and guide.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant