State label component
components specs/components/state-label.kmd
The status pill for a code-hosting entity (issue or pull request) whose value is drawn from a per-entity state machine, not a free tag. Distinct from a notification badge (count/dot) and a chip (user-editable filter): a state label is read-only, single-valued, and semantically colored by state. Modeled after GitHub Primer StateLabel. Used by Koder Flow issue lists, PR headers, dashboards, and any surface that shows VCS entity status.
Quando esta spec se aplica
Triggers primários
- Display issue or pull-request status in a code-hosting surface
Todos os triggers
- Show whether an issue/PR is open, closed, merged, or draft
- Render a status pill whose value comes from a fixed state machine
Corpo da especificação
Component — State label
Status: v0.1.0 — Draft. Promoted from the GitHub Primer parity scan (meta/docs/stack #092). Live URL once rendered:
kds.koder.dev/<locale>/components/components-state-label.html. Source: https://primer.style/components/state-label
R1 — What it is (and is not)
A state label is a read-only pill bound to ONE value from a fixed, entity-specific state machine (R2). It is NOT:
- a badge (
specs/components/badges.kmd) — that signals a count/dot; - a chip (
specs/components/chips.kmd) — that is user-editable / a filter input; - a free-text tag/label (issue labels are a separate, multi-valued, user-defined concept).
There is exactly one state label per entity instance.
R2 — State machines (closed sets)
The valid values and their semantics depend on the entity:
Issue
| State | Meaning | Semantic color | Icon |
|---|---|---|---|
Open | Active issue | success (open-green) | issue-opened |
Closed — completed | Resolved as done | done (purple) | issue-closed |
Closed — not planned | Closed without action | neutral (grey) | skip/circle-slash |
Pull request
| State | Meaning | Semantic color | Icon |
|---|---|---|---|
Draft | Not yet ready for review | neutral (grey) | git-pull-request-draft |
Open | Ready / in review | success (open-green) | git-pull-request |
Merged | Merged into target | done (purple) | git-merge |
Closed | Closed unmerged | danger (red) | git-pull-request-closed |
No other values exist. The state is derived from entity data, never set by hand in the view.
R3 — Anatomy
- Pill container with a leading icon + a text label.
- Sized in two scales:
small(inline, in lists/tables) anddefault(entity header). Both keep the icon+label pair. - Fill uses the state's semantic color at the established surface contrast; the label text meets WCAG AA on that fill.
R4 — Color is never the only signal
Each state is distinguished by icon + text label, not color alone (WCAG 1.4.1). The icon shape per row in R2 is mandatory; a state label without its icon is non-conformant.
R5 — Tokens
All fills, text, and icon colors come from Verge semantic tokens
(specs/themes/verge.kmd) — --kds-color-open, --kds-color-done,
--kds-color-danger, --kds-color-neutral (or their canonical names).
No raw hex. Light/dark are handled by the token layer, not by the
component.
R6 — Accessibility
- The label renders its state in words; the icon is decorative
(
aria-hidden) since the text carries meaning. - When used as the accessible name of an entity row, the state is part of that row's label ("Issue #214, Open").
- Non-interactive: a state label is not a button/link. If a surface makes the surrounding row clickable, the click target is the row, not the pill.
R7 — i18n
The visible state label is translated per specs/i18n/contract.kmd
("Open"→"Aberto", "Merged"→"Mesclado", etc.). The underlying state KEY
(used in code/filters) stays stable and language-invariant.
Não-escopo
- User-defined issue labels (multi-valued, colored tags) — separate.
- The state-transition rules themselves (owned by Koder Flow backend).
- Review-decision states (approved / changes-requested) — those belong to
the PR review surface (
specs/components/review spec, #138).
Referências
specs/components/badges.kmdspecs/components/chips.kmdspecs/themes/verge.kmdspecs/i18n/contract.kmd